diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 77738287f..000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7ccb96f74..1c6a45a4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,6 @@ -node_modules/ -/.idea/ -#demo.js -#demo.css -.DS_Store -coverage -unit.test.statistic.json -package-lock.json -yarn.lock -*.tgz -dist/ +node_modules +packages/demo/dist +packages/fineui/dist/* +!packages/fineui/dist/font +!packages/fineui/dist/images +.idea/ diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 0f0f7d2e4..000000000 --- a/.npmignore +++ /dev/null @@ -1,44 +0,0 @@ -* -!public/less/*.less -!src/less/**/* -!dist/lib/*.d.ts -!dist/lib/**/*.d.ts -!dist/font.css -!dist/fineui.css -!dist/fineui.js -!dist/fineui.js.map -!dist/fineui.min.css -!dist/fineui_without_normalize.min.css -!dist/fineui.min.js -!dist/fineui.min.js.map -!dist/core.css -!dist/core.js -!dist/resource.css -!dist/resource.js -!dist/utils.js -!dist/utils.js.map -!dist/utils.min.js -!dist/utils.min.js.map -!dist/fineui_without_jquery_polyfill.js -!dist/2.0/fineui.css -!dist/2.0/fineui.js -!dist/2.0/fineui.js.map -!dist/2.0/fineui.min.css -!dist/2.0/fineui.min.js -!dist/2.0/fineui.min.js.map -!dist/2.0/fineui_without_normalize.css -!dist/2.0/fineui_without_normalize.min.css -!dist/font/* -!dist/font/**/* -!dist/images/* -!dist/images/**/* -!dist/router.js -!babel.config.js -!babel.config.ie8.js -!.eslintrc -!dist/2.0/jsy.min.css -!dist/2.0/bi.min.css -!bin/* -!bin/**/* -!plugins/* -!plugins/**/* diff --git a/.npmrc b/.npmrc index 92937ea32..529f7ef76 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ puppeteer_download_host=https://npm.taobao.org/mirrors -@fui:registry=https://npm.fineres.com/ +@fui:registry=https://npm.fineres.com/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..0b2315b16 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "singleQuote": false, + "tabWidth": 4, + "printWidth": 120, + "arrowParens": "avoid", + "endOfLine": "auto" +} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 76cf19ec8..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright©2015-present 帆软软件有限公司 - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 000000000..b050a1689 --- /dev/null +++ b/README @@ -0,0 +1,38 @@ +# FineUI + +[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) + + +> 帆软前端 UI 开发框架。 + +For more details, see the website [http://www.fanruan.com](http://www.fanruan.com). + +## 文档 + +http://fanruan.design/doc.html?post=0169cf558d + +## 开发 + +`pnpm run dev` + +* demo: [http://localhost:3000/](http://localhost:3000/) +* fineui: [http://localhost:9001/fineui.js](http://localhost:9001/fineui.js) + +## 构建 + +`pnpm run build` + +## 自定义less变量构建 + +``` +cd ./packages/fineui +cross-env LESS_CONFIG_PATH=your_less_config.json LESS_FILE_NAME=your_file_name pnpm --filter @fui/core webpack:css +``` + +## 发布 + +@Treecat + +License +============ +Please refer to [LICENSE](https://code.fanruan.com/fanruan/fineui/src/branch/master/LICENSE) file. diff --git a/README.md b/README.md deleted file mode 100644 index d77fa284b..000000000 --- a/README.md +++ /dev/null @@ -1,15 +0,0 @@ -FineUI -============ -[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) -> UI Framework used in FineBI and FineReport - -For more details, see the website [http://www.fanruan.com](http://www.fanruan.com). - -Documentation -============= - -http://fanruan.design/doc.html?post=0169cf558d - -License -============ -Please refer to [LICENSE](https://code.fanruan.com/fanruan/fineui/src/branch/master/LICENSE) file. diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 12cd09e66..000000000 --- a/babel.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@fui/babel-preset-fineui').configs.base; diff --git a/bin/cli/cli.js b/bin/cli/cli.js deleted file mode 100755 index 513024023..000000000 --- a/bin/cli/cli.js +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env node -const yargs = require('yargs/yargs'); -const { hideBin } = require('yargs/helpers'); - -const workerCmd = require('./worker/cli.worker'); - -const argv = yargs(hideBin(process.argv)).argv; - -const cmd = argv._[0]; - -const cmds = new Map([ - ['worker', workerCmd], -]); - -if (!cmd) throw new Error('Command is undefined!'); - -if (cmds.has(cmd)) { - cmds.get(cmd)?.exec(argv); -} else { - throw new Error(`Command ${cmd} not supported`); -} diff --git a/bin/cli/worker/cli.worker.js b/bin/cli/worker/cli.worker.js deleted file mode 100644 index b67513fbb..000000000 --- a/bin/cli/worker/cli.worker.js +++ /dev/null @@ -1,76 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -function first2UpperCase(str) { - return str.toLowerCase().replace(/( |^)[a-z]/g, L => L.toUpperCase()); -} - -function scanAndCreate(structure, workerName, root) { - Object.keys(structure) - .forEach(name => { - if (typeof structure[name] === 'object') { - fs.mkdirSync(path.resolve(root, name)); - - scanAndCreate(structure[name], workerName, path.resolve(root, `./${name}`)); - } else if (structure[name] === '') { - fs.appendFileSync(path.resolve(root, name), ''); - } else if (typeof structure[name] === 'string') { - let content = fs.readFileSync(structure[name]).toString(); - - content = content - .replace(/\${WorkerName}/g, first2UpperCase(workerName)) - .replace(/\${workerName}/g, workerName); - - fs.appendFileSync(path.resolve(root, name), content); - } - }); -} - -module.exports = { - exec: async args => { - if (!args.init) { - throw new Error(`Command init not found in args`); - } - - if (!args.name) { - throw new Error('Command --name=... not found in args'); - } - - const name = args.name; - - const structure = { - [`${name}_worker`]: { - 'main_thread': { - action: { - 'action.worker_ability_test.ts': path.resolve(__dirname, './template/main_thread/action/action.worker_ability_test.t'), - }, - [`${name}_main_thread.ts`]: path.resolve(__dirname, './template/main_thread/main_thread.t'), - }, - utils: { - 'action_type.ts': path.resolve(__dirname, './template/utils/action_type.t'), - 'payload_type.ts': path.resolve(__dirname, './template/utils/payload_type.t'), - }, - 'worker_thread': { - action: { - 'action.worker_ability_test.ts': path.resolve(__dirname, './template/worker_thread/action/action.worker_ability_test.t'), - }, - [`${name}_worker_thread.ts`]: path.resolve(__dirname, './template/worker_thread/worker_thread.t'), - }, - [`${name}_main_thread.helper.ts`]: path.resolve(__dirname, './template/main_thread.helper.t'), - }, - }; - - scanAndCreate(structure, name, args.where ? path.resolve(args.where) : process.cwd()); - }, -}; - -// 结构 -// -xxx_worker -// -|--main_thread -// -|--|--action -// -|--|--xxx_main_thread.ts -// -|--utils -// -|--|--action_type.ts -// -|--worker_thread -// -|--|--action -// -|--|--worker_main_thread.ts diff --git a/bin/cli/worker/template/main_thread.helper.t b/bin/cli/worker/template/main_thread.helper.t deleted file mode 100644 index 2ee06acb7..000000000 --- a/bin/cli/worker/template/main_thread.helper.t +++ /dev/null @@ -1,48 +0,0 @@ -import { ${WorkerName}MainThreadWorker } from './main_thread/${workerName}_main_thread'; -// 不需要一起打包的话则不需要引入这行 -// FuiWorkerPlugin中的属性会同步到fui-worker中,同时支持loader行内传入属性 -// 根据实际需求传入inline,返回格式 true -> blob url,false -> servicePath -import workerUrl from 'fui-worker!./worker_thread/${workerName}_worker_thread'; - -export class ${WorkerName}WorkerHelper { - private worker: ${WorkerName}MainThreadWorker; - - /** - * 拿到helper中的worker - */ - public getWorker() { - if (this.worker) { - return this.worker; - } - - this.worker = BI.Workers.createWorker(${WorkerName}MainThreadWorker, { - workerUrl: this.urlFormatter(workerUrl), - workerName: BI.UUID(), - }); - - return this.worker; - } - - /** - * 格式化worker url,比如补充一些环境信息到参数里 - * 可通过 #hash 将参数传入blob url - * @param url worker url - */ - private urlFormatter(url: string) { - return url; - } - - /** - * 终止worker - */ - public terminate() { - this.worker?.terminate(); - } -} - -// 使用示例 -// const workerHelper = new ${WorkerName}WorkerHelper(); - -// workerHelper.getWorker() -// .testCommunication() -// .then(res => console.log(res)); diff --git a/bin/cli/worker/template/main_thread/action/action.worker_ability_test.t b/bin/cli/worker/template/main_thread/action/action.worker_ability_test.t deleted file mode 100644 index 42425b859..000000000 --- a/bin/cli/worker/template/main_thread/action/action.worker_ability_test.t +++ /dev/null @@ -1,13 +0,0 @@ -import { WorkerAbilityTestActionType } from '../../utils/action_type'; -import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; - -export class WorkerAbilityTestMainThreadAction extends BI.Workers.WorkerBaseAction { - /** - * 通信能力检测 - */ - public communicationTest(): Promise { - const mainThreadPostTime: WorkerAbilityTestPayload['CommunicationTest'] = Date.now(); - - return this.controller.requestPromise(WorkerAbilityTestActionType.CommunicationTest, mainThreadPostTime); - } -} diff --git a/bin/cli/worker/template/main_thread/main_thread.t b/bin/cli/worker/template/main_thread/main_thread.t deleted file mode 100644 index 00fb09177..000000000 --- a/bin/cli/worker/template/main_thread/main_thread.t +++ /dev/null @@ -1,13 +0,0 @@ -import { WorkerAbilityTestMainThreadAction } from './action/action.worker_ability_test'; - -export class ${WorkerName}MainThreadWorker extends BI.Workers.MainThreadWorker { - private communicationTest: WorkerAbilityTestMainThreadAction; - - public initActions(): void { - this.communicationTest = this.createAction(WorkerAbilityTestMainThreadAction); - } - - public testCommunication() { - return this.communicationTest.communicationTest(); - } -} diff --git a/bin/cli/worker/template/utils/action_type.t b/bin/cli/worker/template/utils/action_type.t deleted file mode 100644 index c92de897a..000000000 --- a/bin/cli/worker/template/utils/action_type.t +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Worker 事务标识 - * 每类事务有命名空间, 包含多个具体事务 - */ - -export const enum WorkerAbilityTestActionType { - CommunicationTest = 'CommunicationTest', -} diff --git a/bin/cli/worker/template/utils/payload_type.t b/bin/cli/worker/template/utils/payload_type.t deleted file mode 100644 index 6b9a71509..000000000 --- a/bin/cli/worker/template/utils/payload_type.t +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 跨线程通信各事务的发送数据类型声明 - */ -export interface WorkerAbilityTestPayload { - CommunicationTest: number; -} - -/** - * 跨线程通信各事务的响应数据类型声明 - */ -export interface WorkerAbilityTestReponse { - CommunicationTest: number; -} diff --git a/bin/cli/worker/template/worker_thread/action/action.worker_ability_test.t b/bin/cli/worker/template/worker_thread/action/action.worker_ability_test.t deleted file mode 100644 index f7d1248f4..000000000 --- a/bin/cli/worker/template/worker_thread/action/action.worker_ability_test.t +++ /dev/null @@ -1,24 +0,0 @@ -import { WorkerAbilityTestActionType } from '../../utils/action_type'; -import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; - -export class WorkerAbilityTestWorkerThreadAction extends BI.Workers.WorkerBaseAction { - protected addActionHandler(): void { - this.controller.addActionHandler( - WorkerAbilityTestActionType.CommunicationTest, - this.communicationTest.bind(this) - ); - } - - /** - * 通信能力检测的处理器 - */ - private communicationTest( - payload: WorkerAbilityTestPayload['CommunicationTest'] - ): WorkerAbilityTestReponse['CommunicationTest'] { - const mainThreadPostTime = payload; - // 收到主线程信息的耗时 - const workerGetMessageDuration = Date.now() - mainThreadPostTime; - - return workerGetMessageDuration; - } -} diff --git a/bin/cli/worker/template/worker_thread/worker_thread.t b/bin/cli/worker/template/worker_thread/worker_thread.t deleted file mode 100644 index f437bbc23..000000000 --- a/bin/cli/worker/template/worker_thread/worker_thread.t +++ /dev/null @@ -1,12 +0,0 @@ -// TODO: 这边需要先import fineui资源 -import { WorkerAbilityTestWorkerThreadAction } from './action/action.worker_ability_test'; - -class ${WorkerName}WorkerTreadWorker extends BI.Workers.WorkerThreadWorker { - public communicationTest: WorkerAbilityTestWorkerThreadAction; - - public initActions(): void { - this.communicationTest = this.createAction(WorkerAbilityTestWorkerThreadAction); - } -} - -export const ${workerName}WorkerTreadWorker = BI.Workers.createWorker(${WorkerName}WorkerTreadWorker); diff --git a/changelog.md b/changelog.md deleted file mode 100644 index dbcca9ccd..000000000 --- a/changelog.md +++ /dev/null @@ -1,281 +0,0 @@ -# 更新日志 - -3.0(2022-05) -- 下拉选择框支持清空 - -3.0(2022-03) -- 支持响应式 -- 全面支持Typescript -- 增加JSX支持 -- 布局组件支持更多动态特性 -- 底层API支持动画 -- 增加WebWorker支持 -- 支持路由 -- 插件支持版本控制 -- Fix数据流支持proxy版本 - -2.0(2022-01) -- 提供自定义表单 - -2.0(2021-12) -- 新增Context组件 -- toast支持closable属性,可控制是否显示关闭按钮 -- 新增气泡弹框控件 -- BI.point支持widget添加埋点 -- childContext废弃,替换成provide -- 支持BI.useContext获取上下文环境 -- BI.Msg.alert支持message传json格式 -- 支持BI.config(function(){})进行系统配置 - -2.0(2021-11) -- 限制了复选下拉框一次粘贴添加值个数最大2000 - -2.0(2021-10) -- combo增加window.blur事件触发隐藏 - -2.0(2021-09) -- 支持自动watch -- 支持h函数传递left、right,优化left_right_vertical_adapt布局的jsx写法 -- 新增bi.virtual_group_list组件 - -2.0(2021-07) -- layout支持forceUpdate刷新方式 -- width属性支持calc() -- 修改了颜色选择器交互 -- 新增bi.horizontal_fill、bi.vertical_fill布局 -- 增加module定义插件版本号 -- bubble使用popper.js实现 -- 优化了日期类型控件标红时的报错提示 -- 支持虚拟dom -- 修复了树控件节点未初始化时调用树的getValue始终为空的问题 - -2.0(2021-05) -- 支持搜索的控件支持搜索包含空格的字符串 -- 解决了树列表populate调用两次itemsCreator的问题 - -2.0(2021-03) -- 优化left_right_vertical_adapt布局,去掉float属性只使用flex -- inline布局支持用calc计算fill列宽度 -- 时间类型控件无翻页限制 -- 时间类型控件优化动态时间面板的交互 - -2.0(2021-02) -- 增加beforeRender生命周期函数 - -2.0(2021-01) -- 修改了日期下拉面板中的当前时间按钮的交互效果 -- 新增年区间和年季度区间控件 -- 日期类型控件不操作下拉面板收起不发Confirm事件 -- 日期类型控件全系列可设置是否显示动态日期 -- 日期类型控件全系列可设置最大最小日期 -- 调整了combo的popup显示位置计算逻辑 - -2.0(2020-12) -- multi_layer_down_list_combo支持无限层级 -- 新增不带全选的同步复选下拉框 -- 日期选择控件为年月选择器子组件新增POPUP弹出前事件 -- 文件上传控件新增API(setMaxFileLength)以动态设置最大上传文件数量 -- 复选下拉树显示查看已选效果改成和复选下拉列表一致 -- Pane系列提供small和big两种大小的加载动画 -- 同步树列表系列支持不显示节点连接线和展开收起图标 -- 规范了下拉树trigger中显示值的显示顺序 -- bi.editor支持传入autocomplete -- [视觉]editor水印间距统一与文本域水印不可选中 -- 修复bi.file的url参数拼接问题 -- 修复了colorChooser选择透明后, 打开更多选色面板, 直接点保存会选中自动的问题 -- bi.file支持限制上传文件数 - -2.0(2020-11) -- bi.file上传文件errorMsg默认调用国际化 -- 修复了文本标签text传递空字符串后显示value值的问题 -- 限制了title的最大高度 -- bi.textarea_editor添加setWatermark方法 -- 生命周期可以通过属性传递来操作 -- 修复了颜色选择器hex框不能输入为空的问题 -- 增加纯文本组件bi.pure_text -- store支持webworker,引入多线程机制 -- 修复了Popover小屏幕上看不完整的问题 -- 颜色选择器支持输入16进制颜色编号 -- bi.textarea_editor支持气泡提示报错 - -2.0(2020-10) -- 支持Composition API -- pane和loadingPane支持加载时自定义提示文本 - -2.0(2020-09) -- combo增加click-blur(点击显示,blur消失)作为触发条件功能 -- allCountPager支持是否显示总行数 -- 修复区间滑块setEnable(false)滑块不灰化的问题 -- 修复同步复选下拉框系列setValue所有值后触发器不显示全选的问题 -- BI.Tree.traversal方法迭代函数增加父节点参数 - -2.0(2020-08) -- bi.sign_editor支持显示值居左/居中/居右显示 -- bi.iframe新增EVENT_LOADED事件 -- 修复了searcher在允许搜索的情况下输入空格直接退出搜索的问题 -- 修复了复选下拉系列'点按空格添加完全匹配项'添加的是显示值而非实际值的问题 -- search_text_value_combo支持水印 -- BI.makeObject 方法支持传入iteratee - -2.0(2020-07) -- 修复了日期类型控件先展开切换日期月份面板,再设置区间使得该月份不合法,查看该月份面板灰化不对的问题 -- bi.file文件上传控件accept属性与 [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) 统一 -- 修复了日期类型控件设置一个不在minDate和maxDate之间的日期值时,面板灰化与翻页按钮状态不对的问题 -- BI.OB的on方法返回一个解除监听的函数 -- 修复了grid_view执行_unMount时不调用子组件的_unMount的问题 -- combo新增belowMouse属性,允许popup在点击处弹出 -- combo新增hideWhenAnotherComboOpen属性,开启则其他combo下拉时当前combo收起 -- 修复了datePicker在setValue的时候没有动态刷新可用月份的问题 -- 同步复选下拉及其面板新增getAllValue获取所有已选值 -- 同步复选下拉树及其面板新增getAllValue获取完整的选中树节点 -- 修复date_picker最大值最小值与面板展示判断问题 -- 复选下拉树和下拉列表添加showView和hideVIew方法 -- number_editor支持自动检测数值与范围是否合法 -- 修复了颜色选择器设置值为null的时候,trigger和popup表现不一致的问题 - -2.0(2020-06) -- 修复了复选下拉树半选节点的子节点未加载的时候,点选该半选节点是取消选中的问题 -- 下拉树系列支持isNeedAdjustWidth以动态变化宽度 -- 修复了新增值的下拉控件传递valueFormatter搜索完全匹配项提示新增 -- 修复了选色控件历史记录没有选中的问题的问题 -- 修复了单选下拉框新增值的时候没有发事件的问题 -- 修复了单选标红combo类setValue为空字符串会标红的问题 -- BI.history提供与注册路由对应的卸载路由方法unRoute -- 修复了单选标红combo类setValue为空和空数组行为不一致的问题 -- 单选列表支持新增选项 -- 增加组件shortcut未定义的错误提示 - -2.0(2020-05) -- 修复调用BI.history.navigate(XXX, {trigger: false})时, XXX包含中文空格等字符仍然触发回调的问题 -- 新增BI.after和BI.before方法 -- 修复bi.button设置宽度并配置iconCls后,文本很长的情况下显示截断的问题 -- 填加bi-user-select-enable和bi-user-select-disable通用类名 -- 修复树系列多层半选状态下,勾选祖先节点,后代节点不受影响的问题 -- 修复上传控件多个title问题 - -2.0(2020-04) -- 修复树列表通过空格回到初始面板没有刷新的问题 -- 下拉树系列添加下拉popup弹出前事件 -- 修复了复选下拉勾选值和搜索结果中含有父子串关系时提示不正确的问题 -- searcher提供可配是否支持搜索空格的allSearchBlank -- 修复了复选下拉全选状态下使用空格添加值trigger显示更新不对的问题 -- 复选下拉树展开节点提供分页加载和滚动加载两种方式 -- 修复了复选下拉列表初始化的时候发送执行两次itemsCreator的问题 -- 修复了virtual_list重新populate无效的问题 -- 复选下拉框新增值的时候外抛事件 -- 空格不再编码成  -- 支持文本区域水印可滚动 - -2.0(2020-03) -- 修复了IE9下使用bi.file上传包含特殊字符的excel出错的问题 -- 修复了下拉类型控件不允许编辑的时候没有title的问题 -- 修复了连续多次调用BI.Msg.alert后只有最后弹出的可以关闭的问题 -- 修复了time_combo设置格式为%M:%S后value设置大于30分钟的值时标红的问题 -- 复选下拉树系列展开节点性能优化 - -2.0(2020-02) -- 拓展BI.concat,使其可以拼接多个数组 -- 修复勾选节点不影响父子节点勾选状态的树搜索选中getValue不正常的问题 - -2.0(2020-01) -- 修复单值系滑块滑动松手后发两次EVENT_CHANGE的问题 - -2.0(2019-12) -- 修复多层级单选下拉树主动设置container后搜索面板弹出问题 -- bi.search_editor支持搜索中间含有空格的字符串 -- 修复了监听日期下拉框before_popup_view事件,调用setMinDate无效的问题 -- 修复了数值滑块逆向排列滑块后populate显示效果不对的问题 -- 不影响父节点勾选状态的复选树支持自定义水印和默认值 -- 修复text组件重新设置文本后标红丢失问题 -- 添加无全选按钮的复选下拉框组件 - -2.0(2019-11) -- 日期系列新增setMinDate和setMaxDate接口 -- 修复了同步复选树设置节点默认open后, 叶子节点无法选中的问题 -- 修复了连续多音字搜索可能导致结果异常或者标红异常的问题 -- 新增BI.set(object, path, value)方法 -- getSearchResult兼容了对null值的处理 -- 增加了异步单选下拉树请求完数据后加载完节点后会自动调整宽高的逻辑 - -2.0(2019-10) -- 修改了下拉树展开图标模糊的问题 -- 修复了下拉树搜索高亮字符与正常字符间存在间距的问题 -- 复选下拉系列的计数器从trigger中拆分, 作为独立的部分 -- 增加BI.createElement方法 -- 统一了单选下拉和复选下拉添加自定义值的交互效果 - -2.0(2019-09) -- [视觉]popover弹出框增加圆角 -- 文本列表通过复制粘贴的形式选中值的时候发送事件 -- 修复tree_value_chooser选中节点的唯一子节点后搜索该子节点,无法取消选中的问题 -- button的bubble创建的popup在收起的时候会destroy -- 修复了dynamic_date_pane在切换静态时间和动态时间的时候不会发事件的问题 - -2.0(2019-08) -- 修复valueChooser系列不支持value属性的问题 -- 更新了若干icon-font的样式 -- 修复了单选树同步搜索状态下父节点前可能没有展开符号的问题 -- 单选树可展示并选中不存在的值 -- 树类型下拉新增可搜索实际值的配置 -- 可编辑的combo新增水印配置 -- 单选下拉树同步状态下内置搜索 - -2.0(2019-07) -- 修改了下拉框控件默认值的配色 -- input及其派生编辑控件在PAUSE事件之前会触发CHANGE事件 - -2.0(2019-06) -- 单选下拉树支持搜索与异步加载节点 -- 提供了AES加密方法 - -2.0(2019-05) -- editor类控件新增EVENT_CHANGE_CONFIRM事件 -- 复选下拉控件和树下拉控件支持trigger是否可编辑 -- 时分秒控件支持自定义时间显示格式和是否可编辑 -- 日期/时间/日期区间/时间区间支持自定义日期选择范围和是否可编辑 -- 日期/时间/日期区间/时间区间支持自定义日期显示格式和是否可编辑 -- 增加less函数: 字体资源添加函数addFontRes和字体激活函数activeFont - -> @fontList: "dec", "report"; -> .addFontRes("dec"); -> .addFontRes("report"); -> .activateFont(@fontList); - -以上即可使用自定义的dec,report字体和fineui的资源字体 - -2.0(2019-04) -- 新增`bi.multi_tree_list_combo`控件, 此下拉树勾选节点时不会影响父子节点的勾选状态 -- 新增`bi.multi_tree_insert_combo`控件, 此下拉树可以插入不存在的新值 -- 新增`bi.list_tree_value_chooser_insert_combo`部件, 封装`bi.multi_tree_list_combo`数据处理逻辑 -- 新增`bi.tree_value_chooser_insert_combo`部件, 封装`bi.multi_tree_insert_combo`数据处理逻辑 -- 增加BI.DOM.ready方法 - -2.0(2019-03) -- 新增`bi.time_combo`时分秒控件和`bi.time_periods`时间选择区间,时间区间无有效值校验 -- Label控件增加highlight参数, 可指定初始化标蓝 - -2.0(2019-01) -- 加载更多的单选下拉系列新增allowNoSelect参数配置, 使得可以不选任意一个值 - -2.0(2018-12) -- 增加Button的点击动画和Combo下拉时下拉图标动画 - - -2.0(2018-11) -- 增加`bi.html`和`bi.html_label`类型,text支持html文本,不支持keyword - - -2.0(2018-10) -- popover增加高度自适应,即open的时候回根据内容高度调整popover的高度 - - -2.0(2018-09) -- 增加Fix对configuable为false的对象的不内部构造响应式数据的性能优化处理,例如: - -> this.model.json = Object.freeze({name: "zhang"}); - -只会对this.model.json进行响应式处理,不会对内部的name进行响应式处理 - - -2.0(2018-08) -- 增加BI.mount方法,支持同构 diff --git a/demo/app.js b/demo/app.js deleted file mode 100644 index f15b97c14..000000000 --- a/demo/app.js +++ /dev/null @@ -1,124 +0,0 @@ -Demo = { - version: 1.0 -}; - -BI.EVENT_BLUR = false - -BI.$(function () { - var ref; - - BI.each(Demo.CONFIG, function (index, item) { - !item.id && (item.id = item.value || item.text); - }); - var tree = BI.Tree.transformToTreeFormat(Demo.CONFIG); - - var routes = [{ - path: "/", - component: function () { - return Promise.resolve({ - type: "demo.face" - }); - } - }, { - name: "component", - path: "/component/:componentId", - component: function () { - return Promise.resolve({ - type: "demo.router" - }); - }, - }, { - name: "user", - path: "/user/:name", - component: function () { - return Promise.resolve({ - type: "bi.vtape", - items: [{ - type: "bi.label", - text: "user", - height: 50 - }, { - type: "bi.router_view", - deps: 1, - height: 100 - }, { - type: "bi.router_view", - name: 'tool-buttons', - deps: 1 - }] - }); - }, - children: [{ - path: '', - components: { - default: function () { - return Promise.resolve({ - type: "bi.label", - text: 'home' - }); - }, - } - }, { - name: 'dashboard', - path: 'dashboard', - component: function () { - return Promise.resolve({ - type: "bi.label", - text: 'dashboard' - }); - } - }, { - name: 'tables', - path: 'tables/:id', - components: { - default: function () { - return Promise.resolve({ - type: "bi.label", - text: 'table-view' - }); - }, - "tool-buttons": function () { - return Promise.resolve({ - type: "bi.label", - text: '预览按钮', - }); - }, - } - }] - }]; - - // BI.Tree.traversal(tree, function (index, node) { - // if (!node.children || BI.isEmptyArray(node.children)) { - // routes.push({ - // path: "/", - // component: function () { - // return Promise.resolve({ - // type: node.value - // }); - // } - // }); - // } - // }); - - // var AppRouter = BI.inherit(BI.Router, obj); - // new AppRouter; - // BI.history.start(); - - BI.createWidget({ - type: "bi.router", - ref: function (_ref) { - BI.$router = _ref.$router; - }, - element: "#wrapper", - routes: routes, - render: function () { - return { - type: "demo.main", - ref: function (_ref) { - console.log(_ref); - ref = _ref; - } - }; - } - }); -}); diff --git a/demo/config.js b/demo/config.js deleted file mode 100644 index a20f13ebe..000000000 --- a/demo/config.js +++ /dev/null @@ -1,1584 +0,0 @@ -Demo.CONFIG = Demo.CORE_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG).concat(Demo.COMPONENT_CONFIG).concat(Demo.FIX_CONFIG); - -Demo.CONSTANTS = { - SIMPLE_ITEMS: BI.map("柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂".match(/[^\s]+/g), function (i, v) { - return { - text: v, - value: v, - title: v - }; - }), - ITEMS: BI.map("柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 ".match(/[^\s]+/g), function (i, v) { - return { - text: v, - value: v, - title: v - }; - }), - TREEITEMS: [{ pId: "0", id: "0_0", text: "( 共25个 )", value: "", open: true }, { - pId: "0_0", - id: "0_0_0", - text: "安徽省( 共1个 )", - value: "安徽省", - open: true - }, { pId: "0_0_0", id: "0_0_0_0", text: "芜湖市", value: "芜湖市", open: true }, { - pId: "0_0", - id: "0_0_1", - text: "北京市( 共6个 )", - value: "北京市", - open: true - }, { pId: "0_0_1", id: "0_0_1_0", text: "北京市区", value: "北京市区", open: true }, { - pId: "0_0_1", - id: "0_0_1_1", - text: "朝阳区", - value: "朝阳区", - open: true - }, { pId: "0_0_1", id: "0_0_1_2", text: "东城区", value: "东城区", open: true }, { - pId: "0_0_1", - id: "0_0_1_3", - text: "海淀区4内", - value: "海淀区4内", - open: true - }, { pId: "0_0_1", id: "0_0_1_4", text: "海淀区4外", value: "海淀区4外", open: true }, { - pId: "0_0_1", - id: "0_0_1_5", - text: "石景山区", - value: "石景山区", - open: true - }, { pId: "0_0", id: "0_0_2", text: "福建省( 共2个 )", value: "福建省", open: true }, { - pId: "0_0_2", - id: "0_0_2_0", - text: "莆田市", - value: "莆田市", - open: true - }, { pId: "0_0_2", id: "0_0_2_1", text: "泉州市", value: "泉州市", open: true }, { - pId: "0_0", - id: "0_0_3", - text: "甘肃省( 共1个 )", - value: "甘肃省", - open: true - }, { pId: "0_0_3", id: "0_0_3_0", text: "兰州市", value: "兰州市", open: true }, { - pId: "0_0", - id: "0_0_4", - text: "广东省( 共5个 )", - value: "广东省", - open: true - }, { pId: "0_0_4", id: "0_0_4_0", text: "东莞市", value: "东莞市", open: true }, { - pId: "0_0_4", - id: "0_0_4_1", - text: "广州市", - value: "广州市", - open: true - }, { pId: "0_0_4", id: "0_0_4_2", text: "惠州市", value: "惠州市", open: true }, { - pId: "0_0_4", - id: "0_0_4_3", - text: "深圳市", - value: "深圳市", - open: true - }, { pId: "0_0_4", id: "0_0_4_4", text: "珠海市", value: "珠海市", open: true }, { - pId: "0_0", - id: "0_0_5", - text: "广西壮族自治区( 共1个 )", - value: "广西壮族自治区", - open: true - }, { pId: "0_0_5", id: "0_0_5_0", text: "南宁市", value: "南宁市", open: true }, { - pId: "0_0", - id: "0_0_6", - text: "河北省( 共2个 )", - value: "河北省", - open: true - }, { pId: "0_0_6", id: "0_0_6_0", text: "保定市", value: "保定市", open: true }, { - pId: "0_0_6", - id: "0_0_6_1", - text: "邢台市", - value: "邢台市", - open: true - }, { pId: "0_0", id: "0_0_7", text: "河南省( 共1个 )", value: "河南省", open: true }, { - pId: "0_0_7", - id: "0_0_7_0", - text: "郑州市", - value: "郑州市", - open: true - }, { pId: "0_0", id: "0_0_8", text: "黑龙江省( 共7个 )", value: "黑龙江省", open: true }, { - pId: "0_0_8", - id: "0_0_8_0", - text: "大庆市", - value: "大庆市", - open: true - }, { pId: "0_0_8", id: "0_0_8_1", text: "哈尔滨市", value: "哈尔滨市", open: true }, { - pId: "0_0_8", - id: "0_0_8_2", - text: "鸡西市", - value: "鸡西市", - open: true - }, { pId: "0_0_8", id: "0_0_8_3", text: "佳木斯市", value: "佳木斯市", open: true }, { - pId: "0_0_8", - id: "0_0_8_4", - text: "牡丹江市", - value: "牡丹江市", - open: true - }, { pId: "0_0_8", id: "0_0_8_5", text: "齐齐哈尔市", value: "齐齐哈尔市", open: true }, { - pId: "0_0_8", - id: "0_0_8_6", - text: "双鸭山市", - value: "双鸭山市", - open: true - }, { pId: "0_0", id: "0_0_9", text: "湖北省( 共1个 )", value: "湖北省", open: true }, { - pId: "0_0_9", - id: "0_0_9_0", - text: "武汉市", - value: "武汉市", - open: true - }, { pId: "0_0", id: "0_0_10", text: "湖南省( 共3个 )", value: "湖南省", open: true }, { - pId: "0_0_10", - id: "0_0_10_0", - text: "常德市", - value: "常德市", - open: true - }, { pId: "0_0_10", id: "0_0_10_1", text: "长沙市", value: "长沙市", open: true }, { - pId: "0_0_10", - id: "0_0_10_2", - text: "邵阳市", - value: "邵阳市", - open: true - }, { pId: "0_0", id: "0_0_11", text: "吉林省( 共4个 )", value: "吉林省", open: true }, { - pId: "0_0_11", - id: "0_0_11_0", - text: "白山市", - value: "白山市", - open: true - }, { pId: "0_0_11", id: "0_0_11_1", text: "长春市", value: "长春市", open: true }, { - pId: "0_0_11", - id: "0_0_11_2", - text: "松原市", - value: "松原市", - open: true - }, { pId: "0_0_11", id: "0_0_11_3", text: "通化市", value: "通化市", open: true }, { - pId: "0_0", - id: "0_0_12", - text: "江苏省( 共8个 )", - value: "江苏省", - open: true - }, { pId: "0_0_12", id: "0_0_12_0", text: "常州市", value: "常州市", open: true }, { - pId: "0_0_12", - id: "0_0_12_1", - text: "南京市", - value: "南京市", - open: true - }, { pId: "0_0_12", id: "0_0_12_2", text: "南通市", value: "南通市", open: true }, { - pId: "0_0_12", - id: "0_0_12_3", - text: "苏州市", - value: "苏州市", - open: true - }, { pId: "0_0_12", id: "0_0_12_4", text: "宿迁市", value: "宿迁市", open: true }, { - pId: "0_0_12", - id: "0_0_12_5", - text: "泰州市", - value: "泰州市", - open: true - }, { pId: "0_0_12", id: "0_0_12_6", text: "无锡市", value: "无锡市", open: true }, { - pId: "0_0_12", - id: "0_0_12_7", - text: "盐城市", - value: "盐城市", - open: true - }, { pId: "0_0", id: "0_0_13", text: "辽宁省( 共11个 )", value: "辽宁省", open: true }, { - pId: "0_0_13", - id: "0_0_13_0", - text: "鞍山市", - value: "鞍山市", - open: true - }, { pId: "0_0_13", id: "0_0_13_1", text: "本溪市", value: "本溪市", open: true }, { - pId: "0_0_13", - id: "0_0_13_2", - text: "朝阳市", - value: "朝阳市", - open: true - }, { pId: "0_0_13", id: "0_0_13_3", text: "大连市", value: "大连市", open: true }, { - pId: "0_0_13", - id: "0_0_13_4", - text: "抚顺市", - value: "抚顺市", - open: true - }, { pId: "0_0_13", id: "0_0_13_5", text: "葫芦岛市", value: "葫芦岛市", open: true }, { - pId: "0_0_13", - id: "0_0_13_6", - text: "锦州市", - value: "锦州市", - open: true - }, { pId: "0_0_13", id: "0_0_13_7", text: "辽阳市", value: "辽阳市", open: true }, { - pId: "0_0_13", - id: "0_0_13_8", - text: "盘锦市", - value: "盘锦市", - open: true - }, { pId: "0_0_13", id: "0_0_13_9", text: "沈阳市", value: "沈阳市", open: true }, { - pId: "0_0_13", - id: "0_0_13_10", - text: "营口市", - value: "营口市", - open: true - }, { pId: "0_0", id: "0_0_14", text: "内蒙古( 共1个 )", value: "内蒙古", open: true }, { - pId: "0_0_14", - id: "0_0_14_0", - text: "鄂尔多斯市", - value: "鄂尔多斯市", - open: true - }, { pId: "0_0", id: "0_0_15", text: "宁夏回族自治区( 共1个 )", value: "宁夏回族自治区", open: true }, { - pId: "0_0_15", - id: "0_0_15_0", - text: "银川市", - value: "银川市", - open: true - }, { pId: "0_0", id: "0_0_16", text: "山东省( 共7个 )", value: "山东省", open: true }, { - pId: "0_0_16", - id: "0_0_16_0", - text: "济南市", - value: "济南市", - open: true - }, { pId: "0_0_16", id: "0_0_16_1", text: "济宁市", value: "济宁市", open: true }, { - pId: "0_0_16", - id: "0_0_16_2", - text: "聊城市", - value: "聊城市", - open: true - }, { pId: "0_0_16", id: "0_0_16_3", text: "临沂市", value: "临沂市", open: true }, { - pId: "0_0_16", - id: "0_0_16_4", - text: "青岛市", - value: "青岛市", - open: true - }, { pId: "0_0_16", id: "0_0_16_5", text: "烟台市", value: "烟台市", open: true }, { - pId: "0_0_16", - id: "0_0_16_6", - text: "枣庄市", - value: "枣庄市", - open: true - }, { pId: "0_0", id: "0_0_17", text: "山西省( 共1个 )", value: "山西省", open: true }, { - pId: "0_0_17", - id: "0_0_17_0", - text: "太原市", - value: "太原市", - open: true - }, { pId: "0_0", id: "0_0_18", text: "陕西省( 共1个 )", value: "陕西省", open: true }, { - pId: "0_0_18", - id: "0_0_18_0", - text: "西安市", - value: "西安市", - open: true - }, { pId: "0_0", id: "0_0_19", text: "上海市( 共1个 )", value: "上海市", open: true }, { - pId: "0_0_19", - id: "0_0_19_0", - text: "上海市区", - value: "上海市区", - open: true - }, { pId: "0_0", id: "0_0_20", text: "四川省( 共1个 )", value: "四川省", open: true }, { - pId: "0_0_20", - id: "0_0_20_0", - text: "成都市", - value: "成都市", - open: true - }, { pId: "0_0", id: "0_0_21", text: "新疆维吾尔族自治区( 共2个 )", value: "新疆维吾尔族自治区", open: true }, { - pId: "0_0_21", - id: "0_0_21_0", - text: "吐鲁番地区", - value: "吐鲁番地区", - open: true - }, { pId: "0_0_21", id: "0_0_21_1", text: "乌鲁木齐", value: "乌鲁木齐", open: true }, { - pId: "0_0", - id: "0_0_22", - text: "云南省( 共1个 )", - value: "云南省", - open: true - }, { pId: "0_0_22", id: "0_0_22_0", text: "昆明市", value: "昆明市", open: true }, { - pId: "0_0", - id: "0_0_23", - text: "浙江省( 共5个 )", - value: "浙江省", - open: true - }, { pId: "0_0_23", id: "0_0_23_0", text: "杭州市", value: "杭州市", open: true }, { - pId: "0_0_23", - id: "0_0_23_1", - text: "湖州市", - value: "湖州市", - open: true - }, { pId: "0_0_23", id: "0_0_23_2", text: "嘉兴市", value: "嘉兴市", open: true }, { - pId: "0_0_23", - id: "0_0_23_3", - text: "宁波市", - value: "宁波市", - open: true - }, { pId: "0_0_23", id: "0_0_23_4", text: "绍兴市", value: "绍兴市", open: true }, { - pId: "0_0", - id: "0_0_24", - text: "重庆市( 共1个 )", - value: "重庆市", - open: true - }, { pId: "0_0_24", id: "0_0_24_0", text: "重庆市区", value: "重庆市区", open: true }, { - pId: "0", - id: "0_1", - text: "中国( 共34个 )", - value: "中国", - open: true - }, { pId: "0_1", id: "0_1_0", text: "安徽省( 共19个 )", value: "安徽省", open: true }, { - pId: "0_1_0", - id: "0_1_0_0", - text: "安庆市", - value: "安庆市", - open: true - }, { pId: "0_1_0", id: "0_1_0_1", text: "蚌埠市", value: "蚌埠市", open: true }, { - pId: "0_1_0", - id: "0_1_0_2", - text: "亳州市", - value: "亳州市", - open: true - }, { pId: "0_1_0", id: "0_1_0_3", text: "巢湖市", value: "巢湖市", open: true }, { - pId: "0_1_0", - id: "0_1_0_4", - text: "池州市", - value: "池州市", - open: true - }, { pId: "0_1_0", id: "0_1_0_5", text: "滁州市", value: "滁州市", open: true }, { - pId: "0_1_0", - id: "0_1_0_6", - text: "阜阳市", - value: "阜阳市", - open: true - }, { pId: "0_1_0", id: "0_1_0_7", text: "毫州市", value: "毫州市", open: true }, { - pId: "0_1_0", - id: "0_1_0_8", - text: "合肥市", - value: "合肥市", - open: true - }, { pId: "0_1_0", id: "0_1_0_9", text: "淮北市", value: "淮北市", open: true }, { - pId: "0_1_0", - id: "0_1_0_10", - text: "淮南市", - value: "淮南市", - open: true - }, { pId: "0_1_0", id: "0_1_0_11", text: "黄山市", value: "黄山市", open: true }, { - pId: "0_1_0", - id: "0_1_0_12", - text: "六安市", - value: "六安市", - open: true - }, { pId: "0_1_0", id: "0_1_0_13", text: "马鞍山市", value: "马鞍山市", open: true }, { - pId: "0_1_0", - id: "0_1_0_14", - text: "濮阳市", - value: "濮阳市", - open: true - }, { pId: "0_1_0", id: "0_1_0_15", text: "宿州市", value: "宿州市", open: true }, { - pId: "0_1_0", - id: "0_1_0_16", - text: "铜陵市", - value: "铜陵市", - open: true - }, { pId: "0_1_0", id: "0_1_0_17", text: "芜湖市", value: "芜湖市", open: true }, { - pId: "0_1_0", - id: "0_1_0_18", - text: "宣城市", - value: "宣城市", - open: true - }, { pId: "0_1", id: "0_1_1", text: "澳门特别行政区( 共1个 )", value: "澳门特别行政区", open: true }, { - pId: "0_1_1", - id: "0_1_1_0", - text: "澳门", - value: "澳门", - open: true - }, { pId: "0_1", id: "0_1_2", text: "北京市( 共17个 )", value: "北京市", open: true }, { - pId: "0_1_2", - id: "0_1_2_0", - text: "北京市区", - value: "北京市区", - open: true - }, { pId: "0_1_2", id: "0_1_2_1", text: "昌平区", value: "昌平区", open: true }, { - pId: "0_1_2", - id: "0_1_2_2", - text: "朝阳区", - value: "朝阳区", - open: true - }, { pId: "0_1_2", id: "0_1_2_3", text: "大兴区", value: "大兴区", open: true }, { - pId: "0_1_2", - id: "0_1_2_4", - text: "东城区", - value: "东城区", - open: true - }, { pId: "0_1_2", id: "0_1_2_5", text: "房山区", value: "房山区", open: true }, { - pId: "0_1_2", - id: "0_1_2_6", - text: "丰台区", - value: "丰台区", - open: true - }, { pId: "0_1_2", id: "0_1_2_7", text: "海淀区", value: "海淀区", open: true }, { - pId: "0_1_2", - id: "0_1_2_8", - text: "海淀区4内", - value: "海淀区4内", - open: true - }, { pId: "0_1_2", id: "0_1_2_9", text: "海淀区4外", value: "海淀区4外", open: true }, { - pId: "0_1_2", - id: "0_1_2_10", - text: "门头沟区", - value: "门头沟区", - open: true - }, { pId: "0_1_2", id: "0_1_2_11", text: "平谷区", value: "平谷区", open: true }, { - pId: "0_1_2", - id: "0_1_2_12", - text: "石景山区", - value: "石景山区", - open: true - }, { pId: "0_1_2", id: "0_1_2_13", text: "顺义区", value: "顺义区", open: true }, { - pId: "0_1_2", - id: "0_1_2_14", - text: "通州区", - value: "通州区", - open: true - }, { pId: "0_1_2", id: "0_1_2_15", text: "西城区", value: "西城区", open: true }, { - pId: "0_1_2", - id: "0_1_2_16", - text: "西城区 ", - value: "西城区 ", - open: true - }, { pId: "0_1", id: "0_1_3", text: "福建省( 共9个 )", value: "福建省", open: true }, { - pId: "0_1_3", - id: "0_1_3_0", - text: "福州市", - value: "福州市", - open: true - }, { pId: "0_1_3", id: "0_1_3_1", text: "龙岩市", value: "龙岩市", open: true }, { - pId: "0_1_3", - id: "0_1_3_2", - text: "南平市", - value: "南平市", - open: true - }, { pId: "0_1_3", id: "0_1_3_3", text: "宁德市", value: "宁德市", open: true }, { - pId: "0_1_3", - id: "0_1_3_4", - text: "莆田市", - value: "莆田市", - open: true - }, { pId: "0_1_3", id: "0_1_3_5", text: "泉州市", value: "泉州市", open: true }, { - pId: "0_1_3", - id: "0_1_3_6", - text: "三明市", - value: "三明市", - open: true - }, { pId: "0_1_3", id: "0_1_3_7", text: "厦门市", value: "厦门市", open: true }, { - pId: "0_1_3", - id: "0_1_3_8", - text: "漳州市", - value: "漳州市", - open: true - }, { pId: "0_1", id: "0_1_4", text: "甘肃省( 共12个 )", value: "甘肃省", open: true }, { - pId: "0_1_4", - id: "0_1_4_0", - text: "白银市", - value: "白银市", - open: true - }, { pId: "0_1_4", id: "0_1_4_1", text: "嘉峪关市", value: "嘉峪关市", open: true }, { - pId: "0_1_4", - id: "0_1_4_2", - text: "金昌市", - value: "金昌市", - open: true - }, { pId: "0_1_4", id: "0_1_4_3", text: "酒泉市", value: "酒泉市", open: true }, { - pId: "0_1_4", - id: "0_1_4_4", - text: "兰州市", - value: "兰州市", - open: true - }, { pId: "0_1_4", id: "0_1_4_5", text: "陇南市", value: "陇南市", open: true }, { - pId: "0_1_4", - id: "0_1_4_6", - text: "平凉市", - value: "平凉市", - open: true - }, { pId: "0_1_4", id: "0_1_4_7", text: "庆阳市", value: "庆阳市", open: true }, { - pId: "0_1_4", - id: "0_1_4_8", - text: "天津市区", - value: "天津市区", - open: true - }, { pId: "0_1_4", id: "0_1_4_9", text: "天水市", value: "天水市", open: true }, { - pId: "0_1_4", - id: "0_1_4_10", - text: "武威市", - value: "武威市", - open: true - }, { pId: "0_1_4", id: "0_1_4_11", text: "张掖市", value: "张掖市", open: true }, { - pId: "0_1", - id: "0_1_5", - text: "广东省( 共21个 )", - value: "广东省", - open: true - }, { pId: "0_1_5", id: "0_1_5_0", text: "潮州市", value: "潮州市", open: true }, { - pId: "0_1_5", - id: "0_1_5_1", - text: "东莞市", - value: "东莞市", - open: true - }, { pId: "0_1_5", id: "0_1_5_2", text: "佛山市", value: "佛山市", open: true }, { - pId: "0_1_5", - id: "0_1_5_3", - text: "广州市", - value: "广州市", - open: true - }, { pId: "0_1_5", id: "0_1_5_4", text: "河源市", value: "河源市", open: true }, { - pId: "0_1_5", - id: "0_1_5_5", - text: "惠州市", - value: "惠州市", - open: true - }, { pId: "0_1_5", id: "0_1_5_6", text: "江门市", value: "江门市", open: true }, { - pId: "0_1_5", - id: "0_1_5_7", - text: "揭阳市", - value: "揭阳市", - open: true - }, { pId: "0_1_5", id: "0_1_5_8", text: "茂名市", value: "茂名市", open: true }, { - pId: "0_1_5", - id: "0_1_5_9", - text: "梅州市", - value: "梅州市", - open: true - }, { pId: "0_1_5", id: "0_1_5_10", text: "清远市", value: "清远市", open: true }, { - pId: "0_1_5", - id: "0_1_5_11", - text: "汕头市", - value: "汕头市", - open: true - }, { pId: "0_1_5", id: "0_1_5_12", text: "汕尾市", value: "汕尾市", open: true }, { - pId: "0_1_5", - id: "0_1_5_13", - text: "韶关市", - value: "韶关市", - open: true - }, { pId: "0_1_5", id: "0_1_5_14", text: "深圳市", value: "深圳市", open: true }, { - pId: "0_1_5", - id: "0_1_5_15", - text: "阳江市", - value: "阳江市", - open: true - }, { pId: "0_1_5", id: "0_1_5_16", text: "云浮市", value: "云浮市", open: true }, { - pId: "0_1_5", - id: "0_1_5_17", - text: "湛江市", - value: "湛江市", - open: true - }, { pId: "0_1_5", id: "0_1_5_18", text: "肇庆市", value: "肇庆市", open: true }, { - pId: "0_1_5", - id: "0_1_5_19", - text: "中山市", - value: "中山市", - open: true - }, { pId: "0_1_5", id: "0_1_5_20", text: "珠海市", value: "珠海市", open: true }, { - pId: "0_1", - id: "0_1_6", - text: "广西壮族自治区( 共14个 )", - value: "广西壮族自治区", - open: true - }, { pId: "0_1_6", id: "0_1_6_0", text: "百色市", value: "百色市", open: true }, { - pId: "0_1_6", - id: "0_1_6_1", - text: "北海市", - value: "北海市", - open: true - }, { pId: "0_1_6", id: "0_1_6_2", text: "崇左市", value: "崇左市", open: true }, { - pId: "0_1_6", - id: "0_1_6_3", - text: "防城港市", - value: "防城港市", - open: true - }, { pId: "0_1_6", id: "0_1_6_4", text: "桂林市", value: "桂林市", open: true }, { - pId: "0_1_6", - id: "0_1_6_5", - text: "贵港市", - value: "贵港市", - open: true - }, { pId: "0_1_6", id: "0_1_6_6", text: "河池市", value: "河池市", open: true }, { - pId: "0_1_6", - id: "0_1_6_7", - text: "贺州市", - value: "贺州市", - open: true - }, { pId: "0_1_6", id: "0_1_6_8", text: "来宾市", value: "来宾市", open: true }, { - pId: "0_1_6", - id: "0_1_6_9", - text: "柳州市", - value: "柳州市", - open: true - }, { pId: "0_1_6", id: "0_1_6_10", text: "南宁市", value: "南宁市", open: true }, { - pId: "0_1_6", - id: "0_1_6_11", - text: "钦州市", - value: "钦州市", - open: true - }, { pId: "0_1_6", id: "0_1_6_12", text: "梧州市", value: "梧州市", open: true }, { - pId: "0_1_6", - id: "0_1_6_13", - text: "玉林市", - value: "玉林市", - open: true - }, { pId: "0_1", id: "0_1_7", text: "贵州省( 共9个 )", value: "贵州省", open: true }, { - pId: "0_1_7", - id: "0_1_7_0", - text: "安顺市", - value: "安顺市", - open: true - }, { pId: "0_1_7", id: "0_1_7_1", text: "毕节地区", value: "毕节地区", open: true }, { - pId: "0_1_7", - id: "0_1_7_2", - text: "贵阳市", - value: "贵阳市", - open: true - }, { pId: "0_1_7", id: "0_1_7_3", text: "六盘水市", value: "六盘水市", open: true }, { - pId: "0_1_7", - id: "0_1_7_4", - text: "黔东南州", - value: "黔东南州", - open: true - }, { pId: "0_1_7", id: "0_1_7_5", text: "黔南州", value: "黔南州", open: true }, { - pId: "0_1_7", - id: "0_1_7_6", - text: "黔西南市", - value: "黔西南市", - open: true - }, { pId: "0_1_7", id: "0_1_7_7", text: "铜仁地区", value: "铜仁地区", open: true }, { - pId: "0_1_7", - id: "0_1_7_8", - text: "遵义市", - value: "遵义市", - open: true - }, { pId: "0_1", id: "0_1_8", text: "海南省( 共2个 )", value: "海南省", open: true }, { - pId: "0_1_8", - id: "0_1_8_0", - text: "海口市", - value: "海口市", - open: true - }, { pId: "0_1_8", id: "0_1_8_1", text: "三亚市", value: "三亚市", open: true }, { - pId: "0_1", - id: "0_1_9", - text: "河北省( 共12个 )", - value: "河北省", - open: true - }, { pId: "0_1_9", id: "0_1_9_0", text: "保定市", value: "保定市", open: true }, { - pId: "0_1_9", - id: "0_1_9_1", - text: "沧州市", - value: "沧州市", - open: true - }, { pId: "0_1_9", id: "0_1_9_2", text: "承德市", value: "承德市", open: true }, { - pId: "0_1_9", - id: "0_1_9_3", - text: "邯郸市", - value: "邯郸市", - open: true - }, { pId: "0_1_9", id: "0_1_9_4", text: "衡水市", value: "衡水市", open: true }, { - pId: "0_1_9", - id: "0_1_9_5", - text: "廊坊市", - value: "廊坊市", - open: true - }, { pId: "0_1_9", id: "0_1_9_6", text: "秦皇岛市", value: "秦皇岛市", open: true }, { - pId: "0_1_9", - id: "0_1_9_7", - text: "石家庄市", - value: "石家庄市", - open: true - }, { pId: "0_1_9", id: "0_1_9_8", text: "唐山市", value: "唐山市", open: true }, { - pId: "0_1_9", - id: "0_1_9_9", - text: "天津市区", - value: "天津市区", - open: true - }, { pId: "0_1_9", id: "0_1_9_10", text: "邢台市", value: "邢台市", open: true }, { - pId: "0_1_9", - id: "0_1_9_11", - text: "张家口市", - value: "张家口市", - open: true - }, { pId: "0_1", id: "0_1_10", text: "河南省( 共19个 )", value: "河南省", open: true }, { - pId: "0_1_10", - id: "0_1_10_0", - text: "安阳市", - value: "安阳市", - open: true - }, { pId: "0_1_10", id: "0_1_10_1", text: "鹤壁市", value: "鹤壁市", open: true }, { - pId: "0_1_10", - id: "0_1_10_2", - text: "济源市", - value: "济源市", - open: true - }, { pId: "0_1_10", id: "0_1_10_3", text: "焦作市", value: "焦作市", open: true }, { - pId: "0_1_10", - id: "0_1_10_4", - text: "开封市", - value: "开封市", - open: true - }, { pId: "0_1_10", id: "0_1_10_5", text: "廊坊市", value: "廊坊市", open: true }, { - pId: "0_1_10", - id: "0_1_10_6", - text: "洛阳市", - value: "洛阳市", - open: true - }, { pId: "0_1_10", id: "0_1_10_7", text: "漯河市", value: "漯河市", open: true }, { - pId: "0_1_10", - id: "0_1_10_8", - text: "南阳市", - value: "南阳市", - open: true - }, { pId: "0_1_10", id: "0_1_10_9", text: "平顶山市", value: "平顶山市", open: true }, { - pId: "0_1_10", - id: "0_1_10_10", - text: "濮阳市", - value: "濮阳市", - open: true - }, { pId: "0_1_10", id: "0_1_10_11", text: "三门峡市", value: "三门峡市", open: true }, { - pId: "0_1_10", - id: "0_1_10_12", - text: "商丘市", - value: "商丘市", - open: true - }, { pId: "0_1_10", id: "0_1_10_13", text: "新乡市", value: "新乡市", open: true }, { - pId: "0_1_10", - id: "0_1_10_14", - text: "信阳市", - value: "信阳市", - open: true - }, { pId: "0_1_10", id: "0_1_10_15", text: "许昌市", value: "许昌市", open: true }, { - pId: "0_1_10", - id: "0_1_10_16", - text: "郑州市", - value: "郑州市", - open: true - }, { pId: "0_1_10", id: "0_1_10_17", text: "周口市", value: "周口市", open: true }, { - pId: "0_1_10", - id: "0_1_10_18", - text: "驻马店市", - value: "驻马店市", - open: true - }, { pId: "0_1", id: "0_1_11", text: "黑龙江省( 共13个 )", value: "黑龙江省", open: true }, { - pId: "0_1_11", - id: "0_1_11_0", - text: "大庆市", - value: "大庆市", - open: true - }, { pId: "0_1_11", id: "0_1_11_1", text: "大兴安岭地区", value: "大兴安岭地区", open: true }, { - pId: "0_1_11", - id: "0_1_11_2", - text: "大兴安岭市", - value: "大兴安岭市", - open: true - }, { pId: "0_1_11", id: "0_1_11_3", text: "哈尔滨市", value: "哈尔滨市", open: true }, { - pId: "0_1_11", - id: "0_1_11_4", - text: "鹤港市", - value: "鹤港市", - open: true - }, { pId: "0_1_11", id: "0_1_11_5", text: "黑河市", value: "黑河市", open: true }, { - pId: "0_1_11", - id: "0_1_11_6", - text: "佳木斯市", - value: "佳木斯市", - open: true - }, { pId: "0_1_11", id: "0_1_11_7", text: "牡丹江市", value: "牡丹江市", open: true }, { - pId: "0_1_11", - id: "0_1_11_8", - text: "七台河市", - value: "七台河市", - open: true - }, { pId: "0_1_11", id: "0_1_11_9", text: "齐齐哈尔市", value: "齐齐哈尔市", open: true }, { - pId: "0_1_11", - id: "0_1_11_10", - text: "双鸭山市", - value: "双鸭山市", - open: true - }, { pId: "0_1_11", id: "0_1_11_11", text: "绥化市", value: "绥化市", open: true }, { - pId: "0_1_11", - id: "0_1_11_12", - text: "伊春市", - value: "伊春市", - open: true - }, { pId: "0_1", id: "0_1_12", text: "湖北省( 共16个 )", value: "湖北省", open: true }, { - pId: "0_1_12", - id: "0_1_12_0", - text: "鄂州市", - value: "鄂州市", - open: true - }, { pId: "0_1_12", id: "0_1_12_1", text: "恩施土家族苗族自治州", value: "恩施土家族苗族自治州", open: true }, { - pId: "0_1_12", - id: "0_1_12_2", - text: "黄冈市", - value: "黄冈市", - open: true - }, { pId: "0_1_12", id: "0_1_12_3", text: "黄石市", value: "黄石市", open: true }, { - pId: "0_1_12", - id: "0_1_12_4", - text: "荆门市", - value: "荆门市", - open: true - }, { pId: "0_1_12", id: "0_1_12_5", text: "荆州市", value: "荆州市", open: true }, { - pId: "0_1_12", - id: "0_1_12_6", - text: "神农架市", - value: "神农架市", - open: true - }, { pId: "0_1_12", id: "0_1_12_7", text: "十堰市", value: "十堰市", open: true }, { - pId: "0_1_12", - id: "0_1_12_8", - text: "随州市", - value: "随州市", - open: true - }, { pId: "0_1_12", id: "0_1_12_9", text: "天门市", value: "天门市", open: true }, { - pId: "0_1_12", - id: "0_1_12_10", - text: "武汉市", - value: "武汉市", - open: true - }, { pId: "0_1_12", id: "0_1_12_11", text: "咸宁市", value: "咸宁市", open: true }, { - pId: "0_1_12", - id: "0_1_12_12", - text: "襄樊市", - value: "襄樊市", - open: true - }, { pId: "0_1_12", id: "0_1_12_13", text: "襄阳市", value: "襄阳市", open: true }, { - pId: "0_1_12", - id: "0_1_12_14", - text: "孝感市", - value: "孝感市", - open: true - }, { pId: "0_1_12", id: "0_1_12_15", text: "宜昌市", value: "宜昌市", open: true }, { - pId: "0_1", - id: "0_1_13", - text: "湖南省( 共15个 )", - value: "湖南省", - open: true - }, { pId: "0_1_13", id: "0_1_13_0", text: "常德市", value: "常德市", open: true }, { - pId: "0_1_13", - id: "0_1_13_1", - text: "长沙市", - value: "长沙市", - open: true - }, { pId: "0_1_13", id: "0_1_13_2", text: "郴州市", value: "郴州市", open: true }, { - pId: "0_1_13", - id: "0_1_13_3", - text: "衡阳市", - value: "衡阳市", - open: true - }, { pId: "0_1_13", id: "0_1_13_4", text: "怀化市", value: "怀化市", open: true }, { - pId: "0_1_13", - id: "0_1_13_5", - text: "娄底市", - value: "娄底市", - open: true - }, { pId: "0_1_13", id: "0_1_13_6", text: "邵阳市", value: "邵阳市", open: true }, { - pId: "0_1_13", - id: "0_1_13_7", - text: "湘潭市", - value: "湘潭市", - open: true - }, { pId: "0_1_13", id: "0_1_13_8", text: "湘西市", value: "湘西市", open: true }, { - pId: "0_1_13", - id: "0_1_13_9", - text: "湘西土家族苗族自治州", - value: "湘西土家族苗族自治州", - open: true - }, { pId: "0_1_13", id: "0_1_13_10", text: "益阳市", value: "益阳市", open: true }, { - pId: "0_1_13", - id: "0_1_13_11", - text: "永州市", - value: "永州市", - open: true - }, { pId: "0_1_13", id: "0_1_13_12", text: "岳阳市", value: "岳阳市", open: true }, { - pId: "0_1_13", - id: "0_1_13_13", - text: "张家界市", - value: "张家界市", - open: true - }, { pId: "0_1_13", id: "0_1_13_14", text: "株洲市", value: "株洲市", open: true }, { - pId: "0_1", - id: "0_1_14", - text: "吉林省( 共10个 )", - value: "吉林省", - open: true - }, { pId: "0_1_14", id: "0_1_14_0", text: "白城市", value: "白城市", open: true }, { - pId: "0_1_14", - id: "0_1_14_1", - text: "白山市", - value: "白山市", - open: true - }, { pId: "0_1_14", id: "0_1_14_2", text: "长春市", value: "长春市", open: true }, { - pId: "0_1_14", - id: "0_1_14_3", - text: "大庆市", - value: "大庆市", - open: true - }, { pId: "0_1_14", id: "0_1_14_4", text: "吉林市", value: "吉林市", open: true }, { - pId: "0_1_14", - id: "0_1_14_5", - text: "辽源市", - value: "辽源市", - open: true - }, { pId: "0_1_14", id: "0_1_14_6", text: "四平市", value: "四平市", open: true }, { - pId: "0_1_14", - id: "0_1_14_7", - text: "松原市", - value: "松原市", - open: true - }, { pId: "0_1_14", id: "0_1_14_8", text: "通化市", value: "通化市", open: true }, { - pId: "0_1_14", - id: "0_1_14_9", - text: "延边朝鲜族自治州", - value: "延边朝鲜族自治州", - open: true - }, { pId: "0_1", id: "0_1_15", text: "江苏省( 共13个 )", value: "江苏省", open: true }, { - pId: "0_1_15", - id: "0_1_15_0", - text: "常州市", - value: "常州市", - open: true - }, { pId: "0_1_15", id: "0_1_15_1", text: "淮安市", value: "淮安市", open: true }, { - pId: "0_1_15", - id: "0_1_15_2", - text: "连云港市", - value: "连云港市", - open: true - }, { pId: "0_1_15", id: "0_1_15_3", text: "南京市", value: "南京市", open: true }, { - pId: "0_1_15", - id: "0_1_15_4", - text: "南通市", - value: "南通市", - open: true - }, { pId: "0_1_15", id: "0_1_15_5", text: "苏州市", value: "苏州市", open: true }, { - pId: "0_1_15", - id: "0_1_15_6", - text: "宿迁市", - value: "宿迁市", - open: true - }, { pId: "0_1_15", id: "0_1_15_7", text: "泰州市", value: "泰州市", open: true }, { - pId: "0_1_15", - id: "0_1_15_8", - text: "无锡市", - value: "无锡市", - open: true - }, { pId: "0_1_15", id: "0_1_15_9", text: "徐州市", value: "徐州市", open: true }, { - pId: "0_1_15", - id: "0_1_15_10", - text: "盐城市", - value: "盐城市", - open: true - }, { pId: "0_1_15", id: "0_1_15_11", text: "扬州市", value: "扬州市", open: true }, { - pId: "0_1_15", - id: "0_1_15_12", - text: "镇江市", - value: "镇江市", - open: true - }, { pId: "0_1", id: "0_1_16", text: "江西省( 共10个 )", value: "江西省", open: true }, { - pId: "0_1_16", - id: "0_1_16_0", - text: "抚州市", - value: "抚州市", - open: true - }, { pId: "0_1_16", id: "0_1_16_1", text: "赣州市", value: "赣州市", open: true }, { - pId: "0_1_16", - id: "0_1_16_2", - text: "景德镇市", - value: "景德镇市", - open: true - }, { pId: "0_1_16", id: "0_1_16_3", text: "九江市", value: "九江市", open: true }, { - pId: "0_1_16", - id: "0_1_16_4", - text: "南昌市", - value: "南昌市", - open: true - }, { pId: "0_1_16", id: "0_1_16_5", text: "萍乡市", value: "萍乡市", open: true }, { - pId: "0_1_16", - id: "0_1_16_6", - text: "上饶市", - value: "上饶市", - open: true - }, { pId: "0_1_16", id: "0_1_16_7", text: "新余市", value: "新余市", open: true }, { - pId: "0_1_16", - id: "0_1_16_8", - text: "宜春市", - value: "宜春市", - open: true - }, { pId: "0_1_16", id: "0_1_16_9", text: "鹰潭市", value: "鹰潭市", open: true }, { - pId: "0_1", - id: "0_1_17", - text: "辽宁省( 共14个 )", - value: "辽宁省", - open: true - }, { pId: "0_1_17", id: "0_1_17_0", text: "鞍山市", value: "鞍山市", open: true }, { - pId: "0_1_17", - id: "0_1_17_1", - text: "本溪市", - value: "本溪市", - open: true - }, { pId: "0_1_17", id: "0_1_17_2", text: "朝阳市", value: "朝阳市", open: true }, { - pId: "0_1_17", - id: "0_1_17_3", - text: "大连市", - value: "大连市", - open: true - }, { pId: "0_1_17", id: "0_1_17_4", text: "丹东市", value: "丹东市", open: true }, { - pId: "0_1_17", - id: "0_1_17_5", - text: "抚顺市", - value: "抚顺市", - open: true - }, { pId: "0_1_17", id: "0_1_17_6", text: "阜新市", value: "阜新市", open: true }, { - pId: "0_1_17", - id: "0_1_17_7", - text: "葫芦岛市", - value: "葫芦岛市", - open: true - }, { pId: "0_1_17", id: "0_1_17_8", text: "锦州市", value: "锦州市", open: true }, { - pId: "0_1_17", - id: "0_1_17_9", - text: "辽阳市", - value: "辽阳市", - open: true - }, { pId: "0_1_17", id: "0_1_17_10", text: "盘锦市", value: "盘锦市", open: true }, { - pId: "0_1_17", - id: "0_1_17_11", - text: "沈阳市", - value: "沈阳市", - open: true - }, { pId: "0_1_17", id: "0_1_17_12", text: "铁岭市", value: "铁岭市", open: true }, { - pId: "0_1_17", - id: "0_1_17_13", - text: "营口市", - value: "营口市", - open: true - }, { pId: "0_1", id: "0_1_18", text: "内蒙古( 共10个 )", value: "内蒙古", open: true }, { - pId: "0_1_18", - id: "0_1_18_0", - text: "包头市", - value: "包头市", - open: true - }, { pId: "0_1_18", id: "0_1_18_1", text: "赤峰市", value: "赤峰市", open: true }, { - pId: "0_1_18", - id: "0_1_18_2", - text: "鄂尔多斯市", - value: "鄂尔多斯市", - open: true - }, { pId: "0_1_18", id: "0_1_18_3", text: "呼和浩特市", value: "呼和浩特市", open: true }, { - pId: "0_1_18", - id: "0_1_18_4", - text: "呼伦贝尔市", - value: "呼伦贝尔市", - open: true - }, { pId: "0_1_18", id: "0_1_18_5", text: "通辽市", value: "通辽市", open: true }, { - pId: "0_1_18", - id: "0_1_18_6", - text: "乌海市", - value: "乌海市", - open: true - }, { pId: "0_1_18", id: "0_1_18_7", text: "锡林郭勒市", value: "锡林郭勒市", open: true }, { - pId: "0_1_18", - id: "0_1_18_8", - text: "兴安市", - value: "兴安市", - open: true - }, { pId: "0_1_18", id: "0_1_18_9", text: "运城市", value: "运城市", open: true }, { - pId: "0_1", - id: "0_1_19", - text: "宁夏回族自治区( 共5个 )", - value: "宁夏回族自治区", - open: true - }, { pId: "0_1_19", id: "0_1_19_0", text: "固原市", value: "固原市", open: true }, { - pId: "0_1_19", - id: "0_1_19_1", - text: "石嘴山市", - value: "石嘴山市", - open: true - }, { pId: "0_1_19", id: "0_1_19_2", text: "吴忠市", value: "吴忠市", open: true }, { - pId: "0_1_19", - id: "0_1_19_3", - text: "银川市", - value: "银川市", - open: true - }, { pId: "0_1_19", id: "0_1_19_4", text: "中卫市", value: "中卫市", open: true }, { - pId: "0_1", - id: "0_1_20", - text: "青海省( 共4个 )", - value: "青海省", - open: true - }, { pId: "0_1_20", id: "0_1_20_0", text: "海东地区", value: "海东地区", open: true }, { - pId: "0_1_20", - id: "0_1_20_1", - text: "海南藏族自治州", - value: "海南藏族自治州", - open: true - }, { pId: "0_1_20", id: "0_1_20_2", text: "海西蒙古族藏族自治州", value: "海西蒙古族藏族自治州", open: true }, { - pId: "0_1_20", - id: "0_1_20_3", - text: "西宁市", - value: "西宁市", - open: true - }, { pId: "0_1", id: "0_1_21", text: "山东省( 共17个 )", value: "山东省", open: true }, { - pId: "0_1_21", - id: "0_1_21_0", - text: "滨州市", - value: "滨州市", - open: true - }, { pId: "0_1_21", id: "0_1_21_1", text: "德州市", value: "德州市", open: true }, { - pId: "0_1_21", - id: "0_1_21_2", - text: "东营市", - value: "东营市", - open: true - }, { pId: "0_1_21", id: "0_1_21_3", text: "菏泽市", value: "菏泽市", open: true }, { - pId: "0_1_21", - id: "0_1_21_4", - text: "济南市", - value: "济南市", - open: true - }, { pId: "0_1_21", id: "0_1_21_5", text: "济宁市", value: "济宁市", open: true }, { - pId: "0_1_21", - id: "0_1_21_6", - text: "莱芜市", - value: "莱芜市", - open: true - }, { pId: "0_1_21", id: "0_1_21_7", text: "聊城市", value: "聊城市", open: true }, { - pId: "0_1_21", - id: "0_1_21_8", - text: "临沂市", - value: "临沂市", - open: true - }, { pId: "0_1_21", id: "0_1_21_9", text: "青岛市", value: "青岛市", open: true }, { - pId: "0_1_21", - id: "0_1_21_10", - text: "日照市", - value: "日照市", - open: true - }, { pId: "0_1_21", id: "0_1_21_11", text: "泰安市", value: "泰安市", open: true }, { - pId: "0_1_21", - id: "0_1_21_12", - text: "威海市", - value: "威海市", - open: true - }, { pId: "0_1_21", id: "0_1_21_13", text: "潍坊市", value: "潍坊市", open: true }, { - pId: "0_1_21", - id: "0_1_21_14", - text: "烟台市", - value: "烟台市", - open: true - }, { pId: "0_1_21", id: "0_1_21_15", text: "枣庄市", value: "枣庄市", open: true }, { - pId: "0_1_21", - id: "0_1_21_16", - text: "淄博市", - value: "淄博市", - open: true - }, { pId: "0_1", id: "0_1_22", text: "山西省( 共12个 )", value: "山西省", open: true }, { - pId: "0_1_22", - id: "0_1_22_0", - text: "长治市", - value: "长治市", - open: true - }, { pId: "0_1_22", id: "0_1_22_1", text: "大同市", value: "大同市", open: true }, { - pId: "0_1_22", - id: "0_1_22_2", - text: "晋城市", - value: "晋城市", - open: true - }, { pId: "0_1_22", id: "0_1_22_3", text: "晋中市", value: "晋中市", open: true }, { - pId: "0_1_22", - id: "0_1_22_4", - text: "临汾市", - value: "临汾市", - open: true - }, { pId: "0_1_22", id: "0_1_22_5", text: "吕梁市", value: "吕梁市", open: true }, { - pId: "0_1_22", - id: "0_1_22_6", - text: "青岛市", - value: "青岛市", - open: true - }, { pId: "0_1_22", id: "0_1_22_7", text: "朔州市", value: "朔州市", open: true }, { - pId: "0_1_22", - id: "0_1_22_8", - text: "太原市", - value: "太原市", - open: true - }, { pId: "0_1_22", id: "0_1_22_9", text: "忻州市", value: "忻州市", open: true }, { - pId: "0_1_22", - id: "0_1_22_10", - text: "阳泉市", - value: "阳泉市", - open: true - }, { pId: "0_1_22", id: "0_1_22_11", text: "运城市", value: "运城市", open: true }, { - pId: "0_1", - id: "0_1_23", - text: "陕西省( 共9个 )", - value: "陕西省", - open: true - }, { pId: "0_1_23", id: "0_1_23_0", text: "安康市", value: "安康市", open: true }, { - pId: "0_1_23", - id: "0_1_23_1", - text: "宝鸡市", - value: "宝鸡市", - open: true - }, { pId: "0_1_23", id: "0_1_23_2", text: "汉中市", value: "汉中市", open: true }, { - pId: "0_1_23", - id: "0_1_23_3", - text: "商洛市", - value: "商洛市", - open: true - }, { pId: "0_1_23", id: "0_1_23_4", text: "渭南市", value: "渭南市", open: true }, { - pId: "0_1_23", - id: "0_1_23_5", - text: "西安市", - value: "西安市", - open: true - }, { pId: "0_1_23", id: "0_1_23_6", text: "咸阳市", value: "咸阳市", open: true }, { - pId: "0_1_23", - id: "0_1_23_7", - text: "延安市", - value: "延安市", - open: true - }, { pId: "0_1_23", id: "0_1_23_8", text: "榆林市", value: "榆林市", open: true }, { - pId: "0_1", - id: "0_1_24", - text: "上海市( 共19个 )", - value: "上海市", - open: true - }, { pId: "0_1_24", id: "0_1_24_0", text: "宝山区", value: "宝山区", open: true }, { - pId: "0_1_24", - id: "0_1_24_1", - text: "长宁区", - value: "长宁区", - open: true - }, { pId: "0_1_24", id: "0_1_24_2", text: "崇明县", value: "崇明县", open: true }, { - pId: "0_1_24", - id: "0_1_24_3", - text: "奉贤区", - value: "奉贤区", - open: true - }, { pId: "0_1_24", id: "0_1_24_4", text: "虹口区", value: "虹口区", open: true }, { - pId: "0_1_24", - id: "0_1_24_5", - text: "黄浦区", - value: "黄浦区", - open: true - }, { pId: "0_1_24", id: "0_1_24_6", text: "嘉定区", value: "嘉定区", open: true }, { - pId: "0_1_24", - id: "0_1_24_7", - text: "金山区", - value: "金山区", - open: true - }, { pId: "0_1_24", id: "0_1_24_8", text: "静安区", value: "静安区", open: true }, { - pId: "0_1_24", - id: "0_1_24_9", - text: "昆明市", - value: "昆明市", - open: true - }, { pId: "0_1_24", id: "0_1_24_10", text: "闵行区", value: "闵行区", open: true }, { - pId: "0_1_24", - id: "0_1_24_11", - text: "普陀区", - value: "普陀区", - open: true - }, { pId: "0_1_24", id: "0_1_24_12", text: "浦东新区", value: "浦东新区", open: true }, { - pId: "0_1_24", - id: "0_1_24_13", - text: "青浦区", - value: "青浦区", - open: true - }, { pId: "0_1_24", id: "0_1_24_14", text: "上海市区", value: "上海市区", open: true }, { - pId: "0_1_24", - id: "0_1_24_15", - text: "松江区", - value: "松江区", - open: true - }, { pId: "0_1_24", id: "0_1_24_16", text: "徐汇区", value: "徐汇区", open: true }, { - pId: "0_1_24", - id: "0_1_24_17", - text: "杨浦区", - value: "杨浦区", - open: true - }, { pId: "0_1_24", id: "0_1_24_18", text: "闸北区", value: "闸北区", open: true }, { - pId: "0_1", - id: "0_1_25", - text: "四川省( 共21个 )", - value: "四川省", - open: true - }, { pId: "0_1_25", id: "0_1_25_0", text: "阿坝藏族羌族自治州", value: "阿坝藏族羌族自治州", open: true }, { - pId: "0_1_25", - id: "0_1_25_1", - text: "巴中市", - value: "巴中市", - open: true - }, { pId: "0_1_25", id: "0_1_25_2", text: "成都市", value: "成都市", open: true }, { - pId: "0_1_25", - id: "0_1_25_3", - text: "达州市", - value: "达州市", - open: true - }, { pId: "0_1_25", id: "0_1_25_4", text: "德阳市", value: "德阳市", open: true }, { - pId: "0_1_25", - id: "0_1_25_5", - text: "甘孜市", - value: "甘孜市", - open: true - }, { pId: "0_1_25", id: "0_1_25_6", text: "广安市", value: "广安市", open: true }, { - pId: "0_1_25", - id: "0_1_25_7", - text: "广元市", - value: "广元市", - open: true - }, { pId: "0_1_25", id: "0_1_25_8", text: "乐山市", value: "乐山市", open: true }, { - pId: "0_1_25", - id: "0_1_25_9", - text: "凉山市", - value: "凉山市", - open: true - }, { pId: "0_1_25", id: "0_1_25_10", text: "泸州市", value: "泸州市", open: true }, { - pId: "0_1_25", - id: "0_1_25_11", - text: "眉山市", - value: "眉山市", - open: true - }, { pId: "0_1_25", id: "0_1_25_12", text: "绵阳市", value: "绵阳市", open: true }, { - pId: "0_1_25", - id: "0_1_25_13", - text: "南充市", - value: "南充市", - open: true - }, { pId: "0_1_25", id: "0_1_25_14", text: "内江市", value: "内江市", open: true }, { - pId: "0_1_25", - id: "0_1_25_15", - text: "攀枝花市", - value: "攀枝花市", - open: true - }, { pId: "0_1_25", id: "0_1_25_16", text: "遂宁市", value: "遂宁市", open: true }, { - pId: "0_1_25", - id: "0_1_25_17", - text: "雅安市", - value: "雅安市", - open: true - }, { pId: "0_1_25", id: "0_1_25_18", text: "宜宾市", value: "宜宾市", open: true }, { - pId: "0_1_25", - id: "0_1_25_19", - text: "资阳市", - value: "资阳市", - open: true - }, { pId: "0_1_25", id: "0_1_25_20", text: "自贡市", value: "自贡市", open: true }, { - pId: "0_1", - id: "0_1_26", - text: "台湾( 共1个 )", - value: "台湾", - open: true - }, { pId: "0_1_26", id: "0_1_26_0", text: "台北市", value: "台北市", open: true }, { - pId: "0_1", - id: "0_1_27", - text: "天津市( 共1个 )", - value: "天津市", - open: true - }, { pId: "0_1_27", id: "0_1_27_0", text: "天津市区", value: "天津市区", open: true }, { - pId: "0_1", - id: "0_1_28", - text: "西藏自治区( 共2个 )", - value: "西藏自治区", - open: true - }, { pId: "0_1_28", id: "0_1_28_0", text: "阿里市", value: "阿里市", open: true }, { - pId: "0_1_28", - id: "0_1_28_1", - text: "日喀则市", - value: "日喀则市", - open: true - }, { pId: "0_1", id: "0_1_29", text: "香港特别行政区( 共1个 )", value: "香港特别行政区", open: true }, { - pId: "0_1_29", - id: "0_1_29_0", - text: "香港", - value: "香港", - open: true - }, { - pId: "0_1", - id: "0_1_30", - text: "新疆维吾尔族自治区( 共11个 )", - value: "新疆维吾尔族自治区", - open: true - }, { pId: "0_1_30", id: "0_1_30_0", text: "巴音郭楞市", value: "巴音郭楞市", open: true }, { - pId: "0_1_30", - id: "0_1_30_1", - text: "哈密市", - value: "哈密市", - open: true - }, { pId: "0_1_30", id: "0_1_30_2", text: "和田市", value: "和田市", open: true }, { - pId: "0_1_30", - id: "0_1_30_3", - text: "喀什地区", - value: "喀什地区", - open: true - }, { pId: "0_1_30", id: "0_1_30_4", text: "克拉玛依市", value: "克拉玛依市", open: true }, { - pId: "0_1_30", - id: "0_1_30_5", - text: "克孜勒苏柯州", - value: "克孜勒苏柯州", - open: true - }, { pId: "0_1_30", id: "0_1_30_6", text: "石河子市", value: "石河子市", open: true }, { - pId: "0_1_30", - id: "0_1_30_7", - text: "塔城市", - value: "塔城市", - open: true - }, { pId: "0_1_30", id: "0_1_30_8", text: "吐鲁番地区", value: "吐鲁番地区", open: true }, { - pId: "0_1_30", - id: "0_1_30_9", - text: "乌鲁木齐", - value: "乌鲁木齐", - open: true - }, { pId: "0_1_30", id: "0_1_30_10", text: "伊犁市", value: "伊犁市", open: true }, { - pId: "0_1", - id: "0_1_31", - text: "云南省( 共12个 )", - value: "云南省", - open: true - }, { pId: "0_1_31", id: "0_1_31_0", text: "保山市", value: "保山市", open: true }, { - pId: "0_1_31", - id: "0_1_31_1", - text: "楚雄彝族自治州", - value: "楚雄彝族自治州", - open: true - }, { pId: "0_1_31", id: "0_1_31_2", text: "大理白族自治州", value: "大理白族自治州", open: true }, { - pId: "0_1_31", - id: "0_1_31_3", - text: "红河哈尼族彝族自治州", - value: "红河哈尼族彝族自治州", - open: true - }, { pId: "0_1_31", id: "0_1_31_4", text: "昆明市", value: "昆明市", open: true }, { - pId: "0_1_31", - id: "0_1_31_5", - text: "丽江市", - value: "丽江市", - open: true - }, { pId: "0_1_31", id: "0_1_31_6", text: "临沧市", value: "临沧市", open: true }, { - pId: "0_1_31", - id: "0_1_31_7", - text: "曲靖市", - value: "曲靖市", - open: true - }, { pId: "0_1_31", id: "0_1_31_8", text: "思茅市", value: "思茅市", open: true }, { - pId: "0_1_31", - id: "0_1_31_9", - text: "文山市", - value: "文山市", - open: true - }, { pId: "0_1_31", id: "0_1_31_10", text: "玉溪市", value: "玉溪市", open: true }, { - pId: "0_1_31", - id: "0_1_31_11", - text: "昭通市", - value: "昭通市", - open: true - }, { pId: "0_1", id: "0_1_32", text: "浙江省( 共12个 )", value: "浙江省", open: true }, { - pId: "0_1_32", - id: "0_1_32_0", - text: "杭州市", - value: "杭州市", - open: true - }, { pId: "0_1_32", id: "0_1_32_1", text: "湖州市", value: "湖州市", open: true }, { - pId: "0_1_32", - id: "0_1_32_2", - text: "嘉兴市", - value: "嘉兴市", - open: true - }, { pId: "0_1_32", id: "0_1_32_3", text: "金华市", value: "金华市", open: true }, { - pId: "0_1_32", - id: "0_1_32_4", - text: "丽水市", - value: "丽水市", - open: true - }, { pId: "0_1_32", id: "0_1_32_5", text: "宁波市", value: "宁波市", open: true }, { - pId: "0_1_32", - id: "0_1_32_6", - text: "衢州市", - value: "衢州市", - open: true - }, { pId: "0_1_32", id: "0_1_32_7", text: "绍兴市", value: "绍兴市", open: true }, { - pId: "0_1_32", - id: "0_1_32_8", - text: "台州市", - value: "台州市", - open: true - }, { pId: "0_1_32", id: "0_1_32_9", text: "温州市", value: "温州市", open: true }, { - pId: "0_1_32", - id: "0_1_32_10", - text: "浙江省", - value: "浙江省", - open: true - }, { pId: "0_1_32", id: "0_1_32_11", text: "舟山市", value: "舟山市", open: true }, { - pId: "0_1", - id: "0_1_33", - text: "重庆市( 共1个 )", - value: "重庆市", - open: true - }, { pId: "0_1_33", id: "0_1_33_0", text: "重庆市区", value: "重庆市区", open: true }], - - TREE: [{ id: -1, pId: -2, value: "根目录", text: "根目录" }, - { id: 1, pId: -1, value: "1", text: "第一级目录1", disabled: true }, - { id: 11, pId: 1, value: "11", text: "第二级文件1" }, - { id: 12, pId: 1, value: "12", text: "第二级目录2" }, - { id: 121, pId: 12, value: "121", text: "第三级目录1" }, - { id: 122, pId: 12, value: "122", text: "第三级文件1" }, - { id: 1211, pId: 121, value: "1211", text: "第四级目录1" }, - { - id: 12111, - pId: 1211, - value: "12111", - text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" - }, - { id: 2, pId: -1, value: "2", text: "第一级目录2" }, - { id: 21, pId: 2, value: "21", text: "第二级目录3" }, - { id: 22, pId: 2, value: "22", text: "第二级文件2" }, - { id: 211, pId: 21, value: "211", text: "第三级目录2" }, - { id: 212, pId: 21, value: "212", text: "第三级文件2" }, - { id: 2111, pId: 211, value: "2111", text: "第四级文件1" }], - LEVELTREE: [{ - id: 1, - text: "第一项", - value: "1" - }, { - id: 2, - text: "第二项", - value: "2" - }, { - id: 3, - text: "第三项", - value: "3", - open: true - }, { - id: 11, - pId: 1, - text: "子项1", - value: "11" - }, { - id: 12, - pId: 1, - text: "子项2", - value: "12" - }, { - id: 13, - pId: 1, - text: "子项3", - value: "13" - }, { - id: 31, - pId: 3, - text: "子项1", - value: "31" - }, { - id: 32, - pId: 3, - text: "子项2", - value: "32" - }, { - id: 33, - pId: 3, - text: "子项3", - value: "33" - }] -}; - diff --git a/demo/js/base/button/demo.button.js b/demo/js/base/button/demo.button.js deleted file mode 100644 index 2514b949e..000000000 --- a/demo/js/base/button/demo.button.js +++ /dev/null @@ -1,408 +0,0 @@ -(function () { - var JokerIcon = BI.inherit(BI.Widget, { - render: function () { - var self = this; - - return { - type: "bi.label", - cls: "anim-rotate", - ref: function(ref) { - self.text = ref; - }, - }; - }, - loading: function () { - this.text.setText("🤡"); - }, - loaded: function () { - this.text.setText(""); - }, - }); - BI.shortcut("demo.joker.icon", JokerIcon); -}()); - -Demo.Button = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-button", - }, - render: function () { - var items = [{ - type: "bi.button", - text: "一般按钮1111111111111", - level: "common", - whiteSpace: "nowrap", - width: 100, - height: 30, - handler() { - console.log("触发点击事件"); - this.loading(); - setTimeout(() => { - this.loaded(); - }, 5 * 1000); - }, - }, { - type: "bi.button", - text: "表示成功状态按钮", - level: "success", - height: 30, - }, { - type: "bi.button", - text: "表示警告状态的按钮", - level: "warning", - height: 30, - }, { - type: "bi.button", - text: "表示错误状态的按钮", - level: "error", - height: 30, - }, { - type: "bi.button", - text: "表示忽略状态的按钮", - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "普通灰化按钮", - disabled: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "忽略状态灰化按钮", - disabled: true, - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "带图标的按钮", - // level: 'ignore', - iconCls: "close-font", - height: 30, - }, { - type: "bi.button", - text: "一般按钮", - block: true, - level: "common", - height: 30, - }, { - type: "bi.button", - text: "表示成功状态按钮", - block: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "表示警告状态的按钮", - block: true, - level: "warning", - height: 30, - }, { - type: "bi.button", - text: "表示忽略状态的按钮", - block: true, - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "普通灰化按钮", - block: true, - disabled: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "忽略状态灰化按钮", - block: true, - disabled: true, - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "带图标的按钮", - block: true, - // level: 'ignore', - iconCls: "close-font", - height: 30, - }, { - type: "bi.button", - text: "一般按钮", - clear: true, - level: "common", - height: 30, - }, { - type: "bi.button", - text: "表示成功状态按钮", - clear: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "表示警告状态的按钮", - clear: true, - level: "warning", - height: 30, - }, { - type: "bi.button", - text: "表示忽略状态的按钮", - clear: true, - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "普通灰化按钮", - clear: true, - disabled: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "忽略状态灰化按钮", - clear: true, - disabled: true, - level: "ignore", - height: 30, - }, { - type: "bi.button", - text: "带图标的按钮", - clear: true, - // level: 'ignore', - iconCls: "close-font", - height: 30, - }, { - type: "bi.text_button", - text: "文字按钮", - height: 30, - }, { - type: "bi.button", - text: "幽灵按钮(common)", - ghost: true, - height: 30, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "幽灵按钮(common)", - ghost: true, - height: 30, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "幽灵按钮(common)", - ghost: true, - level: "warning", - height: 30, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "幽灵按钮(common)", - ghost: true, - level: "error", - height: 30, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "幽灵按钮(common)", - ghost: true, - level: "success", - height: 30, - }, { - type: "bi.button", - text: "幽灵按钮(common)灰化", - disabled: true, - ghost: true, - height: 30, - }, { - type: "bi.button", - text: "弹出bubble", - bubble: function () { - return BI.parseInt(Math.random() * 100) % 10 + "提示"; - }, - handler: function () { - BI.Msg.toast("1111"); - }, - height: 30, - }, { - type: "bi.button", - text: "自动撑开", - iconCls: "close-font", - // textHeight: 32, - // height: 32, - iconGap: 64, - vgap: 16, - hgap: 100, - iconPosition: "bottom", - }, { - type: "bi.button", - text: "图标在下面的按钮", - iconCls: "close-font", - iconPosition: "bottom", - }, { - type: "bi.button", - text: "图标在左边的按钮", - iconCls: "close-font", - iconPosition: "left", - }, { - type: "bi.button", - text: "图标在右边的按钮", - iconCls: "close-font", - iconPosition: "right", - }, { - type: "bi.button", - text: "浅色的一般按钮", - iconCls: "plus-font", - light: true, - }, { - type: "bi.button", - text: "浅色的成功按钮", - level: "success", - iconCls: "plus-font", - light: true, - }, { - type: "bi.button", - text: "浅色的警告按钮", - level: "warning", - iconCls: "plus-font", - light: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "浅色的失败按钮", - level: "error", - cls: "hover-mask", - light: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - level: "common", - plain: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - level: "success", - plain: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - level: "error", - plain: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - level: "warning", - plain: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - level: "ignore", - plain: true, - }, { - type: "bi.button", - iconCls: "plus-font", - plain: true, - level: "error", - }, { - type: "bi.button", - iconCls: "plus-font", - text: "朴素的按钮", - plain: true, - disabled: true, - }, { - type: "bi.button", - iconCls: "plus-font", - text: "点我,更改图标", - handler() { - this.i = this.i === undefined ? 0 : ++this.i; - const arr = ["text-background-font", "check-mark-ha-font", "close-font", "search-font", "date-change-h-font"]; - if (this.i >= arr.length) { - this.i = 0; - } - this.setIcon(arr[this.i]); - }, - height: 24, - }, { - type: "bi.button", - text: "带加载的按钮", - handler() { - console.log("触发点击事件"); - this.loading(); - setTimeout(() => { - this.loaded(); - }, 5 * 1000); - }, - }, { - type: "bi.button", - text: "带加载的按钮", - iconCls: "circle-close-font", - handler() { - console.log("触发点击事件"); - this.loading(); - setTimeout(() => { - this.loaded(); - }, 5 * 1000); - }, - }, { - type: "bi.button", - clear: true, - text: "带加载的按钮", - iconCls: "circle-close-font", - handler() { - console.log("触发点击事件"); - this.loading(); - setTimeout(() => { - this.loaded(); - }, 5 * 1000); - }, - }, { - type: "bi.button", - text: "加载中的按钮", - loading: true, - handler() { - console.log("我是无法被触发的!"); - }, - }, { - type: "bi.button", - text: "自定义图标按钮(点我修改)", - icon: { - type: "demo.joker.icon", - }, - handler() { - console.log("触发点击事件"); - this.loading(); - setTimeout(() => { - this.loaded(); - }, 5 * 1000); - }, - }, { - type: "bi.button", - text: "文字偏左的按钮", - textAlign: "left", - width: 200, - }, { - type: "bi.button", - text: "小于最小宽度的按钮", - width: 50, - }, { - type: "bi.button", - text: "一个文字超级超级长的 button, 他比按钮宽度还长。", - textWidth: 500, - width: 100, - }]; - - return { - type: "bi.left", - scrolly: true, - vgap: 100, - hgap: 20, - items: BI.map(items, function (index, value) { - return { - el: value, - }; - }), - }; - }, -}); -BI.shortcut("demo.button", Demo.Button); diff --git a/demo/js/base/button/demo.icon_button.js b/demo/js/base/button/demo.icon_button.js deleted file mode 100644 index a7bdb6c99..000000000 --- a/demo/js/base/button/demo.icon_button.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.Button = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-button" - }, - render: function () { - var items = [ - { - el: { - type: "bi.icon_button", - cls: "close-ha-font", - width: 25, - height: 25 - } - } - ]; - return { - type: "bi.left", - vgap: 200, - hgap: 20, - items: items - }; - } -}); -BI.shortcut("demo.icon_button", Demo.Button); \ No newline at end of file diff --git a/demo/js/base/button/demo.image_button.js b/demo/js/base/button/demo.image_button.js deleted file mode 100644 index 3a6d475a7..000000000 --- a/demo/js/base/button/demo.image_button.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.Button = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-button" - }, - render: function () { - var items = [ - { - el: { - type: "bi.image_button", - src: "http://www.easyicon.net/api/resizeApi.php?id=1206741&size=128", - width: 100, - height: 100 - } - } - ]; - return { - type: "bi.left", - vgap: 200, - hgap: 20, - items: items - }; - } -}); -BI.shortcut("demo.image_button", Demo.Button); \ No newline at end of file diff --git a/demo/js/base/button/demo.text_button.js b/demo/js/base/button/demo.text_button.js deleted file mode 100644 index a98414a8c..000000000 --- a/demo/js/base/button/demo.text_button.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.Button = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-button" - }, - render: function () { - var items = [ - { - el: { - type: "bi.text_button", - text: "文字按钮", - height: 30, - keyword: "w" - } - } - ]; - return { - type: "bi.left", - vgap: 200, - hgap: 20, - items: items - }; - } -}); -BI.shortcut("demo.text_button", Demo.Button); \ No newline at end of file diff --git a/demo/js/base/demo.html.js b/demo/js/base/demo.html.js deleted file mode 100644 index 73f92f53a..000000000 --- a/demo/js/base/demo.html.js +++ /dev/null @@ -1,20 +0,0 @@ -Demo.Html = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-html" - }, - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.html", - text: "

在bi.html标签中使用html原生标签

" - }, { - type: "bi.html", - text: "" - }], - hgap: 300, - vgap: 20 - }; - } -}); -BI.shortcut("demo.html", Demo.Html); \ No newline at end of file diff --git a/demo/js/base/demo.icon_label.js b/demo/js/base/demo.icon_label.js deleted file mode 100644 index f9fff3b66..000000000 --- a/demo/js/base/demo.icon_label.js +++ /dev/null @@ -1,20 +0,0 @@ -Demo.IconLabel = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-bubble" - }, - render: function () { - return { - type: "bi.default", - items: [{ - type: "bi.label", - text: "这是一个icon标签,在加了border之后仍然是居中显示的" - }, { - type: "bi.icon_label", - cls: "date-font bi-border", - height: 40, - width: 40 - }] - }; - } -}); -BI.shortcut("demo.icon_label", Demo.IconLabel); \ No newline at end of file diff --git a/demo/js/base/demo.label.js b/demo/js/base/demo.label.js deleted file mode 100644 index 0f5158f13..000000000 --- a/demo/js/base/demo.label.js +++ /dev/null @@ -1,139 +0,0 @@ -Demo.Label = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-label" - }, - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - cls: "layout-bg6", - text: "这是一个label控件,默认居中", - disabled: true, - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg1", - text: "这是一个label控件, 高度为30,默认居中", - textAlign: "center", - height: 30 - }, { - type: "bi.label", - cls: "layout-bg3", - text: "这是一个label控件,使用水平居左", - textAlign: "left", - height: 30 - }, { - type: "bi.label", - cls: "layout-bg2", - text: "这是一个label控件,whiteSpace是normal,不设置高度,为了演示这个是真的是normal的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal" - }, { - type: "bi.label", - cls: "layout-bg5", - text: "这是一个label控件,whiteSpace是默认的nowrap,不设置高度,为了演示这个是真的是nowrap的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数" - }, { - type: "bi.label", - cls: "layout-bg7", - text: "这是一个label控件,whiteSpace是默认的nowrap,高度为30,为了演示这个是真的是nowrap的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - height: 30 - }, { - type: "bi.label", - cls: "layout-bg3", - text: "这是一个label控件,whiteSpace设置为normal,高度为60,为了演示这个是真的是normal的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - height: 60 - }, { - type: "bi.label", - cls: "layout-bg5", - text: "这是一个label控件,whiteSpace设置为normal,textHeight控制text的lineHeight,这样可以实现换行效果,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textHeight: 30, - height: 60 - }, { - type: "bi.label", - cls: "layout-bg1", - text: "这是一个label控件,whiteSpace设置为nowrap,textWidth控制text的width", - textWidth: 200, - height: 60 - }, { - type: "bi.label", - cls: "layout-bg8", - text: "这是一个label控件,whiteSpace设置为normal,textWidth控制text的width,这样可以实现换行效果,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textWidth: 200, - height: 60 - }, { - type: "bi.label", - cls: "layout-bg7", - text: "whiteSpace为默认的nowrap,高度设置为60,宽度设置为300", - height: 60, - width: 300 - }, { - type: "bi.label", - cls: "layout-bg6", - text: "设置了宽度300,高度60,whiteSpace设置为normal", - whiteSpace: "normal", - width: 300, - height: 60 - }, { - type: "bi.label", - cls: "layout-bg8", - text: "textWidth设置为200,textHeight设置为30,width设置300,凑点字数看效果", - width: 300, - textWidth: 200, - textHeight: 30, - height: 60, - whiteSpace: "normal" - }, { - type: "bi.label", - cls: "layout-bg1", - text: "textWidth设置为200,width设置300,看下水平居左的换行效果", - textAlign: "left", - width: 300, - textWidth: 200, - textHeight: 30, - height: 60, - whiteSpace: "normal" - }, { - type: "bi.label", - cls: "layout-bg2", - text: "使用默认的nowrap,再去设置textHeight,只会有一行的效果", - textAlign: "left", - width: 300, - textWidth: 200, - textHeight: 30, - height: 60 - }, { - type: "bi.left", - items: [{ - type: "bi.label", - cls: "layout-bg3", - text: "在float布局中自适应的,不设高度和宽度,文字多长这个就有多长" - }], - height: 30 - }, { - type: "bi.left", - items: [{ - type: "bi.label", - cls: "layout-bg4", - text: "在float布局中自适应的,设置了宽度200,后面还有", - width: 200 - }], - height: 30 - }, { - type: "bi.left", - items: [{ - type: "bi.label", - text: "在float布局中自适应的,设置了高度,文字多长这个就有多长", - cls: "layout-bg5", - height: 30 - }], - height: 30 - }], - hgap: 300, - vgap: 20 - }; - } -}); -BI.shortcut("demo.label", Demo.Label); \ No newline at end of file diff --git a/demo/js/base/demo.label.scene.js b/demo/js/base/demo.label.scene.js deleted file mode 100644 index 13f76850a..000000000 --- a/demo/js/base/demo.label.scene.js +++ /dev/null @@ -1,590 +0,0 @@ -/** - * 整理所有label场景 - */ -Demo.LabelScene = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-label" - }, - render: function () { - var items = []; - - items.push(this.createExpander("1.1.1 文字居中,有宽度和高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg6", - text: "设置了textWidth,则一定是嵌套结构,因此需要用center_adapt布局容纳一下.为了实现不足一行时文字水平居中,超出一行时左对齐,需要设置maxWidth.", - whiteSpace: "normal", - height: 50, - width: 500, - textWidth: 200, - textAlign: "center" - })); - - items.push(this.createExpander("1.1.2 居中,有宽度和高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg6", - text: "居中,有宽度高度,有文字宽度,whiteSpace为nowrap,maxWidth会限制文字", - whiteSpace: "nowrap", - height: 50, - width: 500, - textWidth: 350, - textAlign: "center" - })); - - items.push((this.createExpander("1.2.1 居中,有宽度无高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg6", - text: "居中,有宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - width: 500, - textWidth: 200, - textAlign: "center" - }))); - - items.push((this.createExpander("1.2.1 居中,有宽度无高度,有文字宽度,whiteSpace为normal,高度被父容器拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg6", - text: "此时虽然没有对label设置高度,但由于使用了center_adapt布局,依然会垂直方向居中", - whiteSpace: "normal", - width: 500, - textWidth: 200, - textAlign: "center" - }, - top: 0, - left: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("1.2.2 居中,有宽度无高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg6", - text: "居中,有宽度无高度,有文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - width: 500, - textWidth: 350, - textAlign: "center" - }))); - - items.push((this.createExpander("1.3.1 居中,有宽度和高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,有宽度高度,无文字宽度,whiteSpace为normal,只需用center_adapt布局包一下即可.度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,whiteSpace为normal", - width: 500, - whiteSpace: "normal", - textAlign: "center", - height: 50 - }))); - - items.push((this.createExpander("1.3.2 居中,有宽度无高度,无文字宽度,whiteSpace为normal", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg3", - text: "居中,有宽度无高度,无文字宽度,whiteSpace为normal,只需用center_adapt布局包一下即可.度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,whiteSpace为normal", - width: 500, - whiteSpace: "normal", - textAlign: "center" - }, - top: 0, - left: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("1.4 居中,有宽度和高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,有宽度500有高度50,无文字宽度,whiteSpace为nowrap,此处无需两层div,设置text即可,然后设置line-height为传入高度即可实现垂直方向居中", - width: 500, - whiteSpace: "nowrap", - textAlign: "center", - height: 50 - }))); - - items.push((this.createExpander("1.5.1 居中,有宽度无高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,有宽度500无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - width: 500, - whiteSpace: "nowrap", - textAlign: "center" - }))); - - items.push((this.createExpander("1.5.2 居中,有宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 50, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg3", - text: "居中,有宽度500无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - width: 500, - whiteSpace: "nowrap", - textAlign: "center" - }, - top: 0, - left: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("1.6.1 居中,无宽度无高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度,有文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - textWidth: 500, - whiteSpace: "nowrap", - textAlign: "center" - }))); - - items.push((this.createExpander("1.6.2 居中,无宽度无高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - textWidth: 500, - whiteSpace: "normal", - textAlign: "center" - }))); - - items.push((this.createExpander("1.6.3 居中,无宽度无,有文字宽度,whiteSpace为normal,被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - textWidth: 500, - whiteSpace: "normal", - textAlign: "center" - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("1.7.1 居中,无宽度无高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "center" - }))); - - items.push((this.createExpander("1.7.2 居中,无宽度无高度,无文字宽度,whiteSpace为normal,被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "center" - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("1.7.3 居中,无宽度有高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - height: 50, - textAlign: "center" - }))); - - items.push((this.createExpander("1.8 居中,无宽度有高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度有高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - height: 50, - textAlign: "center" - }))); - - items.push((this.createExpander("1.9 居中,无宽度无高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "center" - }))); - - items.push((this.createExpander("1.9.1 居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 50, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg3", - text: "居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "center" - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("2.1.1 居左,有宽度有高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度有高度,有文字宽度,whiteSpace为normal,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - textWidth: 300, - height: 50, - width: 500 - }))); - - items.push((this.createExpander("2.1.2 居左,有宽度有高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度有高度,有文字宽度,whiteSpace为normal,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - textWidth: 300, - height: 50, - width: 500 - }))); - - items.push((this.createExpander("2.2.1 居左,有宽度无高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度无高度,有文字宽度,whiteSpace为normal,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - textWidth: 300, - width: 500 - }))); - - items.push((this.createExpander("2.2.2 居左,有宽度无高度,有文字宽度,whiteSpace为normal,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度无高度,有文字宽度,whiteSpace为normal,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - textWidth: 300, - width: 500 - }, - top: 0, - bottom: 0, - left: 0 - } - ] - }))); - - items.push((this.createExpander("2.2.3 居左,有宽度无高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - textWidth: 300, - width: 500 - }))); - - items.push((this.createExpander("2.2.4 居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - textWidth: 300, - width: 500 - }, - top: 0, - bottom: 0, - left: 0 - } - ] - }))); - - items.push((this.createExpander("2.3.1 居左,有宽度有高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度有高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - height: 50, - vgap: 5, - width: 500 - }))); - - items.push((this.createExpander("2.3.2 居左,有宽度有高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - height: 50, - width: 500 - }))); - - items.push((this.createExpander("2.4.1 居左,有宽度无高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,有宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - width: 500 - }))); - - items.push((this.createExpander("2.4.2 居左,有宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg1", - text: "居左,有宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - width: 500 - }, - top: 0, - left: 0, - bottom: 0 - } - ] - }))); - - items.push((this.createExpander("2.5.1 居左,无宽度无高度,有文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - textWidth: 300 - }))); - - items.push((this.createExpander("2.5.2 居左,无宽度无高度,有文字宽度,whiteSpace为normal,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - textWidth: 300 - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - items.push((this.createExpander("2.5.3 居左,无宽度无高度,有文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - textWidth: 300 - }))); - - items.push((this.createExpander("2.5.4 居左,无宽度无高度,有文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left", - textWidth: 300 - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - items.push((this.createExpander("2.6.1 居左,无宽度有高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度有高度,无文字宽度,whiteSpace为nowrap,注意这个是设置了vgap的,为了实现居中,lineHeight要做计算,才能准确的垂直居中", - whiteSpace: "nowrap", - textAlign: "left", - vgap: 10, - height: 50 - }))); - - items.push((this.createExpander("2.6.2 居左,无宽度有高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left", - height: 50 - }))); - - items.push((this.createExpander("2.7.1 居左,无宽度无高度,无文字宽度,whiteSpace为normal", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left" - }))); - - items.push((this.createExpander("2.7.2 居左,无宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left" - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - items.push((this.createExpander("2.7.3 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap", { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left" - }))); - - items.push((this.createExpander("2.7.4 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left" - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - items.push((this.createExpander("2.8 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "nowrap", - textAlign: "left" - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - items.push((this.createExpander("2.8.2 居左,无宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", { - type: "bi.absolute", - height: 100, - items: [ - { - el: { - type: "bi.label", - cls: "layout-bg2", - text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", - whiteSpace: "normal", - textAlign: "left" - }, - top: 0, - left: 0, - bottom: 0, - right: 0 - } - ] - }))); - - return { - type: "bi.vertical", - items: items, - hgap: 300, - vgap: 20 - }; - }, - - createExpander: function (text, popup) { - return { - type: "bi.vertical", - items: [ - { - type: "bi.label", - cls: "demo-font-weight-bold", - textAlign: "left", - text: text, - height: 30 - }, { - el: popup - } - ] - }; - } -}); -BI.shortcut("demo.label_scene", Demo.LabelScene); \ No newline at end of file diff --git a/demo/js/base/demo.message.js b/demo/js/base/demo.message.js deleted file mode 100644 index ec1a1c27b..000000000 --- a/demo/js/base/demo.message.js +++ /dev/null @@ -1,23 +0,0 @@ -Demo.Message = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-bubble" - }, - render: function () { - return { - type: "bi.center_adapt", - items: [ - { - el: { - type: "bi.button", - text: "点击我弹出一个消息框", - height: 30, - handler: function () { - BI.Msg.alert("测试消息框", "我是测试消息框的内容"); - } - } - } - ] - }; - } -}); -BI.shortcut("demo.message", Demo.Message); \ No newline at end of file diff --git a/demo/js/base/demo.pager.js b/demo/js/base/demo.pager.js deleted file mode 100644 index a5dd380a3..000000000 --- a/demo/js/base/demo.pager.js +++ /dev/null @@ -1,120 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "默认的分页" - }, { - type: "bi.pager", - height: 50, - pages: 18, - groups: 5, - curr: 6, - first: "首页", - last: "尾页" - }, { - type: "bi.label", - height: 30, - text: "显示上一页、下一页、首页、尾页" - }, { - type: "bi.pager", - dynamicShow: false, - height: 50, - pages: 18, - groups: 5, - curr: 1, - first: "首页>", - last: "<尾页" - }, { - type: "bi.label", - height: 30, - text: "显示上一页、下一页" - }, { - type: "bi.pager", - dynamicShow: false, - dynamicShowFirstLast: true, - height: 50, - pages: 18, - groups: 5, - curr: 1, - first: "首页>", - last: "<尾页" - }, { - type: "bi.label", - height: 30, - text: "自定义上一页、下一页" - }, { - type: "bi.pager", - dynamicShow: false, - height: 50, - pages: 18, - groups: 5, - curr: 6, - prev: { - type: "bi.button", - cls: "", - text: "上一页", - value: "prev", - once: false, - height: 30, - handler: function () { - - } - }, - next: { - type: "bi.button", - cls: "", - text: "下一页", - value: "next", - once: false, - handler: function () { - - } - } - }, { - type: "bi.label", - height: 30, - text: "不知道总页数的情况(测试条件 1<=page<=3)" - }, { - type: "bi.pager", - dynamicShow: false, - height: 50, - pages: false, - curr: 1, - prev: { - type: "bi.button", - cls: "", - text: "上一页", - value: "prev", - once: false, - height: 30, - handler: function () { - - } - }, - next: { - type: "bi.button", - cls: "", - text: "下一页", - value: "next", - once: false, - handler: function () { - - } - }, - hasPrev: function (v) { - return v > 1; - }, - hasNext: function (v) { - return v < 3; - } - }] - }; - } -}); -BI.shortcut("demo.pager", Demo.Func); \ No newline at end of file diff --git a/demo/js/base/editor/demo.editor.js b/demo/js/base/editor/demo.editor.js deleted file mode 100644 index bc06b2242..000000000 --- a/demo/js/base/editor/demo.editor.js +++ /dev/null @@ -1,113 +0,0 @@ -Demo.Editor = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-editor", - }, - render: function () { - var editor1 = BI.createWidget({ - type: "bi.editor", - cls: "bi-border", - watermark: "报错信息显示在控件上方", - errorText: "字段不可重名!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", - width: 200, - height: 24, - }); - editor1.on(BI.Editor.EVENT_ENTER, function () { - editor1.blur(); - }); - var editor2 = BI.createWidget({ - type: "bi.editor", - cls: "bi-border", - watermark: "输入'a'会有错误信息", - disabled: true, - errorText: "字段不可重名", - validationChecker: function (v) { - if (v == "a") { - return false; - } - - return true; - }, - allowBlank: true, - width: 200, - height: 24, - }); - var editor3 = BI.createWidget({ - type: "bi.editor", - cls: "bi-border", - watermark: "输入'a'会有错误信息且回车键不能退出编辑", - errorText: "字段不可重名", - value: "a", - validationChecker: function (v) { - if (v == "a") { - return false; - } - - return true; - }, - quitChecker: function (v) { - return false; - }, - allowBlank: true, - width: 300, - height: 24, - }); - var editor4 = BI.createWidget({ - type: "bi.editor", - cls: "bi-border", - inputType: "password", - autocomplete: "new-password", - watermark: "请输入密码", - allowBlank: true, - width: 300, - height: 24, - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: editor1, - left: 0, - top: 0, - }, { - el: editor2, - left: 250, - top: 30, - }, { - el: editor3, - left: 500, - top: 60, - }, { - el: editor4, - left: 700, - top: 60, - }, { - el: { - type: "bi.button", - text: "disable", - handler: function () { - editor1.setEnable(false); - editor2.setEnable(false); - editor3.setEnable(false); - }, - height: 30, - }, - left: 100, - bottom: 60, - }, { - el: { - type: "bi.button", - text: "enable", - handler: function () { - editor1.setEnable(true); - editor2.setEnable(true); - editor3.setEnable(true); - }, - height: 30, - }, - left: 200, - bottom: 60, - }], - }); - }, -}); -BI.shortcut("demo.editor", Demo.Editor); diff --git a/demo/js/base/editor/demo.multifile_editor.js b/demo/js/base/editor/demo.multifile_editor.js deleted file mode 100644 index ef37a9d7e..000000000 --- a/demo/js/base/editor/demo.multifile_editor.js +++ /dev/null @@ -1,26 +0,0 @@ -Demo.CodeEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-editor" - }, - render: function () { - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.adaptive", - cls: "layout-bg1", - items: [{ - type: "bi.multifile_editor", - width: 400, - height: 300 - }], - width: 400, - height: 300 - }, - top: 50, - left: 50 - }] - }; - } -}); -BI.shortcut("demo.multifile_editor", Demo.CodeEditor); \ No newline at end of file diff --git a/demo/js/base/editor/demo.textarea_editor.js b/demo/js/base/editor/demo.textarea_editor.js deleted file mode 100644 index 4eb6356dc..000000000 --- a/demo/js/base/editor/demo.textarea_editor.js +++ /dev/null @@ -1,44 +0,0 @@ -Demo.CodeEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-editor" - }, - render: function () { - var editor = BI.createWidget({ - type: "bi.textarea_editor", - cls: "bi-border", - width: 600, - height: 400, - watermark: "请输入内容", - errorText: "检测内容有误", - validationChecker: function (v) { - return BI.isNotEmptyString(v); - }, - }); - editor.on(BI.TextAreaEditor.EVENT_FOCUS, function () { - BI.Msg.toast("Focus"); - }); - editor.on(BI.TextAreaEditor.EVENT_BLUR, function () { - BI.Msg.toast("Blur"); - }); - BI.createWidget({ - type: "bi.vertical", - element: this, - hgap: 30, - vgap: 20, - items: [editor, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(editor.getValue())); - } - }, { - type: "bi.button", - text: "setValue", - handler: function () { - editor.setValue("测试数据"); - } - }] - }); - } -}); -BI.shortcut("demo.textarea_editor", Demo.CodeEditor); \ No newline at end of file diff --git a/demo/js/base/tip/demo.bubble.js b/demo/js/base/tip/demo.bubble.js deleted file mode 100644 index 717ff82d2..000000000 --- a/demo/js/base/tip/demo.bubble.js +++ /dev/null @@ -1,77 +0,0 @@ -Demo.Bubble = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-bubble" - }, - render: function () { - var btns = []; - var items = [ - { - el: { - ref: function (_ref) { - btns.push(_ref); - }, - type: "bi.button", - text: "bubble测试(消息)", - title: "123", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble1", "bubble测试", this, { - level: "common" - }); - } - } - }, { - el: { - ref: function (_ref) { - btns.push(_ref); - }, - type: "bi.button", - text: "bubble测试(成功)", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble2", "bubble测试", this, { - offsetStyle: "center", - level: "success" - }); - } - } - }, { - el: { - ref: function (_ref) { - btns.push(_ref); - }, - type: "bi.button", - text: "bubble测试(错误)", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble3", "bubble测试", this, { - offsetStyle: "right", - level: "error" - }); - } - } - }, { - el: { - ref: function (_ref) { - btns.push(_ref); - }, - type: "bi.button", - text: "bubble测试(警告)", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble4", "bubble测试", this, { - level: "warning" - }); - } - } - } - ]; - return { - type: "bi.left", - vgap: 200, - hgap: 20, - items: items - }; - } -}); -BI.shortcut("demo.bubble", Demo.Bubble); \ No newline at end of file diff --git a/demo/js/base/tip/demo.title.js b/demo/js/base/tip/demo.title.js deleted file mode 100644 index 5a983068d..000000000 --- a/demo/js/base/tip/demo.title.js +++ /dev/null @@ -1,59 +0,0 @@ -Demo.Title = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-title" - }, - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - cls: "layout-bg1", - height: 50, - title: "title提示", - text: "移上去有title提示", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg6", - height: 50, - disabled: true, - warningTitle: "title错误提示", - text: "移上去有title错误提示", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg2", - height: 50, - disabled: true, - tipType: "success", - title: "自定义title提示效果", - warningTitle: "自定义title提示效果", - text: "自定义title提示效果", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg3", - height: 50, - title: () => "函数返回值作为title提示", - text: "title提示支持函数", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg4", - height: 50, - title: function () { - return { - level: "success", - text: "自定义title\n提示效果", - textAlign: "center" - }; - }, - text: "title提示支持对象,作为bi.tooltip的props", - textAlign: "center" - }], - hgap: 300, - vgap: 20 - }; - } -}); -BI.shortcut("demo.title", Demo.Title); diff --git a/demo/js/base/tip/demo.toast.js b/demo/js/base/tip/demo.toast.js deleted file mode 100644 index fcb845964..000000000 --- a/demo/js/base/tip/demo.toast.js +++ /dev/null @@ -1,74 +0,0 @@ -Demo.Toast = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-toast" - }, - render: function () { - var items = [ - { - el: { - type: "bi.button", - text: "简单Toast测试(success)", - height: 30, - handler: function () { - BI.Msg.toast("这是一条简单的数据", { - level: "success" - }); - } - } - }, { - el: { - type: "bi.button", - text: "很长的Toast测试(normal)", - height: 30, - handler: function () { - BI.Msg.toast("这是一条很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的数据", { - - }); - } - } - }, { - el: { - type: "bi.button", - text: "非常长的Toast测试(warning)", - height: 30, - handler: function () { - BI.Msg.toast("这是一条非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长的数据", { - level: "warning", - autoClose: false - }); - } - } - }, { - el: { - type: "bi.button", - text: "错误提示Toast测试(error)", - height: 30, - handler: function () { - BI.Msg.toast("错误提示Toast测试", { - level: "error" - }); - } - } - }, { - el: { - type: "bi.button", - text: "错误提示Toast测试(error), 此toast不会自动消失", - height: 30, - handler: function () { - BI.Msg.toast("错误提示Toast测试", { - autoClose: false - }); - } - } - } - ]; - BI.createWidget({ - type: "bi.left", - element: this, - vgap: 200, - hgap: 20, - items: items - }); - } -}); -BI.shortcut("demo.toast", Demo.Toast); \ No newline at end of file diff --git a/demo/js/base/tree/demo.part_tree.js b/demo/js/base/tree/demo.part_tree.js deleted file mode 100644 index 339fdabd1..000000000 --- a/demo/js/base/tree/demo.part_tree.js +++ /dev/null @@ -1,81 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - mounted: function () { - this.partTree.stroke({ - keyword: "1" - }); - }, - - render: function () { - var self = this; - return { - type: "bi.vtape", - items: [{ - type: "bi.label", - height: 50, - text: "先初始化一份数据,然后再异步获取数据的树" - }, { - type: "bi.part_tree", - ref: function (_ref) { - self.partTree = _ref; - }, - paras: { - selectedValues: {"1": {}, "2": {"1": {}}} - }, - itemsCreator: function (op, callback) { - if (op.type === BI.TreeView.REQ_TYPE_INIT_DATA) { - callback({ - items: [{ - id: "1", - text: 1, - isParent: true, - open: true - }, { - id: "11", - pId: "1", - text: 11, - isParent: true, - open: true - }, { - id: "111", - pId: "11", - text: 111, - isParent: true - }, { - id: "2", - text: 2 - }, { - id: "3", - text: 3 - }], - hasNext: BI.isNull(op.id) - }); - return; - } - callback({ - items: [{ - id: (op.id || "") + "1", - pId: op.id, - text: 1, - isParent: true - }, { - id: (op.id || "") + "2", - pId: op.id, - text: 2 - }, { - id: (op.id || "") + "3", - pId: op.id, - text: 3 - }], - hasNext: BI.isNull(op.id) - }); - } - }] - }; - - } -}); -BI.shortcut("demo.part_tree", Demo.Func); \ No newline at end of file diff --git a/demo/js/base/tree/demo.sync_tree.js b/demo/js/base/tree/demo.sync_tree.js deleted file mode 100644 index 682619b7f..000000000 --- a/demo/js/base/tree/demo.sync_tree.js +++ /dev/null @@ -1,107 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - mounted: function () { - this.syncTree1.stroke({ - keyword: "1" - }); - this.syncTree2.stroke({ - keyword: "1" - }); - }, - - render: function () { - var self = this; - return { - type: "bi.vtape", - rowSize: [0.5, 0.5], - items: [ - { - type: "bi.vtape", - items: [ - { - type: "bi.label", - height: 50, - text: "可以异步获取数据的树" - }, { - type: "bi.async_tree", - ref: function (_ref) { - self.syncTree1 = _ref; - }, - paras: { - selectedValues: { "1": {}, "2": { "1": {} } } - }, - itemsCreator: function (op, callback) { - callback({ - items: [{ - id: (op.id || "") + "1", - pId: op.id, - text: (op.id || "") + "1", - isParent: true, - iconCls: "close-h-font" - }, { - id: (op.id || "") + "2", - pId: op.id, - text: (op.id || "") + "2", - iconCls: "search-font" - }, { - id: (op.id || "") + "3", - pId: op.id, - text: (op.id || "") + "3", - iconCls: "date-font" - }], - hasNext: BI.isNull(op.id) - }); - } - }, - ] - }, - { - type: "bi.vtape", - items: [ - { - type: "bi.label", - height: 50, - text: "showIcon属性搭配节点iconCls,可以显示图标" - }, { - type: "bi.async_tree", - ref: function (_ref) { - self.syncTree2 = _ref; - }, - paras: { - selectedValues: { "1": {}, "2": { "1": {} } } - }, - showIcon: true, - itemsCreator: function (op, callback) { - callback({ - items: [{ - id: (op.id || "") + "1", - pId: op.id, - text: (op.id || "") + "1", - isParent: true, - iconCls: "close-h-font" - }, { - id: (op.id || "") + "2", - pId: op.id, - text: (op.id || "") + "2", - iconCls: "search-font" - }, { - id: (op.id || "") + "3", - pId: op.id, - text: (op.id || "") + "3", - iconCls: "date-font" - }], - hasNext: BI.isNull(op.id) - }); - } - }, - ] - } - ] - }; - - } -}); -BI.shortcut("demo.sync_tree", Demo.Func); diff --git a/demo/js/base/tree/demo.tree_view.js b/demo/js/base/tree/demo.tree_view.js deleted file mode 100644 index 959742a4c..000000000 --- a/demo/js/base/tree/demo.tree_view.js +++ /dev/null @@ -1,52 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createDefaultTree: function () { - var tree = BI.createWidget({ - type: "bi.tree_view" - }); - tree.initTree([ - {id: 1, pId: 0, text: "test1", open: true}, - {id: 11, pId: 1, text: "test11"}, - {id: 12, pId: 1, text: "test12"}, - {id: 111, pId: 11, text: "test111"}, - {id: 2, pId: 0, text: "test2", open: true}, - {id: 21, pId: 2, text: "test21"}, - {id: 22, pId: 2, text: "test22"} - ]); - return tree; - }, - - render: function () { - var self = this; - BI.createWidget({ - type: "bi.grid", - columns: 1, - rows: 1, - element: this, - items: [{ - column: 0, - row: 0, - el: { - type: "bi.vtape", - items: [ - { - el: this._createDefaultTree() - }, - { - el: { - type: "bi.label", - text: "tree.initTree([{\"id\":1, \"pId\":0, \"text\":\"test1\", open:true},{\"id\":11, \"pId\":1, \"text\":\"test11\"},{\"id\":12, \"pId\":1, \"text\":\"test12\"},{\"id\":111, \"pId\":11, \"text\":\"test111\"}])", - whiteSpace: "normal" - }, - height: 50 - } - ] - } - }] - }); - } -}); -BI.shortcut("demo.tree_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/combo/demo.bubble_combo.js b/demo/js/case/combo/demo.bubble_combo.js deleted file mode 100644 index 00072f6bc..000000000 --- a/demo/js/case/combo/demo.bubble_combo.js +++ /dev/null @@ -1,121 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this, count = 1; - var combo1 = BI.createWidget({ - type: "bi.bubble_combo", - trigger: "click,hover", - el: { - type: "bi.button", - text: "测试", - height: 24 - }, - popup: { - el: { - type: "bi.button_group", - items: BI.makeArray(100, { - type: "bi.text_item", - height: 24, - text: "item" - }), - layouts: [{ - type: "bi.vertical" - }] - }, - maxHeight: 200 - } - }); - var combo2 = BI.createWidget({ - type: "bi.bubble_combo", - direction: "right", - el: { - type: "bi.button", - text: "测试", - height: 24 - }, - popup: { - type: "bi.text_bubble_bar_popup_view", - text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", - ref: function () { - self.popup = this; - } - }, - listeners: [{ - eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.populate((count++) % 2 === 1 ? "我的文字变少了" : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字"); - } - }] - }); - - var combo3 = BI.createWidget({ - type: "bi.bubble_combo", - el: { - type: "bi.button", - text: "测试", - height: 25 - }, - popup: { - type: "bi.text_bubble_bar_popup_view", - text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", - ref: function () { - self.popup = this; - } - }, - listeners: [{ - eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.populate((count++) % 2 === 1 ? "我的文字变少了" : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字"); - } - }] - }); - - var combo4 = BI.createWidget({ - type: "bi.bubble_combo", - el: { - type: "bi.button", - text: "测试", - height: 25 - }, - popup: { - type: "bi.text_bubble_bar_popup_view", - text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", - ref: function () { - self.popup = this; - } - }, - listeners: [{ - eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.populate((count++) % 2 === 1 ? "我的文字变少了" : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字"); - } - }] - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: combo1, - left: 150, - top: 10 - }, { - el: combo2, - left: 10, - bottom: 200 - }, { - el: combo3, - right: 10, - bottom: 10 - }, { - el: combo4, - right: 10, - top: 10 - }] - }); - } -}); -BI.shortcut("demo.bubble_combo", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/combo/demo.editor_icon_check_combo.js b/demo/js/case/combo/demo.editor_icon_check_combo.js deleted file mode 100644 index b4048f2ba..000000000 --- a/demo/js/case/combo/demo.editor_icon_check_combo.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.TextValueCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.editor_icon_check_combo", - ref: function () { - self.combo = this; - }, - watermark: "默认值", - width: 200, - height: 24, - value: 2, - items: [{ - // text: "MVC-1", - value: "1" - }, { - // text: "MVC-2", - value: "2" - }, { - // text: "MVC-3", - value: "3" - }] - }, { - type: "bi.button", - width: 90, - height: 25, - text: "setValue为空", - handler: function () { - self.combo.setValue() - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.editor_icon_check_combo", Demo.TextValueCombo); \ No newline at end of file diff --git a/demo/js/case/combo/demo.icon_combo.js b/demo/js/case/combo/demo.icon_combo.js deleted file mode 100644 index bdd90d423..000000000 --- a/demo/js/case/combo/demo.icon_combo.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Created by Dailer on 2017/7/12. - */ -Demo.IconCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - - var self = this; - - - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.icon_combo", - container: "body", - ref: function (_ref) { - self.refs = _ref; - }, - value: "第二项", - items: [{ - value: "第一项", - iconCls: "close-font" - }, { - value: "第二项", - iconCls: "search-font" - }, { - value: "第三项", - iconCls: "copy-font" - }] - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.icon_combo", Demo.IconCombo); \ No newline at end of file diff --git a/demo/js/case/combo/demo.icon_text_value_combo.js b/demo/js/case/combo/demo.icon_text_value_combo.js deleted file mode 100644 index d473c87bf..000000000 --- a/demo/js/case/combo/demo.icon_text_value_combo.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Created by Windy on 2017/12/13. - */ -Demo.IconTextValueCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.icon_text_value_combo", - text: "默认值", - // defaultIconCls: "next-page-h-font", - width: 300, - items: [{ - text: "MVC-1", - iconCls: "close-font", - value: 1 - }, { - text: "MVC-2", - iconCls: "date-font", - value: 2 - }, { - text: "MVC-3", - iconCls: "search-close-h-font", - value: 3 - }] - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.icon_text_value_combo", Demo.IconTextValueCombo); \ No newline at end of file diff --git a/demo/js/case/combo/demo.search_text_value_combo.js b/demo/js/case/combo/demo.search_text_value_combo.js deleted file mode 100644 index 7491283d6..000000000 --- a/demo/js/case/combo/demo.search_text_value_combo.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Created by Windy on 2018/2/4. - */ -Demo.SearchTextValueCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var combo, searchCombo; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.search_text_value_combo", - ref: function () { - combo = this; - }, - warningTitle: "111", - text: "默认值", - value: 14, - width: 300, - items: [{ - text: "ABC-1", - iconCls: "date-font", - value: 1 - }, { - text: "BCD-2", - iconCls: "search-font", - value: 2 - }, { - text: "CDE-3", - iconCls: "pull-right-font", - value: 3 - }, { - text: "DEF-3", - iconCls: "pull-right-font", - value: 4 - }, { - text: "FEG-3", - iconCls: "pull-right-font", - value: 5 - }, { - text: "FGH-3", - iconCls: "pull-right-font", - value: 6 - }, { - text: "GHI-3", - iconCls: "pull-right-font", - value: 7 - }, { - text: "HIJ-3", - iconCls: "pull-right-font", - value: 8 - }, { - text: "IJK-3", - iconCls: "pull-right-font", - value: 9 - }, { - text: "JKL-3", - iconCls: "pull-right-font", - value: 10 - }] - }, { - type: "bi.all_value_multi_text_value_combo", - items: Demo.CONSTANTS.ITEMS, - text: "提示文本", - width: 200, - value: { - type: 1, - value: ["1", "2", "柳州市城贸金属材料有限责任公司", "3"] - }, - ref: function () { - searchCombo = this; - }, - listeners: [{ - eventName: "BI.AllValueMultiTextValueCombo.EVENT_CONFIRM", - action: function () { - BI.Msg.toast(JSON.stringify(searchCombo.getValue())); - } - }] - }, { - type: "bi.button", - text: "setValue(3)", - width: 90, - height: 25, - handler: function () { - combo.setValue(11); - } - }, { - type: "bi.button", - text: "getValue()", - width: 90, - height: 25, - handler: function () { - BI.Msg.toast(JSON.stringify(searchCombo.getValue())); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.search_text_value_combo", Demo.SearchTextValueCombo); \ No newline at end of file diff --git a/demo/js/case/combo/demo.text_value_combo.js b/demo/js/case/combo/demo.text_value_combo.js deleted file mode 100644 index 4f8c4a92e..000000000 --- a/demo/js/case/combo/demo.text_value_combo.js +++ /dev/null @@ -1,260 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.TextValueCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var combo1, combo2; - - var items = [ - { - text: "MVC-1", - iconCls: "date-font", - value: 1 - }, { - text: "MVC-2", - iconCls: "search-font", - value: 2 - }, { - text: "MVC-3", - iconCls: "pull-right-font", - value: 3 - } - ]; - - // 创建下拉框各种场景用例 - return { - type: "bi.vertical", - vgap: 20, - hgap: 20, - items: [ - this.createCombo("无初始值,带提示文字", { - type: "bi.text_value_combo", - ref: (ref) => { - this.combo1 = ref; - }, - defaultText: "请选择", - width: 300, - items: items, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }), - this.createCombo("自动根据value匹配text", { - type: "bi.text_value_combo", - ref: function () { - combo = this; - }, - defaultText: "请选择", - width: 300, - value: 1, - items: items, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }), - this.createCombo("无初始值,可以清空", { - type: "bi.text_value_combo", - ref: function () { - combo = this; - }, - defaultText: "请选择", - width: 300, - items: items, - allowClear: true, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }), - this.createCombo("有初始值,可以清空", { - type: "bi.text_value_combo", - ref: function () { - combo = this; - }, - defaultText: "请选择", - width: 300, - value: 1, - items: items, - allowClear: true, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }), - this.createCombo("有初始值,value不匹配,自动标红,指定标红文字", { - type: "bi.text_value_combo", - ref: function () { - combo = this; - }, - width: 300, - text: "MVC-111", - value: 111, - items: items, - allowClear: true, - defaultText: "请选择", - warningTitle: "value值不合法", - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }), - this.createCombo("无初始值,外部受控调用setValue", { - type: "bi.vertical", - items: [ - { - type: "bi.text_value_combo", - ref: function () { - combo1 = this; - }, - width: 300, - items: items, - allowClear: true, - defaultText: "请选择", - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }, { - el: { - type: "bi.button", - text: "setValue(1)", - handler: function () { - combo1.setValue(1); - }, - }, - vgap: 10, - } - ] - }), - this.createCombo("无初始值,外部受控调用setStatus", { - type: "bi.vertical", - items: [ - { - type: "bi.text_value_combo", - ref: function () { - combo2 = this; - }, - width: 300, - items: items, - allowClear: true, - defaultText: "请选择", - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - }, { - el: { - type: "bi.button", - text: "setStatus()", - handler: function () { - combo2.setStatus("error"); - }, - }, - vgap: 10, - } - ] - }), - this.createCombo("支持复选", { - type: "bi.vertical", - items: [ - { - type: "bi.text_value_combo", - width: 300, - items: items, - allowClear: true, - defaultText: "请选择", - chooseType: BI.Selection.Multi, - value: [1], - // allowSelectAll: false, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - } - ] - }), - this.createCombo("支持复选,不要全选功能", { - type: "bi.vertical", - items: [ - { - type: "bi.text_value_combo", - width: 300, - items: items, - allowClear: true, - defaultText: "请选择", - chooseType: BI.Selection.Multi, - value: [1], - allowSelectAll: false, - listeners: [ - { - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - console.log(this.getValue()); - } - } - ] - } - ] - }) - ] - }; - }, - - createCombo: function (text, combo) { - return { - type: "bi.vertical", - items: [ - { - el: { - type: "bi.label", - textAlign: "left", - text, - }, - bgap: 10 - }, { - el: combo, - bgap: 10, - }, - ] - }; - } -}); - -BI.shortcut("demo.text_value_combo", Demo.TextValueCombo); diff --git a/demo/js/case/combo/demo.text_value_down_list_combo.js b/demo/js/case/combo/demo.text_value_down_list_combo.js deleted file mode 100644 index 3f0a7af54..000000000 --- a/demo/js/case/combo/demo.text_value_down_list_combo.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.TextValueDownListCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.text_value_down_list_combo", - width: 300, - ref: function (_ref) { - self.refs = _ref; - }, - text: "默认值", - value: 11, - items: [[{ - text: "属于", - value: 1, - cls: "dot-e-font" - }, { - text: "不属于", - value: 2, - cls: "dot-e-font" - }], [{ - el: { - text: "大于", - value: 3, - iconCls1: "dot-e-font" - }, - value: 3, - children: [{ - text: "固定值", - value: 4, - cls: "dot-e-font" - }, { - text: "平均值", - value: 5, - cls: "dot-e-font" - }] - }]] - }, { - type: "bi.button", - width: 90, - height: 25, - text: "setValue", - handler: function () { - self.refs.setValue(2); - } - }, { - type: "bi.button", - width: 90, - height: 25, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(self.refs.getValue())); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.text_value_down_list_combo", Demo.TextValueDownListCombo); \ No newline at end of file diff --git a/demo/js/case/combo/demo.text_vlaue_check_combo.js b/demo/js/case/combo/demo.text_vlaue_check_combo.js deleted file mode 100644 index 607a060c9..000000000 --- a/demo/js/case/combo/demo.text_vlaue_check_combo.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.TextValueCheckCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.text_value_check_combo", - ref: function () { - self.combo = this; - }, - text: "默认值", - //value: 1, - width: 300, - items: [{ - text: "MVC-1", - value: 1 - }, { - text: "MVC-2", - value: 2 - }, { - text: "MVC-3", - value: 3 - }] - }, { - type: "bi.button", - width: 90, - height: 25, - handler: function () { - BI.Msg.alert("", JSON.stringify(self.combo.getValue())); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.text_value_check_combo", Demo.TextValueCheckCombo); \ No newline at end of file diff --git a/demo/js/case/demo.calendar.js b/demo/js/case/demo.calendar.js deleted file mode 100644 index 8b747adc2..000000000 --- a/demo/js/case/demo.calendar.js +++ /dev/null @@ -1,32 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - var date = new Date(); - return { - type: "bi.calendar", - ref: function () { - self.calendar = this; - }, - logic: { - dynamic: false - }, - year: date.getFullYear(), - month: date.getMonth(), - day: date.getDate() - }; - }, - - mounted: function () { - var date = new Date(); - this.calendar.setValue({ - year: date.getFullYear(), - month: date.getMonth(), - day: date.getDate() - }); - } -}); -BI.shortcut("demo.calendar", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/demo.click.effect.js b/demo/js/case/demo.click.effect.js deleted file mode 100644 index 4d36952c9..000000000 --- a/demo/js/case/demo.click.effect.js +++ /dev/null @@ -1,40 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - return { - type: "bi.vertical", - items: BI.createItems([{ - text: "bi-list-item", - cls: "bi-list-item close-font" - }, { - text: "bi-list-item-simple", - cls: "bi-list-item-simple close-font" - }, { - text: "bi-list-item-effect", - cls: "bi-list-item-effect close-font" - }, { - text: "bi-list-item-active", - cls: "bi-list-item-active close-font" - }, { - text: "bi-list-item-active2", - cls: "bi-list-item-active2 close-font" - }, { - text: "bi-list-item-select", - cls: "bi-list-item-select close-font" - }, { - text: "bi-list-item-select2", - cls: "bi-list-item-select2 close-font" - }], { - type: "bi.icon_text_item", - logic: { - dynamic: true - } - }), - vgap: 10 - }; - } -}); -BI.shortcut("demo.click_item_effect", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/demo.color_chooser.js b/demo/js/case/demo.color_chooser.js deleted file mode 100644 index 81a719864..000000000 --- a/demo/js/case/demo.color_chooser.js +++ /dev/null @@ -1,40 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.color_chooser", - recommendColorsGetter: function () { - return ["#ffffff", "#9d775f", "#dd4b4b", "#ef8b07", "#fcc800"] - }, - width: 24, - height: 24 - }, - left: 100, - top: 250 - }, { - el: { - type: "bi.simple_color_chooser", - width: 30, - height: 24 - }, - left: 400, - top: 250 - }, { - el: { - type: "bi.color_chooser", - width: 230, - height: 24 - }, - left: 100, - top: 350 - }] - }; - } -}); -BI.shortcut("demo.color_chooser", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/demo.color_chooser_popup.js b/demo/js/case/demo.color_chooser_popup.js deleted file mode 100644 index 68135d1c3..000000000 --- a/demo/js/case/demo.color_chooser_popup.js +++ /dev/null @@ -1,27 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.color_chooser_popup", - cls: "bi-card" - }, - left: 100, - top: 250 - }, { - el: { - type: "bi.simple_color_chooser_popup", - cls: "bi-card" - }, - left: 400, - top: 250 - }] - }; - } -}); -BI.shortcut("demo.color_chooser_popup", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/demo.segment.js b/demo/js/case/demo.segment.js deleted file mode 100644 index 946c5d952..000000000 --- a/demo/js/case/demo.segment.js +++ /dev/null @@ -1,28 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func", - }, - - render: function () { - BI.createWidget({ - type: "bi.horizontal", - element: this, - vgap: 20, - hgap: 30, - items: [{ - type: "bi.segment", - items: [{ - text: "较长的选项1", - value: 1, - }, { - text: "选项2", - value: 2, - }, { - text: "选项3", - value: 3, - }], - }], - }); - }, -}); -BI.shortcut("demo.segment", Demo.Func); diff --git a/demo/js/case/editor/demo.clear_editor.js b/demo/js/case/editor/demo.clear_editor.js deleted file mode 100644 index 6ad9b4283..000000000 --- a/demo/js/case/editor/demo.clear_editor.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.ClearEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.clear_editor", - cls: "bi-border", - width: 300, - watermark: "这个是带清除按钮的", - value: 123 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.clear_editor", Demo.ClearEditor); \ No newline at end of file diff --git a/demo/js/case/editor/demo.shelter_editor.js b/demo/js/case/editor/demo.shelter_editor.js deleted file mode 100644 index 2d351df62..000000000 --- a/demo/js/case/editor/demo.shelter_editor.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.ClearEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var editor = BI.createWidget({ - type: "bi.shelter_editor", - cls: "bi-border", - validationChecker: function (v) { - return v != "a"; - }, - watermark: "可以设置标记的输入框", - value: "这是一个遮罩", - keyword: "z" - }); - BI.createWidget({ - type: "bi.vertical", - element: this, - hgap: 30, - vgap: 20, - bgap: 50, - items: [editor] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.button", - text: "focus", - height: 25, - handler: function () { - editor.focus(); - } - }, - right: 10, - left: 10, - bottom: 10 - }] - }); - } -}); - -BI.shortcut("demo.shelter_editor", Demo.ClearEditor); \ No newline at end of file diff --git a/demo/js/case/editor/demo.sign_editor.js b/demo/js/case/editor/demo.sign_editor.js deleted file mode 100644 index 4850394f7..000000000 --- a/demo/js/case/editor/demo.sign_editor.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Created by Dailer on 2017/7/14. - */ -Demo.SignEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var editor = BI.createWidget({ - type: "bi.sign_editor", - cls: "bi-border bi-focus-shadow", - validationChecker: function (v) { - return v != "abc"; - }, - watermark: "可以设置标记的输入框", - text: "这是一个标记,点击它即可进行输入" - }); - editor.setValue(2); - BI.createWidget({ - type: "bi.vertical", - element: this, - hgap: 30, - vgap: 20, - items: [editor] - }); - } -}); - -BI.shortcut("demo.sign_editor", Demo.SignEditor); \ No newline at end of file diff --git a/demo/js/case/editor/demo.simple_state_editor.js b/demo/js/case/editor/demo.simple_state_editor.js deleted file mode 100644 index d825a9a8f..000000000 --- a/demo/js/case/editor/demo.simple_state_editor.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.SimpleStateEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_adapt", - items: [{ - type: "bi.simple_state_editor", - ref: function () { - self.editor = this; - }, - cls: "bi-border", - width: 300 - }], - vgap: 20 - - }; - }, - - mounted: function () { - var self = this; - setTimeout(function () { - self.editor.setState(["*", "*"]); - }, 1000); - } -}); - -BI.shortcut("demo.simple_state_editor", Demo.SimpleStateEditor); \ No newline at end of file diff --git a/demo/js/case/editor/demo.state_editor.js b/demo/js/case/editor/demo.state_editor.js deleted file mode 100644 index e87f4c363..000000000 --- a/demo/js/case/editor/demo.state_editor.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.StateEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_adapt", - items: [{ - type: "bi.state_editor", - ref: function () { - self.editor = this; - }, - cls: "bi-border", - width: 300 - }], - vgap: 20 - - }; - }, - - - mounted: function () { - var self = this; - setTimeout(function () { - self.editor.setState(["*", "*"]); - }, 1000); - } -}); - -BI.shortcut("demo.state_editor", Demo.StateEditor); \ No newline at end of file diff --git a/demo/js/case/item/demo.multi_select_item.js b/demo/js/case/item/demo.multi_select_item.js deleted file mode 100644 index f5e35c7eb..000000000 --- a/demo/js/case/item/demo.multi_select_item.js +++ /dev/null @@ -1,22 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "复选item" - }, { - type: "bi.multi_select_item", - text: "复选项" - }], - hgap: 300 - }; - } -}); -BI.shortcut("demo.multi_select_item", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/item/demo.single_select_item.js b/demo/js/case/item/demo.single_select_item.js deleted file mode 100644 index 2244df84b..000000000 --- a/demo/js/case/item/demo.single_select_item.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Items = BI.inherit(BI.Widget, { - - render: function () { - - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "单选item" - }, { - type: "bi.single_select_item", - text: "单选项" - }], - hgap: 300 - }; - } -}); - - -BI.shortcut("demo.single_select_item", Demo.Items); \ No newline at end of file diff --git a/demo/js/case/item/demo.single_select_radio_item.js b/demo/js/case/item/demo.single_select_radio_item.js deleted file mode 100644 index 3052390ce..000000000 --- a/demo/js/case/item/demo.single_select_radio_item.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Items = BI.inherit(BI.Widget, { - - render: function () { - - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "单选item" - }, { - type: "bi.single_select_radio_item", - text: "单选项" - }], - hgap: 300 - }; - } -}); - - -BI.shortcut("demo.single_select_radio_item", Demo.Items); \ No newline at end of file diff --git a/demo/js/case/list/demo.lazy_loader.js b/demo/js/case/list/demo.lazy_loader.js deleted file mode 100644 index 568238791..000000000 --- a/demo/js/case/list/demo.lazy_loader.js +++ /dev/null @@ -1,23 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - BI.createWidget({ - type: "bi.lazy_loader", - element: this, - el: { - layouts: [{ - type: "bi.left", - hgap: 5 - }] - }, - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.button" - }) - }); - } -}); -BI.shortcut("demo.lazy_loader", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/list/demo.select_list.js b/demo/js/case/list/demo.select_list.js deleted file mode 100644 index f32d426be..000000000 --- a/demo/js/case/list/demo.select_list.js +++ /dev/null @@ -1,26 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - BI.createWidget({ - type: "bi.select_list", - toolbar: { - type: "bi.multi_select_bar", - iconWrapperWidth: 26 - }, - element: this, - el: { - el: { - chooseType: BI.Selection.Multi - } - }, - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.SIMPLE_ITEMS), { - type: "bi.multi_select_item" - }) - }); - } -}); -BI.shortcut("demo.select_list", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pager/demo.all_count_pager.js b/demo/js/case/pager/demo.all_count_pager.js deleted file mode 100644 index 829181820..000000000 --- a/demo/js/case/pager/demo.all_count_pager.js +++ /dev/null @@ -1,25 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - BI.createWidget({ - type: "bi.vertical", - hgap: 200, - vgap: 50, - element: this, - items: [{ - type: "bi.label", - height: 30, - text: " (测试条件:总页数为3)" - }, { - type: "bi.all_count_pager", - pages: 3, - curr: 1, - count: 1000 - }] - }); - } -}); -BI.shortcut("demo.all_count_pager", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pager/demo.direction_pager.js b/demo/js/case/pager/demo.direction_pager.js deleted file mode 100644 index d554d50df..000000000 --- a/demo/js/case/pager/demo.direction_pager.js +++ /dev/null @@ -1,50 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - mounted: function () { - this.pager.populate(); - }, - - render: function () { - var self = this; - BI.createWidget({ - type: "bi.vertical", - hgap: 200, - vgap: 50, - element: this, - items: [{ - type: "bi.direction_pager", - ref: function (_ref) { - self.pager = _ref; - }, - horizontal: { - pages: false, // 总页数 - curr: 1, // 初始化当前页, pages为数字时可用 - - hasPrev: function (v) { - return v > 1; - }, - hasNext: function () { - return true; - }, - firstPage: 1 - }, - vertical: { - pages: false, // 总页数 - curr: 1, // 初始化当前页, pages为数字时可用 - - hasPrev: function (v) { - return v > 1; - }, - hasNext: function () { - return true; - }, - firstPage: 1 - } - }] - }); - } -}); -BI.shortcut("demo.direction_pager", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pane/demo.list_pane.js b/demo/js/case/pane/demo.list_pane.js deleted file mode 100644 index 5766be4fb..000000000 --- a/demo/js/case/pane/demo.list_pane.js +++ /dev/null @@ -1,34 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.list_pane", - ref: function () { - self.pane = this; - }, - itemsCreator: function (op, callback) { - setTimeout(function () { - callback(BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.multi_select_item", - height: 25 - })); - }, 2000); - }, - el: { - type: "bi.button_group", - layouts: [{ - type: "bi.vertical" - }] - } - }; - }, - - mounted: function () { - this.pane.populate(); - } -}); -BI.shortcut("demo.list_pane", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pane/demo.multi_popup_view.js b/demo/js/case/pane/demo.multi_popup_view.js deleted file mode 100644 index de62a15cc..000000000 --- a/demo/js/case/pane/demo.multi_popup_view.js +++ /dev/null @@ -1,39 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - width: 200, - height: 30, - el: { - type: "bi.text_button", - text: "点击", - cls: "bi-border", - height: 30 - }, - popup: { - type: "bi.multi_popup_view", - el: { - type: "bi.button_group", - layouts: [{ - type: "bi.vertical" - }], - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.multi_select_item", - height: 25 - }) - } - } - } - }] - }; - } -}); -BI.shortcut("demo.multi_popup_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pane/demo.panel.js b/demo/js/case/pane/demo.panel.js deleted file mode 100644 index 28b1c3e2a..000000000 --- a/demo/js/case/pane/demo.panel.js +++ /dev/null @@ -1,28 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.panel", - title: "title", - titleButtons: [{ - type: "bi.button", - text: "操作" - }], - el: { - type: "bi.button_group", - layouts: [{ - type: "bi.vertical" - }], - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.multi_select_item", - height: 25 - }) - } - }; - } -}); -BI.shortcut("demo.panel", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/pane/demo.popup_panel.js b/demo/js/case/pane/demo.popup_panel.js deleted file mode 100644 index 503e91962..000000000 --- a/demo/js/case/pane/demo.popup_panel.js +++ /dev/null @@ -1,39 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - width: 200, - height: 30, - el: { - type: "bi.text_button", - text: "点击", - cls: "bi-border", - height: 30 - }, - popup: { - type: "bi.popup_panel", - el: { - type: "bi.button_group", - layouts: [{ - type: "bi.vertical" - }], - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.multi_select_item", - height: 25 - }) - } - } - } - }] - }; - } -}); -BI.shortcut("demo.popup_panel", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/tree/demo.display_tree.js b/demo/js/case/tree/demo.display_tree.js deleted file mode 100644 index b7d2c62ce..000000000 --- a/demo/js/case/tree/demo.display_tree.js +++ /dev/null @@ -1,43 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var tree = BI.createWidget({ - type: "bi.display_tree", - element: this - }); - - tree.initTree([{ - id: 1, - text: "第一项", - open: true - }, { - id: 2, - text: "第二项" - }, { - id: 11, - pId: 1, - text: "子项1(共2个)", - open: true - }, { - id: 111, - pId: 11, - text: "子子项1" - }, { - id: 112, - pId: 11, - text: "子子项2" - }, { - id: 12, - pId: 1, - text: "子项2" - }, { - id: 13, - pId: 1, - text: "子项3" - }]); - } -}); -BI.shortcut("demo.display_tree", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/tree/demo.level_tree.js b/demo/js/case/tree/demo.level_tree.js deleted file mode 100644 index 4b4ac061c..000000000 --- a/demo/js/case/tree/demo.level_tree.js +++ /dev/null @@ -1,92 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var tree = BI.createWidget({ - type: "bi.level_tree", - chooseType: 0, - items: [{ - id: 1, - text: "第一项", - value: 1, - isParent: true - }, { - id: 2, - text: "第二项", - value: 2, - isParent: true - }, { - id: 3, - text: "第三项", - value: 1, - isParent: true, - open: true - }, { - id: 4, - text: "第四项", - value: 1 - }, { - id: 11, - pId: 1, - text: "子项1", - value: 11 - }, { - id: 12, - pId: 1, - text: "子项2", - value: 12 - }, { - id: 13, - pId: 1, - text: "子项3", - value: 13 - }, { - id: 111, - pId: 11, - text: "子项1-1", - value: 111 - }, { - id: 21, - pId: 2, - text: "子项1", - value: 21 - }, { - id: 31, - pId: 3, - text: "子项1", - value: 31 - }, { - id: 32, - pId: 3, - text: "子项2", - value: 32 - }, { - id: 33, - pId: 3, - text: "子项3", - value: 33 - }] - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - el: tree - }, { - height: 30, - el: { - type: "bi.button", - height: 30, - text: "getValue", - handler: function () { - BI.Msg.alert("", tree.getValue()); - } - } - }] - }); - } -}); -BI.shortcut("demo.level_tree", Demo.Func); diff --git a/demo/js/case/tree/demo.simple_tree.js b/demo/js/case/tree/demo.simple_tree.js deleted file mode 100644 index 291700a34..000000000 --- a/demo/js/case/tree/demo.simple_tree.js +++ /dev/null @@ -1,130 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - // value值一定要是字符串 - var tree = BI.createWidget({ - type: "bi.simple_tree", - items: [{ - id: 1, - text: "第一项", - value: "1" - }, { - id: 2, - text: "第二项", - value: "2" - }, { - id: 3, - text: "第三项", - value: "3", - open: true - }, { - id: 11, - pId: 1, - text: "子项1", - value: "11" - }, { - id: 12, - pId: 1, - text: "子项2", - value: "12" - }, { - id: 13, - pId: 1, - text: "子项3", - value: "13" - }, { - id: 31, - pId: 3, - text: "子项1", - value: "31" - }, { - id: 32, - pId: 3, - text: "子项2", - value: "32" - }, { - id: 33, - pId: 3, - text: "子项3", - value: "33" - }], - value: ["31", "32", "33"] - }); - - // tree.populate([{ - // id: 1, - // text: "第一项", - // value: "1" - // }, { - // id: 2, - // text: "第二项", - // value: "2" - // }, { - // id: 3, - // text: "第三项", - // value: "3", - // open: true - // }, { - // id: 11, - // pId: 1, - // text: "子项1", - // value: "11" - // }, { - // id: 12, - // pId: 1, - // text: "子项2", - // value: "12" - // }, { - // id: 13, - // pId: 1, - // text: "子项3", - // value: "13" - // }, { - // id: 31, - // pId: 3, - // text: "子项1", - // value: "31" - // }, { - // id: 32, - // pId: 3, - // text: "子项2", - // value: "32" - // }, { - // id: 33, - // pId: 3, - // text: "子项3", - // value: "33" - // }], "z"); - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - el: tree - }, { - height: 30, - el: { - type: "bi.button", - height: 30, - text: "setValue(['31', '32', '33'])", - handler: function () { - tree.setValue(["31", "32", "33"]); - } - } - }, { - height: 30, - el: { - type: "bi.button", - height: 30, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(tree.getValue())); - } - } - }] - }); - } -}); -BI.shortcut("demo.simple_tree", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/triggers/demo.editor_trigger.js b/demo/js/case/triggers/demo.editor_trigger.js deleted file mode 100644 index d13361c3b..000000000 --- a/demo/js/case/triggers/demo.editor_trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [{ - type: "bi.label", - text: "输入框加图标的trigger" - }, { - type: "bi.editor_trigger", - watermark: "这是水印", - width: 200, - height: 24 - }], - hgap: 20, - vgap: 20 - }); - } -}); -BI.shortcut("demo.editor_trigger", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/triggers/demo.icon_trigger.js b/demo/js/case/triggers/demo.icon_trigger.js deleted file mode 100644 index dfc5e447c..000000000 --- a/demo/js/case/triggers/demo.icon_trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [{ - type: "bi.label", - text: "只有一个图标的trigger" - }, { - type: "bi.icon_trigger", - width: 30, - height: 24 - }], - hgap: 20, - vgap: 20 - }); - } -}); -BI.shortcut("demo.icon_trigger", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/triggers/demo.select_text_trigger.js b/demo/js/case/triggers/demo.select_text_trigger.js deleted file mode 100644 index f0511832c..000000000 --- a/demo/js/case/triggers/demo.select_text_trigger.js +++ /dev/null @@ -1,25 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [{ - type: "bi.label", - text: "可被选择的trigger" - }, { - type: "bi.select_text_trigger", - text: "这是一个简单的trigger", - width: 200, - height: 24 - }], - hgap: 20, - vgap: 20 - }); - } -}); -BI.shortcut("demo.select_text_trigger", Demo.Func); \ No newline at end of file diff --git a/demo/js/case/triggers/demo.text_trigger.js b/demo/js/case/triggers/demo.text_trigger.js deleted file mode 100644 index 8e4264453..000000000 --- a/demo/js/case/triggers/demo.text_trigger.js +++ /dev/null @@ -1,25 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [{ - type: "bi.label", - text: "文本加图标的trigger" - }, { - type: "bi.text_trigger", - text: "这是一个简单的trigger", - width: 200, - height: 24 - }], - hgap: 20, - vgap: 20 - }); - } -}); -BI.shortcut("demo.text_trigger", Demo.Func); \ No newline at end of file diff --git a/demo/js/center.js b/demo/js/center.js deleted file mode 100644 index b7febb6c4..000000000 --- a/demo/js/center.js +++ /dev/null @@ -1,26 +0,0 @@ -Demo.Center = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-center" - }, - render: function () { - var self = this; - return { - type: "bi.router_view" - } - } -}); -BI.shortcut("demo.center", Demo.Center); - -Demo.Router = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-router" - }, - render: function () { - var self = this; - var params = BI.Router.$router.history.current.params; - return { - type: params.componentId - } - } -}); -BI.shortcut("demo.router", Demo.Router); diff --git a/demo/js/component/demo.form.js b/demo/js/component/demo.form.js deleted file mode 100644 index 31ca38195..000000000 --- a/demo/js/component/demo.form.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2022/1/11 - */ -Demo.Form = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-form" - }, - render: function () { - var widget = BI.createWidget({ - type: "bi.custom_form", - width: 300, - labelWidth: 100, - items: [{ - validate: function (v) { - return v !== "a" && v !== ""; - }, - tip: function (v) { - if (BI.isEmpty(v)) { - return "不能为空"; - } - return "不合法格式" - }, - label: "E-mail", - el: { - type: 'bi.text_editor', - watermark: "输入a报错", - allowBlank: true, - } - }, { - validate: function (v) { - return BI.isNotEmptyArray(v); - }, - tip: function () { - return "不能为空"; - }, - label: "性别", - el: { - type: 'bi.text_value_combo', - text: "请选择", - items: [{ - text: "男", - value: 1 - }, { - text: "女", - value: 2 - }] - } - }, { - validate: function (v) { - return v !== ""; - }, - tip: function () { - return "不能为空"; - }, - label: "姓名", - el: { - type: 'bi.text_editor', - watermark: "输入姓名", - allowBlank: true, - } - }, { - validate: function (v) { - return v !== ""; - }, - tip: function () { - return "不能为空"; - }, - label: "姓名", - el: { - type: 'bi.textarea_editor', - cls: 'bi-border', - watermark: "输入简介", - allowBlank: true, - height: 200, - } - }], - layout: { - type: "bi.vertical", - vgap: 30 - } - }); - return { - type: "bi.vertical", - hgap: 200, - vgap: 10, - items: [widget, { - type: "bi.button", - text: "提交", - handler: function () { - widget.validate(); - - console.log(widget.getValue()); - } - }] - }; - } -}); -BI.shortcut("demo.form", Demo.Form); \ No newline at end of file diff --git a/demo/js/component/demo.treevaluechoosercombo.js b/demo/js/component/demo.treevaluechoosercombo.js deleted file mode 100644 index 9a38fe428..000000000 --- a/demo/js/component/demo.treevaluechoosercombo.js +++ /dev/null @@ -1,24 +0,0 @@ -Demo.TreeValueChooser = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-tree-value-chooser-combo" - }, - render: function () { - - var widget = BI.createWidget({ - type: "bi.tree_value_chooser_combo", - width: 300, - // items: BI.deepClone(Demo.CONSTANTS.TREEITEMS), - itemsCreator: function (op, callback) { - callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); - }, - defaultText: "请选择", - }); - return { - type: "bi.vertical", - hgap: 200, - vgap: 10, - items: [widget] - }; - } -}); -BI.shortcut("demo.tree_value_chooser_combo", Demo.TreeValueChooser); diff --git a/demo/js/component/demo.treevaluechooserpane.js b/demo/js/component/demo.treevaluechooserpane.js deleted file mode 100644 index b37f026b3..000000000 --- a/demo/js/component/demo.treevaluechooserpane.js +++ /dev/null @@ -1,16 +0,0 @@ -Demo.TreeValueChooser = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-tree-value-chooser" - }, - render: function () { - - return { - type: "bi.tree_value_chooser_pane", - items: BI.deepClone(Demo.CONSTANTS.TREEITEMS) - // itemsCreator: function (op, callback) { - // callback(tree); - // } - }; - } -}); -BI.shortcut("demo.tree_value_chooser_pane", Demo.TreeValueChooser); diff --git a/demo/js/component/demo.valuechoosercombo.js b/demo/js/component/demo.valuechoosercombo.js deleted file mode 100644 index bd0d84112..000000000 --- a/demo/js/component/demo.valuechoosercombo.js +++ /dev/null @@ -1,20 +0,0 @@ -Demo.ValueChooserCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-value-chooser-combo" - }, - render: function () { - var widget = BI.createWidget({ - type: "bi.value_chooser_combo", - itemsCreator: function (op, callback) { - callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); - } - }); - return { - type: "bi.vertical", - hgap: 200, - vgap: 10, - items: [widget] - }; - } -}); -BI.shortcut("demo.value_chooser_combo", Demo.ValueChooserCombo); \ No newline at end of file diff --git a/demo/js/component/demo.valuechooserpane.js b/demo/js/component/demo.valuechooserpane.js deleted file mode 100644 index 9e401f8ab..000000000 --- a/demo/js/component/demo.valuechooserpane.js +++ /dev/null @@ -1,15 +0,0 @@ -Demo.ValueChooserPane = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-value-chooser-pane" - }, - render: function () { - return { - type: "bi.value_chooser_pane", - items: BI.deepClone(Demo.CONSTANTS.ITEMS) - // itemsCreator: function (op, callback) { - // callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); - // } - }; - } -}); -BI.shortcut("demo.value_chooser_pane", Demo.ValueChooserPane); \ No newline at end of file diff --git a/demo/js/config/base.js b/demo/js/config/base.js deleted file mode 100644 index d4fa19205..000000000 --- a/demo/js/config/base.js +++ /dev/null @@ -1,89 +0,0 @@ -Demo.BASE_CONFIG = [{ - id: 2, - text: "基础控件", - open: false -}, { - pId: 2, - text: "bi.label", - value: "demo.label" -},{ - pId: 2, - text: "bi.label_scene", - value: "demo.label_scene" -}, { - pId: 2, - text: "bi.icon_label", - value: "demo.icon_label" -}, { - pId: 2, - text: "bi.html", - value: "demo.html" -}, { - pId: 2, - text: "title提示", - value: "demo.title" -}, { - pId: 2, - text: "气泡提示", - value: "demo.bubble" -}, { - pId: 2, - text: "toast提示", - value: "demo.toast" -}, { - pId: 2, - id: 201, - text: "button" -}, { - pId: 201, - text: "bi.button", - value: "demo.button" -}, { - pId: 201, - text: "bi.text_button", - value: "demo.text_button" -}, { - pId: 201, - text: "bi.icon_button", - value: "demo.icon_button" -}, { - pId: 201, - text: "bi.image_button", - value: "demo.image_button" -}, { - pId: 2, - id: 202, - text: "editor" -}, { - pId: 202, - text: "bi.editor", - value: "demo.editor" -}, { - pId: 202, - text: "bi.multifile_editor", - value: "demo.multifile_editor" -}, { - pId: 202, - text: "bi.textarea_editor", - value: "demo.textarea_editor" -}, { - pId: 2, - id: 203, - text: "tree" -}, { - pId: 203, - text: "bi.tree_view", - value: "demo.tree_view" -}, { - pId: 203, - text: "bi.async_tree", - value: "demo.sync_tree" -}, { - pId: 203, - text: "bi.part_tree", - value: "demo.part_tree" -}, { - pId: 2, - text: "bi.pager", - value: "demo.pager" -}]; \ No newline at end of file diff --git a/demo/js/config/case.js b/demo/js/config/case.js deleted file mode 100644 index 7b62db09e..000000000 --- a/demo/js/config/case.js +++ /dev/null @@ -1,185 +0,0 @@ -Demo.CASE_CONFIG = [{ - id: 3, - text: "实例控件", - open: false -}, { - pId: 3, - id: 300, - text: "按钮" -}, { - pId: 300, - text: "bi.multi_select_item", - value: "demo.multi_select_item" -}, { - pId: 300, - text: "bi.single_select_item", - value: "demo.single_select_item" -}, { - pId: 300, - text: "bi.single_select_radio_item", - value: "demo.single_select_radio_item" -}, { - pId: 3, - id: 301, - text: "editors" -}, { - pId: 301, - text: "bi.shelter_editor", - value: "demo.shelter_editor" -}, { - pId: 301, - text: "bi.sign_editor", - value: "demo.sign_editor" -}, { - pId: 301, - text: "bi.state_editor", - value: "demo.state_editor" -}, { - pId: 301, - text: "bi.simple_state_editor", - value: "demo.simple_state_editor" -}, { - pId: 301, - text: "bi.clear_editor", - value: "demo.clear_editor" -}, { - pId: 3, - id: 302, - text: "列表" -}, { - pId: 302, - text: "bi.select_list", - value: "demo.select_list" -}, { - pId: 302, - text: "bi.lazy_loader", - value: "demo.lazy_loader" -}, { - pId: 3, - id: 303, - text: "面板" -}, { - pId: 303, - text: "bi.list_pane", - value: "demo.list_pane" -}, { - pId: 303, - text: "bi.panel", - value: "demo.panel" -}, { - pId: 3, - id: 304, - text: "popup弹出层" -}, { - pId: 304, - text: "bi.multi_popup_view", - value: "demo.multi_popup_view" -}, { - pId: 304, - text: "bi.popup_panel", - value: "demo.popup_panel" -}, { - pId: 3, - id: 305, - text: "触发器trigger" -}, { - pId: 305, - text: "bi.editor_trigger", - value: "demo.editor_trigger" -}, { - pId: 305, - text: "bi.icon_trigger", - value: "demo.icon_trigger" -}, { - pId: 305, - text: "bi.text_trigger", - value: "demo.text_trigger" -}, { - pId: 305, - text: "bi.select_text_trigger", - value: "demo.select_text_trigger" -}, { - pId: 3, - id: 306, - text: "combo" -}, { - pId: 306, - text: "bi.bubble_combo", - value: "demo.bubble_combo" -}, { - pId: 306, - text: "bi.icon_combo", - value: "demo.icon_combo" -}, { - pId: 306, - text: "bi.text_value_combo", - value: "demo.text_value_combo" -}, { - pId: 306, - text: "bi.search_text_value_combo", - value: "demo.search_text_value_combo" -}, { - pId: 306, - text: "bi.icon_text_value_combo", - value: "demo.icon_text_value_combo" -}, { - pId: 306, - text: "bi.text_value_check_combo", - value: "demo.text_value_check_combo" -}, { - pId: 306, - text: "bi.editor_icon_check_combo", - value: "demo.editor_icon_check_combo" -}, { - pId: 306, - text: "bi.text_value_down_list_combo", - value: "demo.text_value_down_list_combo" -}, { - pId: 3, - id: 307, - text: "tree" -}, { - pId: 307, - text: "bi.display_tree", - value: "demo.display_tree" -}, { - pId: 307, - text: "bi.simple_tree", - value: "demo.simple_tree" -}, { - pId: 307, - text: "bi.level_tree", - value: "demo.level_tree" -}, { - pId: 3, - id: 309, - text: "pager" -}, { - pId: 309, - text: "bi.all_count_pager", - value: "demo.all_count_pager" -}, { - pId: 309, - text: "bi.direction_pager", - value: "demo.direction_pager" -}, { - pId: 3, - text: "bi.calendar", - value: "demo.calendar" -}, { - pId: 3, - text: "bi.color_chooser", - value: "demo.color_chooser" -}, { - pId: 3, - text: "bi.color_chooser_popup", - value: "demo.color_chooser_popup" -}, { - pId: 3, - text: "bi.segment", - value: "demo.segment" -}, { - pId: 3, - text: "点击项样式查看", - value: "demo.click_item_effect" -}]; \ No newline at end of file diff --git a/demo/js/config/category.js b/demo/js/config/category.js deleted file mode 100644 index 1902196ff..000000000 --- a/demo/js/config/category.js +++ /dev/null @@ -1,8 +0,0 @@ -Demo.CATEGORY_CONFIG = [{ - id: 100000, - text: "专题" -}, { - pId: 100000, - text: "可以排序的树", - value: "demo.sort_tree" -}]; \ No newline at end of file diff --git a/demo/js/config/component.js b/demo/js/config/component.js deleted file mode 100644 index e6bbb9cf0..000000000 --- a/demo/js/config/component.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.COMPONENT_CONFIG = [{ - id: 5, - text: "部件+服务" -}, { - pId: 5, - text: "bi.value_chooser_combo", - value: "demo.value_chooser_combo" -}, { - pId: 5, - text: "bi.value_chooser_pane", - value: "demo.value_chooser_pane" -}, { - pId: 5, - text: "bi.tree_value_chooser_combo", - value: "demo.tree_value_chooser_combo" -}, { - pId: 5, - text: "bi.tree_value_chooser_pane", - value: "demo.tree_value_chooser_pane" -}, { - pId: 5, - text: "demo.form", - value: "demo.form" -}]; \ No newline at end of file diff --git a/demo/js/config/core.js b/demo/js/config/core.js deleted file mode 100644 index 2c5794488..000000000 --- a/demo/js/config/core.js +++ /dev/null @@ -1,203 +0,0 @@ -Demo.CORE_CONFIG = [{ - id: 1, - text: "核心控件" -}, { - id: 101, - pId: 1, - text: "布局" -}, { - pId: 101, - text: "bi.absolute", - value: "demo.absolute" -}, { - pId: 101, - text: "bi.center_adapt", - value: "demo.center_adapt" -}, { - pId: 101, - text: "bi.vertical_adapt", - value: "demo.vertical_adapt" -}, { - pId: 101, - text: "bi.horizontal_adapt", - value: "demo.horizontal_adapt" -}, { - pId: 101, - text: "bi.horizontal_auto", - value: "demo.horizontal_auto" -}, { - pId: 101, - text: "bi.horizontal_float", - value: "demo.horizontal_float" -}, { - pId: 101, - text: "bi.left_right_vertical_adapt", - value: "demo.left_right_vertical_adapt" -}, { - pId: 101, - text: "bi.center", - value: "demo.center_layout" -}, { - pId: 101, - text: "bi.float_center", - value: "demo.float_center" -}, { - pId: 101, - text: "bi.vertical", - value: "demo.vertical" -}, { - pId: 101, - text: "bi.horizontal", - value: "demo.horizontal" -}, { - pId: 101, - text: "bi.border", - value: "demo.border" -}, { - pId: 101, - text: "bi.left, bi.right", - value: "demo.flow" -}, { - pId: 101, - text: "bi.htape", - value: "demo.htape" -}, { - pId: 101, - text: "bi.vtape", - value: "demo.vtape" -}, { - pId: 101, - text: "bi.grid", - value: "demo.grid" -}, { - pId: 101, - text: "bi.table", - value: "demo.table_layout" -}, { - pId: 101, - text: "bi.td", - value: "demo.td" -}, { - pId: 101, - text: "..." -}, { - pId: 1, - id: 102, - text: "抽象控件" -}, { - pId: 102, - text: "bi.button_group", - value: "demo.button_group" -}, { - pId: 102, - text: "bi.button_tree", - value: "demo.button_tree" -}, { - pId: 102, - text: "bi.virtual_group", - value: "demo.virtual_group" -}, { - pId: 102, - text: "bi.custom_tree", - value: "demo.custom_tree" -}, { - pId: 102, - text: "bi.grid_view", - value: "demo.grid_view" -}, { - pId: 102, - text: "bi.collection_view", - value: "demo.collection_view" -}, { - pId: 102, - text: "bi.list_view", - value: "demo.list_view" -}, { - pId: 102, - text: "bi.virtual_list", - value: "demo.virtual_list" -}, { - pId: 102, - id: 10201, - text: "组合控件" -}, { - pId: 10201, - text: "bi.combo", - value: "demo.combo" -}, { - pId: 10201, - text: "bi.combo(各种位置)", - value: "demo.combo2" -}, { - pId: 10201, - text: "bi.combo(內部位置)", - value: "demo.combo3" -}, { - pId: 10201, - text: "bi.expander", - value: "demo.expander" -}, { - pId: 10201, - text: "bi.combo_group", - value: "demo.combo_group" -}, { - pId: 10201, - text: "bi.loader", - value: "demo.loader" -}, { - pId: 10201, - text: "bi.navigation", - value: "demo.navigation" -}, { - pId: 10201, - text: "bi.searcher", - value: "demo.searcher" -}, { - pId: 10201, - text: "bi.switcher", - value: "demo.switcher" -}, { - pId: 10201, - text: "bi.tab", - value: "demo.tab" -}, { - pId: 102, - id: 10202, - text: "弹出层" -}, { - pId: 10202, - text: "layer", - value: "demo.layer" -}, { - pId: 10202, - text: "bi.popover", - value: "demo.popover" -}, { - pId: 10202, - text: "bi.popup_view", - value: "demo.popup_view" -}, { - pId: 10202, - text: "bi.searcher_view", - value: "demo.searcher_view" -}, { - pId: 1, - text: "Widget(继承)", - value: "demo.widget" -}, { - pId: 1, - text: "Single(继承)", - value: "demo.single" -}, { - pId: 1, - text: "BasicButton(继承)", - value: "demo.basic_button" -}, { - pId: 1, - text: "NodeButton(继承)", - value: "demo.node_button" -}, { - pId: 1, - text: "Pane(继承)", - value: "demo.pane" -}]; \ No newline at end of file diff --git a/demo/js/config/demo.pane.js b/demo/js/config/demo.pane.js deleted file mode 100644 index e6cb35c62..000000000 --- a/demo/js/config/demo.pane.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * author: young - * createdDate: 2018/11/30 - * description: - */ -!(function () { - var Pane = BI.inherit(BI.Pane, { - props: { - - }, - - mounted: function () { - console.log('loading pane mounted'); - }, - - render: function () { - return { - type: "bi.center_adapt", - items: [{ - type: "bi.label", - text: "this is pane center" - }] - }; - }, - - beforeRender: function (callback) { - var self = this; - this.loading(); - setTimeout(function () { - self.loaded(); - callback(); - }, 3000); - } - }); - BI.shortcut("demo.pane", Pane); -})(); diff --git a/demo/js/config/fix.js b/demo/js/config/fix.js deleted file mode 100644 index 6eacf396e..000000000 --- a/demo/js/config/fix.js +++ /dev/null @@ -1,54 +0,0 @@ -Demo.FIX_CONFIG = [{ - id: 7, - text: "数据流框架fix-2.0" -}, { - id: 71, - pId: 7, - text: "定义响应式数据", - value: "demo.fix_define" -}, { - id: 72, - pId: 7, - text: "state属性", - value: "demo.fix_state" -}, { - id: 73, - pId: 7, - text: "计算属性", - value: "demo.fix_computed" -}, { - id: 74, - pId: 7, - text: "store", - value: "demo.fix_store" -}, { - id: 75, - pId: 7, - text: "watcher且或表达式", - value: "demo.fix_watcher" -}, { - id: 76, - pId: 7, - text: "watcher星号表达式", - value: "demo.fix_global_watcher" -}, { - id: 77, - pId: 7, - text: "context", - value: "demo.fix_context" -}, { - id: 78, - pId: 7, - text: "一个混合的例子", - value: "demo.fix" -}, { - id: 79, - pId: 7, - text: "场景", - value: "demo.fix_scene" -}, { - id: 80, - pId: 7, - text: "inject", - value: "demo.fix_inject" -}]; diff --git a/demo/js/config/widget.js b/demo/js/config/widget.js deleted file mode 100644 index e48282492..000000000 --- a/demo/js/config/widget.js +++ /dev/null @@ -1,205 +0,0 @@ -Demo.WIDGET_CONFIG = [{ - id: 4, - text: "详细控件", - open: true -}, { - pId: 4, - id: 401, - text: "各种小控件" -}, { - pId: 401, - text: "各种通用按钮", - value: "demo.buttons" -}, { - pId: 401, - text: "各种提示性信息", - value: "demo.tips" -}, { - pId: 401, - text: "各种items", - value: "demo.items" -}, { - pId: 401, - text: "各种节点node", - value: "demo.nodes" -}, { - pId: 401, - text: "各种segment", - value: "demo.segments" -}, { - pId: 4, - id: 402, - text: "文本框控件" -}, { - pId: 402, - text: "bi.text_editor", - value: "demo.text_editor" -}, { - pId: 402, - text: "bi.search_editor", - value: "demo.search_editor" -}, { - pId: 402, - text: "bi.number_editor", - value: "demo.number_editor" -}, { - pId: 4, - id: 403, - text: "tree" -}, { - pId: 403, - text: "bi.single_level_tree", - value: "demo.single_level_tree" -}, { - pId: 403, - text: "bi.select_level_tree", - value: "demo.select_level_tree" -}, { - pId: 403, - text: "bi.multilayer_single_level_tree", - value: "demo.multilayer_single_level_tree" -}, { - pId: 403, - text: "bi.multilayer_select_level_tree", - value: "demo.multilayer_select_level_tree" -}, { - pId: 4, - id: 405, - text: "下拉列表" -}, { - pId: 405, - text: "bi.down_list_combo", - value: "demo.down_list" -}, { - pId: 4, - id: 421, - text: "单选下拉框" -}, { - pId: 421, - text: "bi.single_select_combo", - value: "demo.single_select_combo" -}, { - pId: 4, - id: 406, - text: "复选下拉框" -}, { - pId: 406, - text: "bi.multi_select_combo", - value: "demo.multi_select_combo" -}, { - pId: 406, - text: "bi.multi_select_list", - value: "demo.multi_select_list" -}, { - pId: 4, - id: 407, - text: "简单下拉树" -}, { - pId: 407, - text: "bi.single_tree_combo", - value: "demo.single_tree_combo" -}, { - pId: 4, - id: 408, - text: "多层级下拉树" -}, { - pId: 408, - text: "bi.multilayer_single_tree_combo", - value: "demo.multilayer_single_tree_combo" -}, { - pId: 4, - id: 409, - text: "可选下拉树" -}, { - pId: 409, - text: "bi.select_tree_combo", - value: "demo.select_tree_combo" -}, { - pId: 4, - id: 410, - text: "多层级可选下拉树" -}, { - pId: 410, - text: "bi.multilayer_select_tree_combo", - value: "demo.multilayer_select_tree_combo" -}, { - pId: 4, - id: 411, - text: "复选下拉树" -}, { - pId: 411, - text: "bi.multi_tree_combo", - value: "demo.multi_tree_combo" -}, { - pId: 411, - text: "bi.multi_select_tree", - value: "demo.multi_select_tree" -}, { - pId: 4, - id: 412, - text: "日期相关控件" -}, { - pId: 412, - text: "bi.year_combo", - value: "demo.year" -}, { - pId: 412, - text: "bi.year_month_combo", - value: "demo.year_month_combo" -}, { - pId: 412, - text: "bi.year_quarter_combo", - value: "demo.year_quarter_combo" -}, { - pId: 412, - text: "bi.date_pane", - value: "demo.date_pane" -}, { - pId: 412, - text: "bi.multidate_combo", - value: "demo.multidate_combo" -}, { - pId: 412, - text: "bi.date_time", - value: "demo.date_time" -}, { - pId: 412, - text: "bi.time_combo", - value: "demo.time_combo" -}, { - pId: 412, - text: "bi.time_interval", - value: "demo.time_interval" -}, { - pId: 412, - text: "bi.year_month_interval", - value: "demo.year_month_interval" -}, { - pId: 412, - text: "bi.year_quarter_interval", - value: "demo.year_quarter_interval" -}, { - pId: 412, - text: "bi.year_interval", - value: "demo.year_interval" -}, { - pId: 4, - id: 413, - text: "数值区间控件" -}, { - pId: 413, - text: "bi.number_interval", - value: "demo.number_interval" -}, { - id: 420, - text: "数值滑块sliders", - value: "demo.slider" -}, { - pId: 4, - id: 414, - text: "折叠面板" -}, { - pId: 414, - text: "bi.collapse", - value: "demo.collapse" -}]; diff --git a/demo/js/core/abstract/combination/demo.combo.js b/demo/js/core/abstract/combination/demo.combo.js deleted file mode 100644 index 2ec3619b1..000000000 --- a/demo/js/core/abstract/combination/demo.combo.js +++ /dev/null @@ -1,495 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - years: [{ - text: "2010年", value: 2010, iconCls: "close-ha-font" - }, { - text: "2011年", value: 2011 - }, { - text: "2012年", value: 2012, iconCls: "close-ha-font" - }, { - text: "2013年", value: 2013 - }, { - text: "2014年", value: 2014, iconCls: "close-ha-font" - }, { - text: "2015年", value: 2015, iconCls: "close-ha-font" - }, { - text: "2016年", value: 2016, iconCls: "close-ha-font" - }, { - text: "2017年", value: 2017, iconCls: "close-ha-font" - }], - child: [{ - type: "bi.combo_group", - el: { - type: "bi.icon_text_icon_item", - text: "2010年", - value: 2010, - height: 25, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font" - }, - children: [{ - type: "bi.single_select_item", - height: 25, - text: "一月", - value: 11 - }, { - type: "bi.icon_text_icon_item", - height: 25, - text: "二月", - value: 12, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - children: [{ type: "bi.single_select_item", text: "一号", value: 101, height: 25 }] - }] - }, { - text: "2011年", value: 2011 - }, { - text: "2012年", value: 2012, iconCls: "close-ha-font" - }, { - text: "2013年", value: 2013 - }, { - text: "2014年", value: 2014, iconCls: "close-ha-font" - }, { - text: "2015年", value: 2015, iconCls: "close-ha-font" - }], - - months: [[{ - el: { - text: "一月", value: 1 - } - }, { - el: { - text: "二月", value: 2 - } - }], [{ - el: { - text: "三月", value: 3 - } - }, { - el: { - text: "四月", value: 4 - } - }], [{ - el: { - text: "五月", value: 5 - } - }, { - el: { - text: "六月", value: 6 - } - }], [{ - el: { - text: "七月", value: 7 - } - }, { - el: { - text: "八月", value: 8 - } - }], [{ - el: { - text: "九月", value: 9 - } - }, { - el: { - text: "十月", value: 10 - } - }], [{ - el: { - text: "十一月", value: 11 - } - }, { - el: { - text: "十二月", value: 12 - } - }]], - - dynamic: [ - { - text: "2010年", value: 1 - }, { - text: "20112222年", value: 2 - }, { - text: "201233333年", value: 3 - }, { - text: "2013年", value: 4 - }, { - text: "2012324年", value: 5 - }, { - text: "2015年", value: 6 - }, { - text: "2016年", value: 7 - }, { - text: "201744444444444444444444444444444444444年", value: 8 - } - ], - - week: [{ - text: "周一", value: 100, iconClsLeft: "close-ha-font", iconClsRight: "close-font" - }, { - text: "周二", value: 101, iconClsLeft: "close-ha-font" - }, { - text: "周三", value: 102 - }, { - text: "周四", value: 103, iconClsRight: "close-ha-font" - }, { - text: "周五", value: 104, iconClsLeft: "close-ha-font", iconClsRight: "close-font" - }, { - text: "周六", value: 105, iconClsLeft: "close-font", iconClsRight: "close-ha-font" - }, { - text: "周日", value: 106, iconClsLeft: "close-font" - }], - _createTop: function () { - var self = this; - - var yearCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.button", - text: "简单下拉框", - height: 30 - }, - popup: { - el: { - type: "bi.button_group", - items: BI.createItems(BI.deepClone(this.years), { - type: "bi.single_select_radio_item", - height: 25, - handler: function (v) { - - } - }), - layouts: [{ - type: "bi.vertical" - }] - } - }, - width: 200 - }); - - var multiCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.button", - text: "多选下拉框", - height: 30 - }, - popup: { - el: { - items: BI.createItems(BI.deepClone(this.years), { - type: "bi.multi_select_item", - height: 25, - handler: function (v) { - - } - }), - chooseType: 1, - layouts: [{ - type: "bi.vertical" - }] - }, - tool: { - type: "bi.label", - text: "这是一个下拉框", - height: 35 - }, - tabs: [{ - type: "bi.multi_select_bar", - height: 25, - text: "全选", - onCheck: function (v) { - if (v) { - multiCombo.setValue(BI.map(BI.deepClone(self.years), "value")); - } else { - multiCombo.setValue([]); - } - - }, - isAllCheckedBySelectedValue: function (selectedValue) { - return selectedValue.length == self.years.length; - // return true; - } - }], - buttons: [{ - type: "bi.text_button", - text: "清空", - handler: function () { - multiCombo.setValue([]); - } - }, { - type: "bi.text_button", - text: "确定", - handler: function () { - BI.Msg.alert("", multiCombo.getValue()); - } - }] - }, - width: 200 - }); - - var dynamicPopupCombo = BI.createWidget({ - type: "bi.combo", - isNeedAdjustWidth: false, - offsetStyle: "center", - el: { - type: "bi.button", - text: "动态调整宽度", - height: 30 - }, - popup: { - el: { - items: BI.createItems(BI.deepClone(this.dynamic), { - type: "bi.single_select_item", - height: 25 - }), - layouts: [{ - type: "bi.vertical" - }] - } - }, - width: 200 - }); - - var dynamicCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.button", - text: "搜索", - height: 30 - }, - popup: { - el: { - type: "bi.loader", - logic: { - dynamic: true, - scrolly: true - }, - el: { - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [{ - type: "bi.vertical" - }] - }, - itemsCreator: function (options, popuplate) { - var times = options.times; - BI.delay(function () { - if (times == 3) { - popuplate([{ - type: "bi.single_select_item", - text: "这是最后一个", - value: "这是最后一个", - py: "zszhyg", - height: 25 - }]); - return; - } - - var map = BI.map(BI.makeArray(3, null), function (i, v) { - var val = i + "_" + BI.random(1, 100); - return { - type: "bi.single_select_item", - text: val, - value: val, - height: 25 - }; - }); - popuplate(map); - - }, 1000); - - }, - hasNext: function (options) { - return options.times < 3; - } - }, - buttons: [{ - type: "bi.text_button", - text: "清空", - handler: function () { - dynamicCombo.setValue([]); - } - }, { - type: "bi.text_button", - text: "确定", - handler: function () { - BI.Msg.alert("", dynamicCombo.getValue()); - } - }] - }, - width: 200 - }); - - return BI.createWidget({ - type: "bi.left", - items: [yearCombo, multiCombo, dynamicPopupCombo, dynamicCombo], - hgap: 20, - vgap: 20 - }); - }, - - _createBottom: function () { - var combo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.text_button", - cls: "button-combo", - height: 30 - }, - popup: { - el: { - type: "bi.button_group", - items: BI.createItems(BI.deepClone(this.years), { - type: "bi.single_select_item", - iconWidth: 25, - height: 25, - handler: function (v) { - - } - }), - chooseType: 1, - layouts: [{ - type: "bi.vertical" - }] - } - }, - width: 200 - }); - combo.setValue(BI.deepClone(this.years)[0].value); - - var childCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.text_button", - cls: "button-combo", - height: 30 - }, - popup: { - el: { - type: "bi.button_tree", - items: BI.createItems(BI.deepClone(this.child), { - type: "bi.single_select_item", - height: 25, - handler: function (v) { - - } - }), - layouts: [{ - type: "bi.vertical" - }] - } - }, - width: 200 - }); - childCombo.setValue(BI.deepClone(this.child)[0].children[0].value); - - var monthCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.button", - text: "多层样式下拉框", - height: 30 - }, - popup: { - el: { - items: BI.createItems(BI.deepClone(this.months), { - type: "bi.single_select_item", - cls: "button-combo", - handler: function (v) { - - } - }), - layouts: [{ - type: "bi.adaptive", - items: [{ - el: { - type: "bi.table", - columns: 2, - rows: 6, - columnSize: [0.5, "fill"], - rowSize: 30 - }, - left: 4, - right: 4, - top: 2, - bottom: 2 - }] - }, { - type: "bi.absolute", - el: { left: 4, top: 2, right: 4, bottom: 2 } - }] - } - }, - width: 200 - }); - - var yearCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.button", - text: "自定义控件", - height: 30 - }, - popup: { - el: { - type: "bi.navigation", - direction: "bottom", - logic: { - dynamic: true - }, - tab: { - height: 30, - items: [{ - once: false, - text: "后退", - value: -1, - cls: "mvc-button layout-bg3" - }, { - once: false, - text: "前进", - value: 1, - cls: "mvc-button layout-bg4" - }] - }, - cardCreator: function (v) { - return BI.createWidget({ - type: "bi.text_button", - whiteSpace: "normal", - text: new Date().getFullYear() + v - }); - } - } - }, - width: 200 - }); - - return BI.createWidget({ - type: "bi.left", - items: [combo, childCombo, monthCombo, yearCombo], - hgap: 20, - vgap: 20 - }); - }, - - render: function () { - return { - type: "bi.grid", - columns: 1, - rows: 2, - items: [{ - column: 0, - row: 0, - el: this._createTop() - }, { - column: 0, - row: 1, - el: this._createBottom() - }] - }; - } -}); -BI.shortcut("demo.combo", Demo.Func); diff --git a/demo/js/core/abstract/combination/demo.combo2.js b/demo/js/core/abstract/combination/demo.combo2.js deleted file mode 100644 index a4b63b3c9..000000000 --- a/demo/js/core/abstract/combination/demo.combo2.js +++ /dev/null @@ -1,163 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createEl: function () { - return { - type: "bi.button", - height: 25, - text: "点击" - }; - }, - - oneCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustLength: 5, - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - height: 500 - }, - maxHeight: 400 - } - }); - }, - - twoCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "bottom,left", - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - height: 1200 - } - } - }); - }, - - threeCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustYOffset: 5, - el: this._createEl(), - isNeedAdjustHeight: false, - popup: { - el: { - type: "bi.layout", - height: 1200 - } - } - }); - }, - - fourCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "left", - el: this._createEl(), - isNeedAdjustHeight: true, - popup: { - el: { - type: "bi.layout", - height: 1200 - } - } - }); - }, - - fiveCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "left,top", - el: this._createEl(), - isNeedAdjustHeight: true, - popup: { - el: { - type: "bi.layout", - height: 1200 - }, - maxHeight: 2000 - } - }); - }, - - sixCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "top,left", - el: this._createEl(), - isNeedAdjustHeight: true, - popup: { - el: { - type: "bi.layout", - height: 1200 - } - } - }); - }, - - sevenCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "bottom", - isNeedAdjustWidth: false, - // isNeedAdjustHeight: false, - offsetStyle: "center", - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - width: 200, - height: 1200 - } - } - }); - }, - - eightCombo: function () { - return BI.createWidget({ - type: "bi.combo", - adjustXOffset: 25, - adjustYOffset: 5, - direction: "right", - isNeedAdjustWidth: false, - // isNeedAdjustHeight: false, - offsetStyle: "middle", - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - width: 200, - height: 200 - } - } - }); - }, - - render: function () { - return { - type: "bi.grid", - hgap: 10, - vgap: 5, - items: [[this.oneCombo(), this.twoCombo(), this.threeCombo()], - [this.fourCombo(), this.fiveCombo(), this.sixCombo()], - [this.sevenCombo(), this.eightCombo()]] - }; - } -}); -BI.shortcut("demo.combo2", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.combo3.js b/demo/js/core/abstract/combination/demo.combo3.js deleted file mode 100644 index 614c36ddd..000000000 --- a/demo/js/core/abstract/combination/demo.combo3.js +++ /dev/null @@ -1,75 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createEl: function () { - return { - type: "bi.label", - cls:"bi-border", - height: "100%", - text: "点击" - }; - }, - - oneCombo: function () { - return BI.createWidget({ - type: "bi.combo", - direction: "right,innerRight", - isNeedAdjustWidth: false, - isNeedAdjustHeight: false, - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - width: 200, - height: 200 - } - } - }); - }, - - twoCombo: function () { - return BI.createWidget({ - type: "bi.combo", - direction: "right,innerRight", - isNeedAdjustWidth: false, - isNeedAdjustHeight: false, - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - width: 1000, - height: 200 - } - } - }); - }, - - threeCombo: function () { - return BI.createWidget({ - type: "bi.combo", - direction: "right,innerRight", - isNeedAdjustWidth: false, - isNeedAdjustHeight: false, - el: this._createEl(), - popup: { - el: { - type: "bi.layout", - width: 400, - height: 200 - } - } - }); - }, - - render: function () { - return { - type: "bi.grid", - hgap: 10, - vgap: 5, - items: [[this.oneCombo()], [this.twoCombo()], [this.threeCombo()]] - }; - } -}); -BI.shortcut("demo.combo3", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.combo_group.js b/demo/js/core/abstract/combination/demo.combo_group.js deleted file mode 100644 index 2cd391b7d..000000000 --- a/demo/js/core/abstract/combination/demo.combo_group.js +++ /dev/null @@ -1,89 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - child: [{ - type: "bi.combo_group", - el: { - type: "bi.icon_text_icon_item", - text: "2010年", - value: 2010, - height: 25, - iconCls: "close-ha-font" - }, - items: [{ - type: "bi.single_select_item", - height: 25, - text: "一月", - value: 11 - }, { - type: "bi.icon_text_icon_item", - height: 25, - text: "二月", - value: 12, - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - children: [{type: "bi.single_select_item", text: "一号", value: 101, height: 25}] - }] - }, { - text: "2011年", value: 2011 - }, { - text: "2012年", value: 2012, iconCls: "close-ha-font" - }, { - text: "2013年", value: 2013 - }, { - text: "2014年", value: 2014, iconCls: "close-ha-font" - }, { - text: "2015年", value: 2015, iconCls: "close-ha-font" - }], - - _createBottom: function () { - var childCombo = BI.createWidget({ - type: "bi.combo", - el: { - type: "bi.text_button", - cls: "button-combo", - height: 30 - }, - popup: { - el: { - type: "bi.button_tree", - items: BI.createItems(BI.deepClone(this.child), { - type: "bi.single_select_item", - height: 25, - handler: function (v) { - - } - }), - layouts: [{ - type: "bi.vertical" - }] - } - }, - width: 200 - }); - childCombo.setValue(BI.deepClone(this.child)[0].items[0].value); - - return BI.createWidget({ - type: "bi.left", - items: [childCombo], - hgap: 20, - vgap: 20 - }); - }, - - render: function () { - return { - type: "bi.grid", - columns: 1, - rows: 1, - items: [{ - column: 0, - row: 0, - el: this._createBottom() - }] - }; - } -}); -BI.shortcut("demo.combo_group", Demo.Func); diff --git a/demo/js/core/abstract/combination/demo.expander.js b/demo/js/core/abstract/combination/demo.expander.js deleted file mode 100644 index f2d1e1757..000000000 --- a/demo/js/core/abstract/combination/demo.expander.js +++ /dev/null @@ -1,41 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.vertical", - hgap: 30, - vgap: 20, - items: [{ - type: "bi.expander", - el: { - type: "bi.icon_text_node", - cls: "pull-right-ha-font mvc-border", - height: 25, - text: "Expander" - }, - popup: { - cls: "mvc-border", - items: BI.createItems([{ - text: "项目1", - value: 1 - }, { - text: "项目2", - value: 2 - }, { - text: "项目3", - value: 3 - }, { - text: "项目4", - value: 4 - }], { - type: "bi.single_select_item", - height: 25 - }) - } - }] - }; - } -}); -BI.shortcut("demo.expander", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.loader.js b/demo/js/core/abstract/combination/demo.loader.js deleted file mode 100644 index b095ea1e1..000000000 --- a/demo/js/core/abstract/combination/demo.loader.js +++ /dev/null @@ -1,27 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var self = this; - this.all = 0; - var items = BI.deepClone(Demo.CONSTANTS.ITEMS); - return { - type: "bi.loader", - itemsCreator: function (options, populate) { - setTimeout(function () { - populate(BI.map(items.slice((options.times - 1) * 10, options.times * 10), function (i, v) { - return BI.extend(v, { - type: "bi.single_select_item", - height: 25 - }); - })); - }, 1000); - }, - hasNext: function (options) { - return options.times * 10 < items.length; - } - }; - } -}); -BI.shortcut("demo.loader", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.navigation.js b/demo/js/core/abstract/combination/demo.navigation.js deleted file mode 100644 index ff3e97bb7..000000000 --- a/demo/js/core/abstract/combination/demo.navigation.js +++ /dev/null @@ -1,35 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - _createNav: function (v) { - return BI.createWidget({ - type: "bi.label", - cls: "layout-bg" + BI.random(1, 8), - text: "第" + v + "页" - }); - }, - - render: function () { - return { - type: "bi.navigation", - showIndex: 0, - tab: { - height: 30, - items: [{ - once: false, - text: "后退", - value: -1, - cls: "mvc-button layout-bg3" - }, { - once: false, - text: "前进", - value: 1, - cls: "mvc-button layout-bg4" - }] - }, - cardCreator: BI.bind(this._createNav, this) - }; - } -}); -BI.shortcut("demo.navigation", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.sercher.js b/demo/js/core/abstract/combination/demo.sercher.js deleted file mode 100644 index d8c20480c..000000000 --- a/demo/js/core/abstract/combination/demo.sercher.js +++ /dev/null @@ -1,84 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createItems: function (items) { - return BI.createItems(items, { - type: "bi.multi_select_item", - height: 25, - handler: function (v) { - - } - }); - }, - - render: function () { - var self = this; - var items = [{ - text: "2010年", value: 2010, py: "2010n", title: "1111111111111111111111111111111111" - }, { - text: "2011年", value: 2011, py: "2011n", title: "1111111111111111111111111111111111" - }, { - text: "2012年", value: 2012, py: "2012n", title: "1111111111111111111111111111111111" - }, { - text: "2013年", value: 2013, py: "2013n", title: "1111111111111111111111111111111111" - }, { - text: "2014年", value: 2014, py: "2014n", title: "1111111111111111111111111111111111" - }, { - text: "2015年", value: 2015, py: "2015n", title: "1111111111111111111111111111111111" - }, { - text: "2016年", value: 2016, py: "2016n", title: "1111111111111111111111111111111111" - }, { - text: "2017年", value: 2017, py: "2017n", title: "1111111111111111111111111111111111" - }]; - - var adapter = BI.createWidget({ - type: "bi.button_group", - cls: "layout-bg1", - items: this._createItems(items), - chooseType: 1, - behaviors: {}, - layouts: [{ - type: "bi.vertical" - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: adapter, - top: 50, - left: 50, - width: 200, - height: 100 - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.absolute", - width: 200, - height: 30, - items: [{ - el: { - type: "bi.searcher", - adapter: adapter, - width: 200, - height: 30 - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }, - top: 100, - left: 300 - }] - }); - } -}); -BI.shortcut("demo.searcher", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.switcher.js b/demo/js/core/abstract/combination/demo.switcher.js deleted file mode 100644 index 897ce35ce..000000000 --- a/demo/js/core/abstract/combination/demo.switcher.js +++ /dev/null @@ -1,59 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - - var adapter = BI.createWidget({ - type: "bi.label", - cls: "layout-bg2", - text: "将在该处弹出switcher" - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: adapter, - top: 50, - left: 20, - width: 200, - height: 300 - }] - }); - BI.createWidget({ - type: "bi.vertical", - element: this, - hgap: 30, - vgap: 20, - items: [{ - type: "bi.switcher", - el: { - type: "bi.button", - height: 25, - text: "Switcher" - }, - popup: { - cls: "mvc-border layout-bg5", - items: BI.createItems([{ - text: "项目1", - value: 1 - }, { - text: "项目2", - value: 2 - }, { - text: "项目3", - value: 3 - }, { - text: "项目4", - value: 4 - }], { - type: "bi.single_select_item", - height: 25 - }) - }, - adapter: adapter - }] - }); - } -}); -BI.shortcut("demo.switcher", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/combination/demo.tab.js b/demo/js/core/abstract/combination/demo.tab.js deleted file mode 100644 index 558baec05..000000000 --- a/demo/js/core/abstract/combination/demo.tab.js +++ /dev/null @@ -1,69 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createTabs: function (v) { - switch (v) { - case 1: - return BI.createWidget({ - type: "bi.label", - cls: "layout-bg1", - text: "面板1" - }); - case 2: - return BI.createWidget({ - type: "bi.label", - cls: "layout-bg2", - text: "面板2" - }); - } - }, - - render: function () { - this.tab = BI.createWidget({ - type: "bi.button_group", - height: 30, - items: [{ - text: "Tab1", - value: 1, - width: 50, - cls: "mvc-button layout-bg3" - }, { - text: "Tab2", - value: 2, - width: 50, - cls: "mvc-button layout-bg4" - }], - layouts: [{ - type: "bi.center_adapt", - items: [{ - el: { - type: "bi.horizontal", - width: 100 - } - }] - }] - }); - - var tab = BI.createWidget({ - direction: "custom", - type: "bi.tab", - element: this, - tab: this.tab, - cardCreator: BI.bind(this._createTabs, this) - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.tab, - left: 200, - top: 200 - }] - }); - - tab.setSelect(2); - } -}); -BI.shortcut("demo.tab", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.button_group.js b/demo/js/core/abstract/demo.button_group.js deleted file mode 100644 index 21652ad58..000000000 --- a/demo/js/core/abstract/demo.button_group.js +++ /dev/null @@ -1,62 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var ref; - return { - type: "bi.vertical", - items: [{ - type: "bi.button_group", - ref: function (_ref) { - ref = _ref; - }, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_NONE, - layouts: [{ - type: "bi.vertical", - items: [{ - type: "bi.vtape", - height: 200 - }] - }], - items: [{ - el: { - type: "bi.label", - text: "button_group是一类具有相同属性或相似属性的抽象, 本案例实现的是布局的嵌套(vertical布局下内嵌center_adapt布局)" - }, - height: 150 - }, { - el: { - type: "bi.button", - text: "1" - } - }] - }, { - type: "bi.button", - text: "populate", - handler: function () { - ref.populate([{ - el: { - type: "bi.label", - text: "1" - }, - height: 50 - }, { - el: { - type: "bi.button", - text: "2" - }, - height: 50 - }, { - el: { - type: "bi.label", - text: "3" - } - }]); - } - }] - - }; - } -}); -BI.shortcut("demo.button_group", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.button_tree.js b/demo/js/core/abstract/demo.button_tree.js deleted file mode 100644 index 94a34e776..000000000 --- a/demo/js/core/abstract/demo.button_tree.js +++ /dev/null @@ -1,26 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.button_tree", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - layouts: [{ - type: "bi.vertical" - }, { - type: "bi.center_adapt" - }], - items: [{ - type: "bi.label", - text: "0", - value: 0 - }, { - type: "bi.button", - text: "1", - value: 1 - }] - }; - } -}); -BI.shortcut("demo.button_tree", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.collection_view.js b/demo/js/core/abstract/demo.collection_view.js deleted file mode 100644 index fe8604fe0..000000000 --- a/demo/js/core/abstract/demo.collection_view.js +++ /dev/null @@ -1,41 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var items = []; - var cellCount = 100; - for (var i = 0; i < cellCount; i++) { - items[i] = { - type: "bi.label", - text: i - }; - } - var grid = BI.createWidget({ - type: "bi.collection_view", - width: 400, - height: 300, - items: items, - cellSizeAndPositionGetter: function (index) { - return { - x: index % 10 * 50, - y: Math.floor(index / 10) * 50, - width: 50, - height: 50 - }; - } - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: grid, - left: 10, - right: 10, - top: 10, - bottom: 10 - }] - }); - } -}); -BI.shortcut("demo.collection_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.custom_tree.js b/demo/js/core/abstract/demo.custom_tree.js deleted file mode 100644 index d512e4ff2..000000000 --- a/demo/js/core/abstract/demo.custom_tree.js +++ /dev/null @@ -1,245 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createDefaultTree: function () { - var TREEITEMS = [{id: -1, pId: -2, value: "根目录", open: true, type: "bi.plus_group_node", height: 25}, - {id: 1, pId: -1, value: "第一级目录1", type: "bi.plus_group_node", height: 25}, - {id: 11, pId: 1, value: "第二级文件1", type: "bi.single_select_item", height: 25}, - {id: 12, pId: 1, value: "第二级目录2", type: "bi.plus_group_node", height: 25}, - {id: 121, pId: 12, value: "第三级目录1", type: "bi.plus_group_node", height: 25}, - {id: 122, pId: 12, value: "第三级文件1", type: "bi.single_select_item", height: 25}, - {id: 1211, pId: 121, value: "第四级目录1", type: "bi.plus_group_node", height: 25}, - {id: 12111, pId: 1211, value: "第五级文件1", type: "bi.single_select_item", height: 25}, - {id: 2, pId: -1, value: "第一级目录2", type: "bi.plus_group_node", height: 25}, - {id: 21, pId: 2, value: "第二级目录3", type: "bi.plus_group_node", height: 25}, - {id: 22, pId: 2, value: "第二级文件2", type: "bi.single_select_item", height: 25}, - {id: 211, pId: 21, value: "第三级目录2", type: "bi.plus_group_node", height: 25}, - {id: 212, pId: 21, value: "第三级文件2", type: "bi.single_select_item", height: 25}, - {id: 2111, pId: 211, value: "第四级文件1", type: "bi.single_select_item", height: 25}]; - this.tree = BI.createWidget({ - type: "bi.custom_tree", - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical", - hgap: 30 - }] - }, - items: BI.deepClone(TREEITEMS) - }); - return this.tree; - }, - - _createAsyncTree: function () { - this.asyncTree = BI.createWidget({ - type: "bi.custom_tree", - itemsCreator: function (op, callback) { - if (!op.node) {// 根节点 - callback([{ - id: 1, - pId: 0, - type: "bi.plus_group_node", - text: "test1", - value: 1, - height: 25, - isParent: true - }, { - id: 2, - pId: 0, - type: "bi.plus_group_node", - text: "test2", - value: 1, - isParent: true, - open: true, - height: 25 - }]); - } else { - if (op.node.id == 1) { - callback([ - { - id: 11, - pId: 1, - type: "bi.plus_group_node", - text: "test11", - value: 11, - height: 25, - isParent: true - }, - { - id: 12, - pId: 1, - type: "bi.single_select_item", - text: "test12", - value: 12, - height: 35 - }, - { - id: 13, - pId: 1, - type: "bi.single_select_item", - text: "test13", - value: 13, - height: 35 - }, - { - id: 14, - pId: 1, - type: "bi.single_select_item", - text: "test14", - value: 14, - height: 35 - }, - { - id: 15, - pId: 1, - type: "bi.single_select_item", - text: "test15", - value: 15, - height: 35 - }, - { - id: 16, - pId: 1, - type: "bi.single_select_item", - text: "test16", - value: 16, - height: 35 - }, - {id: 17, pId: 1, type: "bi.single_select_item", text: "test17", value: 17, height: 35} - ]); - } else if (op.node.id == 2) { - callback([{ - id: 21, - pId: 2, - type: "bi.single_select_item", - text: "test21", - value: 21, - height: 35 - }, - { - id: 22, - pId: 2, - type: "bi.single_select_item", - text: "test22", - value: 22, - height: 35 - }]); - } else if (op.node.id == 11) { - callback([{ - id: 111, - pId: 11, - type: "bi.single_select_item", - text: "test111", - value: 111, - height: 35 - }]); - } - } - }, - el: { - type: "bi.loader", - next: false, - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical", - hgap: 30, - vgap: 0 - }] - } - } - }); - return this.asyncTree; - }, - - render: function () { - var self = this; - BI.createWidget({ - type: "bi.grid", - columns: 2, - rows: 1, - element: this, - items: [{ - column: 0, - row: 0, - el: { - type: "bi.vtape", - items: [ - { - el: this._createDefaultTree() - }, - { - el: { - type: "bi.center", - hgap: 10, - items: [{ - type: "bi.text_button", - cls: "mvc-button layout-bg2", - text: "getValue", - height: 30, - handler: function () { - BI.Msg.alert("", JSON.stringify(self.tree.getValue())); - } - }, { - type: "bi.text_button", - cls: "mvc-button layout-bg2", - text: "getNodeByValue(第一级目录1)", - height: 30, - handler: function () { - BI.Msg.alert("", "节点名称为: " + self.tree.getNodeByValue("第一级目录1").getValue()); - } - }] - }, - height: 30 - } - ] - } - }, { - column: 1, - row: 0, - el: { - type: "bi.vtape", - items: [ - { - type: "bi.label", - text: "异步加载数据", - height: 30 - }, - { - el: this._createAsyncTree() - }, - { - el: { - type: "bi.center", - hgap: 10, - items: [{ - type: "bi.text_button", - cls: "mvc-button layout-bg2", - text: "getValue", - height: 30, - handler: function () { - BI.Msg.alert("", JSON.stringify(self.asyncTree.getValue())); - } - }, { - type: "bi.text_button", - cls: "mvc-button layout-bg2", - text: "getNodeById(11)", - height: 30, - handler: function () { - BI.Msg.alert("", "节点名称为: " + (self.asyncTree.getNodeById(11) && self.asyncTree.getNodeById(11).getText())); - } - }] - }, - height: 30 - } - ] - } - }] - }); - } -}); -BI.shortcut("demo.custom_tree", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.grid_view.js b/demo/js/core/abstract/demo.grid_view.js deleted file mode 100644 index 87a87f26c..000000000 --- a/demo/js/core/abstract/demo.grid_view.js +++ /dev/null @@ -1,54 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var items = []; - var rowCount = 10000, columnCount = 100; - for (var i = 0; i < rowCount; i++) { - items[i] = []; - for (var j = 0; j < columnCount; j++) { - items[i][j] = { - type: "bi.label", - text: i + "-" + j - }; - } - } - var grid = BI.createWidget({ - type: "bi.grid_view", - width: 400, - height: 300, - estimatedRowSize: 30, - estimatedColumnSize: 100, - items: items, - scrollTop: 100, - rowHeightGetter: function () { - return 30; - }, - columnWidthGetter: function () { - return 100; - } - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.grid", - columns: 1, - rows: 1, - items: [{ - column: 0, - row: 0, - el: grid - }] - }, - left: 10, - right: 10, - top: 10, - bottom: 10 - }] - }); - } -}); -BI.shortcut("demo.grid_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.list_view.js b/demo/js/core/abstract/demo.list_view.js deleted file mode 100644 index d9be37cc1..000000000 --- a/demo/js/core/abstract/demo.list_view.js +++ /dev/null @@ -1,22 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.list_view", - el: { - type: "bi.left" - }, - items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { - return BI.extend({}, item, { - type: "bi.label", - width: 200, - height: 200, - text: (i + 1) + "." + item.text - }); - }) - }; - } -}); -BI.shortcut("demo.list_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.virtual_group.js b/demo/js/core/abstract/demo.virtual_group.js deleted file mode 100644 index 3f1220d60..000000000 --- a/demo/js/core/abstract/demo.virtual_group.js +++ /dev/null @@ -1,111 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - _createItems: function () { - var items = BI.map(BI.range(1000), function (i) { - return { - type: "demo.virtual_group_item", - value: i, - key: i + 1 - }; - }); - return items; - }, - - render: function () { - var self = this; - var buttonGroupItems = self._createItems(); - var virtualGroupItems = self._createItems(); - return { - type: "bi.vertical", - vgap: 20, - items: [{ - type: "bi.label", - cls: "layout-bg5", - height: 50, - text: "共1000个元素,演示button_group和virtual_group每次删除第一个元素,打开控制台看输出" - }, { - type: "bi.button_group", - width: 500, - height: 300, - ref: function () { - self.buttonGroup = this; - }, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - layouts: [{ - type: "bi.vertical" - }], - items: this._createItems() - }, { - type: "bi.button", - text: "演示button_group的刷新", - handler: function () { - buttonGroupItems.shift(); - self.buttonGroup.populate(BI.deepClone(buttonGroupItems)); - } - }, { - type: "bi.virtual_group", - width: 500, - height: 300, - ref: function () { - self.virtualGroup = this; - }, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - layouts: [{ - type: "bi.vertical" - }], - items: this._createItems() - }, { - type: "bi.button", - text: "演示virtual_group的刷新", - handler: function () { - virtualGroupItems.shift(); - self.virtualGroup.populate(BI.deepClone(virtualGroupItems)); - } - }] - - }; - } -}); -BI.shortcut("demo.virtual_group", Demo.Func); - -Demo.Item = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-item", - height: 30 - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.label", - ref: function () { - self.label = this; - }, - height: this.options.height, - text: "key:" + o.key + ",随机数" + BI.UUID() - }; - }, - - shouldUpdate: function (nextProps) { - var o = this.options; - return o.type !== nextProps.type || o.key !== nextProps.key || o.value !== nextProps.value; - }, - - update: function (item) { - this.label.setText(item.value); - console.log("更新了一项"); - return true;// 返回是不是更新成功 - }, - - created: function () { - console.log("创建了一项"); - }, - - destroyed: function () { - console.log("删除了一项"); - } -}); -BI.shortcut("demo.virtual_group_item", Demo.Item); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.virtual_list.js b/demo/js/core/abstract/demo.virtual_list.js deleted file mode 100644 index b2b213b7c..000000000 --- a/demo/js/core/abstract/demo.virtual_list.js +++ /dev/null @@ -1,18 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.virtual_list", - items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { - return BI.extend({}, item, { - type: "bi.label", - height: 30, - text: (i + 1) + "." + item.text - }); - }) - }; - } -}); -BI.shortcut("demo.virtual_list", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/layout/demo.absolute.js b/demo/js/core/layout/demo.absolute.js deleted file mode 100644 index 2137c24df..000000000 --- a/demo/js/core/layout/demo.absolute.js +++ /dev/null @@ -1,22 +0,0 @@ -Demo.AbsoluteLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-absolute" - }, - render: function () { - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.label", - text: "绝对布局", - cls: "layout-bg1", - width: 300, - height: 200 - }, - left: 100, - top: 100 - }] - }; - } -}); -BI.shortcut("demo.absolute", Demo.AbsoluteLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.border.js b/demo/js/core/layout/demo.border.js deleted file mode 100644 index 4d78455b2..000000000 --- a/demo/js/core/layout/demo.border.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.BorderLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-border" - }, - - _createNorth: function () { - return BI.createWidget({ - type: "bi.label", - text: "North", - cls: "layout-bg1", - height: 30 - }); - }, - - _createWest: function () { - return BI.createWidget({ - type: "bi.center", - cls: "layout-bg2", - items: [{ - type: "bi.label", - text: "West", - whiteSpace: "normal" - }] - }); - }, - - _createCenter: function () { - return BI.createWidget({ - type: "bi.center", - cls: "layout-bg3", - items: [{ - type: "bi.label", - text: "Center", - whiteSpace: "normal" - }] - }); - }, - - _createEast: function () { - return BI.createWidget({ - type: "bi.center", - cls: "layout-bg5", - items: [{ - type: "bi.label", - text: "East", - whiteSpace: "normal" - }] - }); - }, - - _createSouth: function () { - return BI.createWidget({ - type: "bi.label", - text: "South", - cls: "layout-bg6", - height: 50 - }); - }, - - render: function () { - return { - type: "bi.border", - cls: "", - items: { - north: { - el: this._createNorth(), - height: 30, - top: 20, - left: 20, - right: 20 - }, - south: { - el: this._createSouth(), - height: 50, - bottom: 20, - left: 20, - right: 20 - }, - west: { - el: this._createWest(), - width: 200, - left: 20 - }, - east: { - el: this._createEast(), - width: 300, - right: 20 - }, - center: this._createCenter() - } - }; - } -}); -BI.shortcut("demo.border", Demo.BorderLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.center.js b/demo/js/core/layout/demo.center.js deleted file mode 100644 index a57d04aa8..000000000 --- a/demo/js/core/layout/demo.center.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.CenterLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-center" - }, - render: function () { - return { - type: "bi.center", - items: [{ - type: "bi.label", - text: "其实是一个grid嵌套absolute的实现", - cls: "layout-bg1", - whiteSpace: "normal" - }, { - type: "bi.label", - text: "Center 2,为了演示label是占满整个的,用了一个whiteSpace:normal", - cls: "layout-bg2", - whiteSpace: "normal" - }, { - type: "bi.label", - text: "Center 3", - cls: "layout-bg3" - }, { - type: "bi.label", - text: "Center 4", - cls: "layout-bg5" - }], - hgap: 20, - vgap: 20 - }; - } -}); -BI.shortcut("demo.center_layout", Demo.CenterLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.center_adapt.js b/demo/js/core/layout/demo.center_adapt.js deleted file mode 100644 index 2dd5afa3b..000000000 --- a/demo/js/core/layout/demo.center_adapt.js +++ /dev/null @@ -1,18 +0,0 @@ -Demo.CenterAdapt = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-absolute" - }, - render: function () { - return { - type: "bi.center_adapt", - items: [{ - type: "bi.label", - text: "水平垂直居中", - width: 300, - height: 200, - cls: "layout-bg1" - }] - }; - } -}); -BI.shortcut("demo.center_adapt", Demo.CenterAdapt); \ No newline at end of file diff --git a/demo/js/core/layout/demo.float_center.js b/demo/js/core/layout/demo.float_center.js deleted file mode 100644 index bb249e1a0..000000000 --- a/demo/js/core/layout/demo.float_center.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.FloatCenterLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-float-center" - }, - render: function () { - return { - type: "bi.float_center", - items: [{ - type: "bi.label", - text: "floatCenter与center的不同在于,它可以控制最小宽度和最大宽度", - cls: "layout-bg1", - whiteSpace: "normal" - }, { - type: "bi.label", - text: "浮动式的中间布局", - cls: "layout-bg2", - whiteSpace: "normal" - }], - hgap: 20, - vgap: 20 - }; - } -}); -BI.shortcut("demo.float_center", Demo.FloatCenterLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.flow.js b/demo/js/core/layout/demo.flow.js deleted file mode 100644 index 52376fa63..000000000 --- a/demo/js/core/layout/demo.flow.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.FlowLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-flow" - }, - render: function () { - return { - type: "bi.center_adapt", - items: [{ - type: "bi.left", - items: [{ - type: "bi.label", - height: 30, - text: "Left-1", - cls: "layout-bg1" - - }, { - type: "bi.label", - height: 30, - text: "Left-2", - cls: "layout-bg2" - - }, { - type: "bi.label", - height: 30, - text: "Left-3", - cls: "layout-bg3" - - }, { - type: "bi.label", - height: 30, - text: "Left-4", - cls: "layout-bg4" - - }, { - type: "bi.label", - height: 30, - text: "Left-5", - cls: "layout-bg5" - - }], - hgap: 20 - }, { - type: "bi.right", - hgap: 20, - items: [{ - type: "bi.label", - height: 30, - text: "Right-1", - cls: "layout-bg1" - - }, { - type: "bi.label", - height: 30, - text: "Right-2", - cls: "layout-bg2" - - }, { - type: "bi.label", - height: 30, - text: "Right-3", - cls: "layout-bg3" - - }, { - type: "bi.label", - height: 30, - text: "Right-4", - cls: "layout-bg4" - - }, { - type: "bi.label", - height: 30, - text: "Right-5", - cls: "layout-bg5" - - }], - vgap: 20 - }] - }; - } -}); -BI.shortcut("demo.flow", Demo.FlowLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.grid.js b/demo/js/core/layout/demo.grid.js deleted file mode 100644 index c10466197..000000000 --- a/demo/js/core/layout/demo.grid.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.GridLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-grid" - }, - render: function () { - return { - type: "bi.grid", - columns: 5, - rows: 3, - items: [{ - column: 0, - row: 0, - el: { - type: "bi.label", - text: "column-0, row-0", - cls: "layout-bg1" - } - }, { - column: 1, - row: 0, - el: { - type: "bi.label", - text: "column-1, row-0", - cls: "layout-bg2" - } - }, { - column: 2, - row: 0, - el: { - type: "bi.label", - text: "column-2, row-0", - cls: "layout-bg6" - } - }, { - column: 3, - row: 0, - el: { - type: "bi.label", - text: "column-3, row-0", - cls: "layout-bg3" - } - }, { - column: 4, - row: 0, - el: { - type: "bi.label", - text: "column-4, row-0", - cls: "layout-bg4" - } - }, { - column: 0, - row: 1, - el: { - type: "bi.label", - text: "column-0, row-1", - cls: "layout-bg5" - } - }, { - column: 1, - row: 1, - el: { - type: "bi.label", - text: "column-1, row-1", - cls: "layout-bg6" - } - }, { - column: 2, - row: 1, - el: { - type: "bi.label", - text: "column-2, row-1", - cls: "layout-bg7" - } - }, { - column: 3, - row: 1, - el: { - type: "bi.label", - text: "column-3, row-1", - cls: "layout-bg1" - } - }, { - column: 4, - row: 1, - el: { - type: "bi.label", - text: "column-4, row-1", - cls: "layout-bg3" - } - }, { - column: 0, - row: 2, - el: { - type: "bi.label", - text: "column-0, row-2", - cls: "layout-bg2" - } - }, { - column: 1, - row: 2, - el: { - type: "bi.label", - text: "column-1, row-2", - cls: "layout-bg3" - } - }, { - column: 2, - row: 2, - el: { - type: "bi.label", - text: "column-2, row-2", - cls: "layout-bg4" - } - }, { - column: 3, - row: 2, - el: { - type: "bi.label", - text: "column-3, row-2", - cls: "layout-bg5" - } - }, { - column: 4, - row: 2, - el: { - type: "bi.label", - text: "column-4, row-2", - cls: "layout-bg6" - } - }] - }; - } -}); -BI.shortcut("demo.grid", Demo.GridLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.horizontal.js b/demo/js/core/layout/demo.horizontal.js deleted file mode 100644 index 377fd79c4..000000000 --- a/demo/js/core/layout/demo.horizontal.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Created by User on 2017/3/21. - */ -Demo.Horizontal = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-horizontal" - }, - render: function () { - return { - type: "bi.vertical", - vgap: 10, - items: [{ - type: "bi.horizontal", - height: 150, - hgap: 10, - items: [{ - type: "bi.label", - whiteSpace: "normal", - text: "因为大多数场景下都需要垂直居中,所以这个布局一般会被vertical_adapt布局设置scrollx=true取代", - cls: "layout-bg3", - width: 500, - height: 50 - }, { - type: "bi.label", - text: "水平布局", - cls: "layout-bg4", - width: 300, - height: 30 - }, { - type: "bi.label", - text: "水平布局", - cls: "layout-bg5", - width: 300, - height: 30 - }, { - type: "bi.label", - text: "水平布局", - cls: "layout-bg6", - width: 300, - height: 30 - }] - }, { - type: "bi.layout", - height: 1, - cls: "bi-border-bottom bi-high-light-border" - }, { - type: "bi.horizontal", - height: 150, - verticalAlign: BI.VerticalAlign.Middle, - horizontalAlign: BI.HorizontalAlign.Left, - vgap: 10, - items: [{ - type: "bi.label", - text: "以horizontal实现的vertical_adapt垂直居中", - cls: "layout-bg1", - width: 300, - height: 30 - }, { - type: "bi.label", - text: "以horizontal实现的vertical_adapt垂直居中", - cls: "layout-bg2", - width: 300, - height: 30 - }] - }, { - type: "bi.layout", - height: 1, - cls: "bi-border-bottom bi-high-light-border" - }, { - type: "bi.horizontal", - height: 150, - verticalAlign: BI.VerticalAlign.Top, - horizontalAlign: BI.HorizontalAlign.Center, - items: [{ - type: "bi.label", - text: "以horizontal代替horizontal_adapt实现的水平居中(单元素)", - cls: "layout-bg1", - width: 300, - height: 30 - }] - }, { - type: "bi.layout", - height: 1, - cls: "bi-border-bottom bi-high-light-border" - }, { - type: "bi.horizontal", - height: 150, - verticalAlign: BI.VerticalAlign.Top, - horizontalAlign: BI.HorizontalAlign.Center, - columnSize: [300, "fill"], - items: [{ - type: "bi.label", - text: "以horizontal代替horizontal_adapt实现的用于水平适应布局", - cls: "layout-bg1", - height: 30 - }, { - type: "bi.label", - text: "以horizontal代替horizontal_adapt实现的水平自适应列", - cls: "layout-bg2", - height: 30 - }] - }, { - type: "bi.layout", - height: 1, - cls: "bi-border-bottom bi-high-light-border" - }, { - type: "bi.center_adapt", - height: 150, - verticalAlign: BI.VerticalAlign.Middle, - horizontalAlign: BI.HorizontalAlign.Center, - items: [{ - type: "bi.label", - text: "以horizontal代替center_adapt实现的水平垂直居中", - width: 300, - height: 100, - cls: "layout-bg1" - }] - }, { - type: "bi.layout", - height: 1, - cls: "bi-border-bottom bi-high-light-border" - }] - }; - } -}); -BI.shortcut("demo.horizontal", Demo.Horizontal); \ No newline at end of file diff --git a/demo/js/core/layout/demo.horizontal_adapt.js b/demo/js/core/layout/demo.horizontal_adapt.js deleted file mode 100644 index 316e604a6..000000000 --- a/demo/js/core/layout/demo.horizontal_adapt.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.HorizontalAdapt = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-horizontal-adapt" - }, - - _createLayout: function () { - return BI.createWidget({ - type: "bi.horizontal_adapt", - items: [{ - type: "bi.label", - text: "例子1:可用做水平居中", - cls: "layout-bg1", - width: 300, - height: 30 - }] - }); - }, - - _createAdaptLayout: function () { - return BI.createWidget({ - type: "bi.horizontal_adapt", - columnSize: [300, "fill"], - items: [{ - type: "bi.label", - text: "例子2:用于水平适应布局", - cls: "layout-bg1", - height: 30 - }, { - type: "bi.label", - text: "水平自适应列", - cls: "layout-bg2", - height: 30 - }] - }); - }, - - render: function () { - return { - type: "bi.grid", - columns: 1, - rows: 2, - items: [{ - column: 0, - row: 0, - el: this._createLayout() - }, { - column: 0, - row: 1, - el: this._createAdaptLayout() - }] - }; - } -}); -BI.shortcut("demo.horizontal_adapt", Demo.HorizontalAdapt); \ No newline at end of file diff --git a/demo/js/core/layout/demo.horizontal_auto.js b/demo/js/core/layout/demo.horizontal_auto.js deleted file mode 100644 index 46e10165a..000000000 --- a/demo/js/core/layout/demo.horizontal_auto.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.HorizontalAuto = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-horizontal-auto" - }, - - _createLayout: function () { - return BI.createWidget({ - type: "bi.horizontal_auto", - items: [{ - type: "bi.label", - text: "水平居中", - cls: "layout-bg1", - width: 300, - height: 30 - }, { - type: "bi.label", - text: "水平居中优先使用该布局", - cls: "layout-bg2", - width: 300, - height: 30 - }] - }); - }, - - render: function () { - return { - type: "bi.grid", - columns: 1, - rows: 2, - items: [{ - column: 0, - row: 0, - el: this._createLayout() - }] - }; - } -}); -BI.shortcut("demo.horizontal_auto", Demo.HorizontalAuto); \ No newline at end of file diff --git a/demo/js/core/layout/demo.horizontal_float.js b/demo/js/core/layout/demo.horizontal_float.js deleted file mode 100644 index f5d84bc71..000000000 --- a/demo/js/core/layout/demo.horizontal_float.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.HorizontalFloat = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-horizontal-float" - }, - - render: function () { - return { - type: "bi.horizontal_float", - items: [{ - type: "bi.label", - text: "浮动式水平居中布局方案,用于宽度未知的情况", - cls: "layout-bg1", - height: 30 - }] - }; - } -}); -BI.shortcut("demo.horizontal_float", Demo.HorizontalFloat); \ No newline at end of file diff --git a/demo/js/core/layout/demo.htape.js b/demo/js/core/layout/demo.htape.js deleted file mode 100644 index d2f0d6009..000000000 --- a/demo/js/core/layout/demo.htape.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.HtapeLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-htape" - }, - render: function () { - return { - type: "bi.htape", - items: [ - { - width: 100, - el: { - type: "bi.label", - text: "1", - cls: "bi-background" - } - }, { - width: 200, - el: { - type: "bi.label", - text: "2", - cls: "layout-bg2" - } - }, { - width: "fill", - el: { - type: "bi.label", - text: "3", - cls: "layout-bg3" - } - } - ] - }; - } -}); -BI.shortcut("demo.htape", Demo.HtapeLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.left_right_vertical_adapt.js b/demo/js/core/layout/demo.left_right_vertical_adapt.js deleted file mode 100644 index e5689063b..000000000 --- a/demo/js/core/layout/demo.left_right_vertical_adapt.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.LeftRightVerticalAdaptLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-left-right-vertical-adapt" - }, - render: function () { - return { - type: "bi.left_right_vertical_adapt", - lhgap: 10, - rhgap: 30, - items: { - left: [{ - type: "bi.label", - text: "左边的垂直居中", - cls: "layout-bg1", - width: 100, - height: 30 - }, { - type: "bi.label", - text: "左边的垂直居中", - cls: "layout-bg2", - width: 100, - height: 30 - }], - right: [{ - type: "bi.label", - text: "右边的垂直居中", - cls: "layout-bg1", - width: 100, - height: 30 - }, { - type: "bi.label", - text: "右边的垂直居中", - cls: "layout-bg2", - width: 100, - height: 30 - }] - } - }; - } -}); -BI.shortcut("demo.left_right_vertical_adapt", Demo.LeftRightVerticalAdaptLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.table.js b/demo/js/core/layout/demo.table.js deleted file mode 100644 index 3497c7f9e..000000000 --- a/demo/js/core/layout/demo.table.js +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.TableLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-table-layout" - }, - - _createTable1: function () { - return { - type: "bi.table", - items: BI.createItems([ - [ - { - el: { - cls: "layout-bg1" - } - }, - { - el: { - cls: "layout-bg2" - } - }, - { - el: { - cls: "layout-bg3" - } - } - ], - [ - { - el: { - cls: "layout-bg4" - } - }, - { - el: { - cls: "layout-bg5" - } - }, - { - el: { - cls: "layout-bg6" - } - } - ], - [ - { - el: { - cls: "layout-bg7" - } - }, - { - el: { - cls: "layout-bg8" - } - }, - { - el: { - cls: "layout-bg1" - } - } - ], - [ - { - el: { - cls: "layout-bg2" - } - }, - { - el: { - cls: "layout-bg3" - } - }, - { - el: { - cls: "layout-bg4" - } - } - ], - [ - { - el: { - cls: "layout-bg5" - } - }, - { - el: { - cls: "layout-bg6" - } - }, - { - el: { - cls: "layout-bg7" - } - } - ], - [ - { - el: { - cls: "layout-bg8" - } - }, - { - el: { - cls: "layout-bg1" - } - }, - { - el: { - cls: "layout-bg2" - } - } - ], - [ - { - el: { - cls: "layout-bg6" - } - }, - { - el: { - cls: "layout-bg7" - } - }, - { - el: { - cls: "layout-bg8" - } - } - ] - ], { - type: "bi.layout" - }), - columnSize: [100, "fill", 200], - rowSize: [10, 30, 50, 70, 90, 110, 130], - hgap: 20, - vgap: 10 - }; - }, - - render: function () { - return { - type: "bi.grid", - columns: 1, - rows: 1, - items: [ - { - column: 0, - row: 0, - el: this._createTable1() - } - // , { - // column: 0, - // row: 1, - // el: this._createTable2() - // } - ] - }; - } -}); -BI.shortcut("demo.table_layout", Demo.TableLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.td.js b/demo/js/core/layout/demo.td.js deleted file mode 100644 index cd61eb14a..000000000 --- a/demo/js/core/layout/demo.td.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.TdLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-td" - }, - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.td", - columnSize: [100, 100, ""], - items: BI.createItems([ - [{ - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg1" - } - }, { - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg2" - } - }, { - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg3" - } - }], [{ - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg5" - } - }, { - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg6" - } - }, { - el: { - type: "bi.label", - text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", - cls: "layout-bg7" - } - }] - ], { - whiteSpace: "normal" - }) - }] - }; - } -}); -BI.shortcut("demo.td", Demo.TdLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.vertical.js b/demo/js/core/layout/demo.vertical.js deleted file mode 100644 index 45576eadb..000000000 --- a/demo/js/core/layout/demo.vertical.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Created by User on 2017/3/21. - */ -Demo.VerticalLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-vertical" - }, - render: function () { - return { - type: "bi.vertical", - vgap: 10, - items: [{ - type: "bi.label", - cls: "layout-bg3", - text: "垂直布局", - height: 30 - }, { - type: "bi.label", - cls: "layout-bg4", - text: "垂直布局", - height: 30 - }] - }; - } -}); -BI.shortcut("demo.vertical", Demo.VerticalLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.vertical_adapt.js b/demo/js/core/layout/demo.vertical_adapt.js deleted file mode 100644 index 92783f116..000000000 --- a/demo/js/core/layout/demo.vertical_adapt.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.VerticalAdaptLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-vertical-adapt" - }, - - _createLayout: function () { - return BI.createWidget({ - type: "bi.vertical_adapt", - vgap: 10, - items: [{ - type: "bi.label", - text: "垂直居中", - cls: "layout-bg1", - width: 300, - height: 30 - }, { - type: "bi.label", - text: "垂直居中", - cls: "layout-bg2", - width: 300, - height: 30 - }] - }); - }, - - render: function () { - return { - type: "bi.grid", - columns: 2, - rows: 1, - items: [{ - column: 0, - row: 0, - el: this._createLayout() - }] - }; - } -}); -BI.shortcut("demo.vertical_adapt", Demo.VerticalAdaptLayout); \ No newline at end of file diff --git a/demo/js/core/layout/demo.vtape.js b/demo/js/core/layout/demo.vtape.js deleted file mode 100644 index d10859abc..000000000 --- a/demo/js/core/layout/demo.vtape.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.VtapeLayout = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-vtape" - }, - render: function () { - return { - type: "bi.vtape", - vgap: 10, - items: [ - { - height: 100, - el: { - type: "bi.label", - text: "1", - cls: "layout-bg1" - }, - tgap: 10, - vgap: 10 - }, { - height: 200, - el: { - type: "bi.label", - text: "2", - cls: "layout-bg2" - } - }, { - height: "fill", - el: { - type: "bi.label", - text: "3", - cls: "layout-bg3" - } - } - ] - }; - } -}); -BI.shortcut("demo.vtape", Demo.VtapeLayout); \ No newline at end of file diff --git a/demo/js/core/popup/demo.layer.js b/demo/js/core/popup/demo.layer.js deleted file mode 100644 index 83f18fd8d..000000000 --- a/demo/js/core/popup/demo.layer.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Created by Windy on 2017/12/13. - */ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var self = this, id1 = BI.UUID(), id2 = BI.UUID(); - return { - type: "bi.vertical", - vgap: 10, - items: [{ - type: "bi.button", - text: "create形式创建layer, 遮住当前面板, 返回创建的面板对象", - height: 30, - handler: function () { - BI.Layers.create(id1, self, { - //偏移量 - offset: { - left: 10, - right: 10, - top: 10, - bottom: 10 - }, - type: "bi.center_adapt", - cls: "bi-card", - items: [{ - type: "bi.button", - text: "点击关闭", - handler: function () { - BI.Layers.hide(id1); - } - }] - }); - BI.Layers.show(id1); - } - }, { - type: "bi.button", - text: "make形式创建layer,可以指定放到哪个面板内,这里指定当前面板(默认放在body下撑满), 返回创建的面板对象", - height: 30, - handler: function () { - BI.Layers.make(id2, self, { - //偏移量 - offset: { - left: 10, - right: 10, - top: 10, - bottom: 10 - }, - type: "bi.center_adapt", - cls: "bi-card", - items: [{ - type: "bi.button", - text: "点击关闭", - handler: function () { - BI.Layers.remove(id2); - } - }] - }); - BI.Layers.show(id2); - } - }] - }; - } -}); - -BI.shortcut("demo.layer", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/popup/demo.popover.js b/demo/js/core/popup/demo.popover.js deleted file mode 100644 index 1c736c34e..000000000 --- a/demo/js/core/popup/demo.popover.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * Created by Windy on 2017/12/13. - */ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - var id = BI.UUID(); - var body; - - return { - type: "bi.vertical", - vgap: 10, - items: [{ - type: "bi.text_button", - text: "点击弹出Popover(normal size & fixed)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - type: "bi.bar_popover", - size: "normal", - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.label", - text: "这个是body" - } - }).open(id); - } - }, { - type: "bi.text_button", - text: "点击弹出Popover(small size & fixed)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - type: "bi.bar_popover", - size: "small", - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.label", - text: "这个是body" - } - }).open(id); - } - }, { - type: "bi.text_button", - text: "点击弹出Popover(big size & fixed)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - type: "bi.bar_popover", - size: "big", - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.label", - text: "这个是body" - } - }).open(id); - } - }, { - type: "bi.text_button", - text: "点击弹出Popover(normal size & adapt body区域高度是300)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - type: "bi.bar_popover", - size: "normal", - logic: { - dynamic: true - }, - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.vertical", - items: [{ - type: "bi.button_group", - ref: function () { - body = this; - }, - items: BI.map(BI.range(0, 10), function () { - return { - type: "bi.label", - text: "1", - height: 30 - }; - }), - layouts: [{ - type: "bi.vertical" - }] - }] - } - }).open(id); - } - }, { - type: "bi.text_button", - text: "点击弹出Popover(small size & adapt body区域高度是900)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - type: "bi.bar_popover", - size: "small", - logic: { - dynamic: true - }, - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.vertical", - items: [{ - type: "bi.button_group", - ref: function () { - body = this; - }, - items: BI.map(BI.range(0, 30), function () { - return { - type: "bi.label", - text: "1", - height: 30 - }; - }), - layouts: [{ - type: "bi.vertical" - }] - }] - } - }).open(id); - } - }, { - type: "bi.text_button", - text: "点击弹出Popover(custom)", - height: 30, - handler: function () { - BI.Popovers.remove(id); - BI.Popovers.create(id, { - width: 400, - height: 300, - header: { - type: "bi.label", - text: "这个是header" - }, - body: { - type: "bi.label", - text: "这个是body" - }, - footer: { - type: "bi.label", - text: "这个是footer" - } - }).open(id); - } - }, { - type: "bi.text_button", - height: 30, - text: "弹出一个高度动态的popover层, 此弹出层指定size为small, 但是高度随内容自适应,自适应支持的最大高度为默认为600px", - handler: function() { - var id = "弹出层id1" - BI.Popovers.create(id, { - // String或者是json都行 - header: "弹出层标题", - logic: { - dynamic: true, - maxHeight: 700, - }, - size: "small", - body: { - type: "bi.vertical", - items: BI.map(BI.range(0, 50), function(idx, v) { - return { - type: "bi.label", - text: "弹出层内容", - }; - }), - }, - footer: { - type: "bi.label", - text: "这个是footer", - }, - }).open(id); - }, - }], - }; - } -}); - -BI.shortcut("demo.popover", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/popup/demo.popup_view.js b/demo/js/core/popup/demo.popup_view.js deleted file mode 100644 index b7c6bfad1..000000000 --- a/demo/js/core/popup/demo.popup_view.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Created by Windy on 2017/12/13. - */ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - width: 200, - height: 30, - el: { - type: "bi.text_button", - text: "点击", - cls: "bi-border", - height: 30 - }, - popup: { - type: "bi.popup_view", - el: { - type: "bi.button_group", - layouts: [{ - type: "bi.vertical" - }], - items: BI.createItems(BI.deepClone(Demo.CONSTANTS.ITEMS), { - type: "bi.multi_select_item", - height: 25 - }) - } - } - } - }] - }; - } -}); -BI.shortcut("demo.popup_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/popup/demo.searcher_view.js b/demo/js/core/popup/demo.searcher_view.js deleted file mode 100644 index 8cb1eff7b..000000000 --- a/demo/js/core/popup/demo.searcher_view.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Created by Windy on 2017/12/13. - */ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.searcher_view", - ref: function () { - self.searcherView = this; - } - }, - left: 100, - top: 20, - width: 230 - }] - }; - }, - - mounted: function () { - this.searcherView.populate(BI.createItems([{ - text: 2012 - }, { - text: 2013 - }, { - text: 2014 - }, { - text: 2015 - }], { - type: "bi.label", - textHeight: 24, - height: 24 - }), [{ - text: 2 - }], "2"); - } -}); -BI.shortcut("demo.searcher_view", Demo.Func); \ No newline at end of file diff --git a/demo/js/face.js b/demo/js/face.js deleted file mode 100644 index 62304e8d6..000000000 --- a/demo/js/face.js +++ /dev/null @@ -1,690 +0,0 @@ -Demo.Face = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-face" - }, - - _createLabel: function (text) { - return { - width: 200, - el: { - type: "bi.label", - text: text, - textAlign: "left", - hgap: 5, - height: 40, - cls: "config-label" - } - }; - }, - - _createColorPicker: function (ref, action) { - return { - el: { - type: "bi.vertical_adapt", - items: [{ - type: "bi.color_chooser", - listeners: [{ - eventName: BI.ColorChooser.EVENT_CHANGE, - action: action - }], - ref: ref, - width: 24, - height: 24 - }] - } - }; - }, - - _createBackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("背景色:"), this._createColorPicker(function () { - self.backgroundColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createFontConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("字体颜色:"), this._createColorPicker(function () { - self.fontColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createActiveFontConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("激活状态字体颜色:"), this._createColorPicker(function () { - self.activeFontColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - cls: "bi-list-item-active", - text: "测试激活状态", - } - }] - }; - }, - - _createSelectFontConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("选中状态字体颜色:"), this._createColorPicker(function () { - self.selectFontColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - cls: "bi-list-item-active", - text: "测试选中状态", - } - }] - }; - }, - - _createGrayFontConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("tip提示字体颜色:"), this._createColorPicker(function () { - self.grayFontColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.icon_text_item", - cls: "bi-tips copy-font", - height: 40, - text: "测试提示文字" - } - }] - }; - }, - - _createDisableFontConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("灰化字体颜色:"), this._createColorPicker(function () { - self.disabledFontColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - text: "这个按钮是灰化的", - disabled: true - } - }] - }; - }, - - _createCardBackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("Card背景颜色:"), this._createColorPicker(function () { - self.cardBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createHoverBackgroundColor: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("悬浮状态背景颜色:"), this._createColorPicker(function () { - self.hoverBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - cls: "bi-list-item-active", - text: "测试悬浮状态", - } - }] - }; - }, - - _createActiveBackgroundColor: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("激活状态背景颜色:"), this._createColorPicker(function () { - self.activeBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - cls: "bi-list-item-active", - text: "测试激活状态", - } - }] - }; - }, - - _createSelectBackgroundColor: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("选中状态背景颜色:"), this._createColorPicker(function () { - self.selectBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.text_button", - cls: "bi-list-item-active", - text: "测试选中状态", - } - }] - }; - }, - - _createSlitColor: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("分割线颜色:"), this._createColorPicker(function () { - self.slitColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createBaseConfig: function () { - return { - type: "bi.vertical", - items: [this._createLabel("--通用配色--"), - this._createBackgroundConfig(), - this._createCardBackgroundConfig(), - this._createFontConfig(), - this._createActiveFontConfig(), - this._createSelectFontConfig(), - this._createGrayFontConfig(), - this._createDisableFontConfig(), - this._createHoverBackgroundColor(), - this._createActiveBackgroundColor(), - this._createSelectBackgroundColor(), - this._createSlitColor() - ] - }; - }, - - - _createButton1BackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("按钮背景色1:"), this._createColorPicker(function () { - self.button1BackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - height: 40, - items: [{ - type: "bi.button", - cls: "config-button1", - text: "测试按钮" - }] - } - }] - }; - }, - - _createButton2BackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("按钮背景色2:"), this._createColorPicker(function () { - self.button2BackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - height: 40, - items: [{ - type: "bi.button", - level: "success", - cls: "config-button2", - text: "测试按钮" - }] - } - }] - }; - }, - - _createButton3BackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("按钮背景色3:"), this._createColorPicker(function () { - self.button3BackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - height: 40, - items: [{ - type: "bi.button", - level: "warning", - cls: "config-button3", - text: "测试按钮" - }] - } - }] - }; - }, - - _createButton4BackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("按钮背景色4:"), this._createColorPicker(function () { - self.button4BackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - height: 40, - items: [{ - type: "bi.button", - level: "ignore", - cls: "config-button4", - text: "测试按钮" - }] - } - }] - }; - }, - - _createScrollBackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("滚动条底色:"), this._createColorPicker(function () { - self.scrollBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createScrollThumbConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("滚动条thumb颜色:"), this._createColorPicker(function () { - self.scrollThumbColor = this; - }, function () { - self._runGlobalStyle(); - })] - }; - }, - - _createPopupBackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("下拉框背景颜色:"), this._createColorPicker(function () { - self.popupBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - items: [{ - type: "bi.down_list_combo", - items: [[{ - el: { - text: "column 1111", - iconCls1: "check-mark-e-font", - value: 11 - }, - children: [ - { - text: "column 1.1", - value: 21, - cls: "dot-e-font", - selected: true - }, { - text: "column 1.222222222222222222222222222222222222", - cls: "dot-e-font", - value: 22 - }, { - text: "column 1.3", - cls: "dot-e-font", - value: 23 - }, { - text: "column 1.4", - cls: "dot-e-font", - value: 24 - }, { - text: "column 1.5", - cls: "dot-e-font", - value: 25 - } - ] - }], [ - { - el: { - type: "bi.icon_text_icon_item", - text: "column 2", - iconCls1: "chart-type-e-font", - cls: "dot-e-font", - value: 12 - }, - disabled: true, - children: [{ - type: "bi.icon_text_item", - cls: "dot-e-font", - height: 25, - text: "column 2.1", - value: 11 - }, {text: "column 2.2", value: 12, cls: "dot-e-font"}] - - - } - ], [ - { - text: "column 33333333333333333333333333333333", - cls: "style-set-e-font", - value: 13 - } - ], [ - { - text: "column 4", - cls: "filter-e-font", - value: 14 - } - ], [ - { - text: "column 5", - cls: "copy-e-font", - value: 15 - - } - ], [ - { - text: "column 6", - cls: "delete-e-font", - value: 16 - } - ], [ - { - text: "column 7", - cls: "dimension-from-e-font", - value: 17, - disabled: true - } - ]] - }] - } - }] - }; - }, - - _createMaskBackgroundConfig: function () { - var self = this; - return { - type: "bi.htape", - cls: "config-item bi-border-bottom", - height: 40, - items: [this._createLabel("弹出层蒙版颜色:"), this._createColorPicker(function () { - self.maskBackgroundColor = this; - }, function () { - self._runGlobalStyle(); - }), { - width: 100, - el: { - type: "bi.vertical_adapt", - items: [{ - type: "bi.button", - text: "mask测试", - handler: function () { - BI.Msg.alert("弹出层", "弹出层面板"); - } - }] - } - }] - }; - }, - - _createCommonConfig: function () { - return { - type: "bi.vertical", - items: [this._createLabel("--一般配色--"), - this._createButton1BackgroundConfig(), - this._createButton2BackgroundConfig(), - this._createButton3BackgroundConfig(), - this._createButton4BackgroundConfig(), - this._createScrollBackgroundConfig(), - this._createScrollThumbConfig(), - this._createPopupBackgroundConfig(), - this._createMaskBackgroundConfig() - ] - }; - }, - - render: function () { - var self = this; - return { - type: "bi.grid", - items: [[{ - el: { - type: "bi.vertical", - cls: "face-config bi-border-right", - items: [this._createBaseConfig(), - this._createCommonConfig()] - } - }, { - el: { - type: "bi.layout" - } - }]] - }; - }, - - _setStyle: function (objects) { - var result = ""; - BI.each(objects, function (cls, object) { - result += cls + "{"; - BI.each(object, function (name, value) { - result += name + ":" + value + ";"; - }); - result += "} "; - }); - BI.StyleLoaders.removeStyle("style").loadStyle("style", result); - }, - - _runGlobalStyle: function () { - var backgroundColor = this.backgroundColor.getValue(); - var fontColor = this.fontColor.getValue(); - var activeFontColor = this.activeFontColor.getValue(); - var selectFontColor = this.selectFontColor.getValue(); - var grayFontColor = this.grayFontColor.getValue(); - var disabledFontColor = this.disabledFontColor.getValue(); - var cardBackgroundColor = this.cardBackgroundColor.getValue(); - var hoverBackgroundColor = this.hoverBackgroundColor.getValue(); - var activeBackgroundColor = this.activeBackgroundColor.getValue(); - var selectBackgroundColor = this.selectBackgroundColor.getValue(); - var slitColor = this.slitColor.getValue(); - - var button1BackgroundColor = this.button1BackgroundColor.getValue(); - var button2BackgroundColor = this.button2BackgroundColor.getValue(); - var button3BackgroundColor = this.button3BackgroundColor.getValue(); - var button4BackgroundColor = this.button4BackgroundColor.getValue(); - var scrollBackgroundColor = this.scrollBackgroundColor.getValue(); - var scrollThumbColor = this.scrollThumbColor.getValue(); - var popupBackgroundColor = this.popupBackgroundColor.getValue(); - var maskBackgroundColor = this.maskBackgroundColor.getValue(); - - this._setStyle({ - "body.bi-background, body .bi-background": { - "background-color": backgroundColor, - color: fontColor - }, - "body .bi-card": { - "background-color": cardBackgroundColor, - color: fontColor - }, - "body .bi-tips": { - color: grayFontColor - }, - "div::-webkit-scrollbar,.scrollbar-layout-main": { - "background-color": scrollBackgroundColor + "!important" - }, - "div::-webkit-scrollbar-thumb,.public-scrollbar-face:after": { - "background-color": scrollThumbColor + "!important" - }, - ".base-disabled": { - color: disabledFontColor + "!important" - }, - ".base-disabled .b-font:before": { - color: disabledFontColor + "!important" - }, - ".list-view-outer": { - "background-color": popupBackgroundColor + "!important" - }, - ".bi-z-index-mask": { - "background-color": maskBackgroundColor + "!important" - }, - ".bi-list-item:hover,.bi-list-item-hover:hover,.bi-list-item-active:hover,.bi-list-item-select:hover,.bi-list-item-effect:hover": { - "background-color": hoverBackgroundColor + "!important" - }, - ".bi-list-item-active:active,.bi-list-item-select:active,.bi-list-item-effect:active": { - "background-color": activeBackgroundColor + "!important", - color: activeFontColor + "!important" - }, - ".bi-list-item-active.active,.bi-list-item-select.active,.bi-list-item-effect.active": { - "background-color": selectBackgroundColor + "!important", - color: selectFontColor + "!important" - }, - "body .bi-button.button-common": { - "background-color": button1BackgroundColor, - "border-color": button1BackgroundColor - }, - "body .bi-button.button-success": { - "background-color": button2BackgroundColor, - "border-color": button2BackgroundColor - }, - "body .bi-button.button-warning": { - "background-color": button3BackgroundColor, - "border-color": button3BackgroundColor - }, - "body .bi-button.button-ignore": { - "background-color": button4BackgroundColor - }, - // 以下是分割线颜色 - "body .bi-border,body .bi-border-top,#wrapper .bi-border-bottom,body .bi-border-left,body .bi-border-right": { - "border-color": slitColor - }, - ".bi-collection-table-cell": { - "border-right-color": slitColor, - "border-bottom-color": slitColor - }, - ".bi-collection-table-cell.first-col": { - "border-left-color": slitColor - }, - ".bi-collection-table-cell.first-row": { - "border-top-color": slitColor - } - }); - }, - - mounted: function () { - this.backgroundColor.setValue(""); - this.fontColor.setValue(""); - this.activeFontColor.setValue(""); - this.selectFontColor.setValue(""); - this.grayFontColor.setValue(""); - this.disabledFontColor.setValue(""); - this.cardBackgroundColor.setValue(""); - this.hoverBackgroundColor.setValue(""); - this.activeBackgroundColor.setValue(""); - this.selectBackgroundColor.setValue(""); - - this.button1BackgroundColor.setValue(""); - this.button2BackgroundColor.setValue(""); - this.button3BackgroundColor.setValue(""); - this.button4BackgroundColor.setValue(""); - this.scrollBackgroundColor.setValue(""); - this.scrollThumbColor.setValue(""); - this.popupBackgroundColor.setValue(""); - this.maskBackgroundColor.setValue(""); - this.slitColor.setValue(""); - this._runGlobalStyle(); - } -}); -BI.shortcut("demo.face", Demo.Face); \ No newline at end of file diff --git a/demo/js/fix-2.0/computed.js b/demo/js/fix-2.0/computed.js deleted file mode 100644 index 7dd00c30e..000000000 --- a/demo/js/fix-2.0/computed.js +++ /dev/null @@ -1,52 +0,0 @@ -(function () { - var model = Fix.define({ - name: "原始属性", - arr: [{ - n: "a" - }, { - n: "b" - }] - }); - var Computed = BI.inherit(Fix.Model, { - computed: { - b: function () { - return this.name + "-计算属性"; - } - } - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return new Computed(model); - }, - watch: { - b: function () { - this.button.setText(this.model.b); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.model.name = "这是改变后的属性"; - }, - text: this.model.b - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_computed", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/fix-2.0/context.js b/demo/js/fix-2.0/context.js deleted file mode 100644 index b248b502c..000000000 --- a/demo/js/fix-2.0/context.js +++ /dev/null @@ -1,79 +0,0 @@ -(function () { - var ParentStore = BI.inherit(Fix.Model, { - state: function () { - return { - context: "默认context" - }; - }, - childContext: ["context"] - }); - - BI.model("demo.model.context.parent_store",ParentStore) - - var ChildStore = BI.inherit(Fix.Model, { - context: ["context"], - computed: { - currContext: function () { - return this.model.context; - } - }, - actions: { - changeContext: function () { - this.model.context = "改变后的context"; - } - } - }); - - BI.model("demo.model.context.child_store",ChildStore) - - var Child = BI.inherit(BI.Widget, { - _store: function () { - return BI.Models.getModel("demo.model.context.child_store"); - }, - watch: { - currContext: function (val) { - this.button.setText(val); - } - }, - render: function () { - var self = this; - return { - type: "bi.button", - ref: function () { - self.button = this; - }, - text: this.model.context, - handler: function () { - self.store.changeContext(); - } - }; - }, - mounted: function () { - - } - }); - - BI.shortcut("demo.fix_context_child", Child); - - var Parent = BI.inherit(BI.Widget, { - _store: function () { - return BI.Models.getModel("demo.model.context.parent_store"); - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "demo.fix_context_child" - } - }] - }; - }, - mounted: function () { - - } - }); - - BI.shortcut("demo.fix_context", Parent); -}()); diff --git a/demo/js/fix-2.0/define.js b/demo/js/fix-2.0/define.js deleted file mode 100644 index 969c87f3f..000000000 --- a/demo/js/fix-2.0/define.js +++ /dev/null @@ -1,45 +0,0 @@ -(function () { - var model = Fix.define({ - name: "原始属性", - arr: [{ - n: "a" - }, { - n: "b" - }] - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return model; - }, - watch: { - name: function () { - this.button.setText(this.model.name); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.model.name = "这是改变后的属性"; - }, - text: this.model.name - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_define", Demo.Fix); -}()); diff --git a/demo/js/fix-2.0/demo.js b/demo/js/fix-2.0/demo.js deleted file mode 100644 index dab4b410c..000000000 --- a/demo/js/fix-2.0/demo.js +++ /dev/null @@ -1,74 +0,0 @@ -(function () { - var model = Fix.define({ - name: 1, - arr: [{ - n: "a" - }, { - n: 0 - }] - }); - var Computed = BI.inherit(Fix.Model, { - computed: { - b: function () { - return this.name + 1; - }, - c: function () { - return this.arr[1].n + this.b; - } - } - }); - - var Store = BI.inherit(Fix.Model, { - _init: function () { - this.comp = new Computed(model); - }, - computed: { - b: function () { - return this.comp.c + 1; - }, - c: function () { - return this.comp.arr[1].n & 1; - } - }, - actions: { - run: function () { - this.comp.name++; - this.comp.arr[1].n++; - } - } - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return new Store(); - }, - watch: { - "b&&(c||b)": function () { - this.button.setText(this.model.b); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.store.run(); - }, - text: this.model.b - } - }] - }; - }, - mounted: function () { - - } - }); - - BI.shortcut("demo.fix", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/fix-2.0/globalwatcher.js b/demo/js/fix-2.0/globalwatcher.js deleted file mode 100644 index 248fb1671..000000000 --- a/demo/js/fix-2.0/globalwatcher.js +++ /dev/null @@ -1,52 +0,0 @@ -(function () { - var model = Fix.define({ - name: "原始属性", - arr: [{ - n: "a" - }, { - n: 0 - }] - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return model; - }, - watch: { - "*.*.n": function () { - debugger - }, - "**": function () { - debugger - }, - "arr.1.*": function () { - this.button.setText(this.model.name + "-" + this.model.arr[1].n); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.model.arr[0].n += 1; - self.model.arr[1].n += 1; - }, - text: this.model.name + "-" + this.model.arr[1].n - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_global_watcher", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/fix-2.0/inject.js b/demo/js/fix-2.0/inject.js deleted file mode 100644 index a5734635a..000000000 --- a/demo/js/fix-2.0/inject.js +++ /dev/null @@ -1,102 +0,0 @@ -(function () { - var ParentStore = BI.inherit(Fix.Model, { - state: function () { - return { - context: { - one: { - key: "one.key" - } - } - }; - }, - childContext: ["context"], - - actions: { - changeContext: function () { - this.model.context = { - two: { - key: "two.key" - } - }; - } - } - }); - - BI.model("demo.model.inject.parent_store", ParentStore); - - var ChildStore = BI.inherit(Fix.Model, { - inject: ["context"], - computed: { - currContext: function () { - return this.model.context.one.key; - } - }, - actions: { - changeContext: function () { - this.model.context = { - one: { - key: "one.changed_key" - } - }; - } - } - }); - - BI.model("demo.model.inject.child_store", ChildStore); - - var Child = BI.inherit(BI.Widget, { - _store: function () { - return BI.Models.getModel("demo.model.inject.child_store"); - }, - watch: { - currContext: function (val) { - this.button.setText(val); - } - }, - render: function () { - var self = this; - return { - type: "bi.button", - ref: function () { - self.button = this; - }, - text: this.model.currContext, - handler: function () { - self.store.changeContext(); - } - }; - }, - }); - - BI.shortcut("demo.fix_inject_child", Child); - - var Parent = BI.inherit(BI.Widget, { - _store: function () { - return BI.Models.getModel("demo.model.inject.parent_store"); - }, - render: function () { - var self = this; - return { - type: "bi.vertical", - items: [{ - el: { - type: "demo.fix_inject_child" - } - }, { - el: { - type: "bi.button", - text: "点击修改parent state", - handler: function () { - self.store.changeContext(); - } - } - }] - }; - }, - mounted: function () { - - } - }); - - BI.shortcut("demo.fix_inject", Parent); -}()); diff --git a/demo/js/fix-2.0/scene.js b/demo/js/fix-2.0/scene.js deleted file mode 100644 index 821da1d6f..000000000 --- a/demo/js/fix-2.0/scene.js +++ /dev/null @@ -1,445 +0,0 @@ -/** - * @Author: Young - * @CreationDate 2017-11-06 10:32 - * @Description - */ -(function () { - var model = Fix.define({ - groups: [{ - id: "27a9c8bf159e99e", - name: "功能数据", - packages: [{ - id: "82a96a4b03ac17e6", - name: "通信行业", - type: 1, - tables: [{ - id: "品类", - name: "品类", - connName: "BIDemo", - fields: [{ - id: "sd2ad2f343ca23", - name: "类别", - type: 32, - enable: true, - usable: true - }, { - id: "f34ds34aw2345w", - name: "描述", - type: 32, - enable: true, - usable: true - }] - }] - }] - }, { - id: "das2dw24214sa4", - name: "样式数据", - packages: [{ - id: "hi23i1o34a34we", - name: "零售行业", - type: 1, - tables: [{ - id: "销售记录", - name: "销售记录", - connName: "BIDemo", - fields: [{ - id: "wr213d24t345", - name: "分类", - type: 16, - enable: true, - usable: true - }, { - id: "faw134r24al344", - name: "金额", - type: 32, - enable: true, - usable: true - }] - }] - }, { - id: "fwr124f3453fa", - name: "地产行业", - tables: [{ - id: "开发商名称", - name: "开发商名称", - connName: "BIDemo", - fields: [{ - id: "sa13f345fg356", - name: "编号", - type: 32, - enable: true, - usable: true - }, { - id: "ad2r24tt232a22", - name: "名称", - type: 16, - enable: true, - usable: true - }] - }, { - id: "楼盘", - name: "楼盘", - connName: "BIDemo", - fields: [{ - id: "hfe3345fg356", - name: "编号", - type: 32, - enable: true, - usable: true - }, { - id: "kl224tt232a22", - name: "名称", - type: 16, - enable: true, - usable: true - }] - }] - }] - }], - fineIndexUpdate: { - needUpdate: false, - lastUpdate: 1509953199062 - } - }); - - Demo.FixScene = BI.inherit(BI.Widget, { - constant: { - TAB1: 1, - TAB2: 2 - }, - - _store: function () { - return model; - }, - - watch: { - "groups.*.name": function () { - this.fineIndexTab.setText("FineIndex更新(******* 分组名变化 需要更新 *******)"); - this.model.fineIndexUpdate.needUpdate = true; - }, - "groups.*.packages.*.name": function () { - this.fineIndexTab.setText("FineIndex更新(******* 业务包名变化 需要更新 *******)"); - this.model.fineIndexUpdate.needUpdate = true; - }, - "groups.*.packages.*.tables.*.name": function () { - this.fineIndexTab.setText("FineIndex更新(******* 表名变化 需要更新 *******)"); - this.model.fineIndexUpdate.needUpdate = true; - }, - "groups.*.packages.*.tables.*.fields.*.name": function () { - this.fineIndexTab.setText("FineIndex更新(******* 字段名变化 需要更新 *******)"); - this.model.fineIndexUpdate.needUpdate = true; - }, - "fineIndexUpdate.needUpdate": function (needUpdate) { - !needUpdate && this.fineIndexTab.setText("FineIndex更新"); - } - }, - - render: function () { - var self = this; - return { - type: "bi.tab", - showIndex: this.constant.TAB1, - single: true, - tab: { - type: "bi.button_group", - items: BI.createItems([{ - text: "业务包管理", - value: this.constant.TAB1 - }, { - text: "FineIndex更新", - value: this.constant.TAB2, - ref: function (ref) { - self.fineIndexTab = ref; - } - }], { - type: "bi.text_button", - cls: "bi-list-item-active", - height: 50 - }), - height: 50 - }, - cardCreator: BI.bind(this.cardCreator, this) - }; - }, - - cardCreator: function (v) { - switch (v) { - case this.constant.TAB1: - return { - type: "demo.fix_scene_data_manager", - data: this.model - }; - case this.constant.TAB2: - return { - type: "demo.fix_scene_fine_index_update" - }; - } - } - }); - BI.shortcut("demo.fix_scene", Demo.FixScene); - - Demo.FixSceneDataManager = BI.inherit(BI.Widget, { - _store: function () { - return this.options.data; - }, - - watch: { - "*.name": function () { - - } - }, - - render: function () { - var items = []; - BI.each(this.model.groups, function (i, group) { - items.push({ - type: "demo.fix_scene_group", - group: group - }); - }); - - return { - type: "bi.vertical", - items: [{ - type: "bi.left", - items: BI.createItems([{ - text: "分组名" - }, { - text: "业务包名" - }, { - text: "表名" - }, { - text: "字段名" - }], { - type: "bi.label", - cls: "layout-bg1", - width: 150 - }) - - }, { - type: "bi.vertical", - items: items - }], - vgap: 20, - hgap: 20 - }; - } - - }); - BI.shortcut("demo.fix_scene_data_manager", Demo.FixSceneDataManager); - - Demo.FixSceneGroup = BI.inherit(BI.Widget, { - props: { - group: {} - }, - - _store: function () { - return this.options.group; - }, - - render: function () { - var self = this; - var items = []; - BI.each(this.model.packages, function (i, child) { - items.push({ - type: "demo.fix_scene_package", - pack: child - }); - }); - return { - type: "bi.left", - items: [{ - type: "bi.sign_editor", - cls: "bi-border-bottom", - width: 100, - height: 30, - value: this.model.name, - listeners: [{ - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - self.model.name = this.getValue(); - } - }] - }, { - type: "bi.vertical", - items: items - }], - hgap: 20 - }; - } - }); - BI.shortcut("demo.fix_scene_group", Demo.FixSceneGroup); - - - Demo.FixScenePackage = BI.inherit(BI.Widget, { - props: { - pack: {} - }, - - _store: function () { - return this.options.pack; - }, - - render: function () { - var self = this; - var items = []; - BI.each(this.model.tables, function (i, child) { - items.push({ - type: "demo.fix_scene_table", - table: child - }); - }); - return { - type: "bi.left", - items: [{ - type: "bi.sign_editor", - cls: "bi-border-bottom", - width: 100, - height: 30, - value: this.model.name, - listeners: [{ - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - self.model.name = this.getValue(); - } - }] - }, { - type: "bi.vertical", - items: items - }], - hgap: 20 - }; - } - }); - BI.shortcut("demo.fix_scene_package", Demo.FixScenePackage); - - Demo.FixSceneTable = BI.inherit(BI.Widget, { - props: { - table: {} - }, - - _store: function () { - return this.options.table; - }, - - render: function () { - var self = this; - var items = []; - BI.each(this.model.fields, function (i, child) { - items.push({ - type: "demo.fix_scene_field", - field: child - }); - }); - return { - type: "bi.left", - items: [{ - type: "bi.sign_editor", - cls: "bi-border-bottom", - width: 100, - height: 30, - value: this.model.name, - listeners: [{ - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - self.model.name = this.getValue(); - } - }] - }, { - type: "bi.vertical", - items: items - }], - hgap: 20 - }; - } - }); - BI.shortcut("demo.fix_scene_table", Demo.FixSceneTable); - - Demo.FixSceneField = BI.inherit(BI.Widget, { - props: { - field: {} - }, - - _store: function () { - return this.options.field; - }, - - render: function () { - var self = this; - return { - type: "bi.center_adapt", - items: [{ - type: "bi.sign_editor", - cls: "bi-border-bottom", - width: 100, - height: 30, - value: this.model.name, - listeners: [{ - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - self.model.name = this.getValue(); - } - }] - }] - }; - } - }); - BI.shortcut("demo.fix_scene_field", Demo.FixSceneField); - - Demo.FixSceneFineIndexUpdateStore = BI.inherit(Fix.Model, { - _init: function () { - this.fineIndexUpdate = model.fineIndexUpdate; - }, - computed: { - text: function () { - return "立即更新(上次更新时间:" + BI.date2Str(new Date(this.fineIndexUpdate.lastUpdate), "yyyy-MM-dd HH:mm:ss") + ")"; - }, - needUpdate: function () { - return this.fineIndexUpdate.needUpdate; - } - }, - actions: { - updateFineIndex: function () { - this.fineIndexUpdate.needUpdate = false; - this.fineIndexUpdate.lastUpdate = new Date().getTime(); - } - } - }); - - Demo.FixSceneFineIndexUpdate = BI.inherit(BI.Widget, { - _store: function () { - return new Demo.FixSceneFineIndexUpdateStore(); - }, - - watch: { - needUpdate: function () { - this.button.setEnable(this.model.needUpdate); - }, - text: function () { - this.button.setText(this.model.text); - } - }, - - render: function () { - var self = this; - return { - type: "bi.center_adapt", - items: [{ - type: "bi.button", - text: this.model.text, - disabled: !this.model.needUpdate, - height: 30, - width: 360, - handler: function () { - self.store.updateFineIndex(); - }, - ref: function (ref) { - self.button = ref; - } - }] - }; - } - }); - BI.shortcut("demo.fix_scene_fine_index_update", Demo.FixSceneFineIndexUpdate); - -})(); \ No newline at end of file diff --git a/demo/js/fix-2.0/state.js b/demo/js/fix-2.0/state.js deleted file mode 100644 index ce33b7f0b..000000000 --- a/demo/js/fix-2.0/state.js +++ /dev/null @@ -1,49 +0,0 @@ -(function () { - var State = BI.inherit(Fix.Model, { - state: function () { - return { - name: "原始属性" - }; - }, - computed: { - b: function () { - return this.model.name + "-计算属性"; - } - } - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return new State(); - }, - watch: { - b: function () { - this.button.setText(this.model.b); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.model.name = "这是改变后的属性"; - }, - text: this.model.b - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_state", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/fix-2.0/store.js b/demo/js/fix-2.0/store.js deleted file mode 100644 index 188a5b906..000000000 --- a/demo/js/fix-2.0/store.js +++ /dev/null @@ -1,60 +0,0 @@ -(function () { - var model = Fix.define({ - name: "原始属性", - arr: [{ - n: "a" - }, { - n: "b" - }] - }); - - var Store = BI.inherit(Fix.Model, { - _init: function () { - }, - computed: { - b: function () { - return model.name + "-计算属性"; - } - }, - actions: { - run: function () { - model.name = "这是改变后的属性"; - } - } - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return new Store(); - }, - watch: { - b: function () { - this.button.setText(this.model.b); - } - }, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - self.store.run(); - }, - text: this.model.b - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_store", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/fix-2.0/watcher.js b/demo/js/fix-2.0/watcher.js deleted file mode 100644 index 98716ed59..000000000 --- a/demo/js/fix-2.0/watcher.js +++ /dev/null @@ -1,51 +0,0 @@ -(function () { - var model = Fix.define({ - name: "原始属性", - arr: [{ - n: "a" - }, { - n: 0 - }] - }); - - Demo.Fix = BI.inherit(BI.Widget, { - _store: function () { - return model; - }, - watch: { - "name||arr.1.n": function () { - this.button.setText(this.model.name + "-" + this.model.arr[1].n); - } - }, - render: function () { - var self = this; - var cnt = 0; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.button", - ref: function () { - self.button = this; - }, - handler: function () { - if (cnt & 1) { - self.model.name += 1; - } else { - self.model.arr[1].n += 1; - } - cnt++; - }, - text: this.model.name + "-" + this.model.arr[1].n - } - }] - }; - }, - mounted: function () { - - - } - }); - - BI.shortcut("demo.fix_watcher", Demo.Fix); -}()); \ No newline at end of file diff --git a/demo/js/main.js b/demo/js/main.js deleted file mode 100644 index ab57470d5..000000000 --- a/demo/js/main.js +++ /dev/null @@ -1,55 +0,0 @@ -Demo.Main = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-main bi-background" - }, - - _store: function () { - return BI.Stores.getStore("demo.store.main"); - }, - - beforeInit: function (cb) { - this.store.init(cb); - }, - - render: function () { - var self = this; - return { - type: "bi.border", - items: { - north: { - height: 50, - el: { - type: "demo.north", - listeners: [{ - eventName: Demo.North.EVENT_VALUE_CHANGE, - action: function (v) { - self.store.handleTreeSelectChange(v); - } - }] - } - }, - west: { - width: 230, - el: { - type: "demo.west", - listeners: [{ - eventName: Demo.West.EVENT_VALUE_CHANGE, - action: function (v) { - self.store.handleTreeSelectChange(v); - } - }] - } - }, - center: { - el: { - type: "demo.center", - ref: function (_ref) { - self.center = _ref; - } - } - } - } - }; - } -}); -BI.shortcut("demo.main", Demo.Main); \ No newline at end of file diff --git a/demo/js/main.store.js b/demo/js/main.store.js deleted file mode 100644 index 82d3b81df..000000000 --- a/demo/js/main.store.js +++ /dev/null @@ -1,65 +0,0 @@ -!(function () { - var Store = BI.inherit(Fix.Model, { - _init: function () { - - }, - - computed: {}, - - watch: {}, - - actions: { - init: function (cb) { - var tree = BI.Tree.transformToTreeFormat(Demo.CONFIG); - var traversal = function (array, callback) { - var t = []; - BI.some(array, function (i, item) { - var match = callback(i, item); - if (match) { - t.push(item.id); - } - var b = traversal(item.children, callback); - if (BI.isNotEmptyArray(b)) { - t = BI.concat([item.id], b); - } - }); - return t; - }; - var paths = traversal(tree, function (index, node) { - if (!node.children || BI.isEmptyArray(node.children)) { - if (node.value === Demo.showIndex) { - return true; - } - } - }); - BI.each(Demo.CONFIG, function (index, item) { - if (BI.contains(paths, item.id)) { - item.open = true; - } - }); - - cb(); - }, - - handleTreeSelectChange: function (v) { - var matched = BI.some(Demo.CONFIG, function (index, item) { - if (item.value === v) { - BI.Router.$router.push({ - name: "component", - params: { - componentId: item.value - } - }); - // BI.history.navigate(item.text, {trigger: true}); - return true; - } - }); - if (!matched) { - BI.Router.$router.push("/"); - // BI.history.navigate("", {trigger: true}); - } - } - } - }); - BI.store("demo.store.main", Store); -})(); diff --git a/demo/js/north.js b/demo/js/north.js deleted file mode 100644 index 90b9b1473..000000000 --- a/demo/js/north.js +++ /dev/null @@ -1,46 +0,0 @@ -Demo.North = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-north" - }, - render: function () { - var self = this; - return { - type: "bi.htape", - items: [{ - width: 230, - el: { - type: "bi.text_button", - listeners: [{ - eventName: BI.Button.EVENT_CHANGE, - action: function () { - self.fireEvent(Demo.North.EVENT_VALUE_CHANGE, ""); - } - }], - cls: "logo", - height: 50, - text: "FineUI2.0" - } - }, { - el: { - type: "bi.right", - hgap: 10, - items: [{ - type: "bi.text_button", - text: "星空蓝", - handler: function () { - BI.$("html").removeClass("bi-theme-default").addClass("bi-theme-dark"); - } - }, { - type: "bi.text_button", - text: "典雅白", - handler: function () { - BI.$("html").removeClass("bi-theme-dark").addClass("bi-theme-default"); - } - }] - } - }] - }; - } -}); -Demo.North.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.shortcut("demo.north", Demo.North); \ No newline at end of file diff --git a/demo/js/preview.js b/demo/js/preview.js deleted file mode 100644 index 1602077f8..000000000 --- a/demo/js/preview.js +++ /dev/null @@ -1,81 +0,0 @@ -Demo.Preview = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-preview" - }, - render: function () { - var self = this; - var items = [], header = [], columnSize = []; - - var rowCount = 100, columnCount = 100; - for (var i = 0; i < 1; i++) { - header[i] = []; - for (var j = 0; j < columnCount; j++) { - header[i][j] = { - type: "bi.label", - text: "表头" + i + "-" + j - }; - columnSize[j] = 100; - } - } - for (var i = 0; i < rowCount; i++) { - items[i] = []; - for (var j = 0; j < columnCount; j++) { - items[i][j] = { - type: "bi.label", - text: (i < 3 ? 0 : i) + "-" + j - }; - } - } - return { - type: "bi.absolute", - cls: "preview-background", - items: [{ - el: { - type: "bi.vtape", - cls: "preview-card bi-card", - items: [{ - el: { - type: "bi.label", - cls: "preview-title bi-border-bottom", - height: 40, - text: "Card", - hgap: 10, - textAlign: "left" - }, - height: 40 - }, { - type: "bi.center_adapt", - scrollable: true, - items: [{ - type: "bi.resizable_table", - el: { - type: "bi.collection_table" - }, - width: 500, - height: 400, - isResizeAdapt: true, - isNeedResize: true, - isNeedMerge: true, - mergeCols: [0, 1], - mergeRule: function (col1, col2) { - return BI.isEqual(col1, col2); - }, - isNeedFreeze: true, - freezeCols: [0, 1], - columnSize: columnSize, - items: items, - header: header - }] - }] - }, - left: 60, - right: 60, - top: 60, - bottom: 60 - }] - }; - }, - mounted: function () { - } -}); -BI.shortcut("demo.preview", Demo.Preview); \ No newline at end of file diff --git a/demo/js/west.js b/demo/js/west.js deleted file mode 100644 index d2cd70109..000000000 --- a/demo/js/west.js +++ /dev/null @@ -1,77 +0,0 @@ -Demo.West = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-west bi-border-right bi-card" - }, - - mounted: function () { - this.searcher.setAdapter(this.tree); - }, - - render: function () { - var self = this; - - - var selectedId = BI.Router.$router.currentRoute.params?.componentId; - - return { - type: "bi.vtape", - items: [{ - type: "bi.center_adapt", - items: [{ - type: "bi.searcher", - el: { - type: "bi.search_editor", - watermark: "简单搜索" - }, - width: 200, - isAutoSearch: false, - isAutoSync: false, - ref: function (ref) { - self.searcher = ref; - }, - popup: { - type: "bi.multilayer_single_level_tree", - cls: "bi-card", - listeners: [{ - eventName: BI.MultiLayerSingleLevelTree.EVENT_CHANGE, - action: function (v) { - self.fireEvent(Demo.West.EVENT_VALUE_CHANGE, v); - } - }] - }, - onSearch: function (op, callback) { - var result = BI.Func.getSearchResult(Demo.CONFIG, op.keyword, "text"); - var items = BI.concat(result.match, result.find); - var children = []; - BI.each(items, function (index, item) { - var childList = BI.Func.getSearchResult(Demo.CONFIG, item.id, "pId"); - BI.each(childList.match, function (index, child) { - if (child.value) { - children.push(child); - } - }); - }); - items = BI.concat(items, children); - callback(items); - } - }], - height: 40 - }, { - type: "bi.multilayer_single_level_tree", - listeners: [{ - eventName: BI.MultiLayerSingleLevelTree.EVENT_CHANGE, - action: function (v) { - self.fireEvent(Demo.West.EVENT_VALUE_CHANGE, v); - } - }], - value: selectedId || Demo.showIndex, - items: Demo.CONFIG, - ref: function (ref) { - self.tree = ref; - } - }] - }; - } -}); -Demo.West.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.shortcut("demo.west", Demo.West); diff --git a/demo/js/widget/basewidget/demo.buttons.js b/demo/js/widget/basewidget/demo.buttons.js deleted file mode 100644 index c8479d341..000000000 --- a/demo/js/widget/basewidget/demo.buttons.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - - -Demo.Buttons = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-button" - }, - render: function () { - var items = [ - { - el: { - type: "bi.button", - text: "一般按钮", - level: "common", - height: 30 - } - }, { - el: { - type: "bi.button", - text: "带图标的按钮", - // level: 'ignore', - iconCls: "close-font", - height: 30 - } - }, { - el: { - type: "bi.button", - text: "一般按钮", - block: true, - level: "common", - height: 30 - } - }, { - el: { - type: "bi.button", - text: "一般按钮", - clear: true, - level: "common", - height: 30 - } - }, { - el: { - type: "bi.multi_select_bar", - selected: true, - halfSelected: true - } - }, { - el: { - type: "bi.multi_select_bar", - selected: true, - halfSelected: false - } - }, { - el: { - type: "bi.multi_select_bar", - selected: false, - halfSelected: true - } - }, { - el: { - type: "bi.multi_select_bar" - } - } - ]; - BI.each(items, function (i, item) { - item.el.handler = function () { - BI.Msg.alert("按钮", this.options.text); - }; - }); - return { - type: "bi.left", - vgap: 100, - hgap: 20, - items: items - }; - } -}); -BI.shortcut("demo.buttons", Demo.Buttons); \ No newline at end of file diff --git a/demo/js/widget/basewidget/demo.items.js b/demo/js/widget/basewidget/demo.items.js deleted file mode 100644 index 0562519b3..000000000 --- a/demo/js/widget/basewidget/demo.items.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Items = BI.inherit(BI.Widget, { - - render: function () { - - return { - type: "bi.vertical", - items: [{ - type: "bi.text_button", - cls: "bi-list-item-select bi-high-light-border bi-border", - height: 30, - level: "warning", - text: "单选item" - }, { - type: "bi.single_select_item", - text: "单选项" - }, { - type: "bi.single_select_radio_item", - text: "单选项" - }, { - type: "bi.label", - height: 30, - text: "复选item" - }, { - type: "bi.multi_select_item", - text: "复选项" - }, { - type: "bi.switch", - selected: true - }], - hgap: 300 - }; - } -}); - - -BI.shortcut("demo.items", Demo.Items); \ No newline at end of file diff --git a/demo/js/widget/basewidget/demo.nodes.js b/demo/js/widget/basewidget/demo.nodes.js deleted file mode 100644 index 5438db02a..000000000 --- a/demo/js/widget/basewidget/demo.nodes.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Nodes = BI.inherit(BI.Widget, { - - render: function (vessel) { - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "十字形的节点" - }, { - type: "bi.plus_group_node", - text: "十字形的节点" - }, { - type: "bi.label", - height: 30, - text: "箭头节点" - }, { - type: "bi.arrow_group_node", - text: "箭头节点" - }, { - type: "bi.icon_arrow_node", - iconCls: "search-font", - text: "箭头图标节点" - }, { - type: "bi.multilayer_icon_arrow_node", - layer: 2 - }] - }; - } -}); - -BI.shortcut("demo.nodes", Demo.Nodes); \ No newline at end of file diff --git a/demo/js/widget/basewidget/demo.sagments.js b/demo/js/widget/basewidget/demo.sagments.js deleted file mode 100644 index 19946dc04..000000000 --- a/demo/js/widget/basewidget/demo.sagments.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Segments = BI.inherit(BI.Widget, { - - render: function () { - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - height: 30, - text: "默认风格" - }, { - type: "bi.segment", - items: [{ - text: "tab1", - value: 1, - selected: true - }, { - text: "tab2", - value: 2 - }, { - text: "tab3 disabled", - disabled: true, - value: 3 - }] - }], - hgap: 50, - vgap: 20 - }; - } -}); - -BI.shortcut("demo.segments", Demo.Segments); \ No newline at end of file diff --git a/demo/js/widget/basewidget/demo.tips.js b/demo/js/widget/basewidget/demo.tips.js deleted file mode 100644 index 063022e03..000000000 --- a/demo/js/widget/basewidget/demo.tips.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Created by Dailer on 2017/7/25. - */ - -Demo.Tips = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-tips" - }, - render: function () { - var btns = []; - var bubble = BI.createWidget({ - type: "bi.left", - items: [{ - el: { - type: "bi.button", - text: "bubble测试", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble1", "bubble测试", this); - btns.push("singleBubble1"); - } - } - }, { - el: { - type: "bi.button", - text: "bubble测试(居中显示)", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble2", "bubble测试", this, { - offsetStyle: "center" - }); - btns.push("singleBubble2"); - } - } - }, { - el: { - type: "bi.button", - text: "bubble测试(右边显示)", - height: 30, - handler: function () { - BI.Bubbles.show("singleBubble3", "bubble测试", this, { - offsetStyle: "right" - }); - btns.push("singleBubble3"); - } - } - }, { - el: { - type: "bi.button", - text: "隐藏所有 bubble", - height: 30, - cls: "layout-bg2", - handler: function () { - BI.each(btns, function (index, value) { - BI.Bubbles.hide(value); - }); - } - } - }], - hgap: 20 - }); - - var title = BI.createWidget({ - type: "bi.vertical", - items: [{ - type: "bi.label", - cls: "layout-bg1", - height: 50, - title: "title提示", - text: "移上去有title提示", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg6", - height: 50, - disabled: true, - warningTitle: "title错误提示", - text: "移上去有title错误提示", - textAlign: "center" - }, { - type: "bi.label", - cls: "layout-bg2", - height: 50, - disabled: true, - tipType: "success", - title: "自定义title提示效果", - warningTitle: "自定义title提示效果", - text: "自定义title提示效果", - textAlign: "center" - }], - hgap: 20, - vgap: 20 - }); - - var toast = BI.createWidget({ - type: "bi.vertical", - items: [{ - el: { - type: "bi.button", - text: "简单Toast测试", - height: 30, - handler: function () { - BI.Msg.toast("这是一条简单的数据"); - } - } - }, { - el: { - type: "bi.button", - text: "很长的Toast测试", - height: 30, - handler: function () { - BI.Msg.toast("这是一条很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的数据"); - } - } - }, { - el: { - type: "bi.button", - text: "非常长的Toast测试", - height: 30, - handler: function () { - BI.Msg.toast("这是一条非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长的数据"); - } - } - }, { - el: { - type: "bi.button", - text: "错误提示Toast测试", - level: "warning", - height: 30, - handler: function () { - BI.Msg.toast("错误提示Toast测试", "warning"); - } - } - }], - vgap: 20 - }); - - return { - type: "bi.horizontal_auto", - vgap: 20, - hgap: 20, - items: [bubble, title, toast] - }; - } -}); -BI.shortcut("demo.tips", Demo.Tips); \ No newline at end of file diff --git a/demo/js/widget/collapase/API.md b/demo/js/widget/collapase/API.md deleted file mode 100644 index 2ba16aa32..000000000 --- a/demo/js/widget/collapase/API.md +++ /dev/null @@ -1,12 +0,0 @@ -## API - -### bi.collapse - -| 参数 | 说明 | 类型 | 默认值 | -| ---------- | ---------- | ------- | -------------------- | -| accordion | 手风琴模式 | boolean | false | -| bordered | 带边框风格的折叠面板 | boolean | true | -| ghost | 使折叠面板透明且无边框 | boolean | false | -| openMotion | 展开动画 | object | { animation: "bi-slide-up", animationDuring: 100} -| value | 初始化选中面板的 key | string\[]
number\[] | - | -| listeners | 监听切换面板事件 | [{eventName: "EVENT_EXPAND", action:(activeKey) => void}] | - | diff --git a/demo/js/widget/collapase/demo.collapse.js b/demo/js/widget/collapase/demo.collapse.js deleted file mode 100644 index b75e29c57..000000000 --- a/demo/js/widget/collapase/demo.collapse.js +++ /dev/null @@ -1,59 +0,0 @@ -Demo.Collapse = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-collapse" - }, - - render: function () { - var self = this; - - var items = [{ - value: "test", - popup: { - cls: "mvc-border", - items: BI.createItems([{ - text: "项目1", - value: 1 - }, { - text: "项目2", - value: 2 - }, { - text: "项目3", - value: 3 - }, { - text: "项目4", - value: 4 - }], { - type: "bi.single_select_item", - height: 25 - }) - } - }, { - value: 2, - popup: { - type: "bi.label", - value: "给岁月以文明,而不是给文明以岁月" - } - }, { - value: 3, - popup: { - type: "bi.label", - value: "漂流瓶隐没于黑暗里,在一千米见方的宇宙中,只有生态球里的小太阳发出一点光芒。在这个小小的生命世界中,几只清澈的水球在零重力环境中静静地飘浮着,有一条小鱼从一只水球中蹦出,跃入另一只水球,轻盈地穿游于绿藻之间。" - } - }]; - - return { - type: "bi.vertical", - items: [{ - type: "bi.collapse", - accordion: true, - items: items, - value: [2], - }], - width: '60%', - tgap: 100, - hgap: 100 - }; - } -}); - -BI.shortcut("demo.collapse", Demo.Collapse); diff --git a/demo/js/widget/date/demo.datepane.js b/demo/js/widget/date/demo.datepane.js deleted file mode 100644 index 0b2e3cec1..000000000 --- a/demo/js/widget/date/demo.datepane.js +++ /dev/null @@ -1,81 +0,0 @@ -Demo.DatePane = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-datepane" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.vertical", - vgap: 10, - items: [{ - type: "bi.label", - cls: "layout-bg2", - text: "bi.date_pane" - }, { - type: "bi.dynamic_date_pane", - // value: { - // type: 1, - // value: { - // year: 2017, - // month: 12, - // day: 11 - // } - // }, - ref: function (_ref) { - self.datepane = _ref; - }, - height: 300 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast("date" + JSON.stringify(self.datepane.getValue())); - } - }, { - type: "bi.dynamic_date_time_pane", - value: { - type: 1, - value: { - year: 2017, - month: 12, - day: 11, - hour: 12, - minute: 12, - second: 12 - } - }, - ref: function (_ref) { - self.dateTimePane = _ref; - }, - height: 340 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast("date" + JSON.stringify(self.dateTimePane.getValue())); - } - }, { - type: "bi.button", - text: "setValue '2017-12-31'", - handler: function () { - self.datepane.setValue({ - year: 2017, - month: 12, - day: 31 - }); - } - } - ], - width: "50%" - }] - }; - }, - - mounted: function () { - this.datepane.setValue();// 不设value值表示当前时间 - } -}); - -BI.shortcut("demo.date_pane", Demo.DatePane); \ No newline at end of file diff --git a/demo/js/widget/date/demo.multidate_combo.js b/demo/js/widget/date/demo.multidate_combo.js deleted file mode 100644 index 61b20892c..000000000 --- a/demo/js/widget/date/demo.multidate_combo.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.Date = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-date" - }, - - _init: function () { - Demo.Date.superclass._init.apply(this, arguments); - }, - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - vgap: 20, - items: [{ - type: "bi.dynamic_date_combo", - ref: function () { - self.datecombo = this; - }, - width: 300, - // allowEdit: false, - // format: "%Y-%X-%d", // yyyy-MM-dd - // format: "%Y/%X/%d", // yyyy/MM/dd - // format: "%Y-%x-%e", // yyyy-M-d - // format: "%Y/%x/%e", // yyyy/M/d - // format: "%X/%d/%Y", // MM/dd/yyyy - // format: "%X/%e/%y", // MM/d/yy - // format: "%X.%d.%Y", // MM.dd.yyyy - // format: "%X.%e.%Y", // MM.d.yyyy - // format: "%X-%e-%y", // MM.d.yyyy - value: { - type: 1, - value: { - year: 2018, - month: 2, - day: 23 - } - } - }, { - type: "bi.button", - text: "getValue", - width: 300, - handler: function () { - BI.Msg.alert("date", JSON.stringify(self.datecombo.getValue())); - } - }, { - type: "bi.dynamic_date_time_combo", - ref: function () { - self.datetimecombo = this; - }, - width: 300, - // allowEdit: false, - // format: "%Y-%X-%d %H:%M:%S", // yyyy-MM-dd HH:mm:ss - // format: "%Y/%X/%d %H:%M:%S", // yyyy/MM/dd HH:mm:ss - // format: "%Y-%X-%d %I:%M:%S", // yyyy-MM-dd hh:mm:ss - // format: "%Y/%X/%d %I:%M:%S", // yyyy/MM/dd hh:mm:ss - // format: "%Y-%X-%d %H:%M:%S %p", // yyyy-MM-dd HH:mm:ss a - // format: "Y/%X/%d %H:%M:%S %p", // yyyy/MM/dd HH:mm:ss a - // format: "%Y-%X-%d %I:%M:%S %p", // yyyy-MM-dd hh:mm:ss a - // format: "%Y/%X/%d %I:%M:%S %p", // yyyy/MM/dd hh:mm:ss a - // format: "%X/%d/%Y %I:%M:%S", // MM/dd/yyyy hh:mm:ss - // format: "%X/%d/%Y %H:%M:%S", // MM/dd/yyyy HH:mm:ss - // format: "%X/%d/%Y %I:%M:%S", // MM/dd/yyyy hh:mm:ss a - // format: "%X/%d/%Y %H:%M:%S %p", // MM/dd/yyyy HH:mm:ss a - // format: "%X/%d/%Y %I:%M:%S %p", // MM/dd/yyyy hh:mm:ss a - // format: "%X/%d/%Y %H:%M:%S %p", // MM/dd/yyyy HH:mm:ss a - // format: "%X/%d/%Y %l:%M %p", // MM/dd/yyyy h:mm a - // format: "%X-%d-%Y %k:%M %p", // MM/dd/yyyy H:mm a - // format: "%Y-%x-%e %l:%M", // yyyy-M-d h:mm - // format: "%Y-%x-%e %k:%M", // yyyy-M-d H:mm - value: { - type: 1, - value: { - year: 2018, - month: 2, - day: 23 - } - } - }, { - type: "bi.button", - text: "getValue", - width: 300, - handler: function () { - BI.Msg.alert("date", JSON.stringify(self.datetimecombo.getValue())); - } - }, { - type: "bi.button", - text: "setValue '2017-12-31'", - width: 300, - handler: function () { - self.datecombo.setValue({ - year: 2017, - month: 11, - day: 31 - }); - } - }] - }; - } -}); - -BI.shortcut("demo.multidate_combo", Demo.Date); \ No newline at end of file diff --git a/demo/js/widget/datetime/demo.datetime.js b/demo/js/widget/datetime/demo.datetime.js deleted file mode 100644 index 548d81679..000000000 --- a/demo/js/widget/datetime/demo.datetime.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Created by Urthur on 2017/7/18. - */ -Demo.CustomDateTime = BI.inherit(BI.Widget, { - props: {}, - render: function () { - var self = this; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.date_time_combo", - listeners: [{ - eventName: BI.DateTimeCombo.EVENT_CONFIRM, - action: function () { - var value = this.getValue(); - var date = new Date(value.year, value.month - 1, value.day, value.hour, value.minute, value.second); - var dateStr = BI.print(date, "%Y-%X-%d %H:%M:%S"); - BI.Msg.alert("日期", dateStr); - } - }, { - eventName: BI.DateTimeCombo.EVENT_CANCEL, - action: function () { - } - }], - value: { - year: 2017, - month: 2, - day: 23, - hour: 12, - minute: 11, - second: 1 - } - }, - top: 200, - left: 200 - }] - }; - } -}); -BI.shortcut("demo.date_time", Demo.CustomDateTime); \ No newline at end of file diff --git a/demo/js/widget/downlist/demo.downlist.js b/demo/js/widget/downlist/demo.downlist.js deleted file mode 100644 index df01a9a28..000000000 --- a/demo/js/widget/downlist/demo.downlist.js +++ /dev/null @@ -1,245 +0,0 @@ -(function () { - var CustomIcon = BI.inherit(BI.Widget, { - render: function () { - return { - type: "bi.label", - text: "✨", - }; - }, - }); - BI.shortcut("demo.downlist.icon", CustomIcon); -}()); - -Demo.Downlist = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-downlist" - }, - - mounted: function () { - var downlist = this.downlist; - var label = this.label; - this.downlist.setValue([{ - value: [11, 6], - childValue: 67 - }]); - downlist.on(BI.DownListCombo.EVENT_CHANGE, function (value, fatherValue) { - label.setValue(JSON.stringify(downlist.getValue())); - }); - - this.downlist.on(BI.DownListCombo.EVENT_SON_VALUE_CHANGE, function (value, fatherValue) { - label.setValue(JSON.stringify(downlist.getValue())); - }); - }, - - - render: function () { - var self = this; - - return { - type: "bi.left", - items: [{ - type: "bi.down_list_combo", - ref: function (_ref) { - self.downlist = _ref; - }, - // value: [{"childValue":22,"value":11},{"value":18},{"value":20}], - height: 30, - width: 100, - items: [ - [{ - text: "column 1111", - iconCls1: "dot-e-font", - value: 12, - children: [{ - text: "column 1.1", - value: 21, - cls: "dot-e-font" - }, { - text: "column 1.2", - value: 22, - cls: "dot-e-font" - }] - }], - [{ - el: { - text: "column 1111", - iconCls1: "dot-e-font", - value: 11 - }, - children: [{ - text: "column 1.1", - value: 21, - cls: "dot-e-font" - }, { - text: "column 1.2", - value: 22, - cls: "dot-e-font" - }] - // children: [{ - // text: BI.i18nText("BI-Basic_None"), - // cls: "dot-e-font", - // value: 1 - // }, { - // text: BI.i18nText("BI-Basic_Calculate_Same_Period"), - // cls: "dot-e-font", - // value: 2 - // }, { - // text: BI.i18nText("BI-Basic_Calculate_Same_Ring"), - // cls: "dot-e-font", - // value: 3 - // }, { - // text: BI.i18nText("BI-Basic_Calculate_Same_Period_Rate"), - // cls: "dot-e-font", - // value: 4 - // }, { - // text: BI.i18nText("BI-Basic_Calculate_Same_Ring_Rate"), - // cls: "dot-e-font", - // value: 5 - // }, { - // el: { - // text: BI.i18nText("BI-Basic_Rank"), - // iconCls1: "dot-e-font", - // value: 6 - // }, - // children: [{ - // text: "test1", - // cls: "dot-e-font", - // value: 67 - // }, { - // text: "test2", - // cls: "dot-e-font", - // value: 68 - // }] - // }, { - // text: BI.i18nText("BI-Basic_Rank_In_Group"), - // cls: "dot-e-font", - // value: 7 - // }, { - // text: BI.i18nText("BI-Basic_Sum_Of_All"), - // cls: "dot-e-font", - // value: 8 - // }, { - // text: BI.i18nText("BI-Basic_Sum_Of_All_In_Group"), - // cls: "dot-e-font", - // value: 9 - // }, { - // text: BI.i18nText("BI-Basic_Sum_Of_Above"), - // cls: "dot-e-font", - // value: 10 - // }, { - // text: BI.i18nText("BI-Basic_Sum_Of_Above_In_Group"), - // cls: "dot-e-font", - // value: 11 - // }, { - // text: BI.i18nText("BI-Design_Current_Dimension_Percent"), - // cls: "dot-e-font", - // value: 12 - // }, { - // text: BI.i18nText("BI-Design_Current_Target_Percent"), - // cls: "dot-e-font", - // value: 13 - // }] - }] - - ], - }, { - type: "bi.down_list_combo", - el: { - type: "bi.button", - ghost: true, - iconPosition: "right", - icon: "column-next-page-h-font", - text: "自定义 trigger 和 icon 的级联下拉框", - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function (v) { - console.log("触发值", v); - } - }, { - eventName: "EVENT_SON_VALUE_CHANGE", - action: function(v) { - console.log("二级菜单触发值", v) - } - }], - items: [ - [{ - text: "选项一", - value: 1, - icon: { - type: "demo.downlist.icon", - }, - children: [{ - text: "选项一", - value: 11, - icon: { - type: "demo.downlist.icon", - }, - }, { - text: "选项二", - value: 12, - }], - }, { - text: "选项二", - value: 2, - }] - ], - }, { - type: "bi.multi_layer_down_list_combo", - ref: function (_ref) { - self.downlist = _ref; - }, - // value: [{"childValue":22,"value":11},{"value":18},{"value":20}], - height: 30, - width: 100, - items: [ - [{ - el: { - text: "column 1111", - iconCls1: "dot-e-font", - value: 12 - }, - children: [{ - text: "column 1.1", - value: 21, - cls: "dot-e-font" - }, { - text: "column 1.2", - value: 22, - cls: "dot-e-font" - }] - }], - [{ - el: { - text: "column 1111", - iconCls1: "dot-e-font", - value: 11 - }, - children: [{ - text: "column 1.1", - value: 21, - cls: "dot-e-font" - }, { - text: "column 1.2", - value: 22, - cls: "dot-e-font" - }] - }] - - ] - - }, { - type: "bi.label", - text: "显示选择值", - width: 500, - cls: "layout-bg3", - ref: function (_ref) { - self.label = _ref; - } - }], - vgap: 20 - }; - }, -}); - -BI.shortcut("demo.down_list", Demo.Downlist); \ No newline at end of file diff --git a/demo/js/widget/editor/demo.search_editor.js b/demo/js/widget/editor/demo.search_editor.js deleted file mode 100644 index 6d878a4c7..000000000 --- a/demo/js/widget/editor/demo.search_editor.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.SearchEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - render: function () { - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.search_editor", - width: 300, - watermark: "添加合法性判断", - errorText: "长度必须大于4", - validationChecker: function () { - return this.getValue().length > 4; - } - }, { - type: "bi.small_search_editor", - width: 300, - watermark: "这个是 small,小一号" - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.search_editor", Demo.SearchEditor); \ No newline at end of file diff --git a/demo/js/widget/editor/demo.text_editor.js b/demo/js/widget/editor/demo.text_editor.js deleted file mode 100644 index e47a48688..000000000 --- a/demo/js/widget/editor/demo.text_editor.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.TextEditor = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - render: function () { - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.text_editor", - watermark: "这是水印,watermark", - width: 300 - }, { - type: "bi.text_editor", - watermark: "这个不予许空", - allowBlank: false, - errorText: "非空!", - width: 300 - }], - vgap: 20 - - }; - } -}); - -BI.shortcut("demo.text_editor", Demo.TextEditor); \ No newline at end of file diff --git a/demo/js/widget/multiselect/demo.multi_select_combo.js b/demo/js/widget/multiselect/demo.multi_select_combo.js deleted file mode 100644 index bcf487f36..000000000 --- a/demo/js/widget/multiselect/demo.multi_select_combo.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.MultiSelectCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-multi-select-combo" - }, - - _createMultiSelectCombo: function () { - var self = this; - var widget = BI.createWidget({ - type: "bi.multi_select_insert_combo", - // allowEdit: false, - itemsCreator: BI.bind(this._itemsCreator, this), - width: 200, - value: { - type: 1, - value: ["柳州市城贸金属材料有限责任公司", "柳州市建福房屋租赁有限公司", "柳州市迅昌数码办公设备有限责任公司"] - } - }); - - widget.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - BI.Msg.toast(JSON.stringify(this.getValue())); - }); - - return widget; - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * 100; items[i] && i < times * 100; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * 100 < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this; - var items = Demo.CONSTANTS.ITEMS; - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.match.concat(search.find); - }); - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - BI.delay(function () { - callback({ - items: self._getItemsByTimes(items, options.times), - hasNext: self._hasNextByTimes(items, options.times) - }); - }, 1000); - }, - - render: function () { - return { - type: "bi.absolute", - scrolly: false, - items: [{ - el: this._createMultiSelectCombo(), - right: "50%", - top: 10 - }] - }; - } -}); -BI.shortcut("demo.multi_select_combo", Demo.MultiSelectCombo); \ No newline at end of file diff --git a/demo/js/widget/multiselect/demo.multi_select_list.js b/demo/js/widget/multiselect/demo.multi_select_list.js deleted file mode 100644 index acfbebfe5..000000000 --- a/demo/js/widget/multiselect/demo.multi_select_list.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.MultiSelectList = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-multi-select-combo" - }, - - mounted: function () { - this.list.populate(); - }, - - _createMultiSelectCombo: function () { - var self = this; - var widget = BI.createWidget({ - type: "bi.multi_select_insert_list", - ref: function (ref) { - self.list = ref; - }, - itemsCreator: BI.bind(this._itemsCreator, this), - value: { - type: 1, - value: ["柳州市城贸金属材料有限责任公司", "柳州市建福房屋租赁有限公司", "柳州市迅昌数码办公设备有限责任公司"] - } - }); - - widget.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - BI.Msg.toast(JSON.stringify(this.getValue())); - }); - - return widget; - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * 10; items[i] && i < times * 10; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * 10 < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this; - var items = Demo.CONSTANTS.ITEMS; - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.match.concat(search.find); - }); - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - BI.delay(function () { - callback({ - items: self._getItemsByTimes(items, options.times), - hasNext: self._hasNextByTimes(items, options.times) - }); - }, 1000); - }, - - render: function () { - return { - type: "bi.absolute", - scrolly: false, - items: [{ - el: this._createMultiSelectCombo(), - top: 50, - left: 50, - right: 50, - bottom: 50 - }] - }; - } -}); -BI.shortcut("demo.multi_select_list", Demo.MultiSelectList); \ No newline at end of file diff --git a/demo/js/widget/multitree/demo.multi_tree_combo.js b/demo/js/widget/multitree/demo.multi_tree_combo.js deleted file mode 100644 index c3e0ffaa4..000000000 --- a/demo/js/widget/multitree/demo.multi_tree_combo.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.MultiTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.TREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.multi_tree_combo", - ref: function (_ref) { - self.tree = _ref; - }, - itemsCreator: function (options, callback) { - console.log(options); - // 根据不同的类型处理相应的结果 - switch (options.type) { - case BI.TreeView.REQ_TYPE_INIT_DATA: - break; - case BI.TreeView.REQ_TYPE_ADJUST_DATA: - break; - case BI.TreeView.REQ_TYPE_SELECT_DATA: - break; - case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: - break; - default : - break; - } - callback({ - items: items - }); - }, - width: 300, - value: { - "根目录": {} - }, - listeners: [ - { - eventName: "EVENT_CONFIRM", - action: function () { - console.log("EVENT_CONFIRM", this.getValue()); - } - } - ] - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.tree.getValue())); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.multi_tree_combo", Demo.MultiTreeCombo); diff --git a/demo/js/widget/multitree/demo.multi_tree_list.js b/demo/js/widget/multitree/demo.multi_tree_list.js deleted file mode 100644 index 6a9044d14..000000000 --- a/demo/js/widget/multitree/demo.multi_tree_list.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.MultiTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - mounted: function () { - this.tree.populate(); - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.TREE); - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.multi_select_tree", - ref: function (_ref) { - self.tree = _ref; - }, - itemsCreator: function (options, callback) { - console.log(options); - // 根据不同的类型处理相应的结果 - switch (options.type) { - case BI.TreeView.REQ_TYPE_INIT_DATA: - break; - case BI.TreeView.REQ_TYPE_ADJUST_DATA: - break; - case BI.TreeView.REQ_TYPE_SELECT_DATA: - break; - case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: - break; - default : - break; - } - callback({ - items: BI.deepClone(items) - }); - }, - width: 300, - value: { - "根目录": {} - } - }, - top: 50, - bottom: 50, - left: 50, - right: 50 - }, { - el: { - type: "bi.button", - height: 30, - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.tree.getValue())); - } - }, - left: 50, - right: 50, - bottom: 20 - }] - }; - } -}); - -BI.shortcut("demo.multi_select_tree", Demo.MultiTreeCombo); \ No newline at end of file diff --git a/demo/js/widget/numbereditor/demo.number_editor.js b/demo/js/widget/numbereditor/demo.number_editor.js deleted file mode 100644 index bbd7181dd..000000000 --- a/demo/js/widget/numbereditor/demo.number_editor.js +++ /dev/null @@ -1,66 +0,0 @@ -/* 文件管理导航 - Created by dailer on 2017 / 7 / 21. - */ -Demo.FileManager = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var editor1 = BI.createWidget({ - type: "bi.number_editor", - validationChecker: function (v) { - return BI.parseFloat(v) <= 100 && BI.parseFloat(v) >= 0; - }, - height: 24, - width: 150, - errorText: "hahah", - watermark: "每个人都是自己健康的第一责任人", - }); - editor1.on(BI.NumberEditor.EVENT_CHANGE, function () { - if (BI.parseFloat(this.getValue()) < 1) { - editor1.setDownEnable(false); - } else { - editor1.setDownEnable(true); - } - BI.Msg.toast(editor1.getValue()); - }); - - - var editor2 = BI.createWidget({ - type: "bi.number_editor", - validationChecker: function (v) { - return BI.parseFloat(v) <= 100 && BI.parseFloat(v) >= 0; - }, - valueFormatter: (v) => `${v}$`, - valueParser: (v) => v.replace(/\$\s?|(,*)/g, ''), - height: 24, - width: 150, - errorText: "hahah" - }); - editor2.on(BI.NumberEditor.EVENT_CHANGE, function () { - if (BI.parseFloat(this.getValue()) < 1) { - editor2.setDownEnable(false); - } else { - editor2.setDownEnable(true); - } - BI.Msg.toast(editor2.getValue()); - }); - - return { - type: "bi.vertical", - hgap: 20, - vgap: 20, - items: [ - { - el: editor1, - height: 24 - }, { - el: editor2, - height: 24 - } - ] - }; - } -}); -BI.shortcut("demo.number_editor", Demo.FileManager); diff --git a/demo/js/widget/numberinterval/demo.number_interval.js b/demo/js/widget/numberinterval/demo.number_interval.js deleted file mode 100644 index 48e5834ae..000000000 --- a/demo/js/widget/numberinterval/demo.number_interval.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Created by Dailer on 2017/7/12. - */ -Demo.NumericalInterval = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - - mounted: function () { - var numerical = this.numerical; - var label = this.label; - numerical.on(BI.NumberInterval.EVENT_CONFIRM, function () { - var temp = numerical.getValue(); - var res = "大于" + (temp.closemin ? "等于 " : " ") + temp.min + " 小于" + (temp.closemax ? "等于 " : " ") + temp.max; - label.setValue(res); - }); - }, - - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.number_interval", - ref: function (_ref) { - self.numerical = _ref; - }, - width: 500, - value: { - max: 300, - closeMax: true, - closeMin: false - } - }, { - type: "bi.label", - ref: function (_ref) { - self.label = _ref; - }, - text: "显示结果" - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.number_interval", Demo.NumericalInterval); \ No newline at end of file diff --git a/demo/js/widget/selecttree/demo.multilayer_select_tree_combo.js b/demo/js/widget/selecttree/demo.multilayer_select_tree_combo.js deleted file mode 100644 index 25ac4e518..000000000 --- a/demo/js/widget/selecttree/demo.multilayer_select_tree_combo.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.MultiLayerSelectTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.TREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.multilayer_select_tree_combo", - ref: function (_ref) { - self.tree = _ref; - }, - defaultText: "请选择", - items: items, - width: 300, - value: ["第五级文件1"] - }, { - type: "bi.button", - text: "getVlaue", - handler: function () { - BI.Msg.toast(self.tree.getValue()[0]); - }, - width: 300 - }, { - type: "bi.button", - text: "setVlaue (第二级文件1)", - handler: function () { - self.tree.setValue(["第二级文件1"]); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.multilayer_select_tree_combo", Demo.MultiLayerSelectTreeCombo); diff --git a/demo/js/widget/selecttree/demo.select_tree_combo.js b/demo/js/widget/selecttree/demo.select_tree_combo.js deleted file mode 100644 index 1862340ab..000000000 --- a/demo/js/widget/selecttree/demo.select_tree_combo.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.SelectTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.LEVELTREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.select_tree_combo", - ref: function (_ref) { - self.tree = _ref; - }, - value: "11", - text: "默认值", - items: items, - width: 300 - }, { - type: "bi.button", - text: "getVlaue", - handler: function () { - BI.Msg.toast(self.tree.getValue()[0]); - }, - width: 300 - }, { - type: "bi.button", - text: "setVlaue (第二级文件1)", - handler: function () { - self.tree.setValue(["2"]); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.select_tree_combo", Demo.SelectTreeCombo); \ No newline at end of file diff --git a/demo/js/widget/singleselct/demo.single_select_combo.js b/demo/js/widget/singleselct/demo.single_select_combo.js deleted file mode 100644 index 1fc68fb6b..000000000 --- a/demo/js/widget/singleselct/demo.single_select_combo.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Created by User on 2017/3/22. - */ -Demo.SingleSelectCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-single-select-combo" - }, - - _createSingleSelectCombo: function () { - var self = this; - var widget = BI.createWidget({ - type: "bi.single_select_combo", - itemsCreator: BI.bind(this._itemsCreator, this), - width: 200, - ref: function () { - self.SingleSelectCombo = this; - }, - value: "柳州市针织总厂" - }); - - widget.populate(); - - widget.on(BI.SingleSelectCombo.EVENT_CONFIRM, function () { - BI.Msg.toast(JSON.stringify(this.getValue())); - }); - - return widget; - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * 100; items[i] && i < times * 100; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * 100 < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this; - var items = Demo.CONSTANTS.ITEMS; - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.match.concat(search.find); - }); - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type == BI.SingleSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type == BI.SingleSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - BI.delay(function () { - callback({ - items: self._getItemsByTimes(items, options.times), - hasNext: self._hasNextByTimes(items, options.times) - }); - }, 1000); - }, - - render: function () { - var self = this; - return { - type: "bi.absolute", - scrolly: false, - items: [{ - el: this._createSingleSelectCombo(), - right: "50%", - top: 10 - }, { - el: { - - type: "bi.button", - text: "setValue(\"柳州市针织总厂\")", - handler: function () { - self.SingleSelectCombo.setValue("柳州市针织总厂"); - } - } - }] - }; - } -}); -BI.shortcut("demo.single_select_combo", Demo.SingleSelectCombo); \ No newline at end of file diff --git a/demo/js/widget/singletree/demo.multilayer_single_tree_combo.js b/demo/js/widget/singletree/demo.multilayer_single_tree_combo.js deleted file mode 100644 index 1a699c2ea..000000000 --- a/demo/js/widget/singletree/demo.multilayer_single_tree_combo.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.MultiLayerSingleTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.TREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.multilayer_single_tree_combo", - ref: function (_ref) { - self.tree = _ref; - }, - defaultText: "请选择", - items: items, - width: 300 - }, { - type: "bi.button", - text: "getVlaue", - handler: function () { - BI.Msg.toast(self.tree.getValue()[0]); - }, - width: 300 - }, { - type: "bi.button", - text: "setVlaue (第二级文件1)", - handler: function () { - self.tree.setValue(["第二级文件1"]); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.multilayer_single_tree_combo", Demo.MultiLayerSingleTreeCombo); diff --git a/demo/js/widget/singletree/demo.single_tree_combo.js b/demo/js/widget/singletree/demo.single_tree_combo.js deleted file mode 100644 index d3c94508e..000000000 --- a/demo/js/widget/singletree/demo.single_tree_combo.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.SingleTreeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.LEVELTREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.single_tree_combo", - ref: function (_ref) { - self.tree = _ref; - }, - defaultText: "请选择", - items: items, - width: 300, - value: "11" - }, { - type: "bi.button", - text: "getVlaue", - handler: function () { - BI.Msg.toast(self.tree.getValue()[0]); - }, - width: 300 - }, { - type: "bi.button", - text: "setVlaue (第二级文件1)", - handler: function () { - self.tree.setValue(["2"]); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.single_tree_combo", Demo.SingleTreeCombo); diff --git a/demo/js/widget/slider/demo.slider.js b/demo/js/widget/slider/demo.slider.js deleted file mode 100644 index 2116ff99e..000000000 --- a/demo/js/widget/slider/demo.slider.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Created by Urthur on 2017/9/4. - */ -Demo.Slider = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-slider", - width: 300, - height: 50, - min: 0, - max: 100 - }, - - render: function () { - var self = this, o = this.options; - var singleSlider = BI.createWidget({ - type: "bi.single_slider", - digit: 0, - width: o.width, - height: o.height, - cls: "layout-bg-white", - value: 30, - min: 10, - max: 100 - }); - singleSlider.on(BI.SingleSlider.EVENT_CHANGE, function () { - console.log(this.getValue()); - }); - - var normalSingleSlider = BI.createWidget({ - type: "bi.single_slider_normal", - width: o.width, - height: 30, - cls: "layout-bg-white", - min: o.min, - max: o.max, - value: 30, - }); - normalSingleSlider.on(BI.SingleSliderNormal.EVENT_DRAG, function () { - console.log(this.getValue()); - }); - - var singleSliderLabel = BI.createWidget({ - type: "bi.single_slider_label", - width: o.width, - height: o.height, - digit: 0, - unit: "个", - cls: "layout-bg-white", - min: o.min, - max: o.max, - value: 10, - }); - - var intervalSlider = BI.createWidget({ - type: "bi.interval_slider", - width: o.width, - digit: 0, - cls: "layout-bg-white", - min: o.min, - max: o.max, - value: { - min: 10, - max: 70 - } - }); - - var intervalSliderLabel = BI.createWidget({ - type: "bi.interval_slider", - width: o.width, - unit: "px", - cls: "layout-bg-white", - digit: 1, - min: 0, - max: 120, - value: { - min: 60, - max: 120 - } - }); - - - return { - type: "bi.vertical", - element: this, - items: [{ - type: "bi.center_adapt", - items: [{ - el: singleSlider - }] - }, { - type: "bi.center_adapt", - items: [{ - el: normalSingleSlider - }] - }, { - type: "bi.center_adapt", - items: [{ - el: singleSliderLabel - }] - }, { - type: "bi.center_adapt", - items: [{ - el: intervalSlider - }] - }, { - type: "bi.center_adapt", - items: [{ - el: intervalSliderLabel - }] - }], - vgap: 20 - }; - } -}); -BI.shortcut("demo.slider", Demo.Slider); diff --git a/demo/js/widget/timecombo/demo.timecombo.js b/demo/js/widget/timecombo/demo.timecombo.js deleted file mode 100644 index 4808c6c33..000000000 --- a/demo/js/widget/timecombo/demo.timecombo.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.TimeCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.time_combo", - ref: function (_ref) { - self.timeCombo = _ref; - }, - // allowEdit: true, - // format: "%H:%M:%S", // HH:mm:ss - // format: "%I:%M:%S", // hh:mm:ss - // format: "%l:%M:%S", // h:mm:ss - // format: "%k:%M:%S", // H:mm:ss - // format: "%l:%M:%S %p", // h:mm:ss a - // format: "%l:%M", // h:mm - // format: "%k:%M", // H:mm - // format: "%I:%M", // hh:mm - // format: "%H:%M", // HH:mm - // format: "%M:%S", // mm:ss - value: { - hour: 12, - minute: 0, - second: 0 - }, - width: 300 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.timeCombo.getValue())); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.time_combo", Demo.TimeCombo); \ No newline at end of file diff --git a/demo/js/widget/timeinterval/demo.time_interval.js b/demo/js/widget/timeinterval/demo.time_interval.js deleted file mode 100644 index 68c46e1a7..000000000 --- a/demo/js/widget/timeinterval/demo.time_interval.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.TimeInterval = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - var items = BI.deepClone(Demo.CONSTANTS.TREE); - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.date_interval", - ref: function (_ref) { - self.dateInterval = _ref; - }, - value: { - start: { - type: 2, - value: { - year: -1, - position: 2 - } - }, - end: { - type: 1, - value: { - year: 2018, - month: 1, - day: 12 - } - } - }, - width: 300 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.dateInterval.getValue())); - }, - width: 300 - }, { - type: "bi.time_interval", - ref: function (_ref) { - self.interval = _ref; - }, - value: { - start: { - type: 2, - value: { - year: -1, - position: 2 - } - }, - end: { - type: 1, - value: { - year: 2018, - month: 1, - day: 12 - } - } - }, - width: 400 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.interval.getValue())); - }, - width: 300 - }, { - type: "bi.time_periods", - value: { - start: { - hour: 7, - minute: 23, - second: 14 - }, - end: { - hour: 23, - minute: 34, - second: 32 - } - }, - ref: function (_ref) { - self.periods = _ref; - }, - width: 180 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.periods.getValue())); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.time_interval", Demo.TimeInterval); \ No newline at end of file diff --git a/demo/js/widget/tree/demo.multilayer_select_level_tree.js b/demo/js/widget/tree/demo.multilayer_select_level_tree.js deleted file mode 100644 index 357b32a23..000000000 --- a/demo/js/widget/tree/demo.multilayer_select_level_tree.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Created by Dailer on 2017/7/26. - */ - - -Demo.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, { - - render: function () { - var self = this; - var tree = BI.createWidget({ - type: "bi.multilayer_select_level_tree", - items: BI.deepClone(Demo.CONSTANTS.TREE), - value: "第五级文件1" - }); - - return { - type: "bi.vtape", - items: [{ - el: tree - }, { - el: { - type: "bi.button", - height: 25, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(tree.getValue())); - } - }, - height: 25 - }, { - el: { - type: "bi.button", - height: 25, - text: "setValue (第二级文件1)", - handler: function () { - tree.setValue(["11"]); - } - }, - height: 25 - }], - width: 500, - hgap: 300 - }; - } -}); - -BI.shortcut("demo.multilayer_select_level_tree", Demo.MultiLayerSelectLevelTree); diff --git a/demo/js/widget/tree/demo.multilayer_single_level_tree.js b/demo/js/widget/tree/demo.multilayer_single_level_tree.js deleted file mode 100644 index 9aa4ab15c..000000000 --- a/demo/js/widget/tree/demo.multilayer_single_level_tree.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Created by Dailer on 2017/7/26. - */ - - -Demo.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, { - - render: function () { - var self = this; - this.tree = BI.createWidget({ - type: "bi.multilayer_single_level_tree", - items: [], - value: "第二级文件1" - }); - - return { - type: "bi.vtape", - items: [{ - el: this.tree - }, { - el: { - type: "bi.button", - height: 25, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(self.tree.getValue())); - } - }, - height: 25 - }, { - el: { - type: "bi.button", - height: 25, - text: "setValue (第二级文件1)", - handler: function () { - self.tree.setValue(["第二级文件1"]); - } - }, - height: 25 - }], - width: 500, - hgap: 300 - }; - }, - - mounted: function () { - var tree = [ - // {id: -2, pId: 0, value: "根目录1", text: "根目录1"}, - { id: -1, pId: 0, value: "根目录", text: "根目录" }, - { id: 1, pId: -1, value: "第一级目录1", text: "第一级目录1" }, - { id: 11, pId: 1, value: "第二级文件1", text: "第二级文件1" }, - { id: 12, pId: 1, value: "第二级目录2", text: "第二级目录2", disabled: true }, - { id: 121, pId: 12, value: "第三级目录1", text: "第三级目录1" }, - { id: 122, pId: 12, value: "第三级文件1", text: "第三级文件1" }, - { id: 1211, pId: 121, value: "第四级目录1", text: "第四级目录1" }, - { id: 2, pId: -1, value: "第一级目录2", text: "第一级目录2" }, - { id: 21, pId: 2, value: "第二级目录3", text: "第二级目录3" }, - { id: 22, pId: 2, value: "第二级文件2", text: "第二级文件2" }, - { id: 211, pId: 21, value: "第三级目录2", text: "第三级目录2" }, - { id: 212, pId: 21, value: "第三级文件2", text: "第三级文件2" }, - { id: 2111, pId: 211, value: "第四级文件1", text: "第四级文件1" }, - { id: 3, pId: -1, value: "第一级目录3", text: "第一级目录3" }, - { id: 31, pId: 3, value: "第二级文件2", text: "第二级文件2" }, - { id: 33, pId: 3, value: "第二级目录3", text: "第二级目录1" }, - { id: 32, pId: 3, value: "第二级文件3", text: "第二级文件3" }, - { id: 331, pId: 33, value: "第三级文件1", text: "第三级文件1" } - ]; - this.tree.populate(tree); - } -}); - -BI.shortcut("demo.multilayer_single_level_tree", Demo.MultiLayerSingleLevelTree); diff --git a/demo/js/widget/tree/demo.select_level_tree.js b/demo/js/widget/tree/demo.select_level_tree.js deleted file mode 100644 index 04ee65fb6..000000000 --- a/demo/js/widget/tree/demo.select_level_tree.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Created by Dailer on 2017/7/26. - */ - - -Demo.SelectLevelTree = BI.inherit(BI.Widget, { - - render: function () { - var self = this; - var tree = BI.createWidget({ - type: "bi.select_level_tree", - items: BI.deepClone(Demo.CONSTANTS.LEVELTREE), - value: "11" - }); - - return { - type: "bi.vtape", - items: [{ - el: tree - }, { - el: { - type: "bi.button", - height: 25, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(tree.getValue())); - } - }, - height: 25 - }, { - el: { - type: "bi.button", - height: 25, - text: "setValue (第二级文件1)", - handler: function () { - tree.setValue(["2"]); - } - }, - height: 25 - }], - width: 500, - hgap: 300 - }; - } -}); - -BI.shortcut("demo.select_level_tree", Demo.SelectLevelTree); \ No newline at end of file diff --git a/demo/js/widget/tree/demo.single_level_tree.js b/demo/js/widget/tree/demo.single_level_tree.js deleted file mode 100644 index c64a9445f..000000000 --- a/demo/js/widget/tree/demo.single_level_tree.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Created by Dailer on 2017/7/26. - */ - - -Demo.SingleLevelTree = BI.inherit(BI.Widget, { - - render: function () { - var self = this; - var tree = BI.createWidget({ - type: "bi.single_level_tree", - items: BI.deepClone(Demo.CONSTANTS.LEVELTREE), - value: "11" - }); - - return { - type: "bi.vtape", - items: [{ - el: tree - }, { - el: { - type: "bi.button", - height: 25, - text: "getValue", - handler: function () { - BI.Msg.alert("", JSON.stringify(tree.getValue())); - } - }, - height: 25 - }, { - el: { - type: "bi.button", - height: 25, - text: "setValue (第二级文件1)", - handler: function () { - tree.setValue(["2"]); - } - }, - height: 25 - }], - width: 500, - hgap: 300 - }; - } -}); - -BI.shortcut("demo.single_level_tree", Demo.SingleLevelTree); \ No newline at end of file diff --git a/demo/js/widget/year/demo.year.js b/demo/js/widget/year/demo.year.js deleted file mode 100644 index 2381ed0f3..000000000 --- a/demo/js/widget/year/demo.year.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Created by Dailer on 2017/7/11. - */ -Demo.Year = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-exceltable" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - vgap: 10, - items: [{ - type: "bi.dynamic_year_combo", - width: 300, - ref: function () { - self.yearcombo = this; - }, - value: { - type: 1, - value: { - year: 2017 - } - } - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.yearcombo.getValue())); - }, - width: 300 - }, { - type: "bi.button", - text: "setValue : 2018", - handler: function () { - self.yearcombo.setValue(2018); - }, - width: 300 - }], - vgap: 10 - }; - } -}); - -BI.shortcut("demo.year", Demo.Year); \ No newline at end of file diff --git a/demo/js/widget/yearinterval/demo.year_interval.js b/demo/js/widget/yearinterval/demo.year_interval.js deleted file mode 100644 index 656ac7732..000000000 --- a/demo/js/widget/yearinterval/demo.year_interval.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/1/25 - */ -Demo.YearInterval = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.year_interval", - ref: function (_ref) { - self.widget = _ref; - }, - width: 300, - minDate: "2012-01-01", - maxDate: "2013-12-31", - value: { - type: 1, - value: { - year: 2012 - } - } - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.widget.getValue())); - }, - width: 300 - }, { - type: "bi.button", - text: "setValue '2017-12'", - width: 300, - handler: function () { - self.widget.setValue({ - year: 2017 - }); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.year_interval", Demo.YearInterval); \ No newline at end of file diff --git a/demo/js/widget/yearmonth/demo.year_month_combo.js b/demo/js/widget/yearmonth/demo.year_month_combo.js deleted file mode 100644 index 5552556e1..000000000 --- a/demo/js/widget/yearmonth/demo.year_month_combo.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.YearMonthCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.dynamic_year_month_combo", - ref: function (_ref) { - self.widget = _ref; - }, - width: 300, - // value: { - // type: 1, - // value: { - // year: 2018, - // month: 1 - // } - // } - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.widget.getValue())); - }, - width: 300 - }, { - type: "bi.button", - text: "setValue '2017-12'", - width: 300, - handler: function () { - self.widget.setValue({ - year: 2017, - month: 12 - }); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.year_month_combo", Demo.YearMonthCombo); \ No newline at end of file diff --git a/demo/js/widget/yearmonthinterval/demo.year_month_interval.js b/demo/js/widget/yearmonthinterval/demo.year_month_interval.js deleted file mode 100644 index b0958b50d..000000000 --- a/demo/js/widget/yearmonthinterval/demo.year_month_interval.js +++ /dev/null @@ -1,45 +0,0 @@ -Demo.YearMonthInterval = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.year_month_interval", - ref: function (_ref) { - self.interval = _ref; - }, - value: { - start: { - type: 2, - value: { - year: -1, - month: 1 - } - }, - end: { - type: 1, - value: { - year: 2018, - month: 1 - } - } - }, - width: 400 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.interval.getValue())); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.year_month_interval", Demo.YearMonthInterval); \ No newline at end of file diff --git a/demo/js/widget/yearquarter/demo.year_quarter_combo.js b/demo/js/widget/yearquarter/demo.year_quarter_combo.js deleted file mode 100644 index e5b017f01..000000000 --- a/demo/js/widget/yearquarter/demo.year_quarter_combo.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Created by Dailer on 2017/7/13. - */ -Demo.YearQuarterCombo = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.dynamic_year_quarter_combo", - width: 300, - ref: function (_ref) { - self.widget = _ref; - }, - yearBehaviors: {}, - quarterBehaviors: {}, - value: { - type: 1, - value: { - year: 2018, - quarter: 1 - } - } - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.widget.getValue())); - }, - width: 300 - }, { - type: "bi.button", - text: "setVlaue '2017 季度3'", - width: 300, - handler: function () { - self.widget.setValue({ - year: 2017, - quarter: 3 - }); - } - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.year_quarter_combo", Demo.YearQuarterCombo); \ No newline at end of file diff --git a/demo/js/widget/yearquarterinterval/demo.yearquarterinterval.js b/demo/js/widget/yearquarterinterval/demo.yearquarterinterval.js deleted file mode 100644 index 25ddd7e80..000000000 --- a/demo/js/widget/yearquarterinterval/demo.yearquarterinterval.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/1/25 - */ -Demo.YearQuarterInterval = BI.inherit(BI.Widget, { - props: { - baseCls: "" - }, - - render: function () { - var self = this; - return { - type: "bi.horizontal_auto", - items: [{ - type: "bi.year_quarter_interval", - ref: function (_ref) { - self.interval = _ref; - }, - minDate: "2012-07-01", - maxDate: "2012-12-31", - value: { - start: { - type: 2, - value: { - year: -1, - month: 1 - } - }, - end: { - type: 1, - value: { - year: 2018, - month: 1 - } - } - }, - width: 400 - }, { - type: "bi.button", - text: "getValue", - handler: function () { - BI.Msg.toast(JSON.stringify(self.interval.getValue())); - }, - width: 300 - }], - vgap: 20 - }; - } -}); - -BI.shortcut("demo.year_quarter_interval", Demo.YearQuarterInterval); \ No newline at end of file diff --git a/demo/less/center.less b/demo/less/center.less deleted file mode 100644 index b15dc85a3..000000000 --- a/demo/less/center.less +++ /dev/null @@ -1,3 +0,0 @@ -.demo-center { - -} \ No newline at end of file diff --git a/demo/less/face.less b/demo/less/face.less deleted file mode 100644 index 3e22a078b..000000000 --- a/demo/less/face.less +++ /dev/null @@ -1,11 +0,0 @@ -@import "index.less"; - -.demo-face { - .face-config { - .config-label { - font-size: 1.4rem; - } - .config-item { - } - } -} \ No newline at end of file diff --git a/demo/less/index.less b/demo/less/index.less deleted file mode 100644 index 9c7a9a367..000000000 --- a/demo/less/index.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../src/less/index.less"; \ No newline at end of file diff --git a/demo/less/main.less b/demo/less/main.less deleted file mode 100644 index 87a094414..000000000 --- a/demo/less/main.less +++ /dev/null @@ -1,102 +0,0 @@ -@import "index.less"; -.layout-bg-white { - background-color: #ffffff; -} - -.layout-bg-gray { - background-color: #eeeeee; -} - -.layout-bg1 { - color: #ffffff; - background-color: #0088cc; -} - -.layout-bg2 { - color: #ffffff; - background-color: #008B8B; -} - -.layout-bg3 { - color: #ffffff; - background-color: #6495ED; -} - -.layout-bg4 { - color: #ffffff; - background-color: #ff69b4; -} - -.layout-bg5 { - color: #ffffff; - background-color: #B8860B; -} - -.layout-bg6 { - color: #ffffff; - background-color: #d9534f; -} - -.layout-bg7 { - color: #ffffff; - background-color: #ea4738; -} - -.layout-bg8 { - color: #ffffff; - background-color: #6495ed; -} - -.demo-main { - & .bg1 { - background-color: #178cdf; - } -} - -body { - background-color: @color-bi-background-normal; -} - -#wrapper { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - font-size: 1.2rem; -} - -.bi-theme-dark body { - background-color: @color-bi-background-normal-theme-dark; -} - -.demo-editor { - border: 1px solid rgb(204, 204, 204); -} - -.demo-clolor { - color: #1a1a1a; -} - -.bi-progress-bar-processor { - transition: all 0.5s ease; - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - background: #3f8ce8; - border-radius: 2rem; - overflow: hidden; - overflow-x: hidden; - overflow-y: hidden; -} - -.bi-progress-text-bar-processor { - transition: all 0.5s ease; - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -o-transition: all 0.5s ease; -} - -.bi-progress-bar-bar { - border-radius: 2rem; -} diff --git a/demo/less/north.less b/demo/less/north.less deleted file mode 100644 index 12fbdb5b4..000000000 --- a/demo/less/north.less +++ /dev/null @@ -1,12 +0,0 @@ -@import "index.less"; - -.demo-north { - background-color: #3c8dbc; - & .logo { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - color: @color-bi-text; - background-color: #367fa9; - font-size: 2rem; - font-weight: 300; - } -} \ No newline at end of file diff --git a/demo/less/preview.less b/demo/less/preview.less deleted file mode 100644 index 600ec4476..000000000 --- a/demo/less/preview.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "index.less"; - -.demo-preview { -} \ No newline at end of file diff --git a/demo/less/vm.less b/demo/less/vm.less deleted file mode 100644 index 45094646a..000000000 --- a/demo/less/vm.less +++ /dev/null @@ -1,123 +0,0 @@ -@import "index.less"; - -.mvc-button { - &:hover, &.hover { - .opacity(0.5); - } - &.active, &:active { - .opacity(0.5) - } -} - -.bi-set-get { - & .left-title, & .right-title { - background: #0088cc; - color: #ffffff; - } - & .left-nav { - border-bottom: 1px solid #cccccc; - &.active, &:active { - color: #ffffff; - background-color: #d9534f; - } - } -} - -.bi-local { - & .top-button { - background-color: #448eea; - color: #ffffff - } - & .bottom-label { - background-color: #EA4738; - color: #ffffff; - } - & .delete-button { - background-color: #008B8B; - color: #ffffff; - } - & .vessel-border { - border-left: 1px solid #cccccc; - border-bottom: 1px solid #cccccc; - border-right: 1px solid #cccccc; - } -} - -.bi-event { - & .title { - background: #0088cc; - color: #ffffff; - } - & .front { - background: #ADD8E6; - } - & .nav { - border: 1px solid #cccccc; - } -} - -.bi-skip-to { - color: #ffffff; - - & .red-pane { - background-color: #0088cc; - } - & .blue-pane { - background-color: #6495ED; - } - & .green-pane { - background-color: #008B8B; - } - & .yellow-pane { - background-color: #B8860B; - } -} - -.bi-change { - & .outer-text { - background-color: #0088cc; - color: #ffffff; - } - & .inner { - border-left: 1px solid #cccccc; - border-bottom: 1px solid #cccccc; - border-right: 1px solid #cccccc; - } - - & .type-first { - background-color: #008B8B; - } - - & .type-second { - background-color: #6495ED; - } - - & .type-third { - background-color: #0088cc; - } -} - -.bi-tmp { - & .tmp-button { - color: #ffffff; - background: #0088cc; - } -} - -.bi-splice-duplicate { - & .superiors-label { - color: white; - background-color: #008B8B; - } - & .sd-child { - border: 1px solid #cccccc; - & .right-button-add { - color: white; - background-color: #0088cc; - } - & .right-button-del { - color: white; - background-color: #d9534f; - } - } -} \ No newline at end of file diff --git a/demo/less/west.less b/demo/less/west.less deleted file mode 100644 index c9f6477ee..000000000 --- a/demo/less/west.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "index.less"; - -.demo-west { -} diff --git a/demo/version.js b/demo/version.js deleted file mode 100644 index 8b1378917..000000000 --- a/demo/version.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dist/README.md b/dist/README.md deleted file mode 100644 index f6a3a9ec7..000000000 --- a/dist/README.md +++ /dev/null @@ -1,31 +0,0 @@ -#### fineui.js - -整个fineui打包文件,不包括配置文件 - -#### fineui.css - -整个fineui打包文件,不包括资源文件 - -#### config.js - -配置文件,这只是一个案例,集成进系统的时候需要进行配置 - -#### resource.css - -app.css background.css icon.css font.css的合并文件,集成进系统的时候需要进行配置 - -#### router.js - -#### 路由文件,使用fineui路由的时候才需要引入 - -#### bundle.js bundle.css - -所有文件的合并文件, 主要给在线demo和文档用的 - -#### core_without_normalize.css - -不带标准化的core.css文件,只引入通用css样式的时候才需要 - -#### chart.js - -封装好的一层图表api diff --git a/dist/fix/fix.compact.js b/dist/fix/fix.compact.js deleted file mode 100644 index dced5e166..000000000 --- a/dist/fix/fix.compact.js +++ /dev/null @@ -1,193 +0,0 @@ -;(function () { - function initWatch (vm, watch) { - vm._watchers || (vm._watchers = []); - for (var key in watch) { - var handler = watch[key]; - if (BI.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - vm._watchers.push(createWatcher(vm, key, handler[i])); - } - } else { - vm._watchers.push(createWatcher(vm, key, handler)); - } - } - BI.each(vm.$watchDelayCallbacks, function (i, watchDelayCallback) { - var innerWatch = watchDelayCallback[0]; - var innerHandler = watchDelayCallback[1]; - if (BI.isKey(innerWatch)) { - var key = innerWatch; - innerWatch = {}; - innerWatch[key] = innerHandler; - } - for (var key in innerWatch) { - var handler = innerWatch[key]; - if (BI.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - vm._watchers.push(createWatcher(vm, key, handler[i])); - } - } else { - vm._watchers.push(createWatcher(vm, key, handler)); - } - } - }); - } - - function createWatcher (vm, keyOrFn, cb, options) { - if (BI.isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - options = options || {}; - return Fix.watch(vm.model, keyOrFn, BI._.bind(cb, vm), BI.extend(options, { - store: vm.store - })); - } - - var target = null; - var targetStack = []; - - function pushTarget (_target) { - if (target) targetStack.push(target); - Fix.Model.target = target = _target; - } - - function popTarget () { - Fix.Model.target = target = targetStack.pop(); - } - - BI.Model = Fix.Model; - - var oldWatch = Fix.watch; - Fix.watch = function (model, expOrFn, cb, options) { - if (BI.isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - if (typeof cb === "string") { - cb = model[cb]; - } - return oldWatch.call(this, model, expOrFn, function () { - options && options.store && pushTarget(options.store); - try { - var res = cb.apply(this, arguments); - } catch (e) { - console.error(e); - } - options && options.store && popTarget(); - return res; - }, options); - }; - - BI.Widget.findStore = function findStore (widget) { - if (target != null) { - return target; - } - widget = widget || BI.Widget.context; - var p = widget; - while (p) { - if (p instanceof Fix.Model || p.store || p.__cacheStore) { - break; - } - p = p._parent || (p.options && p.options.element) || p._context; - } - if (p) { - if (p instanceof Fix.Model) { - return widget.__cacheStore = p; - } - widget.__cacheStore = p.store || p.__cacheStore; - return p.__cacheStore || p.store; - } - } - - function createStore () { - var needPop = false; - var workerMode = BI.Providers.getProvider("bi.provider.system").getWorkerMode(); - if (workerMode && this._worker) { - return; - } - if (this.store) { - pushTarget(this.store); - return true; - } - if (this._store || this.options._store) { - var store = BI.Widget.findStore(this.options.context || this._parent || this.options.element || this._context); - if (store) { - pushTarget(store); - needPop = true; - } - this.store = (this._store || this.options._store).call(this); - this.store && (this.store._widget = this); - needPop && popTarget(); - needPop = false; - pushTarget(this.store); - if (this.store instanceof Fix.Model) { - this.model = this.store.model; - } else { - this.model = this.store; - } - needPop = true; - } - return needPop; - } - - var _init = BI.Widget.prototype._init; - BI.Widget.prototype._init = function () { - var self = this; - var needPop = createStore.call(this); - try { - _init.apply(this, arguments); - } catch (e) { - console.error(e); - } - needPop && popTarget(); - }; - - var __initWatch = BI.Widget.prototype.__initWatch; - BI.Widget.prototype.__initWatch = function () { - __initWatch.apply(this, arguments); - var workerMode = BI.Providers.getProvider("bi.provider.system").getWorkerMode(); - if (workerMode && this._worker) { - return; - } - if (this._store) { - initWatch(this, this.watch); - } - }; - - var unMount = BI.Widget.prototype.__destroy; - BI.Widget.prototype.__destroy = function () { - try { - unMount.apply(this, arguments); - } catch (e) { - console.error(e); - } - this.store && BI.isFunction(this.store.destroy) && this.store.destroy(); - BI.each(this._watchers, function (i, unwatches) { - unwatches = BI.isArray(unwatches) ? unwatches : [unwatches]; - BI.each(unwatches, function (j, unwatch) { - unwatch(); - }); - }); - this._watchers && (this._watchers = []); - if (this.store) { - this.store._parent && (this.store._parent = null); - this.store._widget && (this.store._widget = null); - this.store = null; - } - delete this.__cacheStore; - }; - - BI._.each(["_render", "__afterRender", "_mount", "__afterMount"], function (name) { - var old = BI.Widget.prototype[name]; - old && (BI.Widget.prototype[name] = function () { - this.store && pushTarget(this.store); - try { - var res = old.apply(this, arguments); - } catch (e) { - console.error(e); - } - this.store && popTarget(); - return res; - }); - }); -}()); diff --git a/dist/fix/fix.js b/dist/fix/fix.js deleted file mode 100644 index e87c7e51a..000000000 --- a/dist/fix/fix.js +++ /dev/null @@ -1,1433 +0,0 @@ -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : factory(global.Fix = global.Fix || {}); -})(this, function (exports) { - 'use strict'; - - function noop(a, b, c) {} - - function isNative(Ctor) { - return typeof Ctor === 'function' && /native code/.test(Ctor.toString()); - } - - var hasProto = '__proto__' in {}; - - var _toString = Object.prototype.toString; - - function isPlainObject(obj) { - return _toString.call(obj) === '[object Object]'; - } - - function isConfigurable(obj, key) { - var configurable = true; - var property = Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(obj, key); - if (property && property.configurable === false) { - configurable = false; - } - return configurable; - } - - function isExtensible(obj) { - if (Object.isExtensible) { - return Object.isExtensible(obj); - } - var name = ''; - while (obj.hasOwnProperty(name)) { - name += '?'; - } - obj[name] = true; - var returnValue = obj.hasOwnProperty(name); - delete obj[name]; - return returnValue; - } - - function remove(arr, item) { - if (arr && arr.length) { - var _index = arr.indexOf(item); - if (_index > -1) { - return arr.splice(_index, 1); - } - } - } - - // const bailRE = /[^\w.$]/ - - function parsePath(path) { - // 正常表达式比较慢,能不要的就不要了 - // if (bailRE.test(path)) { - // return - // } - var segments = path.split('.'); - return function (obj) { - for (var i = 0; i < segments.length; i++) { - if (!obj) return; - obj = obj[segments[i]]; - } - return obj; - }; - } - - var nextTick = function () { - var callbacks = []; - var pending = false; - var timerFunc = void 0; - - function nextTickHandler() { - pending = false; - var copies = callbacks.slice(0); - callbacks.length = 0; - for (var i = 0; i < copies.length; i++) { - copies[i](); - } - } - - // An asynchronous deferring mechanism. - // In pre 2.4, we used to use microtasks (Promise/MutationObserver) - // but microtasks actually has too high a priority and fires in between - // supposedly sequential events (e.g. #4521, #6690) or even between - // bubbling of the same event (#6566). Technically setImmediate should be - // the ideal choice, but it's not available everywhere; and the only polyfill - // that consistently queues the callback after all DOM events triggered in the - // same loop is by using MessageChannel. - /* istanbul ignore if */ - if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { - timerFunc = function timerFunc() { - setImmediate(nextTickHandler); - }; - } else if (typeof MessageChannel !== 'undefined' && (isNative(MessageChannel) || - // PhantomJS - MessageChannel.toString() === '[object MessageChannelConstructor]')) { - var channel = new MessageChannel(); - var port = channel.port2; - channel.port1.onmessage = nextTickHandler; - timerFunc = function timerFunc() { - port.postMessage(1); - }; - } else - /* istanbul ignore next */ - if (typeof Promise !== 'undefined' && isNative(Promise)) { - // use microtask in non-DOM environments, e.g. Weex - var p = Promise.resolve(); - timerFunc = function timerFunc() { - p.then(nextTickHandler); - }; - } else { - // fallback to setTimeout - timerFunc = function timerFunc() { - setTimeout(nextTickHandler, 0); - }; - } - - return function queueNextTick(cb, ctx) { - var _resolve = void 0; - callbacks.push(function () { - if (cb) { - try { - cb.call(ctx); - } catch (e) { - console.error(e); - } - } else if (_resolve) { - _resolve(ctx); - } - }); - if (!pending) { - pending = true; - timerFunc(); - } - // $flow-disable-line - if (!cb && typeof Promise !== 'undefined') { - return new Promise(function (resolve, reject) { - _resolve = resolve; - }); - } - }; - }(); - - var falsy; - var $$skipArray = { - __ob__: falsy, - $accessors: falsy, - $vbthis: falsy, - $vbsetter: falsy - }; - - var uid = 0; - - /** - * A dep is an observable that can have multiple - * directives subscribing to it. - */ - - var Dep = function () { - function Dep() { - _classCallCheck(this, Dep); - - this.id = uid++; - this.subs = []; - } - - Dep.prototype.addSub = function addSub(sub) { - this.subs.push(sub); - }; - - Dep.prototype.removeSub = function removeSub(sub) { - remove(this.subs, sub); - }; - - Dep.prototype.depend = function depend() { - if (Dep.target) { - Dep.target.addDep(this); - } - }; - - Dep.prototype.notify = function notify(options) { - // stabilize the subscriber list first - var subs = this.subs.slice(); - for (var i = 0, l = subs.length; i < l; i++) { - subs[i].update(options); - } - }; - - return Dep; - }(); - - // the current target watcher being evaluated. - // this is globally unique because there could be only one - // watcher being evaluated at any time. - - - Dep.target = null; - var targetStack = []; - - function pushTarget(_target) { - if (Dep.target) targetStack.push(Dep.target); - Dep.target = _target; - } - - function popTarget() { - Dep.target = targetStack.pop(); - } - - //如果浏览器不支持ecma262v5的Object.defineProperties或者存在BUG,比如IE8 - //标准浏览器使用__defineGetter__, __defineSetter__实现 - var canHideProperty = true; - try { - Object.defineProperty({}, '_', { - value: 'x' - }); - delete $$skipArray.$vbsetter; - delete $$skipArray.$vbthis; - } catch (e) { - /* istanbul ignore next*/ - canHideProperty = false; - } - - var createViewModel = Object.defineProperties; - var defineProperty = void 0; - - /* istanbul ignore if*/ - if (!canHideProperty) { - if ('__defineGetter__' in {}) { - defineProperty = function defineProperty(obj, prop, desc) { - if ('value' in desc) { - obj[prop] = desc.value; - } - if ('get' in desc) { - obj.__defineGetter__(prop, desc.get); - } - if ('set' in desc) { - obj.__defineSetter__(prop, desc.set); - } - return obj; - }; - createViewModel = function createViewModel(obj, descs) { - for (var prop in descs) { - if (descs.hasOwnProperty(prop)) { - defineProperty(obj, prop, descs[prop]); - } - } - return obj; - }; - } - } - - var createViewModel$1 = createViewModel; - - var queue = []; - var activatedChildren = []; - var has = {}; - var waiting = false; - var flushing = false; - var index = 0; - - function resetSchedulerState() { - index = queue.length = activatedChildren.length = 0; - has = {}; - waiting = flushing = false; - } - - function flushSchedulerQueue() { - flushing = true; - var watcher = void 0, - id = void 0, - options = void 0; - - // Sort queue before flush. - // This ensures that: - // 1. Components are updated from parent to child. (because parent is always - // created before the child) - // 2. A component's user watchers are run before its render watcher (because - // user watchers are created before the render watcher) - // 3. If a component is destroyed during a parent component's watcher run, - // its watchers can be skipped. - queue.sort(function (a, b) { - return a.id - b.id; - }); - - // do not cache length because more watchers might be pushed - // as we run existing watchers - for (index = 0; index < queue.length; index++) { - watcher = queue[index].watcher; - options = queue[index].options; - id = watcher.id; - has[id] = null; - watcher.run(options); - } - - resetSchedulerState(); - } - - function queueWatcher(watcher, options) { - var id = watcher.id; - if (has[id] == null) { - has[id] = true; - if (!flushing) { - queue.push({ watcher: watcher, options: options }); - } else { - // if already flushing, splice the watcher based on its id - // if already past its id, it will be run next immediately. - var i = queue.length - 1; - while (i > index && queue[i].watcher.id > watcher.id) { - i--; - } - queue.splice(i + 1, 0, { watcher: watcher, options: options }); - } - // queue the flush - if (!waiting) { - waiting = true; - nextTick(flushSchedulerQueue); - } - } - } - - var uid$1 = 0; - - var Watcher = function () { - function Watcher(vm, expOrFn, cb, options) { - _classCallCheck(this, Watcher); - - this.vm = vm; - // vm._watchers || (vm._watchers = []) - // vm._watchers.push(this) - // options - if (options) { - this.deep = !!options.deep; - this.user = !!options.user; - this.lazy = !!options.lazy; - this.sync = !!options.sync; - } else { - this.deep = this.user = this.lazy = this.sync = false; - } - this.cb = cb; - this.id = ++uid$1; // uid for batching - this.active = true; - this.dirty = this.lazy; // for lazy watchers - this.deps = []; - this.newDeps = []; - this.depIds = new Set(); - this.newDepIds = new Set(); - this.expression = ''; - // parse expression for getter - if (typeof expOrFn === 'function') { - this.getter = expOrFn; - } else { - this.getter = parsePath(expOrFn); - if (!this.getter) { - this.getter = function () {}; - } - } - this.value = this.lazy ? undefined : this.get(); - } - - Watcher.prototype.get = function get() { - pushTarget(this); - var value = void 0; - var vm = this.vm; - try { - value = this.getter.call(vm, vm); - } catch (e) { - // if (this.user) { - // } else { - // console.error(e) - // } - } finally { - // "touch" every property so they are all tracked as - // dependencies for deep watching - if (this.deep) { - traverse(value); - } - popTarget(); - this.cleanupDeps(); - } - return value; - }; - - Watcher.prototype.addDep = function addDep(dep) { - var id = dep.id; - if (!this.newDepIds.has(id)) { - this.newDepIds.add(id); - this.newDeps.push(dep); - if (!this.depIds.has(id)) { - dep.addSub(this); - } - } - }; - - Watcher.prototype.cleanupDeps = function cleanupDeps() { - var i = this.deps.length; - while (i--) { - var dep = this.deps[i]; - if (!this.newDepIds.has(dep.id)) { - dep.removeSub(this); - } - } - var tmp = this.depIds; - this.depIds = this.newDepIds; - this.newDepIds = tmp; - this.newDepIds.clear(); - tmp = this.deps; - this.deps = this.newDeps; - this.newDeps = tmp; - this.newDeps.length = 0; - }; - - Watcher.prototype.update = function update(options) { - /* istanbul ignore else */ - if (this.lazy) { - this.dirty = true; - } else if (this.sync) { - this.run(options); - } else { - queueWatcher(this, options); - } - }; - - Watcher.prototype.run = function run(options) { - if (this.active) { - var value = this.get(); - if (value !== this.value || - // Deep watchers and watchers on Object/Arrays should fire even - // when the value is the same, because the value may - // have mutated. - BI._.isObject(value) && options && options.refresh || this.deep) { - // set new value - var oldValue = this.value; - this.value = value; - if (this.user) { - try { - this.cb.call(this.vm, value, oldValue, options); - } catch (e) { - console.error(e); - } - } else { - try { - this.cb.call(this.vm, value, oldValue, options); - } catch (e) { - console.error(e); - } - } - } - } - }; - - Watcher.prototype.evaluate = function evaluate() { - this.value = this.get(); - this.dirty = false; - }; - - Watcher.prototype.depend = function depend() { - var i = this.deps.length; - while (i--) { - this.deps[i].depend(); - } - }; - - Watcher.prototype.teardown = function teardown() { - if (this.active) { - // remove self from vm's watcher list - // this is a somewhat expensive operation so we skip it - // if the vm is being destroyed. - remove(this.vm && this.vm._watchers, this); - var i = this.deps.length; - while (i--) { - this.deps[i].removeSub(this); - } - this.active = false; - } - }; - - return Watcher; - }(); - - var seenObjects = new Set(); - - function traverse(val) { - seenObjects.clear(); - _traverse(val, seenObjects); - } - - function _traverse(val, seen) { - var i = void 0, - keys = void 0; - var isA = BI._.isArray(val); - if (!isA && !BI._.isObject(val)) { - return; - } - if (val.__ob__) { - var depId = val.__ob__.dep.id; - if (seen.has(depId)) { - return; - } - seen.add(depId); - } - if (isA) { - i = val.length; - while (i--) { - _traverse(val[i], seen); - } - } else { - keys = BI._.keys(val); - i = keys.length; - while (i--) { - _traverse(val[keys[i]], seen); - } - } - } - - var arrayProto = Array.prototype; - var arrayMethods = []; - BI._.each(['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'], function (method) { - var original = arrayProto[method]; - arrayMethods[method] = function mutator() { - for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) { - args[_key2] = arguments[_key2]; - } - - var ob = this.__ob__; - var inserted = void 0; - switch (method) { - case 'push': - case 'unshift': - inserted = args; - break; - case 'splice': - inserted = args.slice(2); - break; - } - if (inserted) inserted = ob.observeArray(inserted); - switch (method) { - case 'push': - case 'unshift': - args = inserted; - break; - case 'splice': - if (args.length > 2) { - args = [args[0], args[1]].concat(inserted ? inserted : []); - } - break; - } - var result = original.apply(this, args); - notify(ob.parent, ob.parentKey, ob.dep, true); - return result; - }; - }); - - var arrayKeys = BI._.keys(arrayMethods); - - var observerState = { - shouldConvert: true - }; - - function def(obj, key, val, enumerable) { - Object.defineProperty(obj, key, { - value: val, - enumerable: !!enumerable, - writable: true, - configurable: true - }); - } - - /** - * Observer class that are attached to each observed - * object. Once attached, the observer converts target - * object's property keys into getter/setters that - * collect dependencies and dispatches updates. - */ - - var Observer = function () { - function Observer(value) { - _classCallCheck(this, Observer); - - this.value = value; - this.dep = new Dep(); - this.vmCount = 0; - if (BI._.isArray(value)) { - var augment = hasProto ? protoAugment : copyAugment; - augment(value, arrayMethods, arrayKeys); - this.model = this.observeArray(value); - } else { - this.model = this.walk(value); - } - def(this.model, "__ob__", this); - } - - Observer.prototype.walk = function walk(obj) { - return defineReactive(obj, this); - }; - - Observer.prototype.observeArray = function observeArray(items) { - for (var i = 0, l = items.length; i < l; i++) { - var ob = observe(items[i], this, i); - items[i] = ob ? ob.model : items[i]; - } - return items; - }; - - return Observer; - }(); - - function protoAugment(target, src, keys) { - /* eslint-disable no-proto */ - target.__proto__ = src; - /* eslint-enable no-proto */ - } - - /* istanbul ignore next */ - function copyAugment(target, src, keys) { - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - target[key] = src[key]; - } - } - - function observe(value, parentObserver, parentKey) { - if (!BI._.isObject(value)) { - return; - } - var ob = void 0; - if (value.__ob__ instanceof Observer) { - ob = value.__ob__; - } else if (observerState.shouldConvert && isExtensible(value) && (BI._.isArray(value) || isPlainObject(value))) { - ob = new Observer(value); - } - if (ob) { - ob.parent = parentObserver || ob.parent; - ob.parentKey = parentKey; - } - return ob; - } - - function notify(observer, key, dep, refresh) { - dep.notify({ observer: observer, key: key, refresh: refresh }); - if (observer) { - //触发a.*绑定的依赖 - BI._.each(observer._deps, function (dep) { - dep.notify({ observer: observer, key: key }); - }); - //触发a.**绑定的依赖 - var parent = observer, - root = observer, - route = key || ""; - while (parent) { - BI._.each(parent._scopeDeps, function (dep) { - dep.notify({ observer: observer, key: key }); - }); - if (parent.parentKey != null) { - route = parent.parentKey + '.' + route; - } - root = parent; - parent = parent.parent; - } - for (var _key in root._globalDeps) { - var reg = new RegExp(_key); - if (reg.test(route)) { - for (var i = 0; i < root._globalDeps[_key].length; i++) { - root._globalDeps[_key][i].notify({ observer: observer, key: _key }); - } - } - } - } - } - - function defineReactive(obj, observer, shallow) { - var props = {}; - var model = void 0; - BI._.each(obj, function (val, key) { - if (key in $$skipArray) { - return; - } - var configurable = isConfigurable(obj, key); - var dep = observer && observer['__dep' + key] || new Dep(); - observer && (observer['__dep' + key] = dep); - var childOb = configurable && !shallow && observe(val, observer, key); - props[key] = { - enumerable: true, - configurable: true, - get: function reactiveGetter() { - var value = childOb ? childOb.model : val; - if (Dep.target) { - dep.depend(); - if (childOb) { - childOb.dep.depend(); - if (BI._.isArray(value)) { - dependArray(value); - } - } - } - return value; - }, - set: function reactiveSetter(newVal) { - var value = childOb ? childOb.model : val; - if (newVal === value || newVal !== newVal && value !== value) { - return; - } - val = newVal; - childOb = configurable && !shallow && observe(newVal, observer, key); - if (childOb && value && value.__ob__) { - childOb._scopeDeps = value.__ob__._scopeDeps; - childOb._deps = value.__ob__._deps; - } - obj[key] = childOb ? childOb.model : newVal; - notify(model.__ob__, key, dep); - } - }; - }); - return model = createViewModel$1(obj, props); - } - - function defineReactiveProperty(obj, key, val, shallow) { - - var dep = new Dep(); - - var configurable = isConfigurable(obj, key); - if (!configurable) { - return; - } - - if (arguments.length === 2) { - val = obj[key]; - } - - var childOb = !shallow && observe(val); - Object.defineProperty(obj, key, { - enumerable: true, - configurable: true, - get: function reactiveGetter() { - var value = childOb ? childOb.model : val; - if (Dep.target) { - dep.depend(); - if (childOb) { - childOb.dep.depend(); - if (BI._.isArray(value)) { - dependArray(value); - } - } - } - return value; - }, - set: function reactiveSetter(newVal) { - var value = childOb ? childOb.model : val; - if (newVal === value || newVal !== newVal && value !== value) { - return; - } - - childOb = configurable && !shallow && observe(newVal); - val = newVal; - obj[key] = childOb ? childOb.model : newVal; - dep.notify(); - } - }); - } - - /** - * Set a property on an object. Adds the new property and - * triggers change notification if the property doesn't - * already exist. - */ - function set(target, key, val) { - if (BI._.isArray(target)) { - target.length = Math.max(target.length, key); - target.splice(key, 1, val); - return val; - } - if (BI._.has(target, key)) { - target[key] = val; - return val; - } - var ob = target.__ob__; - if (!ob) { - target[key] = val; - return val; - } - ob.value[key] = val; - target = defineReactive(ob.value, ob); - notify(ob, key, ob.dep); - return target; - } - - function freeze() { - return Object.freeze.apply(null, arguments); - } - - /** - * Delete a property and trigger change if necessary. - */ - function del(target, key) { - if (BI._.isArray(target)) { - target.splice(key, 1); - return; - } - var ob = target.__ob__; - if (!BI._.has(target, key)) { - return; - } - if (!ob) { - delete target[key]; - return target; - } - delete ob.value[key]; - target = defineReactive(ob.value, ob); - notify(ob, key, ob.dep); - return target; - } - - /** - * Collect dependencies on array elements when the array is touched, since - * we cannot intercept array element access like property getters. - */ - function dependArray(value) { - for (var e, i = 0, l = value.length; i < l; i++) { - e = value[i]; - e && e.__ob__ && e.__ob__.dep.depend(); - if (BI._.isArray(e)) { - dependArray(e); - } - } - } - - var falsy$1; - var operators = { - '||': falsy$1, - '&&': falsy$1, - '(': falsy$1, - ')': falsy$1 - }; - - function runBinaryFunction(binarys) { - var expr = ''; - for (var i = 0, len = binarys.length; i < len; i++) { - if (BI._.isBoolean(binarys[i]) || BI._.has(operators, binarys[i])) { - expr += binarys[i]; - } else { - expr += 'false'; - } - } - return new Function('return ' + expr)(); - } - - function routeToRegExp(route) { - route = route.replace(/\*\*/g, '[a-zA-Z0-9_]+').replace(/\*./g, '[a-zA-Z0-9_]+.'); - return '^' + route + '$'; - } - - function watch(model, expOrFn, cb, options) { - if (isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - if (typeof cb === 'string') { - cb = model[cb]; - } - options = options || {}; - options.user = true; - var exps = void 0; - if (BI._.isFunction(expOrFn) || !(exps = expOrFn.match(/[a-zA-Z0-9BI._.*]+|[|][|]|[&][&]|[(]|[)]/g)) || exps.length === 1 && expOrFn.indexOf("*") < 0) { - var watcher = new Watcher(model, expOrFn, cb, options); - if (options.immediate) { - cb(watcher.value); - } - return function unwatchFn() { - watcher.teardown(); - }; - } - var watchers = []; - var fns = exps.slice(); - var complete = false, - running = false; - var callback = function callback(index, newValue, oldValue, attrs) { - if (complete === true) { - return; - } - fns[index] = true; - if (runBinaryFunction(fns)) { - complete = true; - cb(newValue, oldValue, attrs); - } - if (options && options.sync) { - complete = false; - running = false; - fns = exps.slice(); - } else { - if (!running) { - running = true; - nextTick(function () { - complete = false; - running = false; - fns = exps.slice(); - }); - } - } - }; - BI._.each(exps, function (exp, i) { - if (BI._.has(operators, exp)) { - return; - } - if (exp.indexOf("*") >= 0) { - //a.**或a.*形式 - if (/^[1-9a-zA-Z.]+(\*\*$|\*$)/.test(exp) || exp === "**" || exp === "*") { - var isGlobal = exp.indexOf("**") >= 0; - if (isGlobal) { - //a.**的形式 - exp = exp.replace(".**", ""); - } else { - //a.*的形式 - exp = exp.replace(".*", ""); - } - var getter = exp === "**" || exp === "*" ? function (m) { - return m; - } : parsePath(exp); - var v = getter.call(model, model); - - if (v.__ob__) { - var _dep = new Dep(); - if (isGlobal) { - (v.__ob__._scopeDeps || (v.__ob__._scopeDeps = [])).push(_dep); - } else { - (v.__ob__._deps || (v.__ob__._deps = [])).push(_dep); - } - var _w = new Watcher(model, function () { - _dep.depend(); - return NaN; - }, function (newValue, oldValue, attrs) { - callback(i, newValue, oldValue, BI._.extend({ index: i }, attrs)); - }, options); - watchers.push(function unwatchFn() { - _w.teardown(); - v.__ob__._scopeDeps && remove(v.__ob__._scopeDeps, _dep); - v.__ob__._deps && remove(v.__ob__._deps, _dep); - }); - } - - return; - } - // **.a.**的情况,场景:a.b.c, 如果用b.**监听, a被重新赋值b上的_scopeDes就不存在了 - if (/^(\*\*\.)+[1-9a-zA-Z]+(\.\*\*$)/.test(exp)) { - //先获取到能获取到的对象 - var _paths = exp.split("."); - var _currentModel = model[_paths[1]]; - - if (!_currentModel.__ob__) { - return; - } - - exp = _paths[1] + ".**"; - //补全路径 - var _parent = _currentModel.__ob__.parent, - _root = _currentModel.__ob__; - while (_parent) { - exp = '*.' + exp; - _root = _parent; - _parent = _parent.parent; - } - var _regStr = routeToRegExp(exp); - var _dep2 = new Dep(); - _root._globalDeps || (_root._globalDeps = {}); - if (BI._.isArray(_root._globalDeps[_regStr])) { - _root._globalDeps[_regStr].push(_dep2); - } else { - _root._globalDeps[_regStr] = [_dep2]; - } - - var _w2 = new Watcher(_currentModel, function () { - _dep2.depend(); - return NaN; - }, function (newValue, oldValue, attrs) { - callback(i, newValue, oldValue, BI._.extend({ index: i }, attrs)); - }, options); - watchers.push(function unwatchFn() { - if (_root._globalDeps) { - remove(_root._globalDeps[_regStr], _dep2); - - if (_root._globalDeps[_regStr].length === 0) { - delete _root._globalDeps[_regStr]; - _w2.teardown(); - } - } - }); - return; - } - // 再有结尾有*的就不支持了 - if (exp[exp.length - 1] === "*") { - throw new Error('not support'); - } - //其他含有*的情况,如*.a,*.*.a,a.*.a - var currentModel = model; - //先获取到能获取到的对象 - var paths = exp.split("."); - for (var _i = 0, len = paths.length; _i < len; _i++) { - if (paths[_i] === "*") { - break; - } - currentModel = model[paths[_i]]; - } - - if (!currentModel.__ob__) { - return; - } - - exp = exp.substr(exp.indexOf("*")); - //补全路径 - var parent = currentModel.__ob__.parent, - root = currentModel.__ob__; - while (parent) { - exp = '*.' + exp; - root = parent; - parent = parent.parent; - } - var regStr = routeToRegExp(exp); - var dep = new Dep(); - root._globalDeps || (root._globalDeps = {}); - if (BI._.isArray(root._globalDeps[regStr])) { - root._globalDeps[regStr].push(dep); - } else { - root._globalDeps[regStr] = [dep]; - } - - var w = new Watcher(currentModel, function () { - dep.depend(); - return NaN; - }, function (newValue, oldValue, attrs) { - callback(i, newValue, oldValue, BI._.extend({ index: i }, attrs)); - }, options); - watchers.push(function unwatchFn() { - if (root._globalDeps) { - remove(root._globalDeps[regStr], dep); - if (root._globalDeps[regStr].length === 0) { - delete root._globalDeps[regStr]; - w.teardown(); - } - } - }); - return; - } - var watcher = new Watcher(model, exp, function (newValue, oldValue, attrs) { - callback(i, newValue, oldValue, BI._.extend({ index: i }, attrs)); - }, options); - watchers.push(function unwatchFn() { - watcher.teardown(); - }); - }); - return watchers; - } - - var mixinInjection = {}; - - function getMixins(type) { - return mixinInjection[type]; - } - - function mixin(xtype, cls) { - mixinInjection[xtype] = BI._.cloneDeep(cls); - } - - var computedWatcherOptions = { lazy: true }; - var REACTIVE = true; - - function initState(vm, state) { - if (state) { - vm.$$state = REACTIVE ? observe(state).model : state; - } - } - - function initComputed(vm, computed) { - var watchers = vm._computedWatchers = {}; - defineComputed(vm, computed); - for (var key in computed) { - watchers[key] = defineComputedWatcher(vm, computed[key]); - } - } - - function defineComputedWatcher(vm, userDef) { - var context = vm.$$model ? vm.model : vm; - var getter = typeof userDef === "function" ? userDef : userDef.get; - - return new Watcher(context, getter || noop, noop, computedWatcherOptions); - } - - function defineOneComputedGetter(vm, key, userDef) { - var shouldCache = true; - var sharedPropertyDefinition = { - enumerable: true, - configurable: true, - get: noop, - set: noop - }; - if (typeof userDef === "function") { - sharedPropertyDefinition.get = createComputedGetter(vm, key); - sharedPropertyDefinition.set = noop; - } else { - sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? createComputedGetter(vm, key) : userDef.get : noop; - sharedPropertyDefinition.set = userDef.set ? userDef.set : noop; - } - return sharedPropertyDefinition; - } - - function defineComputed(vm, computed) { - var props = {}; - for (var key in computed) { - if (!(key in vm)) { - props[key] = defineOneComputedGetter(vm, key, computed[key]); - } - } - vm.$$computed = createViewModel$1({}, props); - } - - function createComputedGetter(vm, key) { - return function computedGetter() { - var watcher = vm._computedWatchers && vm._computedWatchers[key]; - if (watcher) { - if (watcher.dirty) { - watcher.evaluate(); - } - if (REACTIVE && Dep.target) { - watcher.depend(); - } - return watcher.value; - } - }; - } - - function initWatch(vm, watch$$1) { - vm._watchers || (vm._watchers = []); - for (var key in watch$$1) { - var handler = watch$$1[key]; - if (BI._.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - vm._watchers.push(createWatcher(vm, key, handler[i])); - } - } else { - vm._watchers.push(createWatcher(vm, key, handler)); - } - } - } - - function createWatcher(vm, keyOrFn, cb, options) { - if (isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - if (typeof cb === 'string') { - cb = vm[cb]; - } - return watch(vm.model, keyOrFn, BI._.bind(cb, vm.$$model ? vm.model : vm), options); - } - - function initMethods(vm, methods) { - for (var key in methods) { - vm[key] = methods[key] == null ? noop : BI._.bind(methods[key], vm.$$model ? vm.model : vm); - } - } - - function initMixins(vm, mixins) { - mixins = (mixins || []).slice(0); - - BI._.each(mixins.reverse(), function (mixinType) { - var mixin$$1 = getMixins(mixinType); - - for (var key in mixin$$1) { - if (typeof mixin$$1[key] !== "function") continue; - - if (BI._.has(vm, key)) continue; - - vm[key] = BI._.bind(mixin$$1[key], vm.$$model ? vm.model : vm); - } - }); - } - - function defineProps(vm, keys) { - var props = {}; - // if (typeof Proxy === 'function') { - // return vm.model = new Proxy(props, { - // has: function (target, key) { - // return keys.indexOf(key) > -1; - // }, - // get: function (target, key) { - // if (key in $$skipArray) { - // return props[key] - // } - // if (vm.$$computed && key in vm.$$computed) { - // return vm.$$computed[key] - // } - // if (vm.$$state && key in vm.$$state) { - // return vm.$$state[key] - // } - // return vm.$$model[key] - // }, - // set: function (target, key, val) { - // if (key in $$skipArray) { - // return props[key] = val - // } - // if (vm.$$state && key in vm.$$state) { - // return vm.$$state[key] = val - // } - // if (vm.$$model && key in vm.$$model) { - // return vm.$$model[key] = val - // } - // } - // }) - // } - - var _loop = function _loop(i, len) { - var key = keys[i]; - if (!(key in $$skipArray)) { - props[key] = { - enumerable: true, - configurable: true, - get: function get() { - if (vm.$$computed && key in vm.$$computed) { - return vm.$$computed[key]; - } - if (vm.$$state && key in vm.$$state) { - return vm.$$state[key]; - } - if (vm.$$model && key in vm.$$model) { - return vm.$$model[key]; - } - var p = vm._parent; - while (p) { - if (p.$$context && key in p.$$context) { - return p.$$context[key]; - } - p = p._parent; - } - }, - set: function set(val) { - if (vm.$$state && key in vm.$$state) { - return vm.$$state[key] = val; - } - if (vm.$$model && key in vm.$$model) { - return vm.$$model[key] = val; - } - var p = vm._parent; - while (p) { - if (p.$$context && key in p.$$context) { - return p.$$context[key] = val; - } - p = p._parent; - } - } - }; - } - }; - - for (var i = 0, len = keys.length; i < len; i++) { - _loop(i, len); - } - vm.model = createViewModel$1({}, props); - } - - function defineContext(vm, keys) { - var props = {}; - - var _loop2 = function _loop2(i, len) { - var key = keys[i]; - if (!(key in $$skipArray)) { - props[key] = { - enumerable: true, - configurable: true, - get: function get() { - return vm.model[key]; - }, - set: function set(val) { - return vm.model[key] = val; - } - }; - } - }; - - for (var i = 0, len = keys.length; i < len; i++) { - _loop2(i, len); - } - vm.$$context = createViewModel$1({}, props); - } - - function getInjectValue(vm, key) { - var p = vm._parent; - while (p) { - if (p.$$context && key in p.$$context) { - return p.$$context[key]; - } - p = p._parent; - } - } - - function getInjectValues(vm) { - var inject = vm.inject || []; - var result = {}; - BI._.each(inject, function (key) { - result[key] = getInjectValue(vm, key); - }); - return result; - } - - var Model = function () { - function Model() { - _classCallCheck(this, Model); - } - - Model.prototype._constructor = function _constructor(model, destroyHandler) { - if (model instanceof Observer || model instanceof Model) { - model = model.model; - } - if (model && model.__ob__) { - this.$$model = model; - } else { - this.options = model || {}; - } - this._parent = Model.target; - var state = BI._.isFunction(this.state) ? this.state() : this.state; - var computed = this.computed; - var context = this.context; - var inject = this.inject; - var childContext = this.childContext; - var provide = this.provide; - var watch$$1 = this.watch; - var actions = this.actions; - var keys = BI._.keys(this.$$model).concat(BI._.keys(state)).concat(BI._.keys(computed)).concat(inject || []).concat(context || []); - var mixins = this.mixins; - defineProps(this, keys); - // deprecated - childContext && defineContext(this, childContext); - provide && defineContext(this, provide); - this.$$model && (this.model.__ob__ = this.$$model.__ob__); - initMixins(this, mixins); - this.init(); - initState(this, BI._.extend(getInjectValues(this), state)); - initComputed(this, computed); - REACTIVE && initWatch(this, watch$$1); - initMethods(this, actions); - this.created && this.created(); - this._destroyHandler = destroyHandler; - if (this.$$model) { - return this.model; - } - }; - - Model.prototype._init = function _init() {}; - - Model.prototype.init = function init() { - this._init(); - }; - - Model.prototype.destroy = function destroy() { - for (var _key3 in this._computedWatchers) { - this._computedWatchers[_key3].teardown(); - } - BI._.each(this._watchers, function (unwatches) { - unwatches = BI._.isArray(unwatches) ? unwatches : [unwatches]; - BI._.each(unwatches, function (unwatch) { - unwatch(); - }); - }); - this._watchers && (this._watchers = []); - this.destroyed && this.destroyed(); - this.$$model = null; - this.$$computed = null; - this.$$state = null; - this._destroyHandler && this._destroyHandler(); - }; - - return Model; - }(); - - function define(model) { - return REACTIVE ? new Observer(model).model : model; - } - - var reactive = define; - - function config(options) { - options || (options = {}); - if ("reactive" in options) { - REACTIVE = options.reactive; - } - } - - function toJSON(model) { - var result = void 0; - if (BI._.isArray(model)) { - result = []; - for (var i = 0, len = model.length; i < len; i++) { - result[i] = toJSON(model[i]); - } - } else if (model && isPlainObject(model)) { - result = {}; - for (var _key4 in model) { - if (!BI._.has($$skipArray, _key4)) { - result[_key4] = toJSON(model[_key4]); - } - } - } else { - result = model; - } - return result; - } - - var version = '2.0'; - - exports.version = version; - exports.$$skipArray = $$skipArray; - exports.mixin = mixin; - exports.Model = Model; - exports.define = define; - exports.reactive = reactive; - exports.config = config; - exports.observerState = observerState; - exports.Observer = Observer; - exports.observe = observe; - exports.notify = notify; - exports.defineReactive = defineReactive; - exports.defineReactiveProperty = defineReactiveProperty; - exports.set = set; - exports.freeze = freeze; - exports.del = del; - exports.Watcher = Watcher; - exports.pushTarget = pushTarget; - exports.popTarget = popTarget; - exports.watch = watch; - exports.toJSON = toJSON; - - exports.__esModule = true; -}); \ No newline at end of file diff --git a/dist/fix/fix.proxy.js b/dist/fix/fix.proxy.js deleted file mode 100644 index 4a709fb3c..000000000 --- a/dist/fix/fix.proxy.js +++ /dev/null @@ -1,2475 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Fix = {})); -})(this, (function (exports) { 'use strict'; - - function _typeof(obj) { - "@babel/helpers - typeof"; - - return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }, _typeof(obj); - } - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - Object.defineProperty(Constructor, "prototype", { - writable: false - }); - return Constructor; - } - - function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; - } - - function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); - } - - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); - } - - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); - } - - function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; - } - - function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); - } - - function _iterableToArrayLimit(arr, i) { - var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; - - if (_i == null) return; - var _arr = []; - var _n = true; - var _d = false; - - var _s, _e; - - try { - for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; - } - - function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); - } - - function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - - return arr2; - } - - function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - function _createForOfIteratorHelper(o, allowArrayLike) { - var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; - - if (!it) { - if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { - if (it) o = it; - var i = 0; - - var F = function () {}; - - return { - s: F, - n: function () { - if (i >= o.length) return { - done: true - }; - return { - done: false, - value: o[i++] - }; - }, - e: function (e) { - throw e; - }, - f: F - }; - } - - throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - var normalCompletion = true, - didErr = false, - err; - return { - s: function () { - it = it.call(o); - }, - n: function () { - var step = it.next(); - normalCompletion = step.done; - return step; - }, - e: function (e) { - didErr = true; - err = e; - }, - f: function () { - try { - if (!normalCompletion && it.return != null) it.return(); - } finally { - if (didErr) throw err; - } - } - }; - } - - /** - * Make a map and return a function for checking if a key - * is in that map. - * IMPORTANT: all calls of this function must be prefixed with - * \/\*#\_\_PURE\_\_\*\/ - * So that rollup can tree-shake them if necessary. - */ - function makeMap(str, expectsLowerCase) { - var map = Object.create(null); - var list = str.split(','); - - for (var i = 0; i < list.length; i++) { - map[list[i]] = true; - } - - return expectsLowerCase ? function (val) { - return !!map[val.toLowerCase()]; - } : function (val) { - return !!map[val]; - }; - } - - Object.freeze({}); - Object.freeze([]); - var extend = Object.assign; - var hasOwnProperty = Object.prototype.hasOwnProperty; - - var hasOwn = function hasOwn(val, key) { - return hasOwnProperty.call(val, key); - }; - - var isArray = Array.isArray; - - var isMap$1 = function isMap(val) { - return toTypeString$1(val) === '[object Map]'; - }; - - var isFunction = function isFunction(val) { - return typeof val === 'function'; - }; - - var isString = function isString(val) { - return typeof val === 'string'; - }; - - var isSymbol = function isSymbol(val) { - return _typeof(val) === 'symbol'; - }; - - var isObject = function isObject(val) { - return val !== null && _typeof(val) === 'object'; - }; - - var objectToString$1 = Object.prototype.toString; - - var toTypeString$1 = function toTypeString(value) { - return objectToString$1.call(value); - }; - - var toRawType = function toRawType(value) { - // extract "RawType" from strings like "[object RawType]" - return toTypeString$1(value).slice(8, -1); - }; - - var isIntegerKey = function isIntegerKey(key) { - return isString(key) && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key; - }; - - var cacheStringFunction = function cacheStringFunction(fn) { - var cache = Object.create(null); - return function (str) { - var hit = cache[str]; - return hit || (cache[str] = fn(str)); - }; - }; - /** - * @private - */ - - - var capitalize = cacheStringFunction(function (str) { - return str.charAt(0).toUpperCase() + str.slice(1); - }); // compare whether a value has changed, accounting for NaN. - - var hasChanged$1 = function hasChanged(value, oldValue) { - return !Object.is(value, oldValue); - }; - - var activeEffectScope; - - function recordEffectScope(effect, scope) { - scope = scope || activeEffectScope; - - if (scope && scope.active) { - scope.effects.push(effect); - } - } - - var createDep = function createDep(effects) { - var dep = new Set(effects); - dep.w = 0; - dep.n = 0; - return dep; - }; - - var wasTracked = function wasTracked(dep) { - return (dep.w & trackOpBit) > 0; - }; - - var newTracked = function newTracked(dep) { - return (dep.n & trackOpBit) > 0; - }; - - var initDepMarkers = function initDepMarkers(_ref) { - var deps = _ref.deps; - - if (deps.length) { - for (var i = 0; i < deps.length; i++) { - deps[i].w |= trackOpBit; // set was tracked - } - } - }; - - var finalizeDepMarkers = function finalizeDepMarkers(effect) { - var deps = effect.deps; - - if (deps.length) { - var ptr = 0; - - for (var i = 0; i < deps.length; i++) { - var dep = deps[i]; - - if (wasTracked(dep) && !newTracked(dep)) { - dep.delete(effect); - } else { - deps[ptr++] = dep; - } // clear bits - - - dep.w &= ~trackOpBit; - dep.n &= ~trackOpBit; - } - - deps.length = ptr; - } - }; - - var targetMap = new WeakMap(); // The number of effects currently being tracked recursively. - - var effectTrackDepth = 0; - var trackOpBit = 1; - /** - * The bitwise track markers support at most 30 levels of recursion. - * This value is chosen to enable modern JS engines to use a SMI on all platforms. - * When recursion depth is greater, fall back to using a full cleanup. - */ - - var maxMarkerBits = 30; - var effectStack = []; - var activeEffect; - var ITERATE_KEY = Symbol('iterate'); - var MAP_KEY_ITERATE_KEY = Symbol('Map key iterate'); - - var ReactiveEffect = /*#__PURE__*/function () { - function ReactiveEffect(fn) { - var scheduler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var scope = arguments.length > 2 ? arguments[2] : undefined; - - _classCallCheck(this, ReactiveEffect); - - this.fn = fn; - this.scheduler = scheduler; - this.active = true; - this.deps = []; - recordEffectScope(this, scope); - } - - _createClass(ReactiveEffect, [{ - key: "run", - value: function run() { - if (!this.active) { - return this.fn(); - } - - if (!effectStack.includes(this)) { - try { - effectStack.push(activeEffect = this); - enableTracking(); - trackOpBit = 1 << ++effectTrackDepth; - - if (effectTrackDepth <= maxMarkerBits) { - initDepMarkers(this); - } else { - cleanupEffect(this); - } - - return this.fn(); - } finally { - if (effectTrackDepth <= maxMarkerBits) { - finalizeDepMarkers(this); - } - - trackOpBit = 1 << --effectTrackDepth; - resetTracking(); - effectStack.pop(); - var n = effectStack.length; - activeEffect = n > 0 ? effectStack[n - 1] : undefined; - } - } - } - }, { - key: "stop", - value: function stop() { - if (this.active) { - cleanupEffect(this); - - if (this.onStop) { - this.onStop(); - } - - this.active = false; - } - } - }]); - - return ReactiveEffect; - }(); - - function cleanupEffect(effect) { - var deps = effect.deps; - - if (deps.length) { - for (var i = 0; i < deps.length; i++) { - deps[i].delete(effect); - } - - deps.length = 0; - } - } - - function effect(fn, options) { - if (fn.effect) { - fn = fn.effect.fn; - } - - var _effect = new ReactiveEffect(fn); - - if (options) { - extend(_effect, options); - if (options.scope) recordEffectScope(_effect, options.scope); - } - - if (!options || !options.lazy) { - _effect.run(); - } - - var runner = _effect.run.bind(_effect); - - runner.effect = _effect; - return runner; - } - - function stop(runner) { - runner.effect.stop(); - } - - var shouldTrack = true; - var trackStack = []; - - function pauseTracking() { - trackStack.push(shouldTrack); - shouldTrack = false; - } - - function enableTracking() { - trackStack.push(shouldTrack); - shouldTrack = true; - } - - function resetTracking() { - var last = trackStack.pop(); - shouldTrack = last === undefined ? true : last; - } - - function track(target, type, key) { - if (!isTracking()) { - return; - } - - var depsMap = targetMap.get(target); - - if (!depsMap) { - targetMap.set(target, depsMap = new Map()); - } - - var dep = depsMap.get(key); - - if (!dep) { - depsMap.set(key, dep = createDep()); - } - - var eventInfo = { - effect: activeEffect, - target: target, - type: type, - key: key - }; - trackEffects(dep, eventInfo); - } - - function isTracking() { - return shouldTrack && activeEffect !== undefined; - } - - function trackEffects(dep, debuggerEventExtraInfo) { - var shouldTrack = false; - - if (effectTrackDepth <= maxMarkerBits) { - if (!newTracked(dep)) { - dep.n |= trackOpBit; // set newly tracked - - shouldTrack = !wasTracked(dep); - } - } else { - // Full cleanup mode. - shouldTrack = !dep.has(activeEffect); - } - - if (shouldTrack) { - dep.add(activeEffect); - activeEffect.deps.push(dep); - - if (activeEffect.onTrack) { - activeEffect.onTrack(Object.assign({ - effect: activeEffect - }, debuggerEventExtraInfo)); - } - } - } - - function trigger(target, type, key, newValue, oldValue, oldTarget) { - var depsMap = targetMap.get(target); - - if (!depsMap) { - // never been tracked - return; - } - - var deps = []; - - if (type === "clear" - /* CLEAR */ - ) { - // collection being cleared - // trigger all effects for target - deps = _toConsumableArray(depsMap.values()); - } else if (key === 'length' && isArray(target)) { - depsMap.forEach(function (dep, key) { - if (key === 'length' || key >= newValue) { - deps.push(dep); - } - }); - } else { - // schedule runs for SET | ADD | DELETE - if (key !== void 0) { - deps.push(depsMap.get(key)); - } // also run for iteration key on ADD | DELETE | Map.SET - - - switch (type) { - case "add" - /* ADD */ - : - if (!isArray(target)) { - deps.push(depsMap.get(ITERATE_KEY)); - - if (isMap$1(target)) { - deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); - } - } else if (isIntegerKey(key)) { - // new index added to array -> length changes - deps.push(depsMap.get('length')); - } - - break; - - case "delete" - /* DELETE */ - : - if (!isArray(target)) { - deps.push(depsMap.get(ITERATE_KEY)); - - if (isMap$1(target)) { - deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); - } - } - - break; - - case "set" - /* SET */ - : - if (isMap$1(target)) { - deps.push(depsMap.get(ITERATE_KEY)); - } - - break; - } - } - - var eventInfo = { - target: target, - type: type, - key: key, - newValue: newValue, - oldValue: oldValue, - oldTarget: oldTarget - }; - - if (deps.length === 1) { - if (deps[0]) { - { - triggerEffects(deps[0], eventInfo); - } - } - } else { - var effects = []; - - var _iterator = _createForOfIteratorHelper(deps), - _step; - - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var dep = _step.value; - - if (dep) { - effects.push.apply(effects, _toConsumableArray(dep)); - } - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - - { - triggerEffects(createDep(effects), eventInfo); - } - } - } - - function triggerEffects(dep, debuggerEventExtraInfo) { - // spread into array for stabilization - var _iterator2 = _createForOfIteratorHelper(isArray(dep) ? dep : _toConsumableArray(dep)), - _step2; - - try { - for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { - var _effect2 = _step2.value; - - if (_effect2 !== activeEffect || _effect2.allowRecurse) { - if (_effect2.onTrigger) { - _effect2.onTrigger(extend({ - effect: _effect2 - }, debuggerEventExtraInfo)); - } - - if (_effect2.scheduler) { - _effect2.scheduler(); - } else { - _effect2.run(); - } - } - } - } catch (err) { - _iterator2.e(err); - } finally { - _iterator2.f(); - } - } - - var isNonTrackableKeys = /*#__PURE__*/makeMap("__proto__,__v_isRef,__isVue"); - var builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map(function (key) { - return Symbol[key]; - }).filter(isSymbol)); - var get = /*#__PURE__*/createGetter(); - var readonlyGet = /*#__PURE__*/createGetter(true); - var arrayInstrumentations = /*#__PURE__*/createArrayInstrumentations(); - - function createArrayInstrumentations() { - var instrumentations = {}; - ['includes', 'indexOf', 'lastIndexOf'].forEach(function (key) { - instrumentations[key] = function () { - var arr = toRaw(this); - - for (var i = 0, l = this.length; i < l; i++) { - track(arr, "get" - /* GET */ - , i + ''); - } // we run the method using the original args first (which may be reactive) - - - for (var _len2 = arguments.length, args = new Array(_len2), _key3 = 0; _key3 < _len2; _key3++) { - args[_key3] = arguments[_key3]; - } - - var res = arr[key].apply(arr, args); - - if (res === -1 || res === false) { - // if that didn't work, run it again using raw values. - return arr[key].apply(arr, _toConsumableArray(args.map(toRaw))); - } else { - return res; - } - }; - }); - ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(function (key) { - instrumentations[key] = function () { - pauseTracking(); - - for (var _len3 = arguments.length, args = new Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { - args[_key4] = arguments[_key4]; - } - - var res = toRaw(this)[key].apply(this, args); - resetTracking(); - return res; - }; - }); - return instrumentations; - } - - function createGetter() { - var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - var shallow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - return function get(target, key, receiver) { - if (key === "__v_isReactive" - /* IS_REACTIVE */ - ) { - return !isReadonly; - } else if (key === "__v_isReadonly" - /* IS_READONLY */ - ) { - return isReadonly; - } else if (key === "__v_raw" - /* RAW */ - && receiver === (isReadonly ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) { - return target; - } - - var targetIsArray = isArray(target); - - if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) { - return Reflect.get(arrayInstrumentations, key, receiver); - } - - var res = Reflect.get(target, key, receiver); - - if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { - return res; - } - - if (!isReadonly) { - track(target, "get" - /* GET */ - , key); - } - - if (shallow) { - return res; - } - - if (isRef(res)) { - // ref unwrapping - does not apply for Array + integer key. - var shouldUnwrap = !targetIsArray || !isIntegerKey(key); - return shouldUnwrap ? res.value : res; - } - - if (isObject(res)) { - // Convert returned value into a proxy as well. we do the isObject check - // here to avoid invalid value warning. Also need to lazy access readonly - // and reactive here to avoid circular dependency. - return isReadonly ? readonly(res) : reactive(res); - } - - return res; - }; - } - - var set$1 = /*#__PURE__*/createSetter(); - - function createSetter() { - var shallow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - return function set(target, key, value, receiver) { - var oldValue = target[key]; - - if (!shallow && !isReadonly(value)) { - value = toRaw(value); - oldValue = toRaw(oldValue); - - if (!isArray(target) && isRef(oldValue) && !isRef(value)) { - oldValue.value = value; - return true; - } - } - - var hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key); - var result = Reflect.set(target, key, value, receiver); // don't trigger if target is something up in the prototype chain of original - - if (target === toRaw(receiver)) { - if (!hadKey) { - trigger(target, "add" - /* ADD */ - , key, value); - } else if (hasChanged$1(value, oldValue)) { - trigger(target, "set" - /* SET */ - , key, value, oldValue); - } - } - - return result; - }; - } - - function deleteProperty(target, key) { - var hadKey = hasOwn(target, key); - var oldValue = target[key]; - var result = Reflect.deleteProperty(target, key); - - if (result && hadKey) { - trigger(target, "delete" - /* DELETE */ - , key, undefined, oldValue); - } - - return result; - } - - function has$1(target, key) { - var result = Reflect.has(target, key); - - if (!isSymbol(key) || !builtInSymbols.has(key)) { - track(target, "has" - /* HAS */ - , key); - } - - return result; - } - - function ownKeys(target) { - track(target, "iterate" - /* ITERATE */ - , isArray(target) ? 'length' : ITERATE_KEY); - return Reflect.ownKeys(target); - } - - var mutableHandlers = { - get: get, - set: set$1, - deleteProperty: deleteProperty, - has: has$1, - ownKeys: ownKeys - }; - var readonlyHandlers = { - get: readonlyGet, - set: function set(target, key) { - { - console.warn("Set operation on key \"".concat(String(key), "\" failed: target is readonly."), target); - } - return true; - }, - deleteProperty: function deleteProperty(target, key) { - { - console.warn("Delete operation on key \"".concat(String(key), "\" failed: target is readonly."), target); - } - return true; - } - }; - - var toShallow = function toShallow(value) { - return value; - }; - - var getProto = function getProto(v) { - return Reflect.getPrototypeOf(v); - }; - - function get$1(target, key) { - var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var isShallow = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - // #1772: readonly(reactive(Map)) should return readonly + reactive version - // of the value - target = target["__v_raw" - /* RAW */ - ]; - var rawTarget = toRaw(target); - var rawKey = toRaw(key); - - if (key !== rawKey) { - !isReadonly && track(rawTarget, "get" - /* GET */ - , key); - } - - !isReadonly && track(rawTarget, "get" - /* GET */ - , rawKey); - - var _getProto = getProto(rawTarget), - has = _getProto.has; - - var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; - - if (has.call(rawTarget, key)) { - return wrap(target.get(key)); - } else if (has.call(rawTarget, rawKey)) { - return wrap(target.get(rawKey)); - } else if (target !== rawTarget) { - // #3602 readonly(reactive(Map)) - // ensure that the nested reactive `Map` can do tracking for itself - target.get(key); - } - } - - function has$1$1(key) { - var isReadonly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var target = this["__v_raw" - /* RAW */ - ]; - var rawTarget = toRaw(target); - var rawKey = toRaw(key); - - if (key !== rawKey) { - !isReadonly && track(rawTarget, "has" - /* HAS */ - , key); - } - - !isReadonly && track(rawTarget, "has" - /* HAS */ - , rawKey); - return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); - } - - function size(target) { - var isReadonly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - target = target["__v_raw" - /* RAW */ - ]; - !isReadonly && track(toRaw(target), "iterate" - /* ITERATE */ - , ITERATE_KEY); - return Reflect.get(target, 'size', target); - } - - function add(value) { - value = toRaw(value); - var target = toRaw(this); - var proto = getProto(target); - var hadKey = proto.has.call(target, value); - - if (!hadKey) { - target.add(value); - trigger(target, "add" - /* ADD */ - , value, value); - } - - return this; - } - - function set$1$1(key, value) { - value = toRaw(value); - var target = toRaw(this); - - var _getProto2 = getProto(target), - has = _getProto2.has, - get = _getProto2.get; - - var hadKey = has.call(target, key); - - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else { - checkIdentityKeys(target, has, key); - } - - var oldValue = get.call(target, key); - target.set(key, value); - - if (!hadKey) { - trigger(target, "add" - /* ADD */ - , key, value); - } else if (hasChanged$1(value, oldValue)) { - trigger(target, "set" - /* SET */ - , key, value, oldValue); - } - - return this; - } - - function deleteEntry(key) { - var target = toRaw(this); - - var _getProto3 = getProto(target), - has = _getProto3.has, - get = _getProto3.get; - - var hadKey = has.call(target, key); - - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else { - checkIdentityKeys(target, has, key); - } - - var oldValue = get ? get.call(target, key) : undefined; // forward the operation before queueing reactions - - var result = target.delete(key); - - if (hadKey) { - trigger(target, "delete" - /* DELETE */ - , key, undefined, oldValue); - } - - return result; - } - - function clear() { - var target = toRaw(this); - var hadItems = target.size !== 0; - var oldTarget = isMap$1(target) ? new Map(target) : new Set(target); // forward the operation before queueing reactions - - var result = target.clear(); - - if (hadItems) { - trigger(target, "clear" - /* CLEAR */ - , undefined, undefined, oldTarget); - } - - return result; - } - - function createForEach(isReadonly, isShallow) { - return function forEach(callback, thisArg) { - var observed = this; - var target = observed["__v_raw" - /* RAW */ - ]; - var rawTarget = toRaw(target); - var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; - !isReadonly && track(rawTarget, "iterate" - /* ITERATE */ - , ITERATE_KEY); - return target.forEach(function (value, key) { - // important: make sure the callback is - // 1. invoked with the reactive map as `this` and 3rd arg - // 2. the value received should be a corresponding reactive/readonly. - return callback.call(thisArg, wrap(value), wrap(key), observed); - }); - }; - } - - function createIterableMethod(method, isReadonly, isShallow) { - return function () { - var target = this["__v_raw" - /* RAW */ - ]; - var rawTarget = toRaw(target); - var targetIsMap = isMap$1(rawTarget); - var isPair = method === 'entries' || method === Symbol.iterator && targetIsMap; - var isKeyOnly = method === 'keys' && targetIsMap; - var innerIterator = target[method].apply(target, arguments); - var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; - !isReadonly && track(rawTarget, "iterate" - /* ITERATE */ - , isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); // return a wrapped iterator which returns observed versions of the - // values emitted from the real iterator - - return _defineProperty({ - // iterator protocol - next: function next() { - var _innerIterator$next = innerIterator.next(), - value = _innerIterator$next.value, - done = _innerIterator$next.done; - - return done ? { - value: value, - done: done - } : { - value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), - done: done - }; - } - }, Symbol.iterator, function () { - return this; - }); - }; - } - - function createReadonlyMethod(type) { - return function () { - { - var key = (arguments.length <= 0 ? undefined : arguments[0]) ? "on key \"".concat(arguments.length <= 0 ? undefined : arguments[0], "\" ") : ""; - console.warn("".concat(capitalize(type), " operation ").concat(key, "failed: target is readonly."), toRaw(this)); - } - return type === "delete" - /* DELETE */ - ? false : this; - }; - } - - function createInstrumentations() { - var mutableInstrumentations = { - get: function get(key) { - return get$1(this, key); - }, - - get size() { - return size(this); - }, - - has: has$1$1, - add: add, - set: set$1$1, - delete: deleteEntry, - clear: clear, - forEach: createForEach(false, false) - }; - var shallowInstrumentations = { - get: function get(key) { - return get$1(this, key, false, true); - }, - - get size() { - return size(this); - }, - - has: has$1$1, - add: add, - set: set$1$1, - delete: deleteEntry, - clear: clear, - forEach: createForEach(false, true) - }; - var readonlyInstrumentations = { - get: function get(key) { - return get$1(this, key, true); - }, - - get size() { - return size(this, true); - }, - - has: function has(key) { - return has$1$1.call(this, key, true); - }, - add: createReadonlyMethod("add" - /* ADD */ - ), - set: createReadonlyMethod("set" - /* SET */ - ), - delete: createReadonlyMethod("delete" - /* DELETE */ - ), - clear: createReadonlyMethod("clear" - /* CLEAR */ - ), - forEach: createForEach(true, false) - }; - var shallowReadonlyInstrumentations = { - get: function get(key) { - return get$1(this, key, true, true); - }, - - get size() { - return size(this, true); - }, - - has: function has(key) { - return has$1$1.call(this, key, true); - }, - add: createReadonlyMethod("add" - /* ADD */ - ), - set: createReadonlyMethod("set" - /* SET */ - ), - delete: createReadonlyMethod("delete" - /* DELETE */ - ), - clear: createReadonlyMethod("clear" - /* CLEAR */ - ), - forEach: createForEach(true, true) - }; - var iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; - iteratorMethods.forEach(function (method) { - mutableInstrumentations[method] = createIterableMethod(method, false, false); - readonlyInstrumentations[method] = createIterableMethod(method, true, false); - shallowInstrumentations[method] = createIterableMethod(method, false, true); - shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); - }); - return [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations]; - } - - var _createInstrumentatio = /* #__PURE__*/createInstrumentations(), - _createInstrumentatio2 = _slicedToArray(_createInstrumentatio, 4), - mutableInstrumentations = _createInstrumentatio2[0], - readonlyInstrumentations = _createInstrumentatio2[1], - shallowInstrumentations = _createInstrumentatio2[2], - shallowReadonlyInstrumentations = _createInstrumentatio2[3]; - - function createInstrumentationGetter(isReadonly, shallow) { - var instrumentations = shallow ? isReadonly ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations; - return function (target, key, receiver) { - if (key === "__v_isReactive" - /* IS_REACTIVE */ - ) { - return !isReadonly; - } else if (key === "__v_isReadonly" - /* IS_READONLY */ - ) { - return isReadonly; - } else if (key === "__v_raw" - /* RAW */ - ) { - return target; - } - - return Reflect.get(hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver); - }; - } - - var mutableCollectionHandlers = { - get: /*#__PURE__*/createInstrumentationGetter(false, false) - }; - var readonlyCollectionHandlers = { - get: /*#__PURE__*/createInstrumentationGetter(true, false) - }; - - function checkIdentityKeys(target, has, key) { - var rawKey = toRaw(key); - - if (rawKey !== key && has.call(target, rawKey)) { - var type = toRawType(target); - console.warn("Reactive ".concat(type, " contains both the raw and reactive ") + "versions of the same object".concat(type === "Map" ? " as keys" : "", ", ") + "which can lead to inconsistencies. " + "Avoid differentiating between the raw and reactive versions " + "of an object and only use the reactive version if possible."); - } - } - - var reactiveMap = new WeakMap(); - var shallowReactiveMap = new WeakMap(); - var readonlyMap = new WeakMap(); - var shallowReadonlyMap = new WeakMap(); - - function targetTypeMap(rawType) { - switch (rawType) { - case 'Object': - case 'Array': - return 1 - /* COMMON */ - ; - - case 'Map': - case 'Set': - case 'WeakMap': - case 'WeakSet': - return 2 - /* COLLECTION */ - ; - - default: - return 0 - /* INVALID */ - ; - } - } - - function getTargetType(value) { - return value["__v_skip" - /* SKIP */ - ] || !Object.isExtensible(value) ? 0 - /* INVALID */ - : targetTypeMap(toRawType(value)); - } - - function reactive(target) { - // if trying to observe a readonly proxy, return the readonly version. - if (target && target["__v_isReadonly" - /* IS_READONLY */ - ]) { - return target; - } - - return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); - } - /** - * Creates a readonly copy of the original object. Note the returned copy is not - * made reactive, but `readonly` can be called on an already reactive object. - */ - - - function readonly(target) { - return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); - } - - function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { - if (!isObject(target)) { - { - console.warn("value cannot be made reactive: ".concat(String(target))); - } - return target; - } // target is already a Proxy, return it. - // exception: calling readonly() on a reactive object - - - if (target["__v_raw" - /* RAW */ - ] && !(isReadonly && target["__v_isReactive" - /* IS_REACTIVE */ - ])) { - return target; - } // target already has corresponding Proxy - - - var existingProxy = proxyMap.get(target); - - if (existingProxy) { - return existingProxy; - } // only a whitelist of value types can be observed. - - - var targetType = getTargetType(target); - - if (targetType === 0 - /* INVALID */ - ) { - return target; - } - - var proxy = new Proxy(target, targetType === 2 - /* COLLECTION */ - ? collectionHandlers : baseHandlers); - proxyMap.set(target, proxy); - return proxy; - } - - function isReactive(value) { - if (isReadonly(value)) { - return isReactive(value["__v_raw" - /* RAW */ - ]); - } - - return !!(value && value["__v_isReactive" - /* IS_REACTIVE */ - ]); - } - - function isReadonly(value) { - return !!(value && value["__v_isReadonly" - /* IS_READONLY */ - ]); - } - - function toRaw(observed) { - var raw = observed && observed["__v_raw" - /* RAW */ - ]; - return raw ? toRaw(raw) : observed; - } - - var toReactive = function toReactive(value) { - return isObject(value) ? reactive(value) : value; - }; - - var toReadonly = function toReadonly(value) { - return isObject(value) ? readonly(value) : value; - }; - - function trackRefValue(ref) { - if (isTracking()) { - ref = toRaw(ref); - - if (!ref.dep) { - ref.dep = createDep(); - } - - { - trackEffects(ref.dep, { - target: ref, - type: "get" - /* GET */ - , - key: 'value' - }); - } - } - } - - function triggerRefValue(ref, newVal) { - ref = toRaw(ref); - - if (ref.dep) { - { - triggerEffects(ref.dep, { - target: ref, - type: "set" - /* SET */ - , - key: 'value', - newValue: newVal - }); - } - } - } - - function isRef(r) { - return Boolean(r && r.__v_isRef === true); - } - - var ComputedRefImpl = /*#__PURE__*/function () { - function ComputedRefImpl(getter, _setter, isReadonly) { - var _this2 = this; - - _classCallCheck(this, ComputedRefImpl); - - this._setter = _setter; - this.dep = undefined; - this._dirty = true; - this.__v_isRef = true; - this.effect = new ReactiveEffect(getter, function () { - if (!_this2._dirty) { - _this2._dirty = true; - triggerRefValue(_this2); - } - }); - this["__v_isReadonly" - /* IS_READONLY */ - ] = isReadonly; - } - - _createClass(ComputedRefImpl, [{ - key: "value", - get: function get() { - // the computed ref may get wrapped by other proxies e.g. readonly() #3376 - var self = toRaw(this); - trackRefValue(self); - - if (self._dirty) { - self._dirty = false; - self._value = self.effect.run(); - } - - return self._value; - }, - set: function set(newValue) { - this._setter(newValue); - } - }]); - - return ComputedRefImpl; - }(); - - function computed(getterOrOptions, debugOptions) { - var getter; - var setter; - var onlyGetter = isFunction(getterOrOptions); - - if (onlyGetter) { - getter = getterOrOptions; - - setter = function setter() { - console.warn('Write operation failed: computed value is readonly'); - }; - } else { - getter = getterOrOptions.get; - setter = getterOrOptions.set; - } - - var cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter); - - if (debugOptions) { - cRef.effect.onTrack = debugOptions.onTrack; - cRef.effect.onTrigger = debugOptions.onTrigger; - } - - return cRef; - } - - Promise.resolve(); - - function noop() {} - function isNative(Ctor) { - return typeof Ctor === "function" && /native code/.test(Ctor.toString()); - } - var isIE = function isIE() { - if (typeof navigator === "undefined") { - return false; - } - - return /(msie|trident)/i.test(navigator.userAgent.toLowerCase()); - }; - var getIEVersion = function getIEVersion() { - var version = 0; - - if (typeof navigator === "undefined") { - return false; - } - - var agent = navigator.userAgent.toLowerCase(); - var v1 = agent.match(/(?:msie\s([\w.]+))/); - var v2 = agent.match(/(?:trident.*rv:([\w.]+))/); - - if (v1 && v2 && v1[1] && v2[1]) { - version = Math.max(v1[1] * 1, v2[1] * 1); - } else if (v1 && v1[1]) { - version = v1[1] * 1; - } else if (v2 && v2[1]) { - version = v2[1] * 1; - } else { - version = 0; - } - - return version; - }; - isIE() && getIEVersion() < 9; - var _toString = Object.prototype.toString; - function isPlainObject(obj) { - return _toString.call(obj) === "[object Object]"; - } - - function parsePath(path) { - // if (bailRE.test(path)) { - // return; - // } - var segments = path.length > 0 ? path.split(".") : []; - return function (obj) { - for (var i = 0; i < segments.length; i++) { - if (!obj) return; - obj = obj[segments[i]]; - } - - return obj; - }; - } - var nextTick = function () { - var callbacks = []; - var pending = false; - var timerFunc; - - function nextTickHandler() { - pending = false; - var copies = callbacks.slice(0); - callbacks.length = 0; - - for (var i = 0; i < copies.length; i++) { - copies[i](); - } - } // An asynchronous deferring mechanism. - // In pre 2.4, we used to use microtasks (Promise/MutationObserver) - // but microtasks actually has too high a priority and fires in between - // supposedly sequential events (e.g. #4521, #6690) or even between - // bubbling of the same event (#6566). Technically setImmediate should be - // the ideal choice, but it's not available everywhere; and the only polyfill - // that consistently queues the callback after all DOM events triggered in the - // same loop is by using MessageChannel. - - /* istanbul ignore if */ - - - if (typeof setImmediate !== "undefined" && isNative(setImmediate)) { - timerFunc = function timerFunc() { - setImmediate(nextTickHandler); - }; - } else if (typeof MessageChannel !== "undefined" && (isNative(MessageChannel) || // PhantomJS - MessageChannel.toString() === "[object MessageChannelConstructor]")) { - var channel = new MessageChannel(); - var port = channel.port2; - channel.port1.onmessage = nextTickHandler; - - timerFunc = function timerFunc() { - port.postMessage(1); - }; - } else if (typeof Promise !== "undefined" && isNative(Promise)) { - /* istanbul ignore next */ - // use microtask in non-DOM environments, e.g. Weex - var p = Promise.resolve(); - - timerFunc = function timerFunc() { - p.then(nextTickHandler); - }; - } else { - // fallback to setTimeout - timerFunc = function timerFunc() { - setTimeout(nextTickHandler, 0); - }; - } - - return function queueNextTick(cb, ctx) { - var _resolve; - - callbacks.push(function () { - if (cb) { - try { - cb.call(ctx); - } catch (e) { - console.error(e); - } - } else if (_resolve) { - _resolve(ctx); - } - }); - - if (!pending) { - pending = true; - timerFunc(); - } // $flow-disable-line - - - if (!cb && typeof Promise !== "undefined") { - return new Promise(function (resolve) { - _resolve = resolve; - }); - } - }; - }(); - - var mixinInjection = {}; - function getMixins(type) { - return mixinInjection[type]; - } - function mixin(xtype, cls) { - mixinInjection[xtype] = BI._.cloneDeep(cls); - } - - var queue = []; - var has = {}; - var waiting = false; - var flushing = false; - var index = 0; - - function resetSchedulerState() { - index = queue.length = 0; - has = {}; - waiting = flushing = false; - } - - function flushSchedulerQueue() { - flushing = true; - var watcher; - var id; - var options; // Sort queue before flush. - // This ensures that: - // 1. Components are updated from parent to child. (because parent is always - // created before the child) - // 2. A component's user watchers are run before its render watcher (because - // user watchers are created before the render watcher) - // 3. If a component is destroyed during a parent component's watcher run, - // its watchers can be skipped. - - queue.sort(function (a, b) { - return a.id - b.id; - }); // do not cache length because more watchers might be pushed - // as we run existing watchers - - for (index = 0; index < queue.length; index++) { - watcher = queue[index].watcher; - options = queue[index].options; - id = watcher.id; - has[id] = null; - watcher(options); - } - - resetSchedulerState(); - } - - function queueWatcher(watcher, options) { - var id = watcher.id; - - if (has[id] == null) { - has[id] = true; - - if (!flushing) { - queue.push({ - watcher: watcher, - options: options - }); - } else { - // if already flushing, splice the watcher based on its id - // if already past its id, it will be run next immediately. - var i = queue.length - 1; - - while (i > index && queue[i].watcher.id > watcher.id) { - i--; - } - - queue.splice(i + 1, 0, { - watcher: watcher, - options: options - }); - } // queue the flush - - - if (!waiting) { - waiting = true; - nextTick(flushSchedulerQueue); - } - } - } - - function innerWatch(source, cb, options) { - if (!BI._.isFunction(cb)) { - console.warn("`watch(fn, options?)` signature has been moved to a separate API. " + "Use `watchEffect(fn, options?)` instead. `watch` now only " + "supports `watch(source, cb, options?) signature."); - } - - return doWatch(source, cb, options); - } - var INITIAL_WATCHER_VALUE = {}; - var objectToString = Object.prototype.toString; - - var toTypeString = function toTypeString(value) { - return objectToString.call(value); - }; - - var isMap = function isMap(val) { - return toTypeString(val) === "[object Map]"; - }; - - var isSet = function isSet(val) { - return toTypeString(val) === "[object Set]"; - }; - - var hasChanged = function hasChanged(value, oldValue) { - return value !== oldValue && (value === value || oldValue === oldValue); - }; - - var uid = 0; - - function doWatch(source, cb, options, instance) { - options = options || {}; - var _options = options, - immediate = _options.immediate, - deep = _options.deep, - sync = _options.sync, - onTrack = _options.onTrack, - onTrigger = _options.onTrigger; - - if (!cb) { - if (immediate !== undefined) { - console.warn("watch() \"immediate\" option is only respected when using the " + "watch(source, callback, options?) signature."); - } - - if (deep !== undefined) { - console.warn("watch() \"deep\" option is only respected when using the " + "watch(source, callback, options?) signature."); - } - } - - var warnInvalidSource = function warnInvalidSource(s) { - console.warn("Invalid watch source: ", s, "A watch source can only be a getter/effect function, a ref, " + "a reactive object, or an array of these types."); - }; - - var getter; - var forceTrigger = false; - - if (isRef(source)) { - getter = function getter() { - return source.value; - }; - - forceTrigger = !!source._shallow; - } else if (isReactive(source)) { - getter = function getter() { - return source; - }; - - deep = true; - } else if (BI._.isArray(source)) { - getter = function getter() { - return source.map(function (s) { - if (isRef(s)) { - return s.value; - } else if (isReactive(s)) { - return traverse(s); - } else if (BI._.isFunction(s)) { - return s.call(instance); - } else { - warnInvalidSource(s); - } - }); - }; - } else if (BI._.isFunction(source)) { - if (cb) { - // getter with cb - getter = function getter() { - return source.call(instance); - }; - } else { - // no cb -> simple effect - getter = function getter() { - if (instance && instance.isUnmounted) { - return; - } - - if (cleanup) { - cleanup(); - } - - return source.call(instance, onInvalidate); - }; - } - } else { - getter = function getter() {}; - - warnInvalidSource(source); - } - - if (cb && deep) { - var baseGetter = getter; - - getter = function getter() { - return traverse(baseGetter()); - }; - } - - var cleanup; - - var onInvalidate = function onInvalidate(fn) { - cleanup = runner.options.onStop = function () { - fn.call(instance); - }; - }; - - var oldValue = BI._.isArray(source) ? [] : INITIAL_WATCHER_VALUE; - - var job = function job() { - // 这里去掉的原因是,新增属性没有生效也会触发变化监听 - if (!runner.effect.active) { - return; - } - - if (cb) { - // watch(source, cb) - var newValue = runner(); - - if (deep || forceTrigger || hasChanged(newValue, oldValue)) { - // cleanup before running cb again - if (cleanup) { - cleanup(); - } - - cb.apply(instance, [newValue, // pass undefined as the old value when it's changed for the first time - oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, onInvalidate]); - oldValue = newValue; - } - } else { - // watchEffect - runner(); - } - }; // important: mark the job as a watcher callback so that scheduler knows - // it is allowed to self-trigger (#1727) - - - job.allowRecurse = !!cb; - job.id = ++uid; - var scheduler; - - if (sync === true) { - scheduler = job; - } else { - scheduler = function scheduler() { - return queueWatcher(job); - }; - } - - var runner = effect(function () { - try { - return getter(); - } catch (e) {// 吞掉异常 - } - }, { - lazy: true, - onTrack: onTrack, - onTrigger: onTrigger, - scheduler: scheduler - }); // initial run - - if (cb) { - if (immediate) { - job(); - } else { - oldValue = runner(); - } - } else { - runner(); - } - - return function () { - stop(runner); - }; - } - - function traverse(value) { - var seen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set(); - - if (!BI._.isObject(value) || seen.has(value)) { - return value; - } - - seen.add(value); - - if (isRef(value)) { - traverse(value.value, seen); - } else if (BI._.isArray(value)) { - for (var i = 0; i < value.length; i++) { - traverse(value[i], seen); - } - } else if (isSet(value) || isMap(value)) { - value.forEach(function (v) { - traverse(v, seen); - }); - } else { - for (var key in value) { - traverse(value[key], seen); - } - } - - return value; - } - - var falsy; - var operators = { - "||": falsy, - "&&": falsy, - "(": falsy, - ")": falsy - }; - - function runBinaryFunction(binarys) { - var expr = ""; - - for (var i = 0, len = binarys.length; i < len; i++) { - if (BI._.isBoolean(binarys[i]) || BI._.has(operators, binarys[i])) { - expr += binarys[i]; - } else { - expr += "false"; - } - } - - return new Function("return " + expr)(); - } - - function watchExp(model, getter) { - var result = getter.call(model, model); - - if (BI._.isArray(result)) { - return result.concat(); - } - - return result; - } - - function watch(model, expOrFn, cb, options) { - if (isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - - if (typeof cb === "string") { - cb = model[cb]; - } - - options = options || {}; - options.user = true; - var exps; - - if (BI._.isFunction(expOrFn)) { - var watcher = innerWatch(expOrFn, cb, options); - return function unwatchFn() { - watcher(); - }; - } - - if (!(exps = expOrFn.match(/[a-zA-Z0-9BI._.*]+|[|][|]|[&][&]|[(]|[)]/g)) || exps.length === 1 && !/\*/.test(expOrFn)) { - var paths = expOrFn.split("."); - var prePaths = paths.slice(0, paths.length - 1); - var preGetter = parsePath(prePaths.join(".")); - var v = preGetter.call(model, model); - var getter = parsePath(paths[paths.length - 1]); - - var _watcher = innerWatch(function () { - return watchExp(v, getter); - }, cb, options); - - return function unwatchFn() { - _watcher(); - }; - } - - var watchers = []; - var fns = exps.slice(); - var complete = false, - running = false; - - var callback = function callback(index, newValue, oldValue, attrs) { - if (complete === true) { - return; - } - - fns[index] = true; - - if (runBinaryFunction(fns)) { - complete = true; - cb(newValue, oldValue, attrs); - } - - if (options && options.sync) { - complete = false; - running = false; - fns = exps.slice(); - } else { - if (!running) { - running = true; - nextTick(function () { - complete = false; - running = false; - fns = exps.slice(); - }); - } - } - }; - - BI._.each(exps, function (exp, i) { - if (BI._.has(operators, exp)) { - return; - } - - if (exp.indexOf("*") >= 0) { - // eslint-disable-next-line no-inner-declarations - var travers = function travers(root, deps, parent, key, res) { - if (deps.length === _paths.length) { - root !== undefined && res.push({ - parent: parent, - k: key - }); - return; - } - - if (root) { - if (_paths[deps.length] === "*") { - // 遍历所有节点 - for (var k in root) { - travers(root[k], deps.concat([k]), root, k, res); - } - } else { - var nextKey = _paths[deps.length]; - travers(root[nextKey], deps.concat([nextKey]), root, nextKey, res); - } - } - }; - - //a.**形式 - if (/^[1-9a-zA-Z.]+\*\*$/.test(exp) || exp === "**") { - exp = exp.replace(".**", ""); - - var _paths2 = exp.split("."); - - var _prePaths2 = _paths2.slice(0, _paths2.length - 1); - - var _preGetter = parsePath(_prePaths2.join(".")); - - var _v2 = _preGetter.call(model, model); - - var _getter = exp === "**" ? function (m) { - return m; - } : parsePath(_paths2[_paths2.length - 1]); - - watchers.push(innerWatch(function () { - return watchExp(_v2, _getter); - }, function (newValue, oldValue) { - // a.** 在a变化的时候不会触发change - if (!BI._.isArray(newValue) && oldValue !== newValue) { - return; - } - - callback(i, NaN, NaN, BI._.extend({ - index: i - })); - }, BI._.extend({ - deep: true - }, options))); - return; - } - - if (/^(\*\*\.)+[1-9a-zA-Z]+(\.\*\*$)/.test(exp)) { - throw new Error("not support"); - } //含有*的情况,如a.*,如*.a,*.*.a,a.*.a - //先获取到能获取到的对象 - - - var _paths = exp.split("."); - - var _prePaths = []; - - for (var _i = 0, len = _paths.length; _i < len; _i++) { - if (_paths[_i] === "*") { - break; - } - - _prePaths[_i] = _paths[_i]; - } - - var _v; - - if (_prePaths.length > 0) { - var _getter2 = parsePath(_prePaths.join(".")); - - _v = _getter2.call(model, model); - } else { - _v = model; - } - - _paths = _paths.slice(_prePaths.length); - var changes = []; - watchers.push(innerWatch(function () { - var routes = []; - travers(_v, [], _v, null, routes); - - for (var _i2 = 0, _len = routes.length; _i2 < _len; _i2++) { - var _routes$_i = routes[_i2], - parent = _routes$_i.parent, - k = _routes$_i.k; - - for (var j = 0, l = changes.length; j < l; j++) { - var _changes$j = changes[j], - target = _changes$j.target, - key = _changes$j.key; - - if (target === toRaw(parent) && key === k) { - return true; - } - } - } - }, function (newValue) { - changes = []; - - if (newValue === true) { - callback(i, NaN, NaN, BI._.extend({ - index: i - })); - } - }, BI._.extend({}, options, { - deep: true, - onTrigger: function onTrigger(_ref) { - var target = _ref.target, - key = _ref.key; - changes.push({ - target: target, - key: key - }); - } - }))); - return; - } - - var getter = parsePath(exp); - watchers.push(innerWatch(function () { - return watchExp(model, getter); - }, function (newValue, oldValue) { - callback(i, newValue, oldValue, BI._.extend({ - index: i - })); - }, options)); - }); - - return watchers; - } - - var REACTIVE = true; - - function initState(vm, state) { - if (state) { - vm.$$state = REACTIVE ? reactive(state) : state; - } - } - - function initComputed(vm, c) { - var $$computed = vm.$$computed = {}; - - for (var key in c) { - $$computed[key] = computed(BI._.bind(c[key], vm)); - } - } - - function initWatch(vm, watch) { - vm._watchers || (vm._watchers = []); - - for (var key in watch) { - var handler = watch[key]; - - if (BI._.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - vm._watchers.push(createWatcher(vm, key, handler[i])); - } - } else { - vm._watchers.push(createWatcher(vm, key, handler)); - } - } - } - - function createWatcher(vm, keyOrFn, cb, options) { - if (isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - - if (typeof cb === "string") { - cb = vm[cb]; - } - - return watch(vm.model, keyOrFn, BI._.bind(cb, vm), options); - } - - function initMethods(vm, methods) { - for (var key in methods) { - vm[key] = methods[key] == null ? noop : BI._.bind(methods[key], vm); - } - } - - function initMixins(vm, mixins) { - mixins = (mixins || []).slice(0); - - BI._.each(mixins.reverse(), function (mixinType) { - var mixin = getMixins(mixinType); - - for (var key in mixin) { - if (typeof mixin[key] !== "function") continue; - if (BI._.has(vm, key)) continue; - vm[key] = BI._.bind(mixin[key], vm); - } - }); - } - - function defineProps(vm) { - vm.model = new Proxy({}, { - get: function get(target, key) { - if (vm.$$computed && key in vm.$$computed) { - try { - return vm.$$computed[key].value; - } catch (e) {// 吞掉异常 - } - - return; - } - - if (vm.$$state && key in vm.$$state) { - return vm.$$state[key]; - } - - var p = vm._parent; - - while (p) { - if (p.$$context && key in p.$$context) { - return p.$$context[key]; - } - - p = p._parent; - } - }, - set: function set(target, key, value) { - if (vm.$$state && key in vm.$$state) { - vm.$$state[key] = value; - return true; - } - - var p = vm._parent; - - while (p) { - if (p.$$context && key in p.$$context) { - p.$$context[key] = value; - return true; - } - - p = p._parent; - } - - return true; - } - }); - } - - function defineContext(vm, keys) { - var props = {}; - - var _loop = function _loop(i, len) { - var key = keys[i]; - props[key] = { - enumerable: true, - configurable: true, - get: function get() { - return vm.model[key]; - }, - set: function set(val) { - return vm.model[key] = val; - } - }; - }; - - for (var i = 0, len = keys.length; i < len; i++) { - _loop(i); - } - - vm.$$context = Object.defineProperties({}, props); - } - - function getInjectValue(vm, key) { - var p = vm._parent; - - while (p) { - if (p.$$context && key in p.$$context) { - return p.$$context[key]; - } - - p = p._parent; - } - } - - function getInjectValues(vm) { - var inject = vm.inject || []; - var result = {}; - - BI._.each(inject, function (key) { - result[key] = getInjectValue(vm, key); - }); - - return result; - } - - var Model = /*#__PURE__*/function () { - function Model() { - _classCallCheck(this, Model); - } - - _createClass(Model, [{ - key: "_constructor", - value: function _constructor(options, destroyHandler) { - this.options = options || {}; - this._parent = Model.target; - var state = BI._.isFunction(this.state) ? this.state() : this.state; - var computed = this.computed; - var context = this.context; - var inject = this.inject; - var childContext = this.childContext; - var watch = this.watch; - var actions = this.actions; - - BI._.keys(state).concat(BI._.keys(computed)).concat(inject || []).concat(context || []); - - var mixins = this.mixins; - defineProps(this); - childContext && defineContext(this, childContext); - initMixins(this, mixins); - this.init(); - initState(this, BI._.extend(getInjectValues(this), state)); - initComputed(this, computed); - REACTIVE && initWatch(this, watch); - initMethods(this, actions); - this.created && this.created(); - this._destroyHandler = destroyHandler; - } - }, { - key: "_init", - value: function _init() {} - }, { - key: "init", - value: function init() { - this._init(); - } - }, { - key: "destroy", - value: function destroy() { - BI._.each(this._watchers, function (unwatches) { - unwatches = BI._.isArray(unwatches) ? unwatches : [unwatches]; - - BI._.each(unwatches, function (unwatch) { - unwatch(); - }); - }); - - this._watchers && (this._watchers = []); - this.destroyed && this.destroyed(); - this.$$computed = null; - this.$$state = null; - this._destroyHandler && this._destroyHandler(); - } - }]); - - return Model; - }(); - function set(target, key, val) { - if (BI._.isArray(target)) { - target.length = Math.max(target.length, key); - target.splice(key, 1, val); - return val; - } - - target[key] = val; - return target; - } - function freeze(value) { - Object.defineProperty(value, '__v_skip', { - configurable: true, - enumerable: false, - value: value - }); - return value; - } - function del(target, key) { - if (BI._.isArray(target)) { - target.splice(key, 1); - return; - } - - if (!BI._.has(target, key)) { - return; - } - - delete target[key]; - } - function define(model) { - return REACTIVE ? reactive(model) : model; - } - function config(options) { - options || (options = {}); - - if ("reactive" in options) { - REACTIVE = options.reactive; - } - } - - function toJSON(model) { - var result; - - if (BI._.isArray(model)) { - result = []; - - for (var i = 0, len = model.length; i < len; i++) { - result[i] = toJSON(model[i]); - } - } else if (model && isPlainObject(model)) { - result = {}; - - for (var key in model) { - result[key] = toJSON(model[key]); - } - } else { - result = model; - } - - return result; - } - - var version = "3.0"; - - exports.Model = Model; - exports.config = config; - exports.define = define; - exports.del = del; - exports.freeze = freeze; - exports.mixin = mixin; - exports.set = set; - exports.toJSON = toJSON; - exports.version = version; - exports.watch = watch; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); diff --git a/dist/fix/worker.compact.js b/dist/fix/worker.compact.js deleted file mode 100644 index e537706ad..000000000 --- a/dist/fix/worker.compact.js +++ /dev/null @@ -1,123 +0,0 @@ -;(function () { - var contexts = {}; - var init = false; - - var WORKER; - - var enableWorker = function () { - if (init) { - return init; - } - // 开启Worker模式 - BI.config("bi.provider.system", function (provider) { - provider.setWorkerMode(true); - }); - var _init = BI.Widget.prototype._init; - BI.Widget.prototype._init = function () { - this.$destroyWorker = createWorker.call(this); - try { - _init.apply(this, arguments); - } catch (e) { - console.error(e); - } - }; - - var _initRender = BI.Widget.prototype._initRender; - var postMessage = function (data) { - switch (data.eventType) { - case "create": - this.model = data.msg; - _initRender.call(this); - break; - case "watch": - var watchArgs = data.args; - this.watch[data.currentWatchType].apply(this, watchArgs); - break; - } - }; - BI.Widget.prototype._initRender = function () { - if (WORKER && this._worker) { - this.__asking = true; - this.__async = true; - } else { - _initRender.apply(this, arguments); - } - }; - - var unMount = BI.Widget.prototype.__d; - BI.Widget.prototype.__d = function () { - this.$destroyWorker && this.$destroyWorker(); - try { - unMount.apply(this, arguments); - } catch (e) { - console.error(e); - } - }; - init = postMessage; - return postMessage; - }; - - BI.useWorker = function (wk) { - if (!_global.Worker || !_global.Proxy) { - return; - } - var postMessage = enableWorker(); - WORKER = wk; - if (WORKER) { - WORKER.addEventListener("message", function (e) { - var data = e.data; - postMessage.apply(contexts[data.name], [data]); - }, false); - } - }; - - function createWorker () { - var self = this; - if (this._worker) { - var name = this.getName(); - var modelType = this._worker(); - var options; - if (BI.isArray(modelType)) { - options = modelType[1]; - modelType = modelType[0]; - } - if (WORKER) { - contexts[name] = this; - WORKER.postMessage({ - type: modelType, - name: name, - eventType: "create", - options: options, - watches: BI.map(this.$watch || this.watch, function (key) { - return key; - }) - }); - var store = {}; - this.store = new Proxy(store, { - get: function (target, key) { - return function () { - WORKER.postMessage({ - type: modelType, - name: name, - eventType: "action", - action: key, - args: [].slice.call(arguments) - }); - }; - }, - set: function (target, key, value) { - return Reflect.set(target, key, value); - } - }); - return function () { - delete contexts[name]; - WORKER.postMessage({ - type: modelType, - name: name, - eventType: "destroy" - }); - }; - } - } - } -}()); diff --git a/examples/ThemeProvider.html b/examples/ThemeProvider.html deleted file mode 100644 index 7848ee406..000000000 --- a/examples/ThemeProvider.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - -
- - - diff --git a/examples/config-render.html b/examples/config-render.html deleted file mode 100644 index 41545d3b4..000000000 --- a/examples/config-render.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/demo.worker.js b/examples/demo.worker.js deleted file mode 100644 index dae3c723a..000000000 --- a/examples/demo.worker.js +++ /dev/null @@ -1,29 +0,0 @@ -if (this.importScripts) { - importScripts("https://fanruan.design/fineui/fineui_without_jquery_polyfill.js"); - BI.useInWorker(); -} -var Model = BI.inherit(Fix.Model, { - state: function () { - return { - count: 0 - }; - }, - - computed: { - name: function () { - return this.getText(this.model.count); - } - }, - - actions: { - addCount: function () { - this.model.count += 1; - } - }, - - getText (count) { - return "被点击了" + count + "次"; - } -}); - -BI.model("demo.model", Model); diff --git a/examples/dev.html b/examples/dev.html deleted file mode 100644 index 167c18ac5..000000000 --- a/examples/dev.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/effect.html b/examples/effect.html deleted file mode 100644 index 34bae9199..000000000 --- a/examples/effect.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/hooks.html b/examples/hooks.html deleted file mode 100644 index c9302a0d5..000000000 --- a/examples/hooks.html +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/loader-context.html b/examples/loader-context.html deleted file mode 100644 index a8ba36a96..000000000 --- a/examples/loader-context.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/resize.html b/examples/resize.html deleted file mode 100644 index dda9edda3..000000000 --- a/examples/resize.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/style.html b/examples/style.html deleted file mode 100644 index 339f14365..000000000 --- a/examples/style.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/tab-context.html b/examples/tab-context.html deleted file mode 100644 index 6a0a2d130..000000000 --- a/examples/tab-context.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/test-id.html b/examples/test-id.html deleted file mode 100644 index 7eec9e549..000000000 --- a/examples/test-id.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - -
- - - - diff --git a/examples/useContext.html b/examples/useContext.html deleted file mode 100644 index 4092713e9..000000000 --- a/examples/useContext.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - - - - - -
- - - diff --git a/examples/virtual-group.html b/examples/virtual-group.html deleted file mode 100644 index a21a37fe6..000000000 --- a/examples/virtual-group.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/visible.html b/examples/visible.html deleted file mode 100644 index 790d091c1..000000000 --- a/examples/visible.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - - - - -
- - - diff --git a/examples/watch-order.html b/examples/watch-order.html new file mode 100644 index 000000000..7f85acdd6 --- /dev/null +++ b/examples/watch-order.html @@ -0,0 +1,142 @@ + + + + + + + + + +
+ + + diff --git a/examples/worker.html b/examples/worker.html deleted file mode 100644 index 759f0eac4..000000000 --- a/examples/worker.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - -
- - - diff --git a/examples/worker_new.html b/examples/worker_new.html deleted file mode 100644 index 53e83c4ee..000000000 --- a/examples/worker_new.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Document - - - - -
- - - \ No newline at end of file diff --git a/examples/worker_new/index.js b/examples/worker_new/index.js deleted file mode 100644 index b95fbbad6..000000000 --- a/examples/worker_new/index.js +++ /dev/null @@ -1,105 +0,0 @@ -document.cookie = "test=demo"; - -// worker获取主线程资源 -var CookieAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() { - this.controller.addActionHandler("Cookie", this.getCookie.bind(this)); - }, - - getCookie: function() { - return document.cookie; - } -}); - -// 调用worker计算 -var FibonacciAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() {}, - - getResult: function(times) { - return this.controller.requestPromise("Fibonacci", { times: times }) - .then(function(v) { - console.log(v); - }); - } -}); - -// 主线程与worker多次交互 -const HeartBeatCheckAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() { - this.controller.addActionHandler("HeartBeatChecked", this.recieveHeartBeatChecked.bind(this)); - }, - - recieveHeartBeatChecked: function (payload) { - console.log("heartbeat: " + payload.time); - }, - - startHeatBeatCheck: function() { - return this.controller.request("HeartBeatCheckStart"); - }, - - stopHeatBeatCheck: function() { - return this.controller.request("HeartBeatCheckStop"); - } -}); - -var MainThreadWorker = BI.inherit(BI.Workers.MainThreadWorker, { - initActions: function() { - this.cookieAction = this.createAction(CookieAction); - - this.fibonacciAction = this.createAction(FibonacciAction); - - this.heartBeatCheckAction = this.createAction(HeartBeatCheckAction); - }, - - calculateFibonacci: function(times) { - this.fibonacciAction.getResult(times); - }, - - startHeatBeatCheck: function() { - this.heartBeatCheckAction.startHeatBeatCheck(); - }, - - stopHeatBeatCheck: function() { - this.heartBeatCheckAction.stopHeatBeatCheck(); - } -}); - -var mainThreadWorker = BI.Workers.createWorker(MainThreadWorker, { - workerUrl: "./worker_new/worker.js", - workerName: "demo" -}); - -BI.createWidget({ - type: "bi.vertical", - element: "#wrapper", - vgap: 10, - hgap: 10, - items: [ - { - type: "bi.button", - text: "点击计算斐波那契数列第40项", - width: 200, - handler: function() { - console.log("click"); - - mainThreadWorker.calculateFibonacci(40); - } - }, - { - type: "bi.button", - text: "开始心跳", - width: 200, - handler: function() { - mainThreadWorker.startHeatBeatCheck(); - } - }, - { - type: "bi.button", - text: "停止心跳", - width: 200, - handler: function() { - mainThreadWorker.stopHeatBeatCheck(); - } - } - ] -}); diff --git a/examples/worker_new/worker.js b/examples/worker_new/worker.js deleted file mode 100644 index 96e88e542..000000000 --- a/examples/worker_new/worker.js +++ /dev/null @@ -1,80 +0,0 @@ -self.importScripts("https://fanruan.design/fineui/fineui_without_jquery_polyfill.js"); - -var CookieAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() {}, - - getCookie: function() { - return this.controller.requestPromise("Cookie"); - } -}); - -function fibonacci(n) { - if (n === 1 || n === 2) { - return 1; - } - - return fibonacci(n - 2) + fibonacci(n - 1); -} - -var FibonacciAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() { - this.controller.addActionHandler("Fibonacci", this.getResult.bind(this)); - }, - - getResult: function(payload) { - return fibonacci(payload.times); - } -}); - -const HeartBeatCheckAction = BI.inherit(BI.Workers.WorkerBaseAction, { - addActionHandler: function() { - this.controller.addActionHandler("HeartBeatCheckStart", this.startHeatBeatCheck.bind(this)); - this.controller.addActionHandler("HeartBeatCheckStop", this.stopHeatBeatCheck.bind(this)); - }, - - startHeatBeatCheck: function() { - var self = this; - - if (!this.timer) { - console.log("heart beat check started"); - - this.timer = setInterval(function() { - // 模拟请求 - setTimeout(function() { - self.controller.request("HeartBeatChecked", { - time: new Date() - }); - }, 50); - }, 5 * 1000); - } else { - console.log("heart beat has already started!"); - } - }, - - stopHeatBeatCheck: function() { - console.log("heart beat check stopped"); - - clearInterval(this.timer); - } -}); - -var MainThreadWorker = BI.inherit(BI.Workers.WorkerThreadWorker, { - initActions: function() { - this.cookieAction = this.createAction(CookieAction); - - this.fibonacciAction = this.createAction(FibonacciAction); - - this.heartBeatCheckAction = this.createAction(HeartBeatCheckAction); - }, - - fetchCookie: function() { - return this.cookieAction.getCookie() - .then(function (v) { - console.log(v); - }); - } -}); - -var workerThreadWorker = BI.Workers.createWorker(MainThreadWorker); - -workerThreadWorker.fetchCookie(); diff --git a/examples/响应式布局.html b/examples/响应式布局.html deleted file mode 100644 index 72a71951f..000000000 --- a/examples/响应式布局.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - PullRequest | Code Review as a Service - - - - - - - - - -
- - - diff --git a/examples/插件设计.html b/examples/插件设计.html deleted file mode 100644 index 91c2b29c8..000000000 --- a/examples/插件设计.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - -
- - - - diff --git a/examples/替换loading动画.html b/examples/替换loading动画.html deleted file mode 100644 index 9ae3707d4..000000000 --- a/examples/替换loading动画.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - Document - - - - - - -
- - - - \ No newline at end of file diff --git a/i18n/i18n.cn.js b/i18n/i18n.cn.js deleted file mode 100644 index 900ff7630..000000000 --- a/i18n/i18n.cn.js +++ /dev/null @@ -1,204 +0,0 @@ -BI.i18n = { - "BI-Multi_Date_Quarter_End": "季度末", - "BI-Multi_Date_Month_Begin": "月初", - "BI-Multi_Date_YMD": "年月日", - "BI-Custom_Color": "自定义颜色", - "BI-Numerical_Interval_Input_Data": "请输入数值", - "BI-Please_Input_Natural_Number": "请输入非负整数", - "BI-No_More_Data": "无更多数据", - "BI-Basic_Altogether": "共", - "BI-Basic_Sunday": "星期日", - "BI-Widget_Background_Colour": "组件背景", - "BI-Color_Picker_Error_Text": "请输入0-255的正整数", - "BI-Multi_Date_Month": "月", - "BI-No_Selected_Item": "没有可选项", - "BI-Multi_Date_Year_Begin": "年初", - "BI-Quarter_1": "第1季度", - "BI-Quarter_2": "第2季度", - "BI-Quarter_3": "第3季度", - "BI-Quarter_4": "第4季度", - "BI-Multi_Date_Year_Next": "年后", - "BI-Multi_Date_Month_Prev": "个月前", - "BI-Month_Trigger_Error_Text": "请输入1~12的正整数", - "BI-Less_And_Equal": "小于等于", - "BI-Year_Trigger_Invalid_Text": "请输入有效时间", - "BI-Multi_Date_Week_Next": "周后", - "BI-Font_Size": "字号", - "BI-Basic_Total": "共", - "BI-Already_Selected": "已选择", - "BI-Formula_Insert": "插入", - "BI-Select_All": "全选", - "BI-Basic_Tuesday": "星期二", - "BI-Multi_Date_Month_End": "月末", - "BI-Load_More": "点击加载更多数据", - "BI-Basic_September": "九月", - "BI-Current_Is_Last_Page": "当前已是最后一页", - "BI-Basic_Auto": "自动", - "BI-Basic_Count": "个", - "BI-Basic_Value": "值", - "BI-Basic_Unrestricted": "无限制", - "BI-Quarter_Trigger_Error_Text": "请输入1~4的正整数", - "BI-Basic_More": "更多", - "BI-Basic_Wednesday": "星期三", - "BI-Basic_Bold": "加粗", - "BI-Basic_Simple_Saturday": "六", - "BI-Multi_Date_Month_Next": "个月后", - "BI-Basic_March": "三月", - "BI-Current_Is_First_Page": "当前已是第一页", - "BI-Basic_Thursday": "星期四", - "BI-Basic_Prompt": "提示", - "BI-Multi_Date_Today": "今天", - "BI-Multi_Date_Quarter_Prev": "个季度前", - "BI-Row_Header": "行表头", - "BI-Date_Trigger_Error_Text": "日期格式示例:2015-3-11", - "BI-Basic_Cancel": "取消", - "BI-Basic_January": "一月", - "BI-Basic_June": "六月", - "BI-Basic_July": "七月", - "BI-Basic_April": "四月", - "BI-Multi_Date_Quarter_Begin": "季度初", - "BI-Multi_Date_Week": "周", - "BI-Click_Blank_To_Select": "点击\"空格键\"选中完全匹配项", - "BI-Basic_August": "八月", - "BI-Word_Align_Left": "文字居左", - "BI-Basic_November": "十一月", - "BI-Font_Colour": "字体颜色", - "BI-Multi_Date_Day_Prev": "天前", - "BI-Select_Part": "部分选择", - "BI-Multi_Date_Day_Next": "天后", - "BI-Less_Than": "小于", - "BI-Basic_February": "二月", - "BI-Multi_Date_Year": "年", - "BI-Number_Index": "序号", - "BI-Multi_Date_Week_Prev": "周前", - "BI-Next_Page": "下一页", - "BI-Right_Page": "向右翻页", - "BI-Numerical_Interval_Signal_Value": "前后值相等,请将操作符改为“≤”", - "BI-Basic_December": "十二月", - "BI-Basic_Saturday": "星期六", - "BI-Basic_Simple_Wednesday": "三", - "BI-Multi_Date_Quarter_Next": "个季度后", - "BI-Basic_October": "十月", - "BI-Basic_Simple_Friday": "五", - "BI-Basic_Save": "保存", - "BI-Numerical_Interval_Number_Value": "请保证前面的数值小于/等于后面的数值", - "BI-Previous_Page": "上一页", - "BI-No_Select": "搜索结果为空", - "BI-Basic_Clears": "清空", - "BI-Created_By_Me": "我创建的", - "BI-Basic_Simple_Tuesday": "二", - "BI-Word_Align_Right": "文字居右", - "BI-Summary_Values": "汇总", - "BI-Basic_Clear": "清除", - "BI-Upload_File_Size_Error": "文件大小不支持", - "BI-Upload_File_Count_Error": "超出上传数量上限{R1},请重新上传", - "BI-Up_Page": "向上翻页", - "BI-Basic_Simple_Sunday": "日", - "BI-Multi_Date_Relative_Current_Time": "相对当前时间", - "BI-Selected_Data": "已选数据:", - "BI-Multi_Date_Quarter": "季度", - "BI-Check_Selected": "查看已选", - "BI-Basic_Search": "搜索", - "BI-Basic_May": "五月", - "BI-Continue_Select": "继续选择", - "BI-Please_Input_Positive_Integer": "请输入正整数", - "BI-Upload_File_Type_Error": "文件类型不支持", - "BI-Upload_File_Error": "文件上传失败", - "BI-Basic_Friday": "星期五", - "BI-Down_Page": "向下翻页", - "BI-Basic_Monday": "星期一", - "BI-Left_Page": "向左翻页", - "BI-Transparent_Color": "透明", - "BI-Basic_Simple_Monday": "一", - "BI-Multi_Date_Year_End": "年末", - "BI-Time_Interval_Error_Text": "请保证开始时间早于/等于结束时间", - "BI-Basic_Time": "时间", - "BI-Basic_OK": "确定", - "BI-Basic_Sure": "确定", - "BI-Basic_Simple_Thursday": "四", - "BI-Multi_Date_Year_Prev": "年前", - "BI-Tiao_Data": "条数据", - "BI-Basic_Italic": "斜体", - "BI-Basic_Dynamic_Title": "动态时间", - "BI-Basic_Year": "年", - "BI-Basic_Single_Quarter": "季", - "BI-Basic_Month": "月", - "BI-Basic_Week": "周", - "BI-Basic_Day": "天", - "BI-Basic_Work_Day": "工作日", - "BI-Basic_Front": "前", - "BI-Basic_Behind": "后", - "BI-Basic_Empty": "空", - "BI-Basic_Month_End": "月末", - "BI-Basic_Month_Begin": "月初", - "BI-Basic_Year_End": "年末", - "BI-Basic_Year_Begin": "年初", - "BI-Basic_Quarter_End": "季末", - "BI-Basic_Quarter_Begin": "季初", - "BI-Basic_Week_End": "周末", - "BI-Basic_Week_Begin": "周初", - "BI-Basic_Current_Day": "当天", - "BI-Basic_Begin_Start": "初", - "BI-Basic_End_Stop": "末", - "BI-Basic_Current_Year": "今年", - "BI-Basic_Year_Fen": "年份", - "BI-Basic_Current_Month": "本月", - "BI-Basic_Current_Quarter": "本季度", - "BI-Basic_Year_Month": "年月", - "BI-Basic_Year_Quarter": "年季度", - "BI-Basic_Input_Can_Not_Null": "输入框不能为空", - "BI-Basic_Date_Time_Error_Text": "日期格式示例:2015-3-11 00:00:00", - "BI-Basic_Input_From_To_Number": "请输入{R1}的数值", - "BI-Basic_Or": "或", - "BI-Basic_And": "且", - "BI-Conf_Add_Formula": "添加公式", - "BI-Conf_Add_Condition": "添加条件", - "BI-Conf_Formula_And": "且公式条件", - "BI-Conf_Formula_Or": "或公式条件", - "BI-Conf_Condition_And": "且条件", - "BI-Conf_Condition_Or": "或条件", - "BI-Microsoft_YaHei": "微软雅黑", - "BI-Apple_Light": "苹方-light", - "BI-Font_Family": "字体", - "BI-Basic_Please_Input_Content": "请输入内容", - "BI-Word_Align_Center": "文字居中", - "BI-Basic_Please_Enter_Number_Between": "请输入{R1}-{R2}的值", - "BI-More_Than": "大于", - "BI-More_And_Equal": "大于等于", - "BI-Please_Enter_SQL": "请输入SQL", - "BI-Basic_Click_To_Add_Text": "+点击新增\"{R1}\"", - "BI-Basic_Press_Enter_To_Add_Text": "点按回车键添加\"{R1}\"", - "BI-Basic_Please_Select": "请选择", - "BI-Basic_Font_Color": "文字颜色", - "BI-Basic_Background_Color": "背景色", - "BI-Basic_Underline": "下划线", - "BI-Basic_Param_Month": "{R1}月", - "BI-Basic_Param_Day": "{R1}日", - "BI-Basic_Param_Quarter": "{R1}季度", - "BI-Basic_Param_Week_Count": "第{R1}周", - "BI-Basic_Param_Hour": "{R1}时", - "BI-Basic_Param_Minute": "{R1}分", - "BI-Basic_Param_Second": "{R1}秒", - "BI-Basic_Param_Year": "{R1}年", - "BI-Basic_Date_Day": "日", - "BI-Basic_Hour_Sin": "时", - "BI-Basic_Seconds": "秒", - "BI-Basic_Minute": "分", - "BI-Basic_Thousand": "千", - "BI-Basic_Wan": "万", - "BI-Basic_Million": "百万", - "BI-Basic_Billion": "亿", - "BI-Basic_Quarter": "季度", - "BI-Basic_No_Select": "不选", - "BI-Basic_Now": "此刻", - "BI-Color_Picker_Error_Text_Hex": "请输入6位16进制颜色编号", - "BI-Basic_Date_Range_Error": "请选择{R1}年{R2}月{R3}日-{R4}年{R5}月{R6}日的日期", - "BI-Basic_Year_Range_Error": "请选择{R1}年-{R2}年的日期", - "BI-Basic_Year_Month_Range_Error": "请选择{R1}年{R2}月-{R3}年{R4}月的日期", - "BI-Basic_Year_Quarter_Range_Error": "请选择{R1}年{R2}季度-{R3}年{R4}季度的日期", - "BI-Basic_Search_And_Patch_Paste": "搜索,支持批量粘贴、粘贴值通过换行识别", - "BI-Basic_Recommend_Color": "推荐色", - "BI-Basic_Too_Much_Value_Get_Two_Thousand": "粘贴的值过多,只能识别出前2000个值", - "BI-Basic_Simple_Open": "开", - "BI-Basic_Simple_Close": "关", -}; \ No newline at end of file diff --git a/i18n/i18n.en.js b/i18n/i18n.en.js deleted file mode 100644 index 39e7a7758..000000000 --- a/i18n/i18n.en.js +++ /dev/null @@ -1,122 +0,0 @@ -BI.i18n = { - "BI-Multi_Date_Quarter_End": "", - "BI-Multi_Date_Month_Begin": "", - "BI-Multi_Date_YMD": "", - "BI-Custom_Color": "", - "BI-Numerical_Interval_Input_Data": "", - "BI-Please_Input_Natural_Number": "", - "BI-No_More_Data": "No More Data", - "BI-Basic_Altogether": "Altogether", - "BI-Basic_Sunday": "Sunday", - "BI-Widget_Background_Colour": "", - "BI-Color_Picker_Error_Text": "", - "BI-Multi_Date_Month": "", - "BI-No_Selected_Item": "", - "BI-Multi_Date_Year_Begin": "", - "BI-Quarter_1": "First Quarter", - "BI-Quarter_2": "Second Quarter", - "BI-Quarter_3": "Third Quarter", - "BI-Quarter_4": "Fourth Quarter", - "BI-Multi_Date_Year_Next": "", - "BI-Multi_Date_Month_Prev": "", - "BI-Month_Trigger_Error_Text": "", - "BI-Less_And_Equal": "", - "BI-Year_Trigger_Invalid_Text": "", - "BI-Multi_Date_Week_Next": "", - "BI-Font_Size": "", - "BI-Basic_Total": "Total", - "BI-Already_Selected": "Already Selected items", - "BI-Formula_Insert": "", - "BI-Select_All": "Select All", - "BI-Basic_Tuesday": "Tuesday", - "BI-Multi_Date_Month_End": "", - "BI-Load_More": "Click to Load More", - "BI-Basic_September": "September", - "BI-Current_Is_Last_Page": "", - "BI-Basic_Auto": "Auto", - "BI-Basic_Count": "", - "BI-Basic_Value": "value", - "BI-Basic_Unrestricted": "unrestricted", - "BI-Quarter_Trigger_Error_Text": "", - "BI-Basic_More": "More", - "BI-Basic_Wednesday": "Wednesday", - "BI-Basic_Bold": "Bold", - "BI-Basic_Simple_Saturday": "Sat", - "BI-Multi_Date_Month_Next": "", - "BI-Basic_March": "March", - "BI-Current_Is_First_Page": "", - "BI-Basic_Thursday": "Thursday", - "BI-Basic_Prompt": "Prompt", - "BI-Multi_Date_Today": "Toady", - "BI-Multi_Date_Quarter_Prev": "", - "BI-Row_Header": "Row header", - "BI-Date_Trigger_Error_Text": "日期格式示例:2015-3-11", - "BI-Basic_Cancel": "Cancel", - "BI-Basic_January": "January", - "BI-Basic_June": "June", - "BI-Basic_July": "July", - "BI-Basic_April": "April", - "BI-Multi_Date_Quarter_Begin": "", - "BI-Multi_Date_Week": "Week", - "BI-Click_Blank_To_Select": "", - "BI-Basic_August": "August", - "BI-Word_Align_Left": "Align Left", - "BI-Basic_November": "November", - "BI-Font_Colour": "Font Color", - "BI-Multi_Date_Day_Prev": "", - "BI-Select_Part": "", - "BI-Multi_Date_Day_Next": "", - "BI-Less_Than": "Less Than", - "BI-Basic_February": "February", - "BI-Multi_Date_Year": "Year", - "BI-Number_Index": "Number", - "BI-Multi_Date_Week_Prev": "", - "BI-Next_Page": "Next", - "BI-Right_Page": "Right", - "BI-Numerical_Interval_Signal_Value": "", - "BI-Basic_December": "December", - "BI-Basic_Saturday": "Saturday", - "BI-Basic_Simple_Wednesday": "Wed", - "BI-Multi_Date_Quarter_Next": "", - "BI-Basic_October": "October", - "BI-Basic_Simple_Friday": "Fri", - "BI-Basic_Save": "Save", - "BI-Numerical_Interval_Number_Value": "", - "BI-Previous_Page": "Previous", - "BI-No_Select": "Blank", - "BI-Basic_Clears": "Clear", - "BI-Created_By_Me": "Created By Me", - "BI-Basic_Simple_Tuesday": "Tue", - "BI-Word_Align_Right": "Align Right", - "BI-Summary_Values": "Summary", - "BI-Basic_Clear": "Clear", - "BI-Upload_File_Size_Error": "", - "BI-Up_Page": "Up", - "BI-Basic_Simple_Sunday": "Sun", - "BI-Multi_Date_Relative_Current_Time": "", - "BI-Selected_Data": "Selected", - "BI-Multi_Date_Quarter": "Quarter", - "BI-Check_Selected": "", - "BI-Basic_Search": "Search", - "BI-Basic_May": "May", - "BI-Continue_Select": "Continue Select", - "BI-Please_Input_Positive_Integer": "Please Input Positive Integer", - "BI-Upload_File_Type_Error": "", - "BI-Upload_File_Error": "", - "BI-Basic_Friday": "Friday", - "BI-Down_Page": "Down", - "BI-Basic_Monday": "Monday", - "BI-Left_Page": "Left", - "BI-Transparent_Color": "Transparent", - "BI-Basic_Simple_Monday": "Mon", - "BI-Multi_Date_Year_End": "", - "BI-Time_Interval_Error_Text": "", - "BI-Basic_Time": "Time", - "BI-Basic_OK": "Ok", - "BI-Basic_Sure": "Sure", - "BI-Basic_Simple_Thursday": "Thu", - "BI-Multi_Date_Year_Prev": "", - "BI-Tiao_Data": "", - "BI-Basic_Italic": "Italic", - "BI-Color_Picker_Error_Text_Hex": "Please Input Correct Hex Value" -}; \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 03f734a32..000000000 --- a/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - Demo - - - - -
- - - diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 1152ccb6a..000000000 --- a/karma.conf.js +++ /dev/null @@ -1,143 +0,0 @@ -// Karma configuration -// Generated on Mon Nov 27 2017 11:16:26 GMT+0800 (中国标准时间) - -const os = require("os"); - -process.env.CHROME_BIN = require("puppeteer").executablePath(); - -module.exports = function (config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "", - - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha", "chai"], - - - // list of files / patterns to load in the browser - files: [ - "dist/fineui.min.css", - "src/core/**/*.js", - "src/data/**/*.js", - "src/third/**/*.js", - "src/base/**/*.js", - "src/case/**/*.js", - "src/widget/**/*.js", - "src/component/**/*.js", - "dist/fix/fix.js", - "dist/fix/fix.compact.js", - "src/**/*.test.js", - "test/**/*.js" - ], - - exclude: [ - "src/base/single/input/file.js", - "src/case/ztree/**/*.js", - "src/widget/multitree/**/*.js", - "src/widget/multiselecttree/**/*.js", - "src/component/treevaluechooser/*.js" - ], - - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - "src/core/1.base.js": "coverage", - "src/core/func/**/*.js": "coverage", - "src/base/**/!(*.test).js": "coverage", - "src/case/**/!(*.test).js": "coverage", - "src/widget/**/!(*.test).js": "coverage", - "src/component/**/!(*.test).js": "coverage" - }, - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["progress", "coverage"], - - browserDisconnectTolerance: 3, - browserDisconnectTimeout : 300000, - browserNoActivityTimeout : 300000, - - coverageReporter: { - // specify a common output directory - dir: "coverage/", - reporters: [ - // reporters not supporting the `file` property - { type: "html", subdir: "report-html" }, - { type: "json-summary", subdir: "report-json-summary" }, - { type: "cobertura", subdir: "report-cobertura"} - ] - }, - - - // web server port - port: 9878, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - customLaunchers: { - HeadlessChrome: { - base: "ChromeHeadless", - flags: [ - "--no-sandbox", - "--remote-debugging-port=9222", - "--enable-logging", - "--user-data-dir=./karma-chrome", - "--v=1", - "--disable-background-timer-throttling", - "--disable-renderer-backgrounding", - "--proxy-bypass-list=*", - "--disable-web-security", - "--disable-gpu", - "--no-sandbox", - ], - }, - }, - - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: [os.platform() === "win32" - && parseFloat(os.release() - .split(".") - .slice(0, 2) - .join(".")) <= 6.1 - ? "HeadlessChrome" : "ChromeHeadless"], - - retryLimit: 30, - - captureTimeout: 30000, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: Infinity, - - plugins: [ - "karma-mocha", - "karma-chai", - "karma-chrome-launcher", - "karma-coverage" - ] - }); -}; diff --git a/lib/postbuild/postbuild.js b/lib/postbuild/postbuild.js deleted file mode 100644 index 9e7e5301a..000000000 --- a/lib/postbuild/postbuild.js +++ /dev/null @@ -1,52 +0,0 @@ -const { resolve } = require("path"); -const { existsSync, mkdirSync, readFileSync, writeFileSync } = require("fs"); -const rimraf = require("rimraf"); -const concat = require("concat"); -const glob = require("glob"); -const { config } = require("../../webpack/attachments"); - -const dest = resolve(__dirname, '../../dist'); - -const $dest = resolve(dest, './2.0'); - -if (!existsSync($dest)) { - mkdirSync($dest); -} - -const deleteList = [ - "fineui_without_jquery_polyfill.css", - "font.js", - "font.js.map", - "resource.js", - "resource.js.map", - "2.0/fineui_without_normalize.js", - "2.0/fineui_without_normalize.js.map", - "2.0/fineui_without_normalize.min.js", - "2.0/fineui_without_normalize.min.js.map", - "fineui_without_normalize.min.js", - "fineui_without_normalize.min.js.map", -].concat(glob.sync("dist/**/*.css.map").map(name => name.replace("dist/", ""))); - -deleteList.forEach(filename => { - const sourcefile = resolve(dest, `./${filename}`); - - rimraf(sourcefile, () => { - console.log(`${sourcefile} deleted`); - }); -}); - -const fileList = ['demo.js', 'fineui.js', '2.0/fineui.js', 'core.js']; -fileList.forEach(filename => { - const sourcefile = resolve(dest, `./${filename}`); - - const paths = filename.split("/"); - - const name = paths[paths.length - 1]; - - const content = `${readFileSync(sourcefile, { encoding: 'utf8' })} -//# sourceMappingURL=./${name}.map`; - - writeFileSync(sourcefile, content); -}); - -concat(config, resolve(dest, "resource.js")); diff --git a/lib/postpublish/postpublish.js b/lib/postpublish/postpublish.js deleted file mode 100644 index 49b4ae7e6..000000000 --- a/lib/postpublish/postpublish.js +++ /dev/null @@ -1,15 +0,0 @@ -const { resolve } = require("path"); -const { execSync } = require("child_process"); -const { writeFileSync } = require("fs"); - -const packageJSON = require("../../package.json"); - -packageJSON.name = "fineui"; - -packageJSON.publishConfig.registry = 'https://registry.npmjs.org'; - -writeFileSync(resolve(__dirname, "../../package.json"), JSON.stringify(packageJSON, null, 2)); - -execSync('git add dist/'); -execSync('git add package.json'); -execSync(`git diff-index --quiet HEAD || git commit -am "auto upgrade version to ${packageJSON.version}"`); diff --git a/lib/prepublish/prepublish.js b/lib/prepublish/prepublish.js deleted file mode 100644 index 4f082ab6a..000000000 --- a/lib/prepublish/prepublish.js +++ /dev/null @@ -1,63 +0,0 @@ -const { resolve, join } = require("path"); -const { writeFileSync } = require("fs"); -const { spawnSync } = require('child_process'); -const { bundleWithoutNormalize } = require('../../webpack/attachments'); - -function pad2(n) {// always returns a string - return (n < 10 ? "0" : "") + n; -} - -const d = new Date(); - -const version = d.getFullYear() + - pad2(d.getMonth() + 1) + - pad2(d.getDate()) + - pad2(d.getHours()) + - pad2(d.getMinutes()) + - pad2(d.getSeconds()); - -const packageJSON = require("../../package.json"); - -const versionChars = packageJSON.version.split("."); - -versionChars[versionChars.length - 1] = version; - -packageJSON.version = versionChars.join("."); - -packageJSON.publishConfig.registry = 'https://npm.fineres.com/'; - -packageJSON.name = "@fui/core"; - -writeFileSync(resolve(__dirname, "../../package.json"), JSON.stringify(packageJSON, null, 2)); - -// 将less打包成fineui.less发布到npm以供用户定制主题 -const lessPath = join(process.cwd(), '/src/less'); - -function copyFiles(from, to) { - spawnSync('cp', ['-r', from, to]); -} - -function removeFiles(src) { - spawnSync('rm', ['-rf', src]); -} - -function finalizeCompile() { - let lessContent = ''; - - bundleWithoutNormalize.forEach(path => { - const relativePath = path.replace(/.*src\/less/, 'src/less').replace(/.*public\/less/, 'public/less'); - lessContent += `@import "../../${relativePath}";\n`; - }); - - writeFileSync( - join(lessPath, 'fineui.less'), - lessContent, - ); -} - -removeFiles(`${lessPath}/font`); -removeFiles(`${lessPath}/fineui.less`); - -finalizeCompile(); - -copyFiles(`${process.cwd()}/dist/font`, lessPath); diff --git a/package.json b/package.json index 650135d75..f6467bbae 100644 --- a/package.json +++ b/package.json @@ -1,91 +1,56 @@ { - "name": "fineui", - "version": "2.0.20230518101454", - "description": "fineui", - "main": "dist/fineui_without_conflict.min.js", - "types": "dist/lib/index.d.ts", - "bin": { - "fui-cli": "./bin/cli/cli.js" - }, - "devDependencies": { - "@babel/core": "^7.17.4", - "@fui/babel-preset-fineui": "3.0.1", - "@fui/eslint-plugin": "^1.0.19", - "@types/node": "15.6.1", - "@typescript-eslint/eslint-plugin": "2.33.0", - "@typescript-eslint/parser": "2.33.0", - "autoprefixer": "9.6.1", - "babel-loader": "8.0.6", - "chai": "4.2.0", - "concat": "1.0.3", - "core-js": "3.29.1", - "cross-env": "6.0.0", - "css-loader": "3.0.0", - "es6-promise": "4.2.8", - "eslint": "6.0.1", - "expose-loader": "0.7.5", - "express": "4.15.2", - "fork-ts-checker-webpack-plugin": "1.4.3", - "glob": "^7.2.0", - "html-webpack-plugin": "3.2.0", - "husky": "^3.1.0", - "karma": "3.1.4", - "karma-chai": "0.1.0", - "karma-chrome-launcher": "2.2.0", - "karma-coverage": "1.1.2", - "karma-mocha": "1.3.0", - "less": "3.11.2", - "less-loader": "5.0.0", - "mini-css-extract-plugin": "0.7.0", - "mocha": "5.2.0", - "npm-run-all": "4.1.5", - "open": "0.0.5", - "optimize-css-assets-webpack-plugin": "5.0.3", - "postcss-loader": "3.0.0", - "postcss-simple-vars": "5.0.2", - "rimraf": "3.0.2", - "script-loader": "0.7.2", - "source-map-loader": "0.2.4", - "style-loader": "0.23.1", - "terser-webpack-plugin": "4.2.3", - "typescript": "3.9.2", - "webpack": "4.35.2", - "webpack-cli": "3.3.5", - "webpack-dev-server": "3.7.2", - "webpack-merge": "4.2.1" - }, - "scripts": { - "webpack:dev": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js -p --progress --host 0.0.0.0 --config=webpack/webpack.dev.js --mode development", - "webpack:prod": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack -p --progress --config=webpack/webpack.prod.js --mode production && npm run biCss && npm run jsyCss", - "webpack:css": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack -p --progress --config=webpack/webpack.css.js --mode production", - "start": "node server.js", - "build": "npm run webpack:prod && tsc", - "postbuild": "node ./lib/postbuild/postbuild.js", - "test": "karma start", - "dev": "npm run webpack:dev", - "prepublishToPrivate": "npm run build && node ./lib/prepublish/prepublish.js", - "publishToPrivate": "npm publish", - "postpublishToPrivate": " node ./lib/postpublish/postpublish.js", - "biCss": "cross-env LESS_CONFIG_PATH=bi.lessconfig.json LESS_FILE_NAME=bi npm run webpack:css", - "jsyCss": "cross-env LESS_CONFIG_PATH=jsy.lessconfig.json LESS_FILE_NAME=jsy npm run webpack:css" - }, - "repository": { - "type": "git", - "url": "https://git.coding.net/fanruan/fineui.git" - }, - "keywords": [ - "ui", - "fineui", - "finebi" - ], - "publishConfig": { - "registry": "https://registry.npmjs.org" - }, - "author": "fanruan", - "license": "MIT", - "dependencies": { - "@types/yargs": "17.0.13", - "jquery": "3.6.3", - "yargs": "17.6.2" - } -} \ No newline at end of file + "name": "monorepo", + "version": "1.0.0", + "description": "", + "keywords": [], + "author": "", + "license": "ISC", + "engines": { + "node": ">=16.0.0", + "yarn": "please-use-pnpm", + "pnpm": ">=7.0.0" + }, + "scripts": { + "dev": "npm-run-all --parallel dev:*", + "dev:demo": "pnpm --dir packages/demo dev", + "dev:fineui": "pnpm --dir packages/fineui dev", + "build": "pnpm --dir packages/fineui build", + "build:demo": "pnpm --dir packages/demo build", + "tsc": "pnpm --dir packages/fineui tsc" + }, + "devDependencies": { + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/runtime": "^7.21.0", + "@fui/babel-preset-fineui": "^3.0.1", + "@fui/eslint-plugin": "^1.1.0", + "@types/node": "^18.15.11", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.2", + "babel-plugin-module-resolver": "^5.0.0", + "circular-dependency-plugin": "^5.2.2", + "css-loader": "^6.7.3", + "css-minimizer-webpack-plugin": "^5.0.0", + "eslint": "^8.43.0", + "fork-ts-checker-webpack-plugin": "^8.0.0", + "glob": "^9.3.4", + "html-webpack-plugin": "^5.5.0", + "less": "^4.1.3", + "less-loader": "^11.1.0", + "mini-css-extract-plugin": "^2.7.5", + "npm-run-all": "^4.1.5", + "postcss": "^8.4.21", + "postcss-loader": "^7.1.0", + "style-loader": "^3.3.1", + "terser-webpack-plugin": "^5.3.7", + "ts-node": "^10.9.1", + "typescript": "^4.9.5", + "webpack": "^5.75.0", + "webpack-bundle-analyzer": "^4.8.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1", + "webpack-merge": "^5.8.0" + } +} diff --git a/packages/demo/babel.config.js b/packages/demo/babel.config.js new file mode 100644 index 000000000..d01a496d7 --- /dev/null +++ b/packages/demo/babel.config.js @@ -0,0 +1 @@ +module.exports = require('@fui/babel-preset-fineui').configs.base; \ No newline at end of file diff --git a/packages/demo/i18n/i18n.cn.js b/packages/demo/i18n/i18n.cn.js new file mode 100644 index 000000000..879cf1c49 --- /dev/null +++ b/packages/demo/i18n/i18n.cn.js @@ -0,0 +1,205 @@ +window.BI = {}; +window.BI.i18n = { + 'BI-Multi_Date_Quarter_End': '季度末', + 'BI-Multi_Date_Month_Begin': '月初', + 'BI-Multi_Date_YMD': '年月日', + 'BI-Custom_Color': '自定义颜色', + 'BI-Numerical_Interval_Input_Data': '请输入数值', + 'BI-Please_Input_Natural_Number': '请输入非负整数', + 'BI-No_More_Data': '无更多数据', + 'BI-Basic_Altogether': '共', + 'BI-Basic_Sunday': '星期日', + 'BI-Widget_Background_Colour': '组件背景', + 'BI-Color_Picker_Error_Text': '请输入0-255的正整数', + 'BI-Multi_Date_Month': '月', + 'BI-No_Selected_Item': '没有可选项', + 'BI-Multi_Date_Year_Begin': '年初', + 'BI-Quarter_1': '第1季度', + 'BI-Quarter_2': '第2季度', + 'BI-Quarter_3': '第3季度', + 'BI-Quarter_4': '第4季度', + 'BI-Multi_Date_Year_Next': '年后', + 'BI-Multi_Date_Month_Prev': '个月前', + 'BI-Month_Trigger_Error_Text': '请输入1~12的正整数', + 'BI-Less_And_Equal': '小于等于', + 'BI-Year_Trigger_Invalid_Text': '请输入有效时间', + 'BI-Multi_Date_Week_Next': '周后', + 'BI-Font_Size': '字号', + 'BI-Basic_Total': '共', + 'BI-Already_Selected': '已选择', + 'BI-Formula_Insert': '插入', + 'BI-Select_All': '全选', + 'BI-Basic_Tuesday': '星期二', + 'BI-Multi_Date_Month_End': '月末', + 'BI-Load_More': '点击加载更多数据', + 'BI-Basic_September': '九月', + 'BI-Current_Is_Last_Page': '当前已是最后一页', + 'BI-Basic_Auto': '自动', + 'BI-Basic_Count': '个', + 'BI-Basic_Value': '值', + 'BI-Basic_Unrestricted': '无限制', + 'BI-Quarter_Trigger_Error_Text': '请输入1~4的正整数', + 'BI-Basic_More': '更多', + 'BI-Basic_Wednesday': '星期三', + 'BI-Basic_Bold': '加粗', + 'BI-Basic_Simple_Saturday': '六', + 'BI-Multi_Date_Month_Next': '个月后', + 'BI-Basic_March': '三月', + 'BI-Current_Is_First_Page': '当前已是第一页', + 'BI-Basic_Thursday': '星期四', + 'BI-Basic_Prompt': '提示', + 'BI-Multi_Date_Today': '今天', + 'BI-Multi_Date_Quarter_Prev': '个季度前', + 'BI-Row_Header': '行表头', + 'BI-Date_Trigger_Error_Text': '日期格式示例:2015-3-11', + 'BI-Basic_Cancel': '取消', + 'BI-Basic_January': '一月', + 'BI-Basic_June': '六月', + 'BI-Basic_July': '七月', + 'BI-Basic_April': '四月', + 'BI-Multi_Date_Quarter_Begin': '季度初', + 'BI-Multi_Date_Week': '周', + 'BI-Click_Blank_To_Select': '点击"空格键"选中完全匹配项', + 'BI-Basic_August': '八月', + 'BI-Word_Align_Left': '文字居左', + 'BI-Basic_November': '十一月', + 'BI-Font_Colour': '字体颜色', + 'BI-Multi_Date_Day_Prev': '天前', + 'BI-Select_Part': '部分选择', + 'BI-Multi_Date_Day_Next': '天后', + 'BI-Less_Than': '小于', + 'BI-Basic_February': '二月', + 'BI-Multi_Date_Year': '年', + 'BI-Number_Index': '序号', + 'BI-Multi_Date_Week_Prev': '周前', + 'BI-Next_Page': '下一页', + 'BI-Right_Page': '向右翻页', + 'BI-Numerical_Interval_Signal_Value': '前后值相等,请将操作符改为“≤”', + 'BI-Basic_December': '十二月', + 'BI-Basic_Saturday': '星期六', + 'BI-Basic_Simple_Wednesday': '三', + 'BI-Multi_Date_Quarter_Next': '个季度后', + 'BI-Basic_October': '十月', + 'BI-Basic_Simple_Friday': '五', + 'BI-Basic_Save': '保存', + 'BI-Numerical_Interval_Number_Value': '请保证前面的数值小于/等于后面的数值', + 'BI-Previous_Page': '上一页', + 'BI-No_Select': '搜索结果为空', + 'BI-Basic_Clears': '清空', + 'BI-Created_By_Me': '我创建的', + 'BI-Basic_Simple_Tuesday': '二', + 'BI-Word_Align_Right': '文字居右', + 'BI-Summary_Values': '汇总', + 'BI-Basic_Clear': '清除', + 'BI-Upload_File_Size_Error': '文件大小不支持', + 'BI-Upload_File_Count_Error': '超出上传数量上限{R1},请重新上传', + 'BI-Up_Page': '向上翻页', + 'BI-Basic_Simple_Sunday': '日', + 'BI-Multi_Date_Relative_Current_Time': '相对当前时间', + 'BI-Selected_Data': '已选数据:', + 'BI-Multi_Date_Quarter': '季度', + 'BI-Check_Selected': '查看已选', + 'BI-Basic_Search': '搜索', + 'BI-Basic_May': '五月', + 'BI-Continue_Select': '继续选择', + 'BI-Please_Input_Positive_Integer': '请输入正整数', + 'BI-Upload_File_Type_Error': '文件类型不支持', + 'BI-Upload_File_Error': '文件上传失败', + 'BI-Basic_Friday': '星期五', + 'BI-Down_Page': '向下翻页', + 'BI-Basic_Monday': '星期一', + 'BI-Left_Page': '向左翻页', + 'BI-Transparent_Color': '透明', + 'BI-Basic_Simple_Monday': '一', + 'BI-Multi_Date_Year_End': '年末', + 'BI-Time_Interval_Error_Text': '请保证开始时间早于/等于结束时间', + 'BI-Basic_Time': '时间', + 'BI-Basic_OK': '确定', + 'BI-Basic_Sure': '确定', + 'BI-Basic_Simple_Thursday': '四', + 'BI-Multi_Date_Year_Prev': '年前', + 'BI-Tiao_Data': '条数据', + 'BI-Basic_Italic': '斜体', + 'BI-Basic_Dynamic_Title': '动态时间', + 'BI-Basic_Year': '年', + 'BI-Basic_Single_Quarter': '季', + 'BI-Basic_Month': '月', + 'BI-Basic_Week': '周', + 'BI-Basic_Day': '天', + 'BI-Basic_Work_Day': '工作日', + 'BI-Basic_Front': '前', + 'BI-Basic_Behind': '后', + 'BI-Basic_Empty': '空', + 'BI-Basic_Month_End': '月末', + 'BI-Basic_Month_Begin': '月初', + 'BI-Basic_Year_End': '年末', + 'BI-Basic_Year_Begin': '年初', + 'BI-Basic_Quarter_End': '季末', + 'BI-Basic_Quarter_Begin': '季初', + 'BI-Basic_Week_End': '周末', + 'BI-Basic_Week_Begin': '周初', + 'BI-Basic_Current_Day': '当天', + 'BI-Basic_Begin_Start': '初', + 'BI-Basic_End_Stop': '末', + 'BI-Basic_Current_Year': '今年', + 'BI-Basic_Year_Fen': '年份', + 'BI-Basic_Current_Month': '本月', + 'BI-Basic_Current_Quarter': '本季度', + 'BI-Basic_Year_Month': '年月', + 'BI-Basic_Year_Quarter': '年季度', + 'BI-Basic_Input_Can_Not_Null': '输入框不能为空', + 'BI-Basic_Date_Time_Error_Text': '日期格式示例:2015-3-11 00:00:00', + 'BI-Basic_Input_From_To_Number': '请输入{R1}的数值', + 'BI-Basic_Or': '或', + 'BI-Basic_And': '且', + 'BI-Conf_Add_Formula': '添加公式', + 'BI-Conf_Add_Condition': '添加条件', + 'BI-Conf_Formula_And': '且公式条件', + 'BI-Conf_Formula_Or': '或公式条件', + 'BI-Conf_Condition_And': '且条件', + 'BI-Conf_Condition_Or': '或条件', + 'BI-Microsoft_YaHei': '微软雅黑', + 'BI-Apple_Light': '苹方-light', + 'BI-Font_Family': '字体', + 'BI-Basic_Please_Input_Content': '请输入内容', + 'BI-Word_Align_Center': '文字居中', + 'BI-Basic_Please_Enter_Number_Between': '请输入{R1}-{R2}的值', + 'BI-More_Than': '大于', + 'BI-More_And_Equal': '大于等于', + 'BI-Please_Enter_SQL': '请输入SQL', + 'BI-Basic_Click_To_Add_Text': '+点击新增"{R1}"', + 'BI-Basic_Press_Enter_To_Add_Text': '点按回车键添加"{R1}"', + 'BI-Basic_Please_Select': '请选择', + 'BI-Basic_Font_Color': '文字颜色', + 'BI-Basic_Background_Color': '背景色', + 'BI-Basic_Underline': '下划线', + 'BI-Basic_Param_Month': '{R1}月', + 'BI-Basic_Param_Day': '{R1}日', + 'BI-Basic_Param_Quarter': '{R1}季度', + 'BI-Basic_Param_Week_Count': '第{R1}周', + 'BI-Basic_Param_Hour': '{R1}时', + 'BI-Basic_Param_Minute': '{R1}分', + 'BI-Basic_Param_Second': '{R1}秒', + 'BI-Basic_Param_Year': '{R1}年', + 'BI-Basic_Date_Day': '日', + 'BI-Basic_Hour_Sin': '时', + 'BI-Basic_Seconds': '秒', + 'BI-Basic_Minute': '分', + 'BI-Basic_Thousand': '千', + 'BI-Basic_Wan': '万', + 'BI-Basic_Million': '百万', + 'BI-Basic_Billion': '亿', + 'BI-Basic_Quarter': '季度', + 'BI-Basic_No_Select': '不选', + 'BI-Basic_Now': '此刻', + 'BI-Color_Picker_Error_Text_Hex': '请输入6位16进制颜色编号', + 'BI-Basic_Date_Range_Error': '请选择{R1}年{R2}月{R3}日-{R4}年{R5}月{R6}日的日期', + 'BI-Basic_Year_Range_Error': '请选择{R1}年-{R2}年的日期', + 'BI-Basic_Year_Month_Range_Error': '请选择{R1}年{R2}月-{R3}年{R4}月的日期', + 'BI-Basic_Year_Quarter_Range_Error': '请选择{R1}年{R2}季度-{R3}年{R4}季度的日期', + 'BI-Basic_Search_And_Patch_Paste': '搜索,支持批量粘贴、粘贴值通过换行识别', + 'BI-Basic_Recommend_Color': '推荐色', + 'BI-Basic_Too_Much_Value_Get_Two_Thousand': '粘贴的值过多,只能识别出前2000个值', + 'BI-Basic_Simple_Open': '开', + 'BI-Basic_Simple_Close': '关', +}; diff --git a/packages/demo/i18n/i18n.en.js b/packages/demo/i18n/i18n.en.js new file mode 100644 index 000000000..0acc5cb29 --- /dev/null +++ b/packages/demo/i18n/i18n.en.js @@ -0,0 +1,122 @@ +BI.i18n = { + 'BI-Multi_Date_Quarter_End': '', + 'BI-Multi_Date_Month_Begin': '', + 'BI-Multi_Date_YMD': '', + 'BI-Custom_Color': '', + 'BI-Numerical_Interval_Input_Data': '', + 'BI-Please_Input_Natural_Number': '', + 'BI-No_More_Data': 'No More Data', + 'BI-Basic_Altogether': 'Altogether', + 'BI-Basic_Sunday': 'Sunday', + 'BI-Widget_Background_Colour': '', + 'BI-Color_Picker_Error_Text': '', + 'BI-Multi_Date_Month': '', + 'BI-No_Selected_Item': '', + 'BI-Multi_Date_Year_Begin': '', + 'BI-Quarter_1': 'First Quarter', + 'BI-Quarter_2': 'Second Quarter', + 'BI-Quarter_3': 'Third Quarter', + 'BI-Quarter_4': 'Fourth Quarter', + 'BI-Multi_Date_Year_Next': '', + 'BI-Multi_Date_Month_Prev': '', + 'BI-Month_Trigger_Error_Text': '', + 'BI-Less_And_Equal': '', + 'BI-Year_Trigger_Invalid_Text': '', + 'BI-Multi_Date_Week_Next': '', + 'BI-Font_Size': '', + 'BI-Basic_Total': 'Total', + 'BI-Already_Selected': 'Already Selected items', + 'BI-Formula_Insert': '', + 'BI-Select_All': 'Select All', + 'BI-Basic_Tuesday': 'Tuesday', + 'BI-Multi_Date_Month_End': '', + 'BI-Load_More': 'Click to Load More', + 'BI-Basic_September': 'September', + 'BI-Current_Is_Last_Page': '', + 'BI-Basic_Auto': 'Auto', + 'BI-Basic_Count': '', + 'BI-Basic_Value': 'value', + 'BI-Basic_Unrestricted': 'unrestricted', + 'BI-Quarter_Trigger_Error_Text': '', + 'BI-Basic_More': 'More', + 'BI-Basic_Wednesday': 'Wednesday', + 'BI-Basic_Bold': 'Bold', + 'BI-Basic_Simple_Saturday': 'Sat', + 'BI-Multi_Date_Month_Next': '', + 'BI-Basic_March': 'March', + 'BI-Current_Is_First_Page': '', + 'BI-Basic_Thursday': 'Thursday', + 'BI-Basic_Prompt': 'Prompt', + 'BI-Multi_Date_Today': 'Toady', + 'BI-Multi_Date_Quarter_Prev': '', + 'BI-Row_Header': 'Row header', + 'BI-Date_Trigger_Error_Text': '日期格式示例:2015-3-11', + 'BI-Basic_Cancel': 'Cancel', + 'BI-Basic_January': 'January', + 'BI-Basic_June': 'June', + 'BI-Basic_July': 'July', + 'BI-Basic_April': 'April', + 'BI-Multi_Date_Quarter_Begin': '', + 'BI-Multi_Date_Week': 'Week', + 'BI-Click_Blank_To_Select': '', + 'BI-Basic_August': 'August', + 'BI-Word_Align_Left': 'Align Left', + 'BI-Basic_November': 'November', + 'BI-Font_Colour': 'Font Color', + 'BI-Multi_Date_Day_Prev': '', + 'BI-Select_Part': '', + 'BI-Multi_Date_Day_Next': '', + 'BI-Less_Than': 'Less Than', + 'BI-Basic_February': 'February', + 'BI-Multi_Date_Year': 'Year', + 'BI-Number_Index': 'Number', + 'BI-Multi_Date_Week_Prev': '', + 'BI-Next_Page': 'Next', + 'BI-Right_Page': 'Right', + 'BI-Numerical_Interval_Signal_Value': '', + 'BI-Basic_December': 'December', + 'BI-Basic_Saturday': 'Saturday', + 'BI-Basic_Simple_Wednesday': 'Wed', + 'BI-Multi_Date_Quarter_Next': '', + 'BI-Basic_October': 'October', + 'BI-Basic_Simple_Friday': 'Fri', + 'BI-Basic_Save': 'Save', + 'BI-Numerical_Interval_Number_Value': '', + 'BI-Previous_Page': 'Previous', + 'BI-No_Select': 'Blank', + 'BI-Basic_Clears': 'Clear', + 'BI-Created_By_Me': 'Created By Me', + 'BI-Basic_Simple_Tuesday': 'Tue', + 'BI-Word_Align_Right': 'Align Right', + 'BI-Summary_Values': 'Summary', + 'BI-Basic_Clear': 'Clear', + 'BI-Upload_File_Size_Error': '', + 'BI-Up_Page': 'Up', + 'BI-Basic_Simple_Sunday': 'Sun', + 'BI-Multi_Date_Relative_Current_Time': '', + 'BI-Selected_Data': 'Selected', + 'BI-Multi_Date_Quarter': 'Quarter', + 'BI-Check_Selected': '', + 'BI-Basic_Search': 'Search', + 'BI-Basic_May': 'May', + 'BI-Continue_Select': 'Continue Select', + 'BI-Please_Input_Positive_Integer': 'Please Input Positive Integer', + 'BI-Upload_File_Type_Error': '', + 'BI-Upload_File_Error': '', + 'BI-Basic_Friday': 'Friday', + 'BI-Down_Page': 'Down', + 'BI-Basic_Monday': 'Monday', + 'BI-Left_Page': 'Left', + 'BI-Transparent_Color': 'Transparent', + 'BI-Basic_Simple_Monday': 'Mon', + 'BI-Multi_Date_Year_End': '', + 'BI-Time_Interval_Error_Text': '', + 'BI-Basic_Time': 'Time', + 'BI-Basic_OK': 'Ok', + 'BI-Basic_Sure': 'Sure', + 'BI-Basic_Simple_Thursday': 'Thu', + 'BI-Multi_Date_Year_Prev': '', + 'BI-Tiao_Data': '', + 'BI-Basic_Italic': 'Italic', + 'BI-Color_Picker_Error_Text_Hex': 'Please Input Correct Hex Value', +}; diff --git a/packages/demo/index.html b/packages/demo/index.html new file mode 100644 index 000000000..5560a4205 --- /dev/null +++ b/packages/demo/index.html @@ -0,0 +1,16 @@ + + + + + + Document + + + +
+ + diff --git a/packages/demo/jsconfig.json b/packages/demo/jsconfig.json new file mode 100644 index 000000000..215f7a417 --- /dev/null +++ b/packages/demo/jsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "experimentalDecorators": true + } +} diff --git a/packages/demo/package.json b/packages/demo/package.json new file mode 100644 index 000000000..61359751f --- /dev/null +++ b/packages/demo/package.json @@ -0,0 +1,16 @@ +{ + "name": "demo", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "webpack-dev-server --open --config=webpack.dev.js --progress", + "build": "webpack --config=webpack.prod.js --progress" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@fui/core": "workspace:*" + } +} diff --git a/packages/demo/src/center.js b/packages/demo/src/center.js new file mode 100644 index 000000000..0f7beadb3 --- /dev/null +++ b/packages/demo/src/center.js @@ -0,0 +1,32 @@ +import { Decorators , Widget, RouterView, Router } from '@fui/core'; + +@Decorators.shortcut() +export class Center extends Widget { + static xtype = 'demo.center'; + + props = { baseCls: 'demo-center' }; + + render() { + const self = this; + + return { + type: RouterView.xtype, + }; + } +} + +@Decorators.shortcut() +export class RouterDemo extends Widget { + static xtype = 'demo.router'; + + props = { + baseCls: 'demo-router', + }; + + render() { + const params = Router.$router.history.current.params; + return { + type: params.componentId, + }; + } +} diff --git a/packages/demo/src/config/base.js b/packages/demo/src/config/base.js new file mode 100644 index 000000000..195715320 --- /dev/null +++ b/packages/demo/src/config/base.js @@ -0,0 +1,11 @@ +import { basic } from "../base"; +import { transModule2Route } from "./utils"; + +export const baseConfig = [ + { + id: 2, + text: "基础控件", + open: false + }, + ...transModule2Route(basic, 2) +]; diff --git a/packages/demo/src/config/constant.js b/packages/demo/src/config/constant.js new file mode 100644 index 000000000..e6b94b74a --- /dev/null +++ b/packages/demo/src/config/constant.js @@ -0,0 +1,3600 @@ +import { map } from "@fui/core"; + +export const CONSTANTS = { + SIMPLE_ITEMS: map( + "柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂".match( + /[^\s]+/g + ), + function (i, v) { + return { + text: v, + value: v, + title: v + }; + } + ), + ITEMS: map( + "柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 ".match( + /[^\s]+/g + ), + function (i, v) { + return { + text: v, + value: v, + title: v + }; + } + ), + TREEITEMS: [ + { pId: "0", id: "0_0", text: "( 共25个 )", value: "", open: true }, + { + pId: "0_0", + id: "0_0_0", + text: "安徽省( 共1个 )", + value: "安徽省", + open: true + }, + { + pId: "0_0_0", + id: "0_0_0_0", + text: "芜湖市", + value: "芜湖市", + open: true + }, + { + pId: "0_0", + id: "0_0_1", + text: "北京市( 共6个 )", + value: "北京市", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_0", + text: "北京市区", + value: "北京市区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_1", + text: "朝阳区", + value: "朝阳区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_2", + text: "东城区", + value: "东城区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_3", + text: "海淀区4内", + value: "海淀区4内", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_4", + text: "海淀区4外", + value: "海淀区4外", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_5", + text: "石景山区", + value: "石景山区", + open: true + }, + { + pId: "0_0", + id: "0_0_2", + text: "福建省( 共2个 )", + value: "福建省", + open: true + }, + { + pId: "0_0_2", + id: "0_0_2_0", + text: "莆田市", + value: "莆田市", + open: true + }, + { + pId: "0_0_2", + id: "0_0_2_1", + text: "泉州市", + value: "泉州市", + open: true + }, + { + pId: "0_0", + id: "0_0_3", + text: "甘肃省( 共1个 )", + value: "甘肃省", + open: true + }, + { + pId: "0_0_3", + id: "0_0_3_0", + text: "兰州市", + value: "兰州市", + open: true + }, + { + pId: "0_0", + id: "0_0_4", + text: "广东省( 共5个 )", + value: "广东省", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_0", + text: "东莞市", + value: "东莞市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_1", + text: "广州市", + value: "广州市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_2", + text: "惠州市", + value: "惠州市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_3", + text: "深圳市", + value: "深圳市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_4", + text: "珠海市", + value: "珠海市", + open: true + }, + { + pId: "0_0", + id: "0_0_5", + text: "广西壮族自治区( 共1个 )", + value: "广西壮族自治区", + open: true + }, + { + pId: "0_0_5", + id: "0_0_5_0", + text: "南宁市", + value: "南宁市", + open: true + }, + { + pId: "0_0", + id: "0_0_6", + text: "河北省( 共2个 )", + value: "河北省", + open: true + }, + { + pId: "0_0_6", + id: "0_0_6_0", + text: "保定市", + value: "保定市", + open: true + }, + { + pId: "0_0_6", + id: "0_0_6_1", + text: "邢台市", + value: "邢台市", + open: true + }, + { + pId: "0_0", + id: "0_0_7", + text: "河南省( 共1个 )", + value: "河南省", + open: true + }, + { + pId: "0_0_7", + id: "0_0_7_0", + text: "郑州市", + value: "郑州市", + open: true + }, + { + pId: "0_0", + id: "0_0_8", + text: "黑龙江省( 共7个 )", + value: "黑龙江省", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_0", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_1", + text: "哈尔滨市", + value: "哈尔滨市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_2", + text: "鸡西市", + value: "鸡西市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_3", + text: "佳木斯市", + value: "佳木斯市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_4", + text: "牡丹江市", + value: "牡丹江市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_5", + text: "齐齐哈尔市", + value: "齐齐哈尔市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_6", + text: "双鸭山市", + value: "双鸭山市", + open: true + }, + { + pId: "0_0", + id: "0_0_9", + text: "湖北省( 共1个 )", + value: "湖北省", + open: true + }, + { + pId: "0_0_9", + id: "0_0_9_0", + text: "武汉市", + value: "武汉市", + open: true + }, + { + pId: "0_0", + id: "0_0_10", + text: "湖南省( 共3个 )", + value: "湖南省", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_0", + text: "常德市", + value: "常德市", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_1", + text: "长沙市", + value: "长沙市", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_2", + text: "邵阳市", + value: "邵阳市", + open: true + }, + { + pId: "0_0", + id: "0_0_11", + text: "吉林省( 共4个 )", + value: "吉林省", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_0", + text: "白山市", + value: "白山市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_1", + text: "长春市", + value: "长春市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_2", + text: "松原市", + value: "松原市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_3", + text: "通化市", + value: "通化市", + open: true + }, + { + pId: "0_0", + id: "0_0_12", + text: "江苏省( 共8个 )", + value: "江苏省", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_0", + text: "常州市", + value: "常州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_1", + text: "南京市", + value: "南京市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_2", + text: "南通市", + value: "南通市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_3", + text: "苏州市", + value: "苏州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_4", + text: "宿迁市", + value: "宿迁市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_5", + text: "泰州市", + value: "泰州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_6", + text: "无锡市", + value: "无锡市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_7", + text: "盐城市", + value: "盐城市", + open: true + }, + { + pId: "0_0", + id: "0_0_13", + text: "辽宁省( 共11个 )", + value: "辽宁省", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_0", + text: "鞍山市", + value: "鞍山市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_1", + text: "本溪市", + value: "本溪市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_2", + text: "朝阳市", + value: "朝阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_3", + text: "大连市", + value: "大连市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_4", + text: "抚顺市", + value: "抚顺市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_5", + text: "葫芦岛市", + value: "葫芦岛市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_6", + text: "锦州市", + value: "锦州市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_7", + text: "辽阳市", + value: "辽阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_8", + text: "盘锦市", + value: "盘锦市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_9", + text: "沈阳市", + value: "沈阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_10", + text: "营口市", + value: "营口市", + open: true + }, + { + pId: "0_0", + id: "0_0_14", + text: "内蒙古( 共1个 )", + value: "内蒙古", + open: true + }, + { + pId: "0_0_14", + id: "0_0_14_0", + text: "鄂尔多斯市", + value: "鄂尔多斯市", + open: true + }, + { + pId: "0_0", + id: "0_0_15", + text: "宁夏回族自治区( 共1个 )", + value: "宁夏回族自治区", + open: true + }, + { + pId: "0_0_15", + id: "0_0_15_0", + text: "银川市", + value: "银川市", + open: true + }, + { + pId: "0_0", + id: "0_0_16", + text: "山东省( 共7个 )", + value: "山东省", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_0", + text: "济南市", + value: "济南市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_1", + text: "济宁市", + value: "济宁市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_2", + text: "聊城市", + value: "聊城市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_3", + text: "临沂市", + value: "临沂市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_4", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_5", + text: "烟台市", + value: "烟台市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_6", + text: "枣庄市", + value: "枣庄市", + open: true + }, + { + pId: "0_0", + id: "0_0_17", + text: "山西省( 共1个 )", + value: "山西省", + open: true + }, + { + pId: "0_0_17", + id: "0_0_17_0", + text: "太原市", + value: "太原市", + open: true + }, + { + pId: "0_0", + id: "0_0_18", + text: "陕西省( 共1个 )", + value: "陕西省", + open: true + }, + { + pId: "0_0_18", + id: "0_0_18_0", + text: "西安市", + value: "西安市", + open: true + }, + { + pId: "0_0", + id: "0_0_19", + text: "上海市( 共1个 )", + value: "上海市", + open: true + }, + { + pId: "0_0_19", + id: "0_0_19_0", + text: "上海市区", + value: "上海市区", + open: true + }, + { + pId: "0_0", + id: "0_0_20", + text: "四川省( 共1个 )", + value: "四川省", + open: true + }, + { + pId: "0_0_20", + id: "0_0_20_0", + text: "成都市", + value: "成都市", + open: true + }, + { + pId: "0_0", + id: "0_0_21", + text: "新疆维吾尔族自治区( 共2个 )", + value: "新疆维吾尔族自治区", + open: true + }, + { + pId: "0_0_21", + id: "0_0_21_0", + text: "吐鲁番地区", + value: "吐鲁番地区", + open: true + }, + { + pId: "0_0_21", + id: "0_0_21_1", + text: "乌鲁木齐", + value: "乌鲁木齐", + open: true + }, + { + pId: "0_0", + id: "0_0_22", + text: "云南省( 共1个 )", + value: "云南省", + open: true + }, + { + pId: "0_0_22", + id: "0_0_22_0", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_0", + id: "0_0_23", + text: "浙江省( 共5个 )", + value: "浙江省", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_0", + text: "杭州市", + value: "杭州市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_1", + text: "湖州市", + value: "湖州市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_2", + text: "嘉兴市", + value: "嘉兴市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_3", + text: "宁波市", + value: "宁波市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_4", + text: "绍兴市", + value: "绍兴市", + open: true + }, + { + pId: "0_0", + id: "0_0_24", + text: "重庆市( 共1个 )", + value: "重庆市", + open: true + }, + { + pId: "0_0_24", + id: "0_0_24_0", + text: "重庆市区", + value: "重庆市区", + open: true + }, + { + pId: "0", + id: "0_1", + text: "中国( 共34个 )", + value: "中国", + open: true + }, + { + pId: "0_1", + id: "0_1_0", + text: "安徽省( 共19个 )", + value: "安徽省", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_0", + text: "安庆市", + value: "安庆市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_1", + text: "蚌埠市", + value: "蚌埠市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_2", + text: "亳州市", + value: "亳州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_3", + text: "巢湖市", + value: "巢湖市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_4", + text: "池州市", + value: "池州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_5", + text: "滁州市", + value: "滁州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_6", + text: "阜阳市", + value: "阜阳市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_7", + text: "毫州市", + value: "毫州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_8", + text: "合肥市", + value: "合肥市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_9", + text: "淮北市", + value: "淮北市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_10", + text: "淮南市", + value: "淮南市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_11", + text: "黄山市", + value: "黄山市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_12", + text: "六安市", + value: "六安市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_13", + text: "马鞍山市", + value: "马鞍山市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_14", + text: "濮阳市", + value: "濮阳市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_15", + text: "宿州市", + value: "宿州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_16", + text: "铜陵市", + value: "铜陵市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_17", + text: "芜湖市", + value: "芜湖市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_18", + text: "宣城市", + value: "宣城市", + open: true + }, + { + pId: "0_1", + id: "0_1_1", + text: "澳门特别行政区( 共1个 )", + value: "澳门特别行政区", + open: true + }, + { + pId: "0_1_1", + id: "0_1_1_0", + text: "澳门", + value: "澳门", + open: true + }, + { + pId: "0_1", + id: "0_1_2", + text: "北京市( 共17个 )", + value: "北京市", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_0", + text: "北京市区", + value: "北京市区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_1", + text: "昌平区", + value: "昌平区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_2", + text: "朝阳区", + value: "朝阳区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_3", + text: "大兴区", + value: "大兴区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_4", + text: "东城区", + value: "东城区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_5", + text: "房山区", + value: "房山区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_6", + text: "丰台区", + value: "丰台区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_7", + text: "海淀区", + value: "海淀区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_8", + text: "海淀区4内", + value: "海淀区4内", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_9", + text: "海淀区4外", + value: "海淀区4外", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_10", + text: "门头沟区", + value: "门头沟区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_11", + text: "平谷区", + value: "平谷区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_12", + text: "石景山区", + value: "石景山区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_13", + text: "顺义区", + value: "顺义区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_14", + text: "通州区", + value: "通州区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_15", + text: "西城区", + value: "西城区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_16", + text: "西城区 ", + value: "西城区 ", + open: true + }, + { + pId: "0_1", + id: "0_1_3", + text: "福建省( 共9个 )", + value: "福建省", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_0", + text: "福州市", + value: "福州市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_1", + text: "龙岩市", + value: "龙岩市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_2", + text: "南平市", + value: "南平市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_3", + text: "宁德市", + value: "宁德市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_4", + text: "莆田市", + value: "莆田市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_5", + text: "泉州市", + value: "泉州市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_6", + text: "三明市", + value: "三明市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_7", + text: "厦门市", + value: "厦门市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_8", + text: "漳州市", + value: "漳州市", + open: true + }, + { + pId: "0_1", + id: "0_1_4", + text: "甘肃省( 共12个 )", + value: "甘肃省", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_0", + text: "白银市", + value: "白银市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_1", + text: "嘉峪关市", + value: "嘉峪关市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_2", + text: "金昌市", + value: "金昌市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_3", + text: "酒泉市", + value: "酒泉市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_4", + text: "兰州市", + value: "兰州市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_5", + text: "陇南市", + value: "陇南市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_6", + text: "平凉市", + value: "平凉市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_7", + text: "庆阳市", + value: "庆阳市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_8", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_9", + text: "天水市", + value: "天水市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_10", + text: "武威市", + value: "武威市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_11", + text: "张掖市", + value: "张掖市", + open: true + }, + { + pId: "0_1", + id: "0_1_5", + text: "广东省( 共21个 )", + value: "广东省", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_0", + text: "潮州市", + value: "潮州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_1", + text: "东莞市", + value: "东莞市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_2", + text: "佛山市", + value: "佛山市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_3", + text: "广州市", + value: "广州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_4", + text: "河源市", + value: "河源市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_5", + text: "惠州市", + value: "惠州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_6", + text: "江门市", + value: "江门市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_7", + text: "揭阳市", + value: "揭阳市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_8", + text: "茂名市", + value: "茂名市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_9", + text: "梅州市", + value: "梅州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_10", + text: "清远市", + value: "清远市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_11", + text: "汕头市", + value: "汕头市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_12", + text: "汕尾市", + value: "汕尾市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_13", + text: "韶关市", + value: "韶关市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_14", + text: "深圳市", + value: "深圳市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_15", + text: "阳江市", + value: "阳江市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_16", + text: "云浮市", + value: "云浮市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_17", + text: "湛江市", + value: "湛江市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_18", + text: "肇庆市", + value: "肇庆市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_19", + text: "中山市", + value: "中山市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_20", + text: "珠海市", + value: "珠海市", + open: true + }, + { + pId: "0_1", + id: "0_1_6", + text: "广西壮族自治区( 共14个 )", + value: "广西壮族自治区", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_0", + text: "百色市", + value: "百色市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_1", + text: "北海市", + value: "北海市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_2", + text: "崇左市", + value: "崇左市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_3", + text: "防城港市", + value: "防城港市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_4", + text: "桂林市", + value: "桂林市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_5", + text: "贵港市", + value: "贵港市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_6", + text: "河池市", + value: "河池市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_7", + text: "贺州市", + value: "贺州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_8", + text: "来宾市", + value: "来宾市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_9", + text: "柳州市", + value: "柳州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_10", + text: "南宁市", + value: "南宁市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_11", + text: "钦州市", + value: "钦州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_12", + text: "梧州市", + value: "梧州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_13", + text: "玉林市", + value: "玉林市", + open: true + }, + { + pId: "0_1", + id: "0_1_7", + text: "贵州省( 共9个 )", + value: "贵州省", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_0", + text: "安顺市", + value: "安顺市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_1", + text: "毕节地区", + value: "毕节地区", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_2", + text: "贵阳市", + value: "贵阳市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_3", + text: "六盘水市", + value: "六盘水市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_4", + text: "黔东南州", + value: "黔东南州", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_5", + text: "黔南州", + value: "黔南州", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_6", + text: "黔西南市", + value: "黔西南市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_7", + text: "铜仁地区", + value: "铜仁地区", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_8", + text: "遵义市", + value: "遵义市", + open: true + }, + { + pId: "0_1", + id: "0_1_8", + text: "海南省( 共2个 )", + value: "海南省", + open: true + }, + { + pId: "0_1_8", + id: "0_1_8_0", + text: "海口市", + value: "海口市", + open: true + }, + { + pId: "0_1_8", + id: "0_1_8_1", + text: "三亚市", + value: "三亚市", + open: true + }, + { + pId: "0_1", + id: "0_1_9", + text: "河北省( 共12个 )", + value: "河北省", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_0", + text: "保定市", + value: "保定市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_1", + text: "沧州市", + value: "沧州市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_2", + text: "承德市", + value: "承德市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_3", + text: "邯郸市", + value: "邯郸市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_4", + text: "衡水市", + value: "衡水市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_5", + text: "廊坊市", + value: "廊坊市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_6", + text: "秦皇岛市", + value: "秦皇岛市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_7", + text: "石家庄市", + value: "石家庄市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_8", + text: "唐山市", + value: "唐山市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_9", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_10", + text: "邢台市", + value: "邢台市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_11", + text: "张家口市", + value: "张家口市", + open: true + }, + { + pId: "0_1", + id: "0_1_10", + text: "河南省( 共19个 )", + value: "河南省", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_0", + text: "安阳市", + value: "安阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_1", + text: "鹤壁市", + value: "鹤壁市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_2", + text: "济源市", + value: "济源市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_3", + text: "焦作市", + value: "焦作市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_4", + text: "开封市", + value: "开封市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_5", + text: "廊坊市", + value: "廊坊市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_6", + text: "洛阳市", + value: "洛阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_7", + text: "漯河市", + value: "漯河市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_8", + text: "南阳市", + value: "南阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_9", + text: "平顶山市", + value: "平顶山市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_10", + text: "濮阳市", + value: "濮阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_11", + text: "三门峡市", + value: "三门峡市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_12", + text: "商丘市", + value: "商丘市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_13", + text: "新乡市", + value: "新乡市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_14", + text: "信阳市", + value: "信阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_15", + text: "许昌市", + value: "许昌市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_16", + text: "郑州市", + value: "郑州市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_17", + text: "周口市", + value: "周口市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_18", + text: "驻马店市", + value: "驻马店市", + open: true + }, + { + pId: "0_1", + id: "0_1_11", + text: "黑龙江省( 共13个 )", + value: "黑龙江省", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_0", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_1", + text: "大兴安岭地区", + value: "大兴安岭地区", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_2", + text: "大兴安岭市", + value: "大兴安岭市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_3", + text: "哈尔滨市", + value: "哈尔滨市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_4", + text: "鹤港市", + value: "鹤港市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_5", + text: "黑河市", + value: "黑河市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_6", + text: "佳木斯市", + value: "佳木斯市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_7", + text: "牡丹江市", + value: "牡丹江市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_8", + text: "七台河市", + value: "七台河市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_9", + text: "齐齐哈尔市", + value: "齐齐哈尔市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_10", + text: "双鸭山市", + value: "双鸭山市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_11", + text: "绥化市", + value: "绥化市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_12", + text: "伊春市", + value: "伊春市", + open: true + }, + { + pId: "0_1", + id: "0_1_12", + text: "湖北省( 共16个 )", + value: "湖北省", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_0", + text: "鄂州市", + value: "鄂州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_1", + text: "恩施土家族苗族自治州", + value: "恩施土家族苗族自治州", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_2", + text: "黄冈市", + value: "黄冈市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_3", + text: "黄石市", + value: "黄石市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_4", + text: "荆门市", + value: "荆门市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_5", + text: "荆州市", + value: "荆州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_6", + text: "神农架市", + value: "神农架市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_7", + text: "十堰市", + value: "十堰市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_8", + text: "随州市", + value: "随州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_9", + text: "天门市", + value: "天门市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_10", + text: "武汉市", + value: "武汉市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_11", + text: "咸宁市", + value: "咸宁市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_12", + text: "襄樊市", + value: "襄樊市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_13", + text: "襄阳市", + value: "襄阳市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_14", + text: "孝感市", + value: "孝感市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_15", + text: "宜昌市", + value: "宜昌市", + open: true + }, + { + pId: "0_1", + id: "0_1_13", + text: "湖南省( 共15个 )", + value: "湖南省", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_0", + text: "常德市", + value: "常德市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_1", + text: "长沙市", + value: "长沙市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_2", + text: "郴州市", + value: "郴州市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_3", + text: "衡阳市", + value: "衡阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_4", + text: "怀化市", + value: "怀化市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_5", + text: "娄底市", + value: "娄底市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_6", + text: "邵阳市", + value: "邵阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_7", + text: "湘潭市", + value: "湘潭市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_8", + text: "湘西市", + value: "湘西市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_9", + text: "湘西土家族苗族自治州", + value: "湘西土家族苗族自治州", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_10", + text: "益阳市", + value: "益阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_11", + text: "永州市", + value: "永州市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_12", + text: "岳阳市", + value: "岳阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_13", + text: "张家界市", + value: "张家界市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_14", + text: "株洲市", + value: "株洲市", + open: true + }, + { + pId: "0_1", + id: "0_1_14", + text: "吉林省( 共10个 )", + value: "吉林省", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_0", + text: "白城市", + value: "白城市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_1", + text: "白山市", + value: "白山市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_2", + text: "长春市", + value: "长春市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_3", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_4", + text: "吉林市", + value: "吉林市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_5", + text: "辽源市", + value: "辽源市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_6", + text: "四平市", + value: "四平市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_7", + text: "松原市", + value: "松原市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_8", + text: "通化市", + value: "通化市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_9", + text: "延边朝鲜族自治州", + value: "延边朝鲜族自治州", + open: true + }, + { + pId: "0_1", + id: "0_1_15", + text: "江苏省( 共13个 )", + value: "江苏省", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_0", + text: "常州市", + value: "常州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_1", + text: "淮安市", + value: "淮安市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_2", + text: "连云港市", + value: "连云港市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_3", + text: "南京市", + value: "南京市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_4", + text: "南通市", + value: "南通市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_5", + text: "苏州市", + value: "苏州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_6", + text: "宿迁市", + value: "宿迁市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_7", + text: "泰州市", + value: "泰州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_8", + text: "无锡市", + value: "无锡市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_9", + text: "徐州市", + value: "徐州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_10", + text: "盐城市", + value: "盐城市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_11", + text: "扬州市", + value: "扬州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_12", + text: "镇江市", + value: "镇江市", + open: true + }, + { + pId: "0_1", + id: "0_1_16", + text: "江西省( 共10个 )", + value: "江西省", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_0", + text: "抚州市", + value: "抚州市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_1", + text: "赣州市", + value: "赣州市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_2", + text: "景德镇市", + value: "景德镇市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_3", + text: "九江市", + value: "九江市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_4", + text: "南昌市", + value: "南昌市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_5", + text: "萍乡市", + value: "萍乡市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_6", + text: "上饶市", + value: "上饶市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_7", + text: "新余市", + value: "新余市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_8", + text: "宜春市", + value: "宜春市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_9", + text: "鹰潭市", + value: "鹰潭市", + open: true + }, + { + pId: "0_1", + id: "0_1_17", + text: "辽宁省( 共14个 )", + value: "辽宁省", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_0", + text: "鞍山市", + value: "鞍山市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_1", + text: "本溪市", + value: "本溪市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_2", + text: "朝阳市", + value: "朝阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_3", + text: "大连市", + value: "大连市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_4", + text: "丹东市", + value: "丹东市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_5", + text: "抚顺市", + value: "抚顺市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_6", + text: "阜新市", + value: "阜新市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_7", + text: "葫芦岛市", + value: "葫芦岛市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_8", + text: "锦州市", + value: "锦州市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_9", + text: "辽阳市", + value: "辽阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_10", + text: "盘锦市", + value: "盘锦市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_11", + text: "沈阳市", + value: "沈阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_12", + text: "铁岭市", + value: "铁岭市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_13", + text: "营口市", + value: "营口市", + open: true + }, + { + pId: "0_1", + id: "0_1_18", + text: "内蒙古( 共10个 )", + value: "内蒙古", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_0", + text: "包头市", + value: "包头市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_1", + text: "赤峰市", + value: "赤峰市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_2", + text: "鄂尔多斯市", + value: "鄂尔多斯市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_3", + text: "呼和浩特市", + value: "呼和浩特市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_4", + text: "呼伦贝尔市", + value: "呼伦贝尔市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_5", + text: "通辽市", + value: "通辽市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_6", + text: "乌海市", + value: "乌海市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_7", + text: "锡林郭勒市", + value: "锡林郭勒市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_8", + text: "兴安市", + value: "兴安市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_9", + text: "运城市", + value: "运城市", + open: true + }, + { + pId: "0_1", + id: "0_1_19", + text: "宁夏回族自治区( 共5个 )", + value: "宁夏回族自治区", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_0", + text: "固原市", + value: "固原市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_1", + text: "石嘴山市", + value: "石嘴山市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_2", + text: "吴忠市", + value: "吴忠市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_3", + text: "银川市", + value: "银川市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_4", + text: "中卫市", + value: "中卫市", + open: true + }, + { + pId: "0_1", + id: "0_1_20", + text: "青海省( 共4个 )", + value: "青海省", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_0", + text: "海东地区", + value: "海东地区", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_1", + text: "海南藏族自治州", + value: "海南藏族自治州", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_2", + text: "海西蒙古族藏族自治州", + value: "海西蒙古族藏族自治州", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_3", + text: "西宁市", + value: "西宁市", + open: true + }, + { + pId: "0_1", + id: "0_1_21", + text: "山东省( 共17个 )", + value: "山东省", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_0", + text: "滨州市", + value: "滨州市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_1", + text: "德州市", + value: "德州市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_2", + text: "东营市", + value: "东营市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_3", + text: "菏泽市", + value: "菏泽市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_4", + text: "济南市", + value: "济南市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_5", + text: "济宁市", + value: "济宁市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_6", + text: "莱芜市", + value: "莱芜市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_7", + text: "聊城市", + value: "聊城市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_8", + text: "临沂市", + value: "临沂市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_9", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_10", + text: "日照市", + value: "日照市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_11", + text: "泰安市", + value: "泰安市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_12", + text: "威海市", + value: "威海市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_13", + text: "潍坊市", + value: "潍坊市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_14", + text: "烟台市", + value: "烟台市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_15", + text: "枣庄市", + value: "枣庄市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_16", + text: "淄博市", + value: "淄博市", + open: true + }, + { + pId: "0_1", + id: "0_1_22", + text: "山西省( 共12个 )", + value: "山西省", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_0", + text: "长治市", + value: "长治市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_1", + text: "大同市", + value: "大同市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_2", + text: "晋城市", + value: "晋城市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_3", + text: "晋中市", + value: "晋中市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_4", + text: "临汾市", + value: "临汾市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_5", + text: "吕梁市", + value: "吕梁市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_6", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_7", + text: "朔州市", + value: "朔州市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_8", + text: "太原市", + value: "太原市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_9", + text: "忻州市", + value: "忻州市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_10", + text: "阳泉市", + value: "阳泉市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_11", + text: "运城市", + value: "运城市", + open: true + }, + { + pId: "0_1", + id: "0_1_23", + text: "陕西省( 共9个 )", + value: "陕西省", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_0", + text: "安康市", + value: "安康市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_1", + text: "宝鸡市", + value: "宝鸡市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_2", + text: "汉中市", + value: "汉中市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_3", + text: "商洛市", + value: "商洛市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_4", + text: "渭南市", + value: "渭南市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_5", + text: "西安市", + value: "西安市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_6", + text: "咸阳市", + value: "咸阳市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_7", + text: "延安市", + value: "延安市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_8", + text: "榆林市", + value: "榆林市", + open: true + }, + { + pId: "0_1", + id: "0_1_24", + text: "上海市( 共19个 )", + value: "上海市", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_0", + text: "宝山区", + value: "宝山区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_1", + text: "长宁区", + value: "长宁区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_2", + text: "崇明县", + value: "崇明县", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_3", + text: "奉贤区", + value: "奉贤区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_4", + text: "虹口区", + value: "虹口区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_5", + text: "黄浦区", + value: "黄浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_6", + text: "嘉定区", + value: "嘉定区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_7", + text: "金山区", + value: "金山区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_8", + text: "静安区", + value: "静安区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_9", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_10", + text: "闵行区", + value: "闵行区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_11", + text: "普陀区", + value: "普陀区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_12", + text: "浦东新区", + value: "浦东新区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_13", + text: "青浦区", + value: "青浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_14", + text: "上海市区", + value: "上海市区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_15", + text: "松江区", + value: "松江区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_16", + text: "徐汇区", + value: "徐汇区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_17", + text: "杨浦区", + value: "杨浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_18", + text: "闸北区", + value: "闸北区", + open: true + }, + { + pId: "0_1", + id: "0_1_25", + text: "四川省( 共21个 )", + value: "四川省", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_0", + text: "阿坝藏族羌族自治州", + value: "阿坝藏族羌族自治州", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_1", + text: "巴中市", + value: "巴中市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_2", + text: "成都市", + value: "成都市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_3", + text: "达州市", + value: "达州市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_4", + text: "德阳市", + value: "德阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_5", + text: "甘孜市", + value: "甘孜市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_6", + text: "广安市", + value: "广安市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_7", + text: "广元市", + value: "广元市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_8", + text: "乐山市", + value: "乐山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_9", + text: "凉山市", + value: "凉山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_10", + text: "泸州市", + value: "泸州市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_11", + text: "眉山市", + value: "眉山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_12", + text: "绵阳市", + value: "绵阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_13", + text: "南充市", + value: "南充市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_14", + text: "内江市", + value: "内江市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_15", + text: "攀枝花市", + value: "攀枝花市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_16", + text: "遂宁市", + value: "遂宁市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_17", + text: "雅安市", + value: "雅安市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_18", + text: "宜宾市", + value: "宜宾市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_19", + text: "资阳市", + value: "资阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_20", + text: "自贡市", + value: "自贡市", + open: true + }, + { + pId: "0_1", + id: "0_1_26", + text: "台湾( 共1个 )", + value: "台湾", + open: true + }, + { + pId: "0_1_26", + id: "0_1_26_0", + text: "台北市", + value: "台北市", + open: true + }, + { + pId: "0_1", + id: "0_1_27", + text: "天津市( 共1个 )", + value: "天津市", + open: true + }, + { + pId: "0_1_27", + id: "0_1_27_0", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1", + id: "0_1_28", + text: "西藏自治区( 共2个 )", + value: "西藏自治区", + open: true + }, + { + pId: "0_1_28", + id: "0_1_28_0", + text: "阿里市", + value: "阿里市", + open: true + }, + { + pId: "0_1_28", + id: "0_1_28_1", + text: "日喀则市", + value: "日喀则市", + open: true + }, + { + pId: "0_1", + id: "0_1_29", + text: "香港特别行政区( 共1个 )", + value: "香港特别行政区", + open: true + }, + { + pId: "0_1_29", + id: "0_1_29_0", + text: "香港", + value: "香港", + open: true + }, + { + pId: "0_1", + id: "0_1_30", + text: "新疆维吾尔族自治区( 共11个 )", + value: "新疆维吾尔族自治区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_0", + text: "巴音郭楞市", + value: "巴音郭楞市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_1", + text: "哈密市", + value: "哈密市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_2", + text: "和田市", + value: "和田市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_3", + text: "喀什地区", + value: "喀什地区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_4", + text: "克拉玛依市", + value: "克拉玛依市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_5", + text: "克孜勒苏柯州", + value: "克孜勒苏柯州", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_6", + text: "石河子市", + value: "石河子市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_7", + text: "塔城市", + value: "塔城市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_8", + text: "吐鲁番地区", + value: "吐鲁番地区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_9", + text: "乌鲁木齐", + value: "乌鲁木齐", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_10", + text: "伊犁市", + value: "伊犁市", + open: true + }, + { + pId: "0_1", + id: "0_1_31", + text: "云南省( 共12个 )", + value: "云南省", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_0", + text: "保山市", + value: "保山市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_1", + text: "楚雄彝族自治州", + value: "楚雄彝族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_2", + text: "大理白族自治州", + value: "大理白族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_3", + text: "红河哈尼族彝族自治州", + value: "红河哈尼族彝族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_4", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_5", + text: "丽江市", + value: "丽江市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_6", + text: "临沧市", + value: "临沧市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_7", + text: "曲靖市", + value: "曲靖市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_8", + text: "思茅市", + value: "思茅市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_9", + text: "文山市", + value: "文山市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_10", + text: "玉溪市", + value: "玉溪市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_11", + text: "昭通市", + value: "昭通市", + open: true + }, + { + pId: "0_1", + id: "0_1_32", + text: "浙江省( 共12个 )", + value: "浙江省", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_0", + text: "杭州市", + value: "杭州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_1", + text: "湖州市", + value: "湖州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_2", + text: "嘉兴市", + value: "嘉兴市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_3", + text: "金华市", + value: "金华市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_4", + text: "丽水市", + value: "丽水市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_5", + text: "宁波市", + value: "宁波市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_6", + text: "衢州市", + value: "衢州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_7", + text: "绍兴市", + value: "绍兴市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_8", + text: "台州市", + value: "台州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_9", + text: "温州市", + value: "温州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_10", + text: "浙江省", + value: "浙江省", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_11", + text: "舟山市", + value: "舟山市", + open: true + }, + { + pId: "0_1", + id: "0_1_33", + text: "重庆市( 共1个 )", + value: "重庆市", + open: true + }, + { + pId: "0_1_33", + id: "0_1_33_0", + text: "重庆市区", + value: "重庆市区", + open: true + } + ], + + TREE: [ + { id: -1, pId: -2, value: "根目录", text: "根目录" }, + { id: 1, pId: -1, value: "1", text: "第一级目录1", disabled: true }, + { id: 11, pId: 1, value: "11", text: "第二级文件1" }, + { id: 12, pId: 1, value: "12", text: "第二级目录2" }, + { id: 121, pId: 12, value: "121", text: "第三级目录1" }, + { id: 122, pId: 12, value: "122", text: "第三级文件1" }, + { id: 1211, pId: 121, value: "1211", text: "第四级目录1" }, + { + id: 12111, + pId: 1211, + value: "12111", + text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + { id: 2, pId: -1, value: "2", text: "第一级目录2" }, + { id: 21, pId: 2, value: "21", text: "第二级目录3" }, + { id: 22, pId: 2, value: "22", text: "第二级文件2" }, + { id: 211, pId: 21, value: "211", text: "第三级目录2" }, + { id: 212, pId: 21, value: "212", text: "第三级文件2" }, + { id: 2111, pId: 211, value: "2111", text: "第四级文件1" } + ], + LEVELTREE: [ + { + id: 1, + text: "第一项", + value: "1" + }, + { + id: 2, + text: "第二项", + value: "2" + }, + { + id: 3, + text: "第三项", + value: "3", + open: true + }, + { + id: 11, + pId: 1, + text: "子项1", + value: "11" + }, + { + id: 12, + pId: 1, + text: "子项2", + value: "12" + }, + { + id: 13, + pId: 1, + text: "子项3", + value: "13" + }, + { + id: 31, + pId: 3, + text: "子项1", + value: "31" + }, + { + id: 32, + pId: 3, + text: "子项2", + value: "32" + }, + { + id: 33, + pId: 3, + text: "子项3", + value: "33" + } + ] +}; diff --git a/packages/demo/src/config/core.js b/packages/demo/src/config/core.js new file mode 100644 index 000000000..e66c74a8f --- /dev/null +++ b/packages/demo/src/config/core.js @@ -0,0 +1,128 @@ +import { layout, abstract } from "../core"; +import { transModule2Route } from "./utils"; + + + +export const coreConfig = [ + { + id: 1, + text: "核心控件" + }, + { + id: 101, + pId: 1, + text: "布局" + }, + ...transModule2Route(layout, 101), + { + pId: 1, + id: 102, + text: "抽象控件" + }, + ...transModule2Route(abstract, 102), + { + pId: 102, + id: 10201, + text: "组合控件" + }, + // { + // pId: 10201, + // text: "bi.combo", + // value: "demo.combo" + // }, + // { + // pId: 10201, + // text: "bi.combo(各种位置)", + // value: "demo.combo2" + // }, + // { + // pId: 10201, + // text: "bi.combo(內部位置)", + // value: "demo.combo3" + // }, + // { + // pId: 10201, + // text: "bi.expander", + // value: "demo.expander" + // }, + // { + // pId: 10201, + // text: "bi.combo_group", + // value: "demo.combo_group" + // }, + // { + // pId: 10201, + // text: "bi.loader", + // value: "demo.loader" + // }, + // { + // pId: 10201, + // text: "bi.navigation", + // value: "demo.navigation" + // }, + // { + // pId: 10201, + // text: "bi.searcher", + // value: "demo.searcher" + // }, + // { + // pId: 10201, + // text: "bi.switcher", + // value: "demo.switcher" + // }, + // { + // pId: 10201, + // text: "bi.tab", + // value: "demo.tab" + // }, + { + pId: 102, + id: 10202, + text: "弹出层" + }, + // { + // pId: 10202, + // text: "layer", + // value: "demo.layer" + // }, + // { + // pId: 10202, + // text: "bi.popover", + // value: "demo.popover" + // }, + // { + // pId: 10202, + // text: "bi.popup_view", + // value: "demo.popup_view" + // }, + // { + // pId: 10202, + // text: "bi.searcher_view", + // value: "demo.searcher_view" + // }, + // { + // pId: 1, + // text: "Widget(继承)", + // value: "demo.widget" + // }, + // { + // pId: 1, + // text: "Single(继承)", + // value: "demo.single" + // }, + // { + // pId: 1, + // text: "BasicButton(继承)", + // value: "demo.basic_button" + // }, + // { + // pId: 1, + // text: "NodeButton(继承)", + // value: "demo.node_button" + // }, + // { + // pId: 1, + // text: "Pane(继承)", + // value: "demo.pane" + // } +]; diff --git a/packages/demo/src/config/index.js b/packages/demo/src/config/index.js new file mode 100644 index 000000000..100ba07f8 --- /dev/null +++ b/packages/demo/src/config/index.js @@ -0,0 +1,3646 @@ +// import { coreConfig } from "./core"; +// import { baseConfig } from "./base"; +import { map, UUID } from "@fui/core"; +import * as DemoModule from "../demo"; + +const routes = []; +function tranvase(m, parent, text) { + if (m.__esModule) { + const keys = Object.keys(m); + const id = UUID(); + const obj = { + id, + text, + value: id + }; + if (parent) { + obj.pId = parent.id; + routes.push(obj); + } + obj.text = m.meta?.title || text; + keys.sort((keyA, keyB) => { + const rankA = m[keyA].meta?.rank || 0; + const rankB = m[keyB].meta?.rank || 0; + return rankB - rankA; + }); + keys.forEach((key) => { + tranvase(m[key], obj, key); + }); + } else if (m.xtype) { + const obj = { id: m.xtype, value: m.xtype, text: m.xtype }; + if (parent) { + obj.pId = parent.id; + } + routes.push(obj); + } +} +tranvase(DemoModule); + +// console.log(routes); + +export const demoConfig = routes; + +// Demo.CONFIG = Demo.CORE_CONFIG.concat(Demo.BASE_CONFIG) +// .concat(Demo.CASE_CONFIG) +// .concat(Demo.WIDGET_CONFIG) +// .concat(Demo.COMPONENT_CONFIG) +// .concat(Demo.FIX_CONFIG); + +const CONSTANTS = { + SIMPLE_ITEMS: map( + "柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂".match( + /[^\s]+/g + ), + function (i, v) { + return { + text: v, + value: v, + title: v + }; + } + ), + ITEMS: map( + "柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 ".match( + /[^\s]+/g + ), + function (i, v) { + return { + text: v, + value: v, + title: v + }; + } + ), + TREEITEMS: [ + { pId: "0", id: "0_0", text: "( 共25个 )", value: "", open: true }, + { + pId: "0_0", + id: "0_0_0", + text: "安徽省( 共1个 )", + value: "安徽省", + open: true + }, + { + pId: "0_0_0", + id: "0_0_0_0", + text: "芜湖市", + value: "芜湖市", + open: true + }, + { + pId: "0_0", + id: "0_0_1", + text: "北京市( 共6个 )", + value: "北京市", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_0", + text: "北京市区", + value: "北京市区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_1", + text: "朝阳区", + value: "朝阳区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_2", + text: "东城区", + value: "东城区", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_3", + text: "海淀区4内", + value: "海淀区4内", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_4", + text: "海淀区4外", + value: "海淀区4外", + open: true + }, + { + pId: "0_0_1", + id: "0_0_1_5", + text: "石景山区", + value: "石景山区", + open: true + }, + { + pId: "0_0", + id: "0_0_2", + text: "福建省( 共2个 )", + value: "福建省", + open: true + }, + { + pId: "0_0_2", + id: "0_0_2_0", + text: "莆田市", + value: "莆田市", + open: true + }, + { + pId: "0_0_2", + id: "0_0_2_1", + text: "泉州市", + value: "泉州市", + open: true + }, + { + pId: "0_0", + id: "0_0_3", + text: "甘肃省( 共1个 )", + value: "甘肃省", + open: true + }, + { + pId: "0_0_3", + id: "0_0_3_0", + text: "兰州市", + value: "兰州市", + open: true + }, + { + pId: "0_0", + id: "0_0_4", + text: "广东省( 共5个 )", + value: "广东省", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_0", + text: "东莞市", + value: "东莞市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_1", + text: "广州市", + value: "广州市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_2", + text: "惠州市", + value: "惠州市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_3", + text: "深圳市", + value: "深圳市", + open: true + }, + { + pId: "0_0_4", + id: "0_0_4_4", + text: "珠海市", + value: "珠海市", + open: true + }, + { + pId: "0_0", + id: "0_0_5", + text: "广西壮族自治区( 共1个 )", + value: "广西壮族自治区", + open: true + }, + { + pId: "0_0_5", + id: "0_0_5_0", + text: "南宁市", + value: "南宁市", + open: true + }, + { + pId: "0_0", + id: "0_0_6", + text: "河北省( 共2个 )", + value: "河北省", + open: true + }, + { + pId: "0_0_6", + id: "0_0_6_0", + text: "保定市", + value: "保定市", + open: true + }, + { + pId: "0_0_6", + id: "0_0_6_1", + text: "邢台市", + value: "邢台市", + open: true + }, + { + pId: "0_0", + id: "0_0_7", + text: "河南省( 共1个 )", + value: "河南省", + open: true + }, + { + pId: "0_0_7", + id: "0_0_7_0", + text: "郑州市", + value: "郑州市", + open: true + }, + { + pId: "0_0", + id: "0_0_8", + text: "黑龙江省( 共7个 )", + value: "黑龙江省", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_0", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_1", + text: "哈尔滨市", + value: "哈尔滨市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_2", + text: "鸡西市", + value: "鸡西市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_3", + text: "佳木斯市", + value: "佳木斯市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_4", + text: "牡丹江市", + value: "牡丹江市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_5", + text: "齐齐哈尔市", + value: "齐齐哈尔市", + open: true + }, + { + pId: "0_0_8", + id: "0_0_8_6", + text: "双鸭山市", + value: "双鸭山市", + open: true + }, + { + pId: "0_0", + id: "0_0_9", + text: "湖北省( 共1个 )", + value: "湖北省", + open: true + }, + { + pId: "0_0_9", + id: "0_0_9_0", + text: "武汉市", + value: "武汉市", + open: true + }, + { + pId: "0_0", + id: "0_0_10", + text: "湖南省( 共3个 )", + value: "湖南省", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_0", + text: "常德市", + value: "常德市", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_1", + text: "长沙市", + value: "长沙市", + open: true + }, + { + pId: "0_0_10", + id: "0_0_10_2", + text: "邵阳市", + value: "邵阳市", + open: true + }, + { + pId: "0_0", + id: "0_0_11", + text: "吉林省( 共4个 )", + value: "吉林省", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_0", + text: "白山市", + value: "白山市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_1", + text: "长春市", + value: "长春市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_2", + text: "松原市", + value: "松原市", + open: true + }, + { + pId: "0_0_11", + id: "0_0_11_3", + text: "通化市", + value: "通化市", + open: true + }, + { + pId: "0_0", + id: "0_0_12", + text: "江苏省( 共8个 )", + value: "江苏省", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_0", + text: "常州市", + value: "常州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_1", + text: "南京市", + value: "南京市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_2", + text: "南通市", + value: "南通市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_3", + text: "苏州市", + value: "苏州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_4", + text: "宿迁市", + value: "宿迁市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_5", + text: "泰州市", + value: "泰州市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_6", + text: "无锡市", + value: "无锡市", + open: true + }, + { + pId: "0_0_12", + id: "0_0_12_7", + text: "盐城市", + value: "盐城市", + open: true + }, + { + pId: "0_0", + id: "0_0_13", + text: "辽宁省( 共11个 )", + value: "辽宁省", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_0", + text: "鞍山市", + value: "鞍山市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_1", + text: "本溪市", + value: "本溪市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_2", + text: "朝阳市", + value: "朝阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_3", + text: "大连市", + value: "大连市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_4", + text: "抚顺市", + value: "抚顺市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_5", + text: "葫芦岛市", + value: "葫芦岛市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_6", + text: "锦州市", + value: "锦州市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_7", + text: "辽阳市", + value: "辽阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_8", + text: "盘锦市", + value: "盘锦市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_9", + text: "沈阳市", + value: "沈阳市", + open: true + }, + { + pId: "0_0_13", + id: "0_0_13_10", + text: "营口市", + value: "营口市", + open: true + }, + { + pId: "0_0", + id: "0_0_14", + text: "内蒙古( 共1个 )", + value: "内蒙古", + open: true + }, + { + pId: "0_0_14", + id: "0_0_14_0", + text: "鄂尔多斯市", + value: "鄂尔多斯市", + open: true + }, + { + pId: "0_0", + id: "0_0_15", + text: "宁夏回族自治区( 共1个 )", + value: "宁夏回族自治区", + open: true + }, + { + pId: "0_0_15", + id: "0_0_15_0", + text: "银川市", + value: "银川市", + open: true + }, + { + pId: "0_0", + id: "0_0_16", + text: "山东省( 共7个 )", + value: "山东省", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_0", + text: "济南市", + value: "济南市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_1", + text: "济宁市", + value: "济宁市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_2", + text: "聊城市", + value: "聊城市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_3", + text: "临沂市", + value: "临沂市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_4", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_5", + text: "烟台市", + value: "烟台市", + open: true + }, + { + pId: "0_0_16", + id: "0_0_16_6", + text: "枣庄市", + value: "枣庄市", + open: true + }, + { + pId: "0_0", + id: "0_0_17", + text: "山西省( 共1个 )", + value: "山西省", + open: true + }, + { + pId: "0_0_17", + id: "0_0_17_0", + text: "太原市", + value: "太原市", + open: true + }, + { + pId: "0_0", + id: "0_0_18", + text: "陕西省( 共1个 )", + value: "陕西省", + open: true + }, + { + pId: "0_0_18", + id: "0_0_18_0", + text: "西安市", + value: "西安市", + open: true + }, + { + pId: "0_0", + id: "0_0_19", + text: "上海市( 共1个 )", + value: "上海市", + open: true + }, + { + pId: "0_0_19", + id: "0_0_19_0", + text: "上海市区", + value: "上海市区", + open: true + }, + { + pId: "0_0", + id: "0_0_20", + text: "四川省( 共1个 )", + value: "四川省", + open: true + }, + { + pId: "0_0_20", + id: "0_0_20_0", + text: "成都市", + value: "成都市", + open: true + }, + { + pId: "0_0", + id: "0_0_21", + text: "新疆维吾尔族自治区( 共2个 )", + value: "新疆维吾尔族自治区", + open: true + }, + { + pId: "0_0_21", + id: "0_0_21_0", + text: "吐鲁番地区", + value: "吐鲁番地区", + open: true + }, + { + pId: "0_0_21", + id: "0_0_21_1", + text: "乌鲁木齐", + value: "乌鲁木齐", + open: true + }, + { + pId: "0_0", + id: "0_0_22", + text: "云南省( 共1个 )", + value: "云南省", + open: true + }, + { + pId: "0_0_22", + id: "0_0_22_0", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_0", + id: "0_0_23", + text: "浙江省( 共5个 )", + value: "浙江省", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_0", + text: "杭州市", + value: "杭州市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_1", + text: "湖州市", + value: "湖州市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_2", + text: "嘉兴市", + value: "嘉兴市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_3", + text: "宁波市", + value: "宁波市", + open: true + }, + { + pId: "0_0_23", + id: "0_0_23_4", + text: "绍兴市", + value: "绍兴市", + open: true + }, + { + pId: "0_0", + id: "0_0_24", + text: "重庆市( 共1个 )", + value: "重庆市", + open: true + }, + { + pId: "0_0_24", + id: "0_0_24_0", + text: "重庆市区", + value: "重庆市区", + open: true + }, + { + pId: "0", + id: "0_1", + text: "中国( 共34个 )", + value: "中国", + open: true + }, + { + pId: "0_1", + id: "0_1_0", + text: "安徽省( 共19个 )", + value: "安徽省", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_0", + text: "安庆市", + value: "安庆市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_1", + text: "蚌埠市", + value: "蚌埠市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_2", + text: "亳州市", + value: "亳州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_3", + text: "巢湖市", + value: "巢湖市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_4", + text: "池州市", + value: "池州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_5", + text: "滁州市", + value: "滁州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_6", + text: "阜阳市", + value: "阜阳市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_7", + text: "毫州市", + value: "毫州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_8", + text: "合肥市", + value: "合肥市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_9", + text: "淮北市", + value: "淮北市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_10", + text: "淮南市", + value: "淮南市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_11", + text: "黄山市", + value: "黄山市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_12", + text: "六安市", + value: "六安市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_13", + text: "马鞍山市", + value: "马鞍山市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_14", + text: "濮阳市", + value: "濮阳市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_15", + text: "宿州市", + value: "宿州市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_16", + text: "铜陵市", + value: "铜陵市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_17", + text: "芜湖市", + value: "芜湖市", + open: true + }, + { + pId: "0_1_0", + id: "0_1_0_18", + text: "宣城市", + value: "宣城市", + open: true + }, + { + pId: "0_1", + id: "0_1_1", + text: "澳门特别行政区( 共1个 )", + value: "澳门特别行政区", + open: true + }, + { + pId: "0_1_1", + id: "0_1_1_0", + text: "澳门", + value: "澳门", + open: true + }, + { + pId: "0_1", + id: "0_1_2", + text: "北京市( 共17个 )", + value: "北京市", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_0", + text: "北京市区", + value: "北京市区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_1", + text: "昌平区", + value: "昌平区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_2", + text: "朝阳区", + value: "朝阳区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_3", + text: "大兴区", + value: "大兴区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_4", + text: "东城区", + value: "东城区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_5", + text: "房山区", + value: "房山区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_6", + text: "丰台区", + value: "丰台区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_7", + text: "海淀区", + value: "海淀区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_8", + text: "海淀区4内", + value: "海淀区4内", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_9", + text: "海淀区4外", + value: "海淀区4外", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_10", + text: "门头沟区", + value: "门头沟区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_11", + text: "平谷区", + value: "平谷区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_12", + text: "石景山区", + value: "石景山区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_13", + text: "顺义区", + value: "顺义区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_14", + text: "通州区", + value: "通州区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_15", + text: "西城区", + value: "西城区", + open: true + }, + { + pId: "0_1_2", + id: "0_1_2_16", + text: "西城区 ", + value: "西城区 ", + open: true + }, + { + pId: "0_1", + id: "0_1_3", + text: "福建省( 共9个 )", + value: "福建省", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_0", + text: "福州市", + value: "福州市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_1", + text: "龙岩市", + value: "龙岩市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_2", + text: "南平市", + value: "南平市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_3", + text: "宁德市", + value: "宁德市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_4", + text: "莆田市", + value: "莆田市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_5", + text: "泉州市", + value: "泉州市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_6", + text: "三明市", + value: "三明市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_7", + text: "厦门市", + value: "厦门市", + open: true + }, + { + pId: "0_1_3", + id: "0_1_3_8", + text: "漳州市", + value: "漳州市", + open: true + }, + { + pId: "0_1", + id: "0_1_4", + text: "甘肃省( 共12个 )", + value: "甘肃省", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_0", + text: "白银市", + value: "白银市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_1", + text: "嘉峪关市", + value: "嘉峪关市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_2", + text: "金昌市", + value: "金昌市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_3", + text: "酒泉市", + value: "酒泉市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_4", + text: "兰州市", + value: "兰州市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_5", + text: "陇南市", + value: "陇南市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_6", + text: "平凉市", + value: "平凉市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_7", + text: "庆阳市", + value: "庆阳市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_8", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_9", + text: "天水市", + value: "天水市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_10", + text: "武威市", + value: "武威市", + open: true + }, + { + pId: "0_1_4", + id: "0_1_4_11", + text: "张掖市", + value: "张掖市", + open: true + }, + { + pId: "0_1", + id: "0_1_5", + text: "广东省( 共21个 )", + value: "广东省", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_0", + text: "潮州市", + value: "潮州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_1", + text: "东莞市", + value: "东莞市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_2", + text: "佛山市", + value: "佛山市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_3", + text: "广州市", + value: "广州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_4", + text: "河源市", + value: "河源市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_5", + text: "惠州市", + value: "惠州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_6", + text: "江门市", + value: "江门市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_7", + text: "揭阳市", + value: "揭阳市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_8", + text: "茂名市", + value: "茂名市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_9", + text: "梅州市", + value: "梅州市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_10", + text: "清远市", + value: "清远市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_11", + text: "汕头市", + value: "汕头市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_12", + text: "汕尾市", + value: "汕尾市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_13", + text: "韶关市", + value: "韶关市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_14", + text: "深圳市", + value: "深圳市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_15", + text: "阳江市", + value: "阳江市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_16", + text: "云浮市", + value: "云浮市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_17", + text: "湛江市", + value: "湛江市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_18", + text: "肇庆市", + value: "肇庆市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_19", + text: "中山市", + value: "中山市", + open: true + }, + { + pId: "0_1_5", + id: "0_1_5_20", + text: "珠海市", + value: "珠海市", + open: true + }, + { + pId: "0_1", + id: "0_1_6", + text: "广西壮族自治区( 共14个 )", + value: "广西壮族自治区", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_0", + text: "百色市", + value: "百色市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_1", + text: "北海市", + value: "北海市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_2", + text: "崇左市", + value: "崇左市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_3", + text: "防城港市", + value: "防城港市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_4", + text: "桂林市", + value: "桂林市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_5", + text: "贵港市", + value: "贵港市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_6", + text: "河池市", + value: "河池市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_7", + text: "贺州市", + value: "贺州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_8", + text: "来宾市", + value: "来宾市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_9", + text: "柳州市", + value: "柳州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_10", + text: "南宁市", + value: "南宁市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_11", + text: "钦州市", + value: "钦州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_12", + text: "梧州市", + value: "梧州市", + open: true + }, + { + pId: "0_1_6", + id: "0_1_6_13", + text: "玉林市", + value: "玉林市", + open: true + }, + { + pId: "0_1", + id: "0_1_7", + text: "贵州省( 共9个 )", + value: "贵州省", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_0", + text: "安顺市", + value: "安顺市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_1", + text: "毕节地区", + value: "毕节地区", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_2", + text: "贵阳市", + value: "贵阳市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_3", + text: "六盘水市", + value: "六盘水市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_4", + text: "黔东南州", + value: "黔东南州", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_5", + text: "黔南州", + value: "黔南州", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_6", + text: "黔西南市", + value: "黔西南市", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_7", + text: "铜仁地区", + value: "铜仁地区", + open: true + }, + { + pId: "0_1_7", + id: "0_1_7_8", + text: "遵义市", + value: "遵义市", + open: true + }, + { + pId: "0_1", + id: "0_1_8", + text: "海南省( 共2个 )", + value: "海南省", + open: true + }, + { + pId: "0_1_8", + id: "0_1_8_0", + text: "海口市", + value: "海口市", + open: true + }, + { + pId: "0_1_8", + id: "0_1_8_1", + text: "三亚市", + value: "三亚市", + open: true + }, + { + pId: "0_1", + id: "0_1_9", + text: "河北省( 共12个 )", + value: "河北省", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_0", + text: "保定市", + value: "保定市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_1", + text: "沧州市", + value: "沧州市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_2", + text: "承德市", + value: "承德市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_3", + text: "邯郸市", + value: "邯郸市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_4", + text: "衡水市", + value: "衡水市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_5", + text: "廊坊市", + value: "廊坊市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_6", + text: "秦皇岛市", + value: "秦皇岛市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_7", + text: "石家庄市", + value: "石家庄市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_8", + text: "唐山市", + value: "唐山市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_9", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_10", + text: "邢台市", + value: "邢台市", + open: true + }, + { + pId: "0_1_9", + id: "0_1_9_11", + text: "张家口市", + value: "张家口市", + open: true + }, + { + pId: "0_1", + id: "0_1_10", + text: "河南省( 共19个 )", + value: "河南省", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_0", + text: "安阳市", + value: "安阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_1", + text: "鹤壁市", + value: "鹤壁市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_2", + text: "济源市", + value: "济源市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_3", + text: "焦作市", + value: "焦作市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_4", + text: "开封市", + value: "开封市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_5", + text: "廊坊市", + value: "廊坊市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_6", + text: "洛阳市", + value: "洛阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_7", + text: "漯河市", + value: "漯河市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_8", + text: "南阳市", + value: "南阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_9", + text: "平顶山市", + value: "平顶山市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_10", + text: "濮阳市", + value: "濮阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_11", + text: "三门峡市", + value: "三门峡市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_12", + text: "商丘市", + value: "商丘市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_13", + text: "新乡市", + value: "新乡市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_14", + text: "信阳市", + value: "信阳市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_15", + text: "许昌市", + value: "许昌市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_16", + text: "郑州市", + value: "郑州市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_17", + text: "周口市", + value: "周口市", + open: true + }, + { + pId: "0_1_10", + id: "0_1_10_18", + text: "驻马店市", + value: "驻马店市", + open: true + }, + { + pId: "0_1", + id: "0_1_11", + text: "黑龙江省( 共13个 )", + value: "黑龙江省", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_0", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_1", + text: "大兴安岭地区", + value: "大兴安岭地区", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_2", + text: "大兴安岭市", + value: "大兴安岭市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_3", + text: "哈尔滨市", + value: "哈尔滨市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_4", + text: "鹤港市", + value: "鹤港市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_5", + text: "黑河市", + value: "黑河市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_6", + text: "佳木斯市", + value: "佳木斯市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_7", + text: "牡丹江市", + value: "牡丹江市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_8", + text: "七台河市", + value: "七台河市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_9", + text: "齐齐哈尔市", + value: "齐齐哈尔市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_10", + text: "双鸭山市", + value: "双鸭山市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_11", + text: "绥化市", + value: "绥化市", + open: true + }, + { + pId: "0_1_11", + id: "0_1_11_12", + text: "伊春市", + value: "伊春市", + open: true + }, + { + pId: "0_1", + id: "0_1_12", + text: "湖北省( 共16个 )", + value: "湖北省", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_0", + text: "鄂州市", + value: "鄂州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_1", + text: "恩施土家族苗族自治州", + value: "恩施土家族苗族自治州", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_2", + text: "黄冈市", + value: "黄冈市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_3", + text: "黄石市", + value: "黄石市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_4", + text: "荆门市", + value: "荆门市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_5", + text: "荆州市", + value: "荆州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_6", + text: "神农架市", + value: "神农架市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_7", + text: "十堰市", + value: "十堰市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_8", + text: "随州市", + value: "随州市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_9", + text: "天门市", + value: "天门市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_10", + text: "武汉市", + value: "武汉市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_11", + text: "咸宁市", + value: "咸宁市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_12", + text: "襄樊市", + value: "襄樊市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_13", + text: "襄阳市", + value: "襄阳市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_14", + text: "孝感市", + value: "孝感市", + open: true + }, + { + pId: "0_1_12", + id: "0_1_12_15", + text: "宜昌市", + value: "宜昌市", + open: true + }, + { + pId: "0_1", + id: "0_1_13", + text: "湖南省( 共15个 )", + value: "湖南省", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_0", + text: "常德市", + value: "常德市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_1", + text: "长沙市", + value: "长沙市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_2", + text: "郴州市", + value: "郴州市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_3", + text: "衡阳市", + value: "衡阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_4", + text: "怀化市", + value: "怀化市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_5", + text: "娄底市", + value: "娄底市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_6", + text: "邵阳市", + value: "邵阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_7", + text: "湘潭市", + value: "湘潭市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_8", + text: "湘西市", + value: "湘西市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_9", + text: "湘西土家族苗族自治州", + value: "湘西土家族苗族自治州", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_10", + text: "益阳市", + value: "益阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_11", + text: "永州市", + value: "永州市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_12", + text: "岳阳市", + value: "岳阳市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_13", + text: "张家界市", + value: "张家界市", + open: true + }, + { + pId: "0_1_13", + id: "0_1_13_14", + text: "株洲市", + value: "株洲市", + open: true + }, + { + pId: "0_1", + id: "0_1_14", + text: "吉林省( 共10个 )", + value: "吉林省", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_0", + text: "白城市", + value: "白城市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_1", + text: "白山市", + value: "白山市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_2", + text: "长春市", + value: "长春市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_3", + text: "大庆市", + value: "大庆市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_4", + text: "吉林市", + value: "吉林市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_5", + text: "辽源市", + value: "辽源市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_6", + text: "四平市", + value: "四平市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_7", + text: "松原市", + value: "松原市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_8", + text: "通化市", + value: "通化市", + open: true + }, + { + pId: "0_1_14", + id: "0_1_14_9", + text: "延边朝鲜族自治州", + value: "延边朝鲜族自治州", + open: true + }, + { + pId: "0_1", + id: "0_1_15", + text: "江苏省( 共13个 )", + value: "江苏省", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_0", + text: "常州市", + value: "常州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_1", + text: "淮安市", + value: "淮安市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_2", + text: "连云港市", + value: "连云港市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_3", + text: "南京市", + value: "南京市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_4", + text: "南通市", + value: "南通市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_5", + text: "苏州市", + value: "苏州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_6", + text: "宿迁市", + value: "宿迁市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_7", + text: "泰州市", + value: "泰州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_8", + text: "无锡市", + value: "无锡市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_9", + text: "徐州市", + value: "徐州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_10", + text: "盐城市", + value: "盐城市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_11", + text: "扬州市", + value: "扬州市", + open: true + }, + { + pId: "0_1_15", + id: "0_1_15_12", + text: "镇江市", + value: "镇江市", + open: true + }, + { + pId: "0_1", + id: "0_1_16", + text: "江西省( 共10个 )", + value: "江西省", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_0", + text: "抚州市", + value: "抚州市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_1", + text: "赣州市", + value: "赣州市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_2", + text: "景德镇市", + value: "景德镇市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_3", + text: "九江市", + value: "九江市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_4", + text: "南昌市", + value: "南昌市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_5", + text: "萍乡市", + value: "萍乡市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_6", + text: "上饶市", + value: "上饶市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_7", + text: "新余市", + value: "新余市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_8", + text: "宜春市", + value: "宜春市", + open: true + }, + { + pId: "0_1_16", + id: "0_1_16_9", + text: "鹰潭市", + value: "鹰潭市", + open: true + }, + { + pId: "0_1", + id: "0_1_17", + text: "辽宁省( 共14个 )", + value: "辽宁省", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_0", + text: "鞍山市", + value: "鞍山市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_1", + text: "本溪市", + value: "本溪市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_2", + text: "朝阳市", + value: "朝阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_3", + text: "大连市", + value: "大连市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_4", + text: "丹东市", + value: "丹东市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_5", + text: "抚顺市", + value: "抚顺市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_6", + text: "阜新市", + value: "阜新市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_7", + text: "葫芦岛市", + value: "葫芦岛市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_8", + text: "锦州市", + value: "锦州市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_9", + text: "辽阳市", + value: "辽阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_10", + text: "盘锦市", + value: "盘锦市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_11", + text: "沈阳市", + value: "沈阳市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_12", + text: "铁岭市", + value: "铁岭市", + open: true + }, + { + pId: "0_1_17", + id: "0_1_17_13", + text: "营口市", + value: "营口市", + open: true + }, + { + pId: "0_1", + id: "0_1_18", + text: "内蒙古( 共10个 )", + value: "内蒙古", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_0", + text: "包头市", + value: "包头市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_1", + text: "赤峰市", + value: "赤峰市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_2", + text: "鄂尔多斯市", + value: "鄂尔多斯市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_3", + text: "呼和浩特市", + value: "呼和浩特市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_4", + text: "呼伦贝尔市", + value: "呼伦贝尔市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_5", + text: "通辽市", + value: "通辽市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_6", + text: "乌海市", + value: "乌海市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_7", + text: "锡林郭勒市", + value: "锡林郭勒市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_8", + text: "兴安市", + value: "兴安市", + open: true + }, + { + pId: "0_1_18", + id: "0_1_18_9", + text: "运城市", + value: "运城市", + open: true + }, + { + pId: "0_1", + id: "0_1_19", + text: "宁夏回族自治区( 共5个 )", + value: "宁夏回族自治区", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_0", + text: "固原市", + value: "固原市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_1", + text: "石嘴山市", + value: "石嘴山市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_2", + text: "吴忠市", + value: "吴忠市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_3", + text: "银川市", + value: "银川市", + open: true + }, + { + pId: "0_1_19", + id: "0_1_19_4", + text: "中卫市", + value: "中卫市", + open: true + }, + { + pId: "0_1", + id: "0_1_20", + text: "青海省( 共4个 )", + value: "青海省", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_0", + text: "海东地区", + value: "海东地区", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_1", + text: "海南藏族自治州", + value: "海南藏族自治州", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_2", + text: "海西蒙古族藏族自治州", + value: "海西蒙古族藏族自治州", + open: true + }, + { + pId: "0_1_20", + id: "0_1_20_3", + text: "西宁市", + value: "西宁市", + open: true + }, + { + pId: "0_1", + id: "0_1_21", + text: "山东省( 共17个 )", + value: "山东省", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_0", + text: "滨州市", + value: "滨州市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_1", + text: "德州市", + value: "德州市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_2", + text: "东营市", + value: "东营市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_3", + text: "菏泽市", + value: "菏泽市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_4", + text: "济南市", + value: "济南市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_5", + text: "济宁市", + value: "济宁市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_6", + text: "莱芜市", + value: "莱芜市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_7", + text: "聊城市", + value: "聊城市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_8", + text: "临沂市", + value: "临沂市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_9", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_10", + text: "日照市", + value: "日照市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_11", + text: "泰安市", + value: "泰安市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_12", + text: "威海市", + value: "威海市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_13", + text: "潍坊市", + value: "潍坊市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_14", + text: "烟台市", + value: "烟台市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_15", + text: "枣庄市", + value: "枣庄市", + open: true + }, + { + pId: "0_1_21", + id: "0_1_21_16", + text: "淄博市", + value: "淄博市", + open: true + }, + { + pId: "0_1", + id: "0_1_22", + text: "山西省( 共12个 )", + value: "山西省", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_0", + text: "长治市", + value: "长治市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_1", + text: "大同市", + value: "大同市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_2", + text: "晋城市", + value: "晋城市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_3", + text: "晋中市", + value: "晋中市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_4", + text: "临汾市", + value: "临汾市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_5", + text: "吕梁市", + value: "吕梁市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_6", + text: "青岛市", + value: "青岛市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_7", + text: "朔州市", + value: "朔州市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_8", + text: "太原市", + value: "太原市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_9", + text: "忻州市", + value: "忻州市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_10", + text: "阳泉市", + value: "阳泉市", + open: true + }, + { + pId: "0_1_22", + id: "0_1_22_11", + text: "运城市", + value: "运城市", + open: true + }, + { + pId: "0_1", + id: "0_1_23", + text: "陕西省( 共9个 )", + value: "陕西省", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_0", + text: "安康市", + value: "安康市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_1", + text: "宝鸡市", + value: "宝鸡市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_2", + text: "汉中市", + value: "汉中市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_3", + text: "商洛市", + value: "商洛市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_4", + text: "渭南市", + value: "渭南市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_5", + text: "西安市", + value: "西安市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_6", + text: "咸阳市", + value: "咸阳市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_7", + text: "延安市", + value: "延安市", + open: true + }, + { + pId: "0_1_23", + id: "0_1_23_8", + text: "榆林市", + value: "榆林市", + open: true + }, + { + pId: "0_1", + id: "0_1_24", + text: "上海市( 共19个 )", + value: "上海市", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_0", + text: "宝山区", + value: "宝山区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_1", + text: "长宁区", + value: "长宁区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_2", + text: "崇明县", + value: "崇明县", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_3", + text: "奉贤区", + value: "奉贤区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_4", + text: "虹口区", + value: "虹口区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_5", + text: "黄浦区", + value: "黄浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_6", + text: "嘉定区", + value: "嘉定区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_7", + text: "金山区", + value: "金山区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_8", + text: "静安区", + value: "静安区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_9", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_10", + text: "闵行区", + value: "闵行区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_11", + text: "普陀区", + value: "普陀区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_12", + text: "浦东新区", + value: "浦东新区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_13", + text: "青浦区", + value: "青浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_14", + text: "上海市区", + value: "上海市区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_15", + text: "松江区", + value: "松江区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_16", + text: "徐汇区", + value: "徐汇区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_17", + text: "杨浦区", + value: "杨浦区", + open: true + }, + { + pId: "0_1_24", + id: "0_1_24_18", + text: "闸北区", + value: "闸北区", + open: true + }, + { + pId: "0_1", + id: "0_1_25", + text: "四川省( 共21个 )", + value: "四川省", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_0", + text: "阿坝藏族羌族自治州", + value: "阿坝藏族羌族自治州", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_1", + text: "巴中市", + value: "巴中市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_2", + text: "成都市", + value: "成都市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_3", + text: "达州市", + value: "达州市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_4", + text: "德阳市", + value: "德阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_5", + text: "甘孜市", + value: "甘孜市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_6", + text: "广安市", + value: "广安市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_7", + text: "广元市", + value: "广元市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_8", + text: "乐山市", + value: "乐山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_9", + text: "凉山市", + value: "凉山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_10", + text: "泸州市", + value: "泸州市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_11", + text: "眉山市", + value: "眉山市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_12", + text: "绵阳市", + value: "绵阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_13", + text: "南充市", + value: "南充市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_14", + text: "内江市", + value: "内江市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_15", + text: "攀枝花市", + value: "攀枝花市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_16", + text: "遂宁市", + value: "遂宁市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_17", + text: "雅安市", + value: "雅安市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_18", + text: "宜宾市", + value: "宜宾市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_19", + text: "资阳市", + value: "资阳市", + open: true + }, + { + pId: "0_1_25", + id: "0_1_25_20", + text: "自贡市", + value: "自贡市", + open: true + }, + { + pId: "0_1", + id: "0_1_26", + text: "台湾( 共1个 )", + value: "台湾", + open: true + }, + { + pId: "0_1_26", + id: "0_1_26_0", + text: "台北市", + value: "台北市", + open: true + }, + { + pId: "0_1", + id: "0_1_27", + text: "天津市( 共1个 )", + value: "天津市", + open: true + }, + { + pId: "0_1_27", + id: "0_1_27_0", + text: "天津市区", + value: "天津市区", + open: true + }, + { + pId: "0_1", + id: "0_1_28", + text: "西藏自治区( 共2个 )", + value: "西藏自治区", + open: true + }, + { + pId: "0_1_28", + id: "0_1_28_0", + text: "阿里市", + value: "阿里市", + open: true + }, + { + pId: "0_1_28", + id: "0_1_28_1", + text: "日喀则市", + value: "日喀则市", + open: true + }, + { + pId: "0_1", + id: "0_1_29", + text: "香港特别行政区( 共1个 )", + value: "香港特别行政区", + open: true + }, + { + pId: "0_1_29", + id: "0_1_29_0", + text: "香港", + value: "香港", + open: true + }, + { + pId: "0_1", + id: "0_1_30", + text: "新疆维吾尔族自治区( 共11个 )", + value: "新疆维吾尔族自治区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_0", + text: "巴音郭楞市", + value: "巴音郭楞市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_1", + text: "哈密市", + value: "哈密市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_2", + text: "和田市", + value: "和田市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_3", + text: "喀什地区", + value: "喀什地区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_4", + text: "克拉玛依市", + value: "克拉玛依市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_5", + text: "克孜勒苏柯州", + value: "克孜勒苏柯州", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_6", + text: "石河子市", + value: "石河子市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_7", + text: "塔城市", + value: "塔城市", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_8", + text: "吐鲁番地区", + value: "吐鲁番地区", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_9", + text: "乌鲁木齐", + value: "乌鲁木齐", + open: true + }, + { + pId: "0_1_30", + id: "0_1_30_10", + text: "伊犁市", + value: "伊犁市", + open: true + }, + { + pId: "0_1", + id: "0_1_31", + text: "云南省( 共12个 )", + value: "云南省", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_0", + text: "保山市", + value: "保山市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_1", + text: "楚雄彝族自治州", + value: "楚雄彝族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_2", + text: "大理白族自治州", + value: "大理白族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_3", + text: "红河哈尼族彝族自治州", + value: "红河哈尼族彝族自治州", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_4", + text: "昆明市", + value: "昆明市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_5", + text: "丽江市", + value: "丽江市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_6", + text: "临沧市", + value: "临沧市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_7", + text: "曲靖市", + value: "曲靖市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_8", + text: "思茅市", + value: "思茅市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_9", + text: "文山市", + value: "文山市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_10", + text: "玉溪市", + value: "玉溪市", + open: true + }, + { + pId: "0_1_31", + id: "0_1_31_11", + text: "昭通市", + value: "昭通市", + open: true + }, + { + pId: "0_1", + id: "0_1_32", + text: "浙江省( 共12个 )", + value: "浙江省", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_0", + text: "杭州市", + value: "杭州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_1", + text: "湖州市", + value: "湖州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_2", + text: "嘉兴市", + value: "嘉兴市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_3", + text: "金华市", + value: "金华市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_4", + text: "丽水市", + value: "丽水市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_5", + text: "宁波市", + value: "宁波市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_6", + text: "衢州市", + value: "衢州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_7", + text: "绍兴市", + value: "绍兴市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_8", + text: "台州市", + value: "台州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_9", + text: "温州市", + value: "温州市", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_10", + text: "浙江省", + value: "浙江省", + open: true + }, + { + pId: "0_1_32", + id: "0_1_32_11", + text: "舟山市", + value: "舟山市", + open: true + }, + { + pId: "0_1", + id: "0_1_33", + text: "重庆市( 共1个 )", + value: "重庆市", + open: true + }, + { + pId: "0_1_33", + id: "0_1_33_0", + text: "重庆市区", + value: "重庆市区", + open: true + } + ], + + TREE: [ + { id: -1, pId: -2, value: "根目录", text: "根目录" }, + { id: 1, pId: -1, value: "1", text: "第一级目录1", disabled: true }, + { id: 11, pId: 1, value: "11", text: "第二级文件1" }, + { id: 12, pId: 1, value: "12", text: "第二级目录2" }, + { id: 121, pId: 12, value: "121", text: "第三级目录1" }, + { id: 122, pId: 12, value: "122", text: "第三级文件1" }, + { id: 1211, pId: 121, value: "1211", text: "第四级目录1" }, + { + id: 12111, + pId: 1211, + value: "12111", + text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + { id: 2, pId: -1, value: "2", text: "第一级目录2" }, + { id: 21, pId: 2, value: "21", text: "第二级目录3" }, + { id: 22, pId: 2, value: "22", text: "第二级文件2" }, + { id: 211, pId: 21, value: "211", text: "第三级目录2" }, + { id: 212, pId: 21, value: "212", text: "第三级文件2" }, + { id: 2111, pId: 211, value: "2111", text: "第四级文件1" } + ], + LEVELTREE: [ + { + id: 1, + text: "第一项", + value: "1" + }, + { + id: 2, + text: "第二项", + value: "2" + }, + { + id: 3, + text: "第三项", + value: "3", + open: true + }, + { + id: 11, + pId: 1, + text: "子项1", + value: "11" + }, + { + id: 12, + pId: 1, + text: "子项2", + value: "12" + }, + { + id: 13, + pId: 1, + text: "子项3", + value: "13" + }, + { + id: 31, + pId: 3, + text: "子项1", + value: "31" + }, + { + id: 32, + pId: 3, + text: "子项2", + value: "32" + }, + { + id: 33, + pId: 3, + text: "子项3", + value: "33" + } + ] +}; diff --git a/packages/demo/src/config/utils.js b/packages/demo/src/config/utils.js new file mode 100644 index 000000000..b58889c94 --- /dev/null +++ b/packages/demo/src/config/utils.js @@ -0,0 +1,17 @@ +/** + * 把模块转换成路由信息 + * @param {ESModule} module + * @param {string} pId + * @returns + */ +export function transModule2Route(module, pId) { + return Object.keys(module).map((key) => { + const item = module[key]; + const text = item.demoText || item.xtype; + return { + pId, + value: item.xtype, + text: text + }; + }); +} diff --git a/packages/demo/src/demo/base/button/demo.button.js b/packages/demo/src/demo/base/button/demo.button.js new file mode 100644 index 000000000..5da0253b6 --- /dev/null +++ b/packages/demo/src/demo/base/button/demo.button.js @@ -0,0 +1,438 @@ + +import { Button, TextButton, FloatLeftLayout, Decorators, Widget, parseInt, Msg, map } from "@fui/core" + + +@Decorators.shortcut() +export class ButtonDemo extends Widget { + static xtype = "demo.button"; + + props = { baseCls: "demo-button" }; + + render() { + const items = [ + { + type: Button.xtype, + text: "一般按钮1111111111111", + level: "common", + whiteSpace: "nowrap", + width: 100, + height: 30, + handler() { + console.log("触发点击事件"); + this.loading(); + setTimeout(() => { + this.loaded(); + }, 5 * 1000); + }, + }, + { + type: Button.xtype, + text: "表示成功状态按钮", + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "表示警告状态的按钮", + level: "warning", + height: 30, + }, + { + type: Button.xtype, + text: "表示错误状态的按钮", + level: "error", + height: 30, + }, + { + type: Button.xtype, + text: "表示忽略状态的按钮", + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "普通灰化按钮", + disabled: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "忽略状态灰化按钮", + disabled: true, + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "带图标的按钮", + // level: 'ignore', + iconCls: "close-font", + height: 30, + }, + { + type: Button.xtype, + text: "一般按钮", + block: true, + level: "common", + height: 30, + }, + { + type: Button.xtype, + text: "表示成功状态按钮", + block: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "表示警告状态的按钮", + block: true, + level: "warning", + height: 30, + }, + { + type: Button.xtype, + text: "表示忽略状态的按钮", + block: true, + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "普通灰化按钮", + block: true, + disabled: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "忽略状态灰化按钮", + block: true, + disabled: true, + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "带图标的按钮", + block: true, + // level: 'ignore', + iconCls: "close-font", + height: 30, + }, + { + type: Button.xtype, + text: "一般按钮", + clear: true, + level: "common", + height: 30, + }, + { + type: Button.xtype, + text: "表示成功状态按钮", + clear: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "表示警告状态的按钮", + clear: true, + level: "warning", + height: 30, + }, + { + type: Button.xtype, + text: "表示忽略状态的按钮", + clear: true, + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "普通灰化按钮", + clear: true, + disabled: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "忽略状态灰化按钮", + clear: true, + disabled: true, + level: "ignore", + height: 30, + }, + { + type: Button.xtype, + text: "带图标的按钮", + clear: true, + // level: 'ignore', + iconCls: "close-font", + height: 30, + }, + { + type: TextButton.xtype, + text: "文字按钮", + height: 30, + }, + { + type: Button.xtype, + text: "幽灵按钮(common)", + ghost: true, + height: 30, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "幽灵按钮(common)", + ghost: true, + height: 30, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "幽灵按钮(common)", + ghost: true, + level: "warning", + height: 30, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "幽灵按钮(common)", + ghost: true, + level: "error", + height: 30, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "幽灵按钮(common)", + ghost: true, + level: "success", + height: 30, + }, + { + type: Button.xtype, + text: "幽灵按钮(common)灰化", + disabled: true, + ghost: true, + height: 30, + }, + { + type: Button.xtype, + text: "弹出bubble", + bubble() { + return `${parseInt(Math.random() * 100) % 10}提示`; + }, + handler() { + Msg.toast("1111"); + }, + height: 30, + }, + { + type: Button.xtype, + text: "自动撑开", + iconCls: "close-font", + // textHeight: 32, + // height: 32, + iconGap: 64, + vgap: 16, + hgap: 100, + iconPosition: "bottom", + }, + { + type: Button.xtype, + text: "图标在下面的按钮", + iconCls: "close-font", + iconPosition: "bottom", + }, + { + type: Button.xtype, + text: "图标在左边的按钮", + iconCls: "close-font", + iconPosition: "left", + }, + { + type: Button.xtype, + text: "图标在右边的按钮", + iconCls: "close-font", + iconPosition: "right", + }, + { + type: Button.xtype, + text: "浅色的一般按钮", + iconCls: "plus-font", + light: true, + }, + { + type: Button.xtype, + text: "浅色的成功按钮", + level: "success", + iconCls: "plus-font", + light: true, + }, + { + type: Button.xtype, + text: "浅色的警告按钮", + level: "warning", + iconCls: "plus-font", + light: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "浅色的失败按钮", + level: "error", + cls: "hover-mask", + light: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + level: "common", + plain: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + level: "success", + plain: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + level: "error", + plain: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + level: "warning", + plain: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + level: "ignore", + plain: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + plain: true, + level: "error", + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "朴素的按钮", + plain: true, + disabled: true, + }, + { + type: Button.xtype, + iconCls: "plus-font", + text: "点我,更改图标", + handler() { + this.i = this.i === undefined ? 0 : ++this.i; + const arr = [ + "text-background-font", + "check-mark-ha-font", + "close-font", + "search-font", + "date-change-h-font" + ]; + if (this.i >= arr.length) { + this.i = 0; + } + this.setIcon(arr[this.i]); + }, + height: 24, + }, + { + type: Button.xtype, + text: "带加载的按钮", + handler() { + console.log("触发点击事件"); + this.loading(); + setTimeout(() => { + this.loaded(); + }, 5 * 1000); + }, + }, + { + type: Button.xtype, + text: "带加载的按钮", + iconCls: "circle-close-font", + handler() { + console.log("触发点击事件"); + this.loading(); + setTimeout(() => { + this.loaded(); + }, 5 * 1000); + }, + }, + { + type: Button.xtype, + clear: true, + text: "带加载的按钮", + iconCls: "circle-close-font", + handler() { + console.log("触发点击事件"); + this.loading(); + setTimeout(() => { + this.loaded(); + }, 5 * 1000); + }, + }, + { + type: Button.xtype, + text: "加载中的按钮", + loading: true, + handler() { + console.log("我是无法被触发的!"); + }, + }, + { + type: Button.xtype, + text: "文字偏左的按钮", + textAlign: "left", + width: 200, + }, + { + type: Button.xtype, + text: "小于最小宽度的按钮", + width: 50, + }, + { + type: Button.xtype, + text: "一个文字超级超级长的 button, 他比按钮宽度还长。", + textWidth: 500, + width: 100, + } + ]; + + return { + type: FloatLeftLayout.xtype, + scrolly: true, + vgap: 100, + hgap: 20, + items: map(items, (index, value) => { + return { + el: value, + }; + }), + }; + } +} + diff --git a/packages/demo/src/demo/base/button/demo.icon_button.js b/packages/demo/src/demo/base/button/demo.icon_button.js new file mode 100644 index 000000000..9c6aa1efc --- /dev/null +++ b/packages/demo/src/demo/base/button/demo.icon_button.js @@ -0,0 +1,31 @@ + +import { IconButton, FloatLeftLayout, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class IconButtonDemo extends Widget { + static xtype = "demo.icon_button"; + + props = { baseCls: "demo-button" }; + + render() { + const items = [ + { + el: { + type: IconButton.xtype, + cls: "close-ha-font", + width: 25, + height: 25, + }, + } + ]; + + return { + type: FloatLeftLayout.xtype, + vgap: 200, + hgap: 20, + items, + }; + } +} + diff --git a/packages/demo/src/demo/base/button/demo.image_button.js b/packages/demo/src/demo/base/button/demo.image_button.js new file mode 100644 index 000000000..b152b9b84 --- /dev/null +++ b/packages/demo/src/demo/base/button/demo.image_button.js @@ -0,0 +1,31 @@ + +import { ImageButton, FloatLeftLayout, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class ImageButtonDemo extends Widget { + static xtype = "demo.image_button"; + + props = { baseCls: "demo-button" }; + + render() { + const items = [ + { + el: { + type: ImageButton.xtype, + src: "http://www.easyicon.net/api/resizeApi.php?id=1206741&size=128", + width: 100, + height: 100, + }, + } + ]; + + return { + type: FloatLeftLayout.xtype, + vgap: 200, + hgap: 20, + items, + }; + } +} + diff --git a/packages/demo/src/demo/base/button/demo.text_button.js b/packages/demo/src/demo/base/button/demo.text_button.js new file mode 100644 index 000000000..d402480bb --- /dev/null +++ b/packages/demo/src/demo/base/button/demo.text_button.js @@ -0,0 +1,31 @@ + +import { TextButton, FloatLeftLayout, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class TextButtonDemo extends Widget { + static xtype = "demo.text_button"; + + props = { baseCls: "demo-button" }; + + render() { + const items = [ + { + el: { + type: TextButton.xtype, + text: "文字按钮", + height: 30, + keyword: "w", + }, + } + ]; + + return { + type: FloatLeftLayout.xtype, + vgap: 200, + hgap: 20, + items, + }; + } +} + diff --git a/packages/demo/src/demo/base/button/index.js b/packages/demo/src/demo/base/button/index.js new file mode 100644 index 000000000..768de5c1b --- /dev/null +++ b/packages/demo/src/demo/base/button/index.js @@ -0,0 +1,4 @@ +export * from "./demo.button"; +export * from "./demo.icon_button"; +export * from "./demo.image_button"; +export * from "./demo.text_button"; \ No newline at end of file diff --git a/packages/demo/src/demo/base/demo.html.js b/packages/demo/src/demo/base/demo.html.js new file mode 100644 index 000000000..ace76ca7a --- /dev/null +++ b/packages/demo/src/demo/base/demo.html.js @@ -0,0 +1,26 @@ +import { Decorators, Widget, VerticalLayout, Html } from "@fui/core"; + +@Decorators.shortcut() +export class HtmlDemo extends Widget { + static xtype = "demo.html"; + + props = { baseCls: "demo-html" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Html.xtype, + text: "

在bi.html标签中使用html原生标签

" + }, + { + type: Html.xtype, + text: "" + } + ], + hgap: 300, + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/base/demo.icon_label.js b/packages/demo/src/demo/base/demo.icon_label.js new file mode 100644 index 000000000..6393120b5 --- /dev/null +++ b/packages/demo/src/demo/base/demo.icon_label.js @@ -0,0 +1,26 @@ +import { DefaultLayout, Label, IconLabel, Decorators, Widget } from "@fui/core"; + +@Decorators.shortcut() +export class IconLabelDemo extends Widget { + static xtype = "demo.icon_label"; + + props = { baseCls: "demo-bubble" }; + + render() { + return { + type: DefaultLayout.xtype, + items: [ + { + type: Label.xtype, + text: "这是一个icon标签,在加了border之后仍然是居中显示的" + }, + { + type: IconLabel.xtype, + cls: "date-font bi-border", + height: 40, + width: 40 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/base/demo.label.js b/packages/demo/src/demo/base/demo.label.js new file mode 100644 index 000000000..7a2acd4a2 --- /dev/null +++ b/packages/demo/src/demo/base/demo.label.js @@ -0,0 +1,173 @@ +import { + VerticalLayout, + FloatLeftLayout, + Decorators, + Widget, + Label +} from "@fui/core"; + +@Decorators.shortcut() +export class LabelDemo extends Widget { + static xtype = "demo.label"; + + props = { baseCls: "demo-label" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "layout-bg6", + text: "这是一个label控件,默认居中", + disabled: true, + textAlign: "center" + }, + { + type: Label.xtype, + cls: "layout-bg1", + text: "这是一个label控件, 高度为30,默认居中", + textAlign: "center", + height: 30 + }, + { + type: Label.xtype, + cls: "layout-bg3", + text: "这是一个label控件,使用水平居左", + textAlign: "left", + height: 30 + }, + { + type: Label.xtype, + cls: "layout-bg2", + text: "这是一个label控件,whiteSpace是normal,不设置高度,为了演示这个是真的是normal的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal" + }, + { + type: Label.xtype, + cls: "layout-bg5", + text: "这是一个label控件,whiteSpace是默认的nowrap,不设置高度,为了演示这个是真的是nowrap的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数" + }, + { + type: Label.xtype, + cls: "layout-bg7", + text: "这是一个label控件,whiteSpace是默认的nowrap,高度为30,为了演示这个是真的是nowrap的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + height: 30 + }, + { + type: Label.xtype, + cls: "layout-bg3", + text: "这是一个label控件,whiteSpace设置为normal,高度为60,为了演示这个是真的是normal的,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + height: 60 + }, + { + type: Label.xtype, + cls: "layout-bg5", + text: "这是一个label控件,whiteSpace设置为normal,textHeight控制text的lineHeight,这样可以实现换行效果,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textHeight: 30, + height: 60 + }, + { + type: Label.xtype, + cls: "layout-bg1", + text: "这是一个label控件,whiteSpace设置为nowrap,textWidth控制text的width", + textWidth: 200, + height: 60 + }, + { + type: Label.xtype, + cls: "layout-bg8", + text: "这是一个label控件,whiteSpace设置为normal,textWidth控制text的width,这样可以实现换行效果,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textWidth: 200, + height: 60 + }, + { + type: Label.xtype, + cls: "layout-bg7", + text: "whiteSpace为默认的nowrap,高度设置为60,宽度设置为300", + height: 60, + width: 300 + }, + { + type: Label.xtype, + cls: "layout-bg6", + text: "设置了宽度300,高度60,whiteSpace设置为normal", + whiteSpace: "normal", + width: 300, + height: 60 + }, + { + type: Label.xtype, + cls: "layout-bg8", + text: "textWidth设置为200,textHeight设置为30,width设置300,凑点字数看效果", + width: 300, + textWidth: 200, + textHeight: 30, + height: 60, + whiteSpace: "normal" + }, + { + type: Label.xtype, + cls: "layout-bg1", + text: "textWidth设置为200,width设置300,看下水平居左的换行效果", + textAlign: "left", + width: 300, + textWidth: 200, + textHeight: 30, + height: 60, + whiteSpace: "normal" + }, + { + type: Label.xtype, + cls: "layout-bg2", + text: "使用默认的nowrap,再去设置textHeight,只会有一行的效果", + textAlign: "left", + width: 300, + textWidth: 200, + textHeight: 30, + height: 60 + }, + { + type: FloatLeftLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "layout-bg3", + text: "在float布局中自适应的,不设高度和宽度,文字多长这个就有多长" + } + ], + height: 30 + }, + { + type: FloatLeftLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "layout-bg4", + text: "在float布局中自适应的,设置了宽度200,后面还有", + width: 200 + } + ], + height: 30 + }, + { + type: FloatLeftLayout.xtype, + items: [ + { + type: Label.xtype, + text: "在float布局中自适应的,设置了高度,文字多长这个就有多长", + cls: "layout-bg5", + height: 30 + } + ], + height: 30 + } + ], + hgap: 300, + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/base/demo.label.scene.js b/packages/demo/src/demo/base/demo.label.scene.js new file mode 100644 index 000000000..fe4e8dc9e --- /dev/null +++ b/packages/demo/src/demo/base/demo.label.scene.js @@ -0,0 +1,802 @@ +import { + Label, + AbsoluteLayout, + Decorators, + Widget, + VerticalLayout +} from "@fui/core"; + +@Decorators.shortcut() +export class LabelSceneDemo extends Widget { + static xtype = "demo.label_scene"; + + props = { baseCls: "demo-label" }; + + render() { + const items = []; + + items.push( + this.createExpander( + "1.1.1 文字居中,有宽度和高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg6", + text: "设置了textWidth,则一定是嵌套结构,因此需要用center_adapt布局容纳一下.为了实现不足一行时文字水平居中,超出一行时左对齐,需要设置maxWidth.", + whiteSpace: "normal", + height: 50, + width: 500, + textWidth: 200, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.1.2 居中,有宽度和高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg6", + text: "居中,有宽度高度,有文字宽度,whiteSpace为nowrap,maxWidth会限制文字", + whiteSpace: "nowrap", + height: 50, + width: 500, + textWidth: 350, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.2.1 居中,有宽度无高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg6", + text: "居中,有宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + width: 500, + textWidth: 200, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.2.1 居中,有宽度无高度,有文字宽度,whiteSpace为normal,高度被父容器拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg6", + text: "此时虽然没有对label设置高度,但由于使用了center_adapt布局,依然会垂直方向居中", + whiteSpace: "normal", + width: 500, + textWidth: 200, + textAlign: "center" + }, + top: 0, + left: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "1.2.2 居中,有宽度无高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg6", + text: "居中,有宽度无高度,有文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + width: 500, + textWidth: 350, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.3.1 居中,有宽度和高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,有宽度高度,无文字宽度,whiteSpace为normal,只需用center_adapt布局包一下即可.度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,whiteSpace为normal", + width: 500, + whiteSpace: "normal", + textAlign: "center", + height: 50 + } + ) + ); + + items.push( + this.createExpander( + "1.3.2 居中,有宽度无高度,无文字宽度,whiteSpace为normal", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,有宽度无高度,无文字宽度,whiteSpace为normal,只需用center_adapt布局包一下即可.度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,下即可.居中,有宽度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,度,无文字宽度,whiteSpace为normal居中,有宽度,无文字宽度,whiteSpace为normal", + width: 500, + whiteSpace: "normal", + textAlign: "center" + }, + top: 0, + left: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "1.4 居中,有宽度和高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,有宽度500有高度50,无文字宽度,whiteSpace为nowrap,此处无需两层div,设置text即可,然后设置line-height为传入高度即可实现垂直方向居中", + width: 500, + whiteSpace: "nowrap", + textAlign: "center", + height: 50 + } + ) + ); + + items.push( + this.createExpander( + "1.5.1 居中,有宽度无高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,有宽度500无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + width: 500, + whiteSpace: "nowrap", + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.5.2 居中,有宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 50, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,有宽度500无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + width: 500, + whiteSpace: "nowrap", + textAlign: "center" + }, + top: 0, + left: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "1.6.1 居中,无宽度无高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度,有文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + textWidth: 500, + whiteSpace: "nowrap", + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.6.2 居中,无宽度无高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + textWidth: 500, + whiteSpace: "normal", + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.6.3 居中,无宽度无,有文字宽度,whiteSpace为normal,被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + textWidth: 500, + whiteSpace: "normal", + textAlign: "center" + }, + left: 0, + right: 0, + top: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "1.7.1 居中,无宽度无高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.7.2 居中,无宽度无高度,无文字宽度,whiteSpace为normal,被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "center" + }, + left: 0, + right: 0, + top: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "1.7.3 居中,无宽度有高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + height: 50, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.8 居中,无宽度有高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度有高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + height: 50, + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.9 居中,无宽度无高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "center" + } + ) + ); + + items.push( + this.createExpander( + "1.9.1 居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 50, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg3", + text: "居中,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "center" + }, + top: 0, + left: 0, + right: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.1.1 居左,有宽度有高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度有高度,有文字宽度,whiteSpace为normal,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + textWidth: 300, + height: 50, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.1.2 居左,有宽度有高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度有高度,有文字宽度,whiteSpace为normal,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + textWidth: 300, + height: 50, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.2.1 居左,有宽度无高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度无高度,有文字宽度,whiteSpace为normal,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + textWidth: 300, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.2.2 居左,有宽度无高度,有文字宽度,whiteSpace为normal,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度无高度,有文字宽度,whiteSpace为normal,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + textWidth: 300, + width: 500 + }, + top: 0, + bottom: 0, + left: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.2.3 居左,有宽度无高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + textWidth: 300, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.2.4 居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度无高度,有文字宽度,whiteSpace为nowrap,不设置高度,为了演示这个是真的是normal的我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + textWidth: 300, + width: 500 + }, + top: 0, + bottom: 0, + left: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.3.1 居左,有宽度有高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度有高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + height: 50, + vgap: 5, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.3.2 居左,有宽度有高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + height: 50, + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.4.1 居左,有宽度无高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,有宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + width: 500 + } + ) + ); + + items.push( + this.createExpander( + "2.4.2 居左,有宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg1", + text: "居左,有宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + width: 500 + }, + top: 0, + left: 0, + bottom: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.5.1 居左,无宽度无高度,有文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + textWidth: 300 + } + ) + ); + + items.push( + this.createExpander( + "2.5.2 居左,无宽度无高度,有文字宽度,whiteSpace为normal,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + textWidth: 300 + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.5.3 居左,无宽度无高度,有文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + textWidth: 300 + } + ) + ); + + items.push( + this.createExpander( + "2.5.4 居左,无宽度无高度,有文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,有文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left", + textWidth: 300 + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.6.1 居左,无宽度有高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度有高度,无文字宽度,whiteSpace为nowrap,注意这个是设置了vgap的,为了实现居中,lineHeight要做计算,才能准确的垂直居中", + whiteSpace: "nowrap", + textAlign: "left", + vgap: 10, + height: 50 + } + ) + ); + + items.push( + this.createExpander( + "2.6.2 居左,无宽度有高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度有高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left", + height: 50 + } + ) + ); + + items.push( + this.createExpander( + "2.7.1 居左,无宽度无高度,无文字宽度,whiteSpace为normal", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left" + } + ) + ); + + items.push( + this.createExpander( + "2.7.2 居左,无宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.7.3 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap", + { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left" + } + ) + ); + + items.push( + this.createExpander( + "2.7.4 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.8 居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为nowrap,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "nowrap", + textAlign: "left" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + items.push( + this.createExpander( + "2.8.2 居左,无宽度无高度,无文字宽度,whiteSpace为normal,高度被父级拉满", + { + type: AbsoluteLayout.xtype, + height: 100, + items: [ + { + el: { + type: Label.xtype, + cls: "layout-bg2", + text: "居左,无宽度无高度,无文字宽度,whiteSpace为normal,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,我凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数,凑点字数", + whiteSpace: "normal", + textAlign: "left" + }, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + ] + } + ) + ); + + return { + type: VerticalLayout.xtype, + items, + hgap: 300, + vgap: 20 + }; + } + + createExpander(text, popup) { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "demo-font-weight-bold", + textAlign: "left", + text, + height: 30 + }, + { + el: popup + } + ] + }; + } +} diff --git a/packages/demo/src/demo/base/demo.message.js b/packages/demo/src/demo/base/demo.message.js new file mode 100644 index 000000000..8249d1c9f --- /dev/null +++ b/packages/demo/src/demo/base/demo.message.js @@ -0,0 +1,26 @@ +import { Decorators, Widget, Msg, CenterAdaptLayout, Button } from "@fui/core"; + +@Decorators.shortcut() +export class MessageDemo extends Widget { + static xtype = "demo.message"; + + props = { baseCls: "demo-bubble" }; + + render() { + return { + type: CenterAdaptLayout.xtype, + items: [ + { + el: { + type: Button.xtype, + text: "点击我弹出一个消息框", + height: 30, + handler() { + Msg.alert("测试消息框", "我是测试消息框的内容"); + } + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/base/demo.pager.js b/packages/demo/src/demo/base/demo.pager.js new file mode 100644 index 000000000..3421e45cf --- /dev/null +++ b/packages/demo/src/demo/base/demo.pager.js @@ -0,0 +1,126 @@ +import { VerticalLayout, Label, Decorators, Widget, Pager } from "@fui/core"; + +@Decorators.shortcut() +export class FuncDemo extends Widget { + static xtype = "demo.pager"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "默认的分页" + }, + { + type: Pager.xtype, + height: 50, + pages: 18, + groups: 5, + curr: 6, + first: "首页", + last: "尾页" + }, + { + type: Label.xtype, + height: 30, + text: "显示上一页、下一页、首页、尾页" + }, + { + type: Pager.xtype, + dynamicShow: false, + height: 50, + pages: 18, + groups: 5, + curr: 1, + first: "首页>", + last: "<尾页" + }, + { + type: Label.xtype, + height: 30, + text: "显示上一页、下一页" + }, + { + type: Pager.xtype, + dynamicShow: false, + dynamicShowFirstLast: true, + height: 50, + pages: 18, + groups: 5, + curr: 1, + first: "首页>", + last: "<尾页" + }, + { + type: Label.xtype, + height: 30, + text: "自定义上一页、下一页" + }, + { + type: Pager.xtype, + dynamicShow: false, + height: 50, + pages: 18, + groups: 5, + curr: 6, + prev: { + type: Pager.xtype, + cls: "", + text: "上一页", + value: "prev", + once: false, + height: 30, + handler() {} + }, + next: { + type: Pager.xtype, + cls: "", + text: "下一页", + value: "next", + once: false, + handler() {} + } + }, + { + type: Label.xtype, + height: 30, + text: "不知道总页数的情况(测试条件 1<=page<=3)" + }, + { + type: Pager.xtype, + dynamicShow: false, + height: 50, + pages: false, + curr: 1, + prev: { + type: Pager.xtype, + cls: "", + text: "上一页", + value: "prev", + once: false, + height: 30, + handler() {} + }, + next: { + type: Pager.xtype, + cls: "", + text: "下一页", + value: "next", + once: false, + handler() {} + }, + hasPrev(v) { + return v > 1; + }, + hasNext(v) { + return v < 3; + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/base/editor/demo.editor.js b/packages/demo/src/demo/base/editor/demo.editor.js new file mode 100644 index 000000000..e855d5336 --- /dev/null +++ b/packages/demo/src/demo/base/editor/demo.editor.js @@ -0,0 +1,127 @@ + +import { Editor, AbsoluteLayout, Button, Decorators, Widget, createWidget, Editor as BIEditor } from "@fui/core" + + + +@Decorators.shortcut() +export class EditorDemo extends Widget { + static xtype = "demo.editor"; + + props = { baseCls: "demo-editor" }; + + render() { + const editor1 = createWidget({ + type: Editor.xtype, + cls: "bi-border", + watermark: "报错信息显示在控件上方", + errorText: "字段不可重名!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", + width: 200, + height: 24, + }); + editor1.on(BIEditor.EVENT_ENTER, () => { + editor1.blur(); + }); + const editor2 = createWidget({ + type: Editor.xtype, + cls: "bi-border", + watermark: "输入'a'会有错误信息", + disabled: true, + errorText: "字段不可重名", + validationChecker(v) { + if (v == "a") { + return false; + } + + return true; + }, + allowBlank: true, + width: 200, + height: 24, + }); + const editor3 = createWidget({ + type: Editor.xtype, + cls: "bi-border", + watermark: "输入'a'会有错误信息且回车键不能退出编辑", + errorText: "字段不可重名", + value: "a", + validationChecker(v) { + if (v == "a") { + return false; + } + + return true; + }, + quitChecker(v) { + return false; + }, + allowBlank: true, + width: 300, + height: 24, + }); + const editor4 = createWidget({ + type: Editor.xtype, + cls: "bi-border", + inputType: "password", + autocomplete: "new-password", + watermark: "请输入密码", + allowBlank: true, + width: 300, + height: 24, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: editor1, + left: 0, + top: 0, + }, + { + el: editor2, + left: 250, + top: 30, + }, + { + el: editor3, + left: 500, + top: 60, + }, + { + el: editor4, + left: 700, + top: 60, + }, + { + el: { + type: Button.xtype, + text: "disable", + handler() { + editor1.setEnable(false); + editor2.setEnable(false); + editor3.setEnable(false); + }, + height: 30, + }, + left: 100, + bottom: 60, + }, + { + el: { + type: Button.xtype, + text: "enable", + handler() { + editor1.setEnable(true); + editor2.setEnable(true); + editor3.setEnable(true); + }, + height: 30, + }, + left: 200, + bottom: 60, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/base/editor/demo.multifile_editor.js b/packages/demo/src/demo/base/editor/demo.multifile_editor.js new file mode 100644 index 000000000..ec5ae4942 --- /dev/null +++ b/packages/demo/src/demo/base/editor/demo.multifile_editor.js @@ -0,0 +1,36 @@ + +import { AbsoluteLayout, AdaptiveLayout, MultifileEditor, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class CodeEditorDemo extends Widget { + static xtype = "demo.multifile_editor"; + + props = { baseCls: "demo-editor" }; + + render() { + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: AdaptiveLayout.xtype, + cls: "layout-bg1", + items: [ + { + type: MultifileEditor.xtype, + width: 400, + height: 300, + } + ], + width: 400, + height: 300, + }, + top: 50, + left: 50, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/base/editor/demo.textarea_editor.js b/packages/demo/src/demo/base/editor/demo.textarea_editor.js new file mode 100644 index 000000000..41ad85840 --- /dev/null +++ b/packages/demo/src/demo/base/editor/demo.textarea_editor.js @@ -0,0 +1,55 @@ + +import { TextAreaEditor, VerticalLayout, Button, Decorators, Widget, createWidget, isNotEmptyString, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class TextareaEditorDemo extends Widget { + static xtype = "demo.textarea_editor"; + + props = { baseCls: "demo-editor" }; + + render() { + const editor = createWidget({ + type: TextAreaEditor.xtype, + cls: "bi-border", + width: 600, + height: 400, + watermark: "请输入内容", + errorText: "检测内容有误", + validationChecker(v) { + return isNotEmptyString(v); + }, + }); + editor.on(TextAreaEditor.EVENT_FOCUS, () => { + Msg.toast("Focus"); + }); + editor.on(TextAreaEditor.EVENT_BLUR, () => { + Msg.toast("Blur"); + }); + createWidget({ + type: VerticalLayout.xtype, + element: this, + hgap: 30, + vgap: 20, + items: [ + editor, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(editor.getValue())); + }, + }, + { + type: Button.xtype, + text: "setValue", + handler() { + editor.setValue("测试数据"); + }, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/base/editor/index.js b/packages/demo/src/demo/base/editor/index.js new file mode 100644 index 000000000..a56032082 --- /dev/null +++ b/packages/demo/src/demo/base/editor/index.js @@ -0,0 +1,3 @@ +export * from "./demo.editor"; +export * from "./demo.multifile_editor"; +export * from "./demo.textarea_editor"; \ No newline at end of file diff --git a/packages/demo/src/demo/base/index.js b/packages/demo/src/demo/base/index.js new file mode 100644 index 000000000..68df8186a --- /dev/null +++ b/packages/demo/src/demo/base/index.js @@ -0,0 +1,16 @@ +export const meta = { + title: "基础控件 base", + rank: 8 +}; + +export * as button from "./button"; +export * as editor from "./editor"; +export * as tip from "./tip"; +export * as tree from "./tree"; + +export * from "./demo.html"; +export * from "./demo.icon_label"; +export * from "./demo.label"; +export * from "./demo.label.scene"; +export * from "./demo.message"; +export * from "./demo.pager"; diff --git a/packages/demo/src/demo/base/tip/demo.bubble.js b/packages/demo/src/demo/base/tip/demo.bubble.js new file mode 100644 index 000000000..0c7df5539 --- /dev/null +++ b/packages/demo/src/demo/base/tip/demo.bubble.js @@ -0,0 +1,87 @@ + +import { Button, FloatLeftLayout, Decorators, Widget, Bubbles } from "@fui/core" + + +@Decorators.shortcut() +export class BubbleDemo extends Widget { + static xtype = "demo.bubble"; + + props = { baseCls: "demo-bubble" }; + + render() { + const btns = []; + const items = [ + { + el: { + ref(_ref) { + btns.push(_ref); + }, + type: Button.xtype, + text: "bubble测试(消息)", + title: "123", + height: 30, + handler() { + Bubbles.show("singleBubble1", "bubble测试", this, { + level: "common", + }); + }, + }, + }, + { + el: { + ref(_ref) { + btns.push(_ref); + }, + type: Button.xtype, + text: "bubble测试(成功)", + height: 30, + handler() { + Bubbles.show("singleBubble2", "bubble测试", this, { + offsetStyle: "center", + level: "success", + }); + }, + }, + }, + { + el: { + ref(_ref) { + btns.push(_ref); + }, + type: Button.xtype, + text: "bubble测试(错误)", + height: 30, + handler() { + Bubbles.show("singleBubble3", "bubble测试", this, { + offsetStyle: "right", + level: "error", + }); + }, + }, + }, + { + el: { + ref(_ref) { + btns.push(_ref); + }, + type: Button.xtype, + text: "bubble测试(警告)", + height: 30, + handler() { + Bubbles.show("singleBubble4", "bubble测试", this, { + level: "warning", + }); + }, + }, + } + ]; + + return { + type: FloatLeftLayout.xtype, + vgap: 200, + hgap: 20, + items, + }; + } +} + diff --git a/packages/demo/src/demo/base/tip/demo.title.js b/packages/demo/src/demo/base/tip/demo.title.js new file mode 100644 index 000000000..ef429812e --- /dev/null +++ b/packages/demo/src/demo/base/tip/demo.title.js @@ -0,0 +1,71 @@ + +import { VerticalLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class TitleDemo extends Widget { + static xtype = "demo.title"; + + props = { baseCls: "demo-title" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "layout-bg1", + height: 50, + title: "title提示", + text: "移上去有title提示", + textAlign: "center", + }, + { + type: Label.xtype, + cls: "layout-bg6", + height: 50, + disabled: true, + warningTitle: "title错误提示", + text: "移上去有title错误提示", + textAlign: "center", + }, + { + type: Label.xtype, + cls: "layout-bg2", + height: 50, + disabled: true, + tipType: "success", + title: "自定义title提示效果", + warningTitle: "自定义title提示效果", + text: "自定义title提示效果", + textAlign: "center", + }, + { + type: Label.xtype, + cls: "layout-bg3", + height: 50, + title: () => "函数返回值作为title提示", + text: "title提示支持函数", + textAlign: "center", + }, + { + type: Label.xtype, + cls: "layout-bg4", + height: 50, + title() { + return { + level: "success", + text: "自定义title\n提示效果", + textAlign: "center", + }; + }, + text: "title提示支持对象,作为bi.tooltip的props", + textAlign: "center", + } + ], + hgap: 300, + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/base/tip/demo.toast.js b/packages/demo/src/demo/base/tip/demo.toast.js new file mode 100644 index 000000000..06b44d20e --- /dev/null +++ b/packages/demo/src/demo/base/tip/demo.toast.js @@ -0,0 +1,89 @@ + +import { Button, FloatLeftLayout, Decorators, Widget, createWidget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class ToastDemo extends Widget { + static xtype = "demo.toast"; + + props = { baseCls: "demo-toast" }; + + render() { + const items = [ + { + el: { + type: Button.xtype, + text: "简单Toast测试(success)", + height: 30, + handler() { + Msg.toast("这是一条简单的数据", { + level: "success", + }); + }, + }, + }, + { + el: { + type: Button.xtype, + text: "很长的Toast测试(normal)", + height: 30, + handler() { + Msg.toast( + "这是一条很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的数据", + {} + ); + }, + }, + }, + { + el: { + type: Button.xtype, + text: "非常长的Toast测试(warning)", + height: 30, + handler() { + Msg.toast( + "这是一条非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长的数据", + { + level: "warning", + autoClose: false, + } + ); + }, + }, + }, + { + el: { + type: Button.xtype, + text: "错误提示Toast测试(error)", + height: 30, + handler() { + Msg.toast("错误提示Toast测试", { + level: "error", + }); + }, + }, + }, + { + el: { + type: Button.xtype, + text: "错误提示Toast测试(error), 此toast不会自动消失", + height: 30, + handler() { + Msg.toast("错误提示Toast测试", { + autoClose: false, + }); + }, + }, + } + ]; + createWidget({ + type: FloatLeftLayout.xtype, + element: this, + vgap: 200, + hgap: 20, + items, + }); + } +} + diff --git a/packages/demo/src/demo/base/tip/index.js b/packages/demo/src/demo/base/tip/index.js new file mode 100644 index 000000000..bd0c8302b --- /dev/null +++ b/packages/demo/src/demo/base/tip/index.js @@ -0,0 +1,3 @@ +export * from "./demo.bubble"; +export * from "./demo.title"; +export * from "./demo.toast"; \ No newline at end of file diff --git a/packages/demo/src/demo/base/tree/demo.part_tree.js b/packages/demo/src/demo/base/tree/demo.part_tree.js new file mode 100644 index 000000000..7fcfb86c6 --- /dev/null +++ b/packages/demo/src/demo/base/tree/demo.part_tree.js @@ -0,0 +1,101 @@ + +import { VTapeLayout, Label, PartTree, Decorators, Widget, isNull, TreeView } from "@fui/core" + + + +@Decorators.shortcut() +export class PartTreeDemo extends Widget { + static xtype = "demo.part_tree"; + + props = { baseCls: "demo-func" }; + + mounted() { + this.partTree.stroke({ + keyword: "1", + }); + } + + render() { + const self = this; + + return { + type: VTapeLayout.xtype, + items: [ + { + type: Label.xtype, + height: 50, + text: "先初始化一份数据,然后再异步获取数据的树", + }, + { + type: PartTree.xtype, + ref(_ref) { + self.partTree = _ref; + }, + paras: { + selectedValues: { 1: {}, 2: { 1: {} } }, + }, + itemsCreator(op, callback) { + if (op.type === TreeView.REQ_TYPE_INIT_DATA) { + callback({ + items: [ + { + id: "1", + text: 1, + isParent: true, + open: true, + }, + { + id: "11", + pId: "1", + text: 11, + isParent: true, + open: true, + }, + { + id: "111", + pId: "11", + text: 111, + isParent: true, + }, + { + id: "2", + text: 2, + }, + { + id: "3", + text: 3, + } + ], + hasNext: isNull(op.id), + }); + + return; + } + callback({ + items: [ + { + id: `${op.id || ""}1`, + pId: op.id, + text: 1, + isParent: true, + }, + { + id: `${op.id || ""}2`, + pId: op.id, + text: 2, + }, + { + id: `${op.id || ""}3`, + pId: op.id, + text: 3, + } + ], + hasNext: isNull(op.id), + }); + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/base/tree/demo.sync_tree.js b/packages/demo/src/demo/base/tree/demo.sync_tree.js new file mode 100644 index 000000000..18f406e75 --- /dev/null +++ b/packages/demo/src/demo/base/tree/demo.sync_tree.js @@ -0,0 +1,122 @@ + +import { VTapeLayout, Label, AsyncTree, Decorators, Widget, isNull } from "@fui/core" + + +@Decorators.shortcut() +export class SyncTreeDemo extends Widget { + static xtype = "demo.sync_tree"; + + props = { baseCls: "demo-func" }; + + mounted() { + this.syncTree1.stroke({ + keyword: "1", + }); + this.syncTree2.stroke({ + keyword: "1", + }); + } + + render() { + const self = this; + + return { + type: VTapeLayout.xtype, + rowSize: [0.5, 0.5], + items: [ + { + type: VTapeLayout.xtype, + items: [ + { + type: Label.xtype, + height: 50, + text: "可以异步获取数据的树", + }, + { + type: AsyncTree.xtype, + ref(_ref) { + self.syncTree1 = _ref; + }, + paras: { + selectedValues: { 1: {}, 2: { 1: {} } }, + }, + itemsCreator(op, callback) { + callback({ + items: [ + { + id: `${op.id || ""}1`, + pId: op.id, + text: `${op.id || ""}1`, + isParent: true, + iconCls: "close-h-font", + }, + { + id: `${op.id || ""}2`, + pId: op.id, + text: `${op.id || ""}2`, + iconCls: "search-font", + }, + { + id: `${op.id || ""}3`, + pId: op.id, + text: `${op.id || ""}3`, + iconCls: "date-font", + } + ], + hasNext: isNull(op.id), + }); + }, + } + ], + }, + { + type: VTapeLayout.xtype, + items: [ + { + type: Label.xtype, + height: 50, + text: "showIcon属性搭配节点iconCls,可以显示图标", + }, + { + type: AsyncTree.xtype, + ref(_ref) { + self.syncTree2 = _ref; + }, + paras: { + selectedValues: { 1: {}, 2: { 1: {} } }, + }, + showIcon: true, + itemsCreator(op, callback) { + callback({ + items: [ + { + id: `${op.id || ""}1`, + pId: op.id, + text: `${op.id || ""}1`, + isParent: true, + iconCls: "close-h-font", + }, + { + id: `${op.id || ""}2`, + pId: op.id, + text: `${op.id || ""}2`, + iconCls: "search-font", + }, + { + id: `${op.id || ""}3`, + pId: op.id, + text: `${op.id || ""}3`, + iconCls: "date-font", + } + ], + hasNext: isNull(op.id), + }); + }, + } + ], + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/base/tree/demo.tree_view.js b/packages/demo/src/demo/base/tree/demo.tree_view.js new file mode 100644 index 000000000..2b77abdbb --- /dev/null +++ b/packages/demo/src/demo/base/tree/demo.tree_view.js @@ -0,0 +1,60 @@ + +import { TreeView, GridLayout, VTapeLayout, Label, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class FuncDemo extends Widget { + static xtype = "demo.tree_view"; + + props = { baseCls: "demo-func" }; + + _createDefaultTree() { + const tree = createWidget({ + type: TreeView.xtype, + }); + tree.initTree([ + { id: 1, pId: 0, text: "test1", open: true }, + { id: 11, pId: 1, text: "test11" }, + { id: 12, pId: 1, text: "test12" }, + { id: 111, pId: 11, text: "test111" }, + { id: 2, pId: 0, text: "test2", open: true }, + { id: 21, pId: 2, text: "test21" }, + { id: 22, pId: 2, text: "test22" } + ]); + + return tree; + } + + render() { + const self = this; + createWidget({ + type: GridLayout.xtype, + columns: 1, + rows: 1, + element: this, + items: [ + { + column: 0, + row: 0, + el: { + type: VTapeLayout.xtype, + items: [ + { + el: this._createDefaultTree(), + }, + { + el: { + type: Label.xtype, + text: "tree.initTree([{\"id\":1, \"pId\":0, \"text\":\"test1\", open:true},{\"id\":11, \"pId\":1, \"text\":\"test11\"},{\"id\":12, \"pId\":1, \"text\":\"test12\"},{\"id\":111, \"pId\":11, \"text\":\"test111\"}])", + whiteSpace: "normal", + }, + height: 50, + } + ], + }, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/base/tree/index.js b/packages/demo/src/demo/base/tree/index.js new file mode 100644 index 000000000..382d8ec51 --- /dev/null +++ b/packages/demo/src/demo/base/tree/index.js @@ -0,0 +1,3 @@ +export * from "./demo.part_tree"; +export * from "./demo.sync_tree"; +export * from "./demo.tree_view"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/combo/demo.bubble_combo.js b/packages/demo/src/demo/case/combo/demo.bubble_combo.js new file mode 100644 index 000000000..ab5b8482e --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.bubble_combo.js @@ -0,0 +1,161 @@ +import { + BubbleCombo, + Button, + ButtonGroup, + TextItem, + VerticalLayout, + TextBubblePopupBarView, + AbsoluteLayout, + Decorators, + Widget, + createWidget, + makeArray +} from "@fui/core"; + +@Decorators.shortcut() +export class BubbleComboDemo extends Widget { + static xtype = "demo.bubble_combo"; + + props = { baseCls: "demo-func" }; + + render() { + let self = this, + count = 1; + const combo1 = createWidget({ + type: BubbleCombo.xtype, + trigger: "click,hover", + el: { + type: Button.xtype, + text: "测试", + height: 24 + }, + popup: { + el: { + type: ButtonGroup.xtype, + items: makeArray(100, { + type: TextItem.xtype, + height: 24, + text: "item" + }), + layouts: [ + { + type: VerticalLayout.xtype + } + ] + }, + maxHeight: 200 + } + }); + const combo2 = createWidget({ + type: BubbleCombo.xtype, + direction: "right", + el: { + type: Button.xtype, + text: "测试", + height: 24 + }, + popup: { + type: TextBubblePopupBarView.xtype, + text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", + ref() { + self.popup = this; + } + }, + listeners: [ + { + eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW, + action() { + self.popup.populate( + count++ % 2 === 1 + ? "我的文字变少了" + : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字" + ); + } + } + ] + }); + + const combo3 = createWidget({ + type: BubbleCombo.xtype, + el: { + type: Button.xtype, + text: "测试", + height: 25 + }, + popup: { + type: TextBubblePopupBarView.xtype, + text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", + ref() { + self.popup = this; + } + }, + listeners: [ + { + eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW, + action() { + self.popup.populate( + count++ % 2 === 1 + ? "我的文字变少了" + : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字" + ); + } + } + ] + }); + + const combo4 = createWidget({ + type: BubbleCombo.xtype, + el: { + type: Button.xtype, + text: "测试", + height: 25 + }, + popup: { + type: TextBubblePopupBarView.xtype, + text: "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字", + ref() { + self.popup = this; + } + }, + listeners: [ + { + eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW, + action() { + self.popup.populate( + count++ % 2 === 1 + ? "我的文字变少了" + : "我有很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字很多文字" + ); + } + } + ] + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: combo1, + left: 150, + top: 10 + }, + { + el: combo2, + left: 10, + bottom: 200 + }, + { + el: combo3, + right: 10, + bottom: 10 + }, + { + el: combo4, + right: 10, + top: 10 + } + ] + }); + } +} diff --git a/packages/demo/src/demo/case/combo/demo.editor_icon_check_combo.js b/packages/demo/src/demo/case/combo/demo.editor_icon_check_combo.js new file mode 100644 index 000000000..9730e6c69 --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.editor_icon_check_combo.js @@ -0,0 +1,55 @@ + +import { HorizontalAutoLayout, EditorIconCheckCombo, Button, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class EditorIconCheckComboDemo extends Widget { + static xtype = "demo.editor_icon_check_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: EditorIconCheckCombo.xtype, + ref() { + self.combo = this; + }, + watermark: "默认值", + width: 200, + height: 24, + value: 2, + items: [ + { + // text: "MVC-1", + value: "1", + }, + { + // text: "MVC-2", + value: "2", + }, + { + // text: "MVC-3", + value: "3", + } + ], + }, + { + type: Button.xtype, + width: 90, + height: 25, + text: "setValue为空", + handler() { + self.combo.setValue(); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/combo/demo.icon_combo.js b/packages/demo/src/demo/case/combo/demo.icon_combo.js new file mode 100644 index 000000000..652b8993f --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.icon_combo.js @@ -0,0 +1,44 @@ + +import { HorizontalAutoLayout, IconCombo, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class IconComboDemo extends Widget { + static xtype = "demo.icon_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: IconCombo.xtype, + container: "body", + ref(_ref) { + self.refs = _ref; + }, + value: "第二项", + items: [ + { + value: "第一项", + iconCls: "close-font", + }, + { + value: "第二项", + iconCls: "search-font", + }, + { + value: "第三项", + iconCls: "copy-font", + } + ], + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/combo/demo.icon_text_value_combo.js b/packages/demo/src/demo/case/combo/demo.icon_text_value_combo.js new file mode 100644 index 000000000..09ccb6c21 --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.icon_text_value_combo.js @@ -0,0 +1,43 @@ + +import { HorizontalAutoLayout, IconTextValueCombo, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class IconTextValueComboDemo extends Widget { + static xtype = "demo.icon_text_value_combo"; + + props = { baseCls: "" }; + + render() { + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: IconTextValueCombo.xtype, + text: "默认值", + // defaultIconCls: "next-page-h-font", + width: 300, + items: [ + { + text: "MVC-1", + iconCls: "close-font", + value: 1, + }, + { + text: "MVC-2", + iconCls: "date-font", + value: 2, + }, + { + text: "MVC-3", + iconCls: "search-close-h-font", + value: 3, + } + ], + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/combo/demo.search_text_value_combo.js b/packages/demo/src/demo/case/combo/demo.search_text_value_combo.js new file mode 100644 index 000000000..4a9dfcf70 --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.search_text_value_combo.js @@ -0,0 +1,132 @@ +import { CONSTANTS } from "@/config/constant"; +import { + HorizontalAutoLayout, + SearchTextValueCombo, + AllValueMultiTextValueCombo, + Button, + Decorators, + Widget, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class SearchTextValueComboDemo extends Widget { + static xtype = "demo.search_text_value_combo"; + + props = { baseCls: "" }; + + render() { + let combo, searchCombo; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: SearchTextValueCombo.xtype, + ref() { + combo = this; + }, + warningTitle: "111", + text: "默认值", + value: 14, + width: 300, + items: [ + { + text: "ABC-1", + iconCls: "date-font", + value: 1 + }, + { + text: "BCD-2", + iconCls: "search-font", + value: 2 + }, + { + text: "CDE-3", + iconCls: "pull-right-font", + value: 3 + }, + { + text: "DEF-3", + iconCls: "pull-right-font", + value: 4 + }, + { + text: "FEG-3", + iconCls: "pull-right-font", + value: 5 + }, + { + text: "FGH-3", + iconCls: "pull-right-font", + value: 6 + }, + { + text: "GHI-3", + iconCls: "pull-right-font", + value: 7 + }, + { + text: "HIJ-3", + iconCls: "pull-right-font", + value: 8 + }, + { + text: "IJK-3", + iconCls: "pull-right-font", + value: 9 + }, + { + text: "JKL-3", + iconCls: "pull-right-font", + value: 10 + } + ] + }, + { + type: AllValueMultiTextValueCombo.xtype, + items: CONSTANTS.ITEMS, + text: "提示文本", + width: 200, + value: { + type: 1, + value: ["1", "2", "柳州市城贸金属材料有限责任公司", "3"] + }, + ref() { + searchCombo = this; + }, + listeners: [ + { + eventName: + AllValueMultiTextValueCombo.EVENT_CONFIRM, + action() { + Msg.toast( + JSON.stringify(searchCombo.getValue()) + ); + } + } + ] + }, + { + type: Button.xtype, + text: "setValue(3)", + width: 90, + height: 25, + handler() { + combo.setValue(11); + } + }, + { + type: Button.xtype, + text: "getValue()", + width: 90, + height: 25, + handler() { + Msg.toast(JSON.stringify(searchCombo.getValue())); + } + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/case/combo/demo.text_value_combo.js b/packages/demo/src/demo/case/combo/demo.text_value_combo.js new file mode 100644 index 000000000..aa2d8c912 --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.text_value_combo.js @@ -0,0 +1,276 @@ +import { + VerticalLayout, + TextValueCombo, + Button, + Label, + Decorators, + Selection, + Widget +} from "@fui/core"; +/** + * Created by Dailer on 2017/7/11. + */ +@Decorators.shortcut() +export class TextValueComboDemo extends Widget { + static xtype = "demo.text_value_combo"; + + props = { + baseCls: "" + }; + + render() { + let combo, combo1, combo2; + + const items = [ + { + text: "MVC-1", + iconCls: "date-font", + value: 1 + }, + { + text: "MVC-2", + iconCls: "search-font", + value: 2 + }, + { + text: "MVC-3", + iconCls: "pull-right-font", + value: 3 + } + ]; + + // 创建下拉框各种场景用例 + return { + type: VerticalLayout.xtype, + vgap: 20, + hgap: 20, + items: [ + this.createCombo("无初始值,带提示文字", { + type: TextValueCombo.xtype, + ref: (ref) => { + this.combo1 = ref; + }, + defaultText: "请选择", + width: 300, + items: items, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }), + this.createCombo("自动根据value匹配text", { + type: TextValueCombo.xtype, + ref: function () { + combo = this; + }, + defaultText: "请选择", + width: 300, + value: 1, + items: items, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }), + this.createCombo("无初始值,可以清空", { + type: TextValueCombo.xtype, + ref: function () { + combo = this; + }, + defaultText: "请选择", + width: 300, + items: items, + allowClear: true, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }), + this.createCombo("有初始值,可以清空", { + type: TextValueCombo.xtype, + ref: function () { + combo = this; + }, + defaultText: "请选择", + width: 300, + value: 1, + items: items, + allowClear: true, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }), + this.createCombo("有初始值,value不匹配,自动标红,指定标红文字", { + type: TextValueCombo.xtype, + ref: function () { + combo = this; + }, + width: 300, + text: "MVC-111", + value: 111, + items: items, + allowClear: true, + defaultText: "请选择", + warningTitle: "value值不合法", + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }), + this.createCombo("无初始值,外部受控调用setValue", { + type: VerticalLayout.xtype, + items: [ + { + type: TextValueCombo.xtype, + ref: function () { + combo1 = this; + }, + width: 300, + items: items, + allowClear: true, + defaultText: "请选择", + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }, + { + el: { + type: Button.xtype, + text: "setValue(1)", + handler: function () { + combo1.setValue(1); + } + }, + vgap: 10 + } + ] + }), + this.createCombo("无初始值,外部受控调用setStatus", { + type: VerticalLayout.xtype, + items: [ + { + type: TextValueCombo.xtype, + ref: function () { + combo2 = this; + }, + width: 300, + items: items, + allowClear: true, + defaultText: "请选择", + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + }, + { + el: { + type: Button.xtype, + text: "setStatus()", + handler: function () { + combo2.setStatus("error"); + } + }, + vgap: 10 + } + ] + }), + this.createCombo("支持复选", { + type: VerticalLayout.xtype, + items: [ + { + type: TextValueCombo.xtype, + width: 300, + items: items, + allowClear: true, + defaultText: "请选择", + chooseType: Selection.Multi, + value: [1], + // allowSelectAll: false, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + } + ] + }), + this.createCombo("支持复选,不要全选功能", { + type: VerticalLayout.xtype, + items: [ + { + type: TextValueCombo.xtype, + width: 300, + items: items, + allowClear: true, + defaultText: "请选择", + chooseType: Selection.Multi, + value: [1], + allowSelectAll: false, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: function () { + console.log(this.getValue()); + } + } + ] + } + ] + }) + ] + }; + } + + createCombo(text, combo) { + return { + type: VerticalLayout.xtype, + items: [ + { + el: { + type: Label.xtype, + textAlign: "left", + text + }, + bgap: 10 + }, + { + el: combo, + bgap: 10 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/case/combo/demo.text_value_down_list_combo.js b/packages/demo/src/demo/case/combo/demo.text_value_down_list_combo.js new file mode 100644 index 000000000..b054db1de --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.text_value_down_list_combo.js @@ -0,0 +1,86 @@ + +import { HorizontalAutoLayout, TextValueDownListCombo, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class TextValueDownListComboDemo extends Widget { + static xtype = "demo.text_value_down_list_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: TextValueDownListCombo.xtype, + width: 300, + ref(_ref) { + self.refs = _ref; + }, + text: "默认值", + value: 11, + items: [ + [ + { + text: "属于", + value: 1, + cls: "dot-e-font", + }, + { + text: "不属于", + value: 2, + cls: "dot-e-font", + } + ], + [ + { + el: { + text: "大于", + value: 3, + iconCls1: "dot-e-font", + }, + value: 3, + children: [ + { + text: "固定值", + value: 4, + cls: "dot-e-font", + }, + { + text: "平均值", + value: 5, + cls: "dot-e-font", + } + ], + } + ] + ], + }, + { + type: Button.xtype, + width: 90, + height: 25, + text: "setValue", + handler() { + self.refs.setValue(2); + }, + }, + { + type: Button.xtype, + width: 90, + height: 25, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(self.refs.getValue())); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/combo/demo.text_vlaue_check_combo.js b/packages/demo/src/demo/case/combo/demo.text_vlaue_check_combo.js new file mode 100644 index 000000000..59b0e8792 --- /dev/null +++ b/packages/demo/src/demo/case/combo/demo.text_vlaue_check_combo.js @@ -0,0 +1,54 @@ + +import { Msg, HorizontalAutoLayout, TextValueCheckCombo, Button, Decorators, Widget } from "@fui/core" + + + +@Decorators.shortcut() +export class TextValueCheckComboDemo extends Widget { + static xtype = "demo.text_value_check_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: TextValueCheckCombo.xtype, + ref () { + self.combo = this; + }, + text: "默认值", + // value: 1, + width: 300, + items: [ + { + text: "MVC-1", + value: 1, + }, + { + text: "MVC-2", + value: 2, + }, + { + text: "MVC-3", + value: 3, + } + ], + }, + { + type: Button.xtype, + width: 90, + height: 25, + handler () { + Msg.alert("", JSON.stringify(self.combo.getValue())); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/combo/index.js b/packages/demo/src/demo/case/combo/index.js new file mode 100644 index 000000000..560d7ddff --- /dev/null +++ b/packages/demo/src/demo/case/combo/index.js @@ -0,0 +1,8 @@ +export * from "./demo.bubble_combo"; +export * from "./demo.editor_icon_check_combo"; +export * from "./demo.icon_combo"; +export * from "./demo.icon_text_value_combo"; +export * from "./demo.search_text_value_combo"; +export * from "./demo.text_value_combo"; +export * from "./demo.text_value_down_list_combo"; +export * from "./demo.text_vlaue_check_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/demo.calendar.js b/packages/demo/src/demo/case/demo.calendar.js new file mode 100644 index 000000000..ee066762a --- /dev/null +++ b/packages/demo/src/demo/case/demo.calendar.js @@ -0,0 +1,38 @@ + +import { Calendar, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class CalendarDemo extends Widget { + static xtype = "demo.calendar"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + const date = new Date(); + + return { + type: Calendar.xtype, + ref() { + self.calendar = this; + }, + logic: { + dynamic: false, + }, + year: date.getFullYear(), + month: date.getMonth(), + day: date.getDate(), + }; + } + + mounted() { + const date = new Date(); + this.calendar.setValue({ + year: date.getFullYear(), + month: date.getMonth(), + day: date.getDate(), + }); + } +} + diff --git a/packages/demo/src/demo/case/demo.click.effect.js b/packages/demo/src/demo/case/demo.click.effect.js new file mode 100644 index 000000000..f870f833c --- /dev/null +++ b/packages/demo/src/demo/case/demo.click.effect.js @@ -0,0 +1,56 @@ + +import { VerticalLayout, IconTextItem, Decorators, Widget, createItems } from "@fui/core" + + +@Decorators.shortcut() +export class ClickItemEffectDemo extends Widget { + static xtype = "demo.click_item_effect"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: VerticalLayout.xtype, + items: createItems( + [ + { + text: "bi-list-item", + cls: "bi-list-item close-font", + }, + { + text: "bi-list-item-simple", + cls: "bi-list-item-simple close-font", + }, + { + text: "bi-list-item-effect", + cls: "bi-list-item-effect close-font", + }, + { + text: "bi-list-item-active", + cls: "bi-list-item-active close-font", + }, + { + text: "bi-list-item-active2", + cls: "bi-list-item-active2 close-font", + }, + { + text: "bi-list-item-select", + cls: "bi-list-item-select close-font", + }, + { + text: "bi-list-item-select2", + cls: "bi-list-item-select2 close-font", + } + ], + { + type: IconTextItem.xtype, + logic: { + dynamic: true, + }, + } + ), + vgap: 10, + }; + } +} + diff --git a/packages/demo/src/demo/case/demo.color_chooser.js b/packages/demo/src/demo/case/demo.color_chooser.js new file mode 100644 index 000000000..dcecbf2cb --- /dev/null +++ b/packages/demo/src/demo/case/demo.color_chooser.js @@ -0,0 +1,49 @@ + +import { AbsoluteLayout, ColorChooser, SimpleColorChooser, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class ColorChooserDemo extends Widget { + static xtype = "demo.color_chooser"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: ColorChooser.xtype, + recommendColorsGetter() { + return ["#ffffff", "#9d775f", "#dd4b4b", "#ef8b07", "#fcc800"]; + }, + width: 24, + height: 24, + }, + left: 100, + top: 250, + }, + { + el: { + type: SimpleColorChooser.xtype, + width: 30, + height: 24, + }, + left: 400, + top: 250, + }, + { + el: { + type: ColorChooser.xtype, + width: 230, + height: 24, + }, + left: 100, + top: 350, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/case/demo.color_chooser_popup.js b/packages/demo/src/demo/case/demo.color_chooser_popup.js new file mode 100644 index 000000000..260fe26e3 --- /dev/null +++ b/packages/demo/src/demo/case/demo.color_chooser_popup.js @@ -0,0 +1,35 @@ + +import { AbsoluteLayout, ColorChooserPopup, SimpleColorChooserPopup, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class ColorChooserPopupDemo extends Widget { + static xtype = "demo.color_chooser_popup"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: ColorChooserPopup.xtype, + cls: "bi-card", + }, + left: 100, + top: 250, + }, + { + el: { + type: SimpleColorChooserPopup.xtype, + cls: "bi-card", + }, + left: 400, + top: 250, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/case/demo.segment.js b/packages/demo/src/demo/case/demo.segment.js new file mode 100644 index 000000000..6d82ce6c8 --- /dev/null +++ b/packages/demo/src/demo/case/demo.segment.js @@ -0,0 +1,39 @@ + +import { HorizontalLayout, Segment, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class SegmentDemo extends Widget { + static xtype = "demo.segment"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: HorizontalLayout.xtype, + element: this, + vgap: 20, + hgap: 30, + items: [ + { + type: Segment.xtype, + items: [ + { + text: "较长的选项1", + value: 1, + }, + { + text: "选项2", + value: 2, + }, + { + text: "选项3", + value: 3, + } + ], + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/case/editor/demo.clear_editor.js b/packages/demo/src/demo/case/editor/demo.clear_editor.js new file mode 100644 index 000000000..5a11a19c2 --- /dev/null +++ b/packages/demo/src/demo/case/editor/demo.clear_editor.js @@ -0,0 +1,27 @@ + +import { HorizontalAutoLayout, ClearEditor, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class ClearEditorDemo extends Widget { + static xtype = "demo.clear_editor"; + + props = { baseCls: "" }; + + render() { + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: ClearEditor.xtype, + cls: "bi-border", + width: 300, + watermark: "这个是带清除按钮的", + value: 123, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/case/editor/demo.shelter_editor.js b/packages/demo/src/demo/case/editor/demo.shelter_editor.js new file mode 100644 index 000000000..cb057c682 --- /dev/null +++ b/packages/demo/src/demo/case/editor/demo.shelter_editor.js @@ -0,0 +1,51 @@ + +import { ShelterEditor, VerticalLayout, AbsoluteLayout, Button, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class ShelterEditorDemo extends Widget { + static xtype = "demo.shelter_editor"; + + props = { baseCls: "" }; + + render() { + const editor = createWidget({ + type: ShelterEditor.xtype, + cls: "bi-border", + validationChecker(v) { + return v != "a"; + }, + watermark: "可以设置标记的输入框", + value: "这是一个遮罩", + keyword: "z", + }); + createWidget({ + type: VerticalLayout.xtype, + element: this, + hgap: 30, + vgap: 20, + bgap: 50, + items: [editor], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Button.xtype, + text: "focus", + height: 25, + handler() { + editor.focus(); + }, + }, + right: 10, + left: 10, + bottom: 10, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/case/editor/demo.sign_editor.js b/packages/demo/src/demo/case/editor/demo.sign_editor.js new file mode 100644 index 000000000..a46085f43 --- /dev/null +++ b/packages/demo/src/demo/case/editor/demo.sign_editor.js @@ -0,0 +1,31 @@ + +import { SignEditor, VerticalLayout, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class SignEditorDemo extends Widget { + static xtype = "demo.sign_editor"; + + props = { baseCls: "" }; + + render() { + const editor = createWidget({ + type: SignEditor.xtype, + cls: "bi-border bi-focus-shadow", + validationChecker(v) { + return v != "abc"; + }, + watermark: "可以设置标记的输入框", + text: "这是一个标记,点击它即可进行输入", + }); + editor.setValue(2); + createWidget({ + type: VerticalLayout.xtype, + element: this, + hgap: 30, + vgap: 20, + items: [editor], + }); + } +} + diff --git a/packages/demo/src/demo/case/editor/demo.simple_state_editor.js b/packages/demo/src/demo/case/editor/demo.simple_state_editor.js new file mode 100644 index 000000000..ca521209c --- /dev/null +++ b/packages/demo/src/demo/case/editor/demo.simple_state_editor.js @@ -0,0 +1,37 @@ + +import { HorizontalAdaptLayout, SimpleStateEditor, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class SimpleStateEditorDemo extends Widget { + static xtype = "demo.simple_state_editor"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAdaptLayout.xtype, + items: [ + { + type: SimpleStateEditor.xtype, + ref() { + self.editor = this; + }, + cls: "bi-border", + width: 300, + } + ], + vgap: 20, + }; + } + + mounted() { + const self = this; + setTimeout(() => { + self.editor.setState(["*", "*"]); + }, 1000); + } +} + diff --git a/packages/demo/src/demo/case/editor/demo.state_editor.js b/packages/demo/src/demo/case/editor/demo.state_editor.js new file mode 100644 index 000000000..a96f81934 --- /dev/null +++ b/packages/demo/src/demo/case/editor/demo.state_editor.js @@ -0,0 +1,37 @@ + +import { HorizontalAdaptLayout, StateEditor, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class StateEditorDemo extends Widget { + static xtype = "demo.state_editor"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAdaptLayout.xtype, + items: [ + { + type: StateEditor.xtype, + ref() { + self.editor = this; + }, + cls: "bi-border", + width: 300, + } + ], + vgap: 20, + }; + } + + mounted() { + const self = this; + setTimeout(() => { + self.editor.setState(["*", "*"]); + }, 1000); + } +} + diff --git a/packages/demo/src/demo/case/editor/index.js b/packages/demo/src/demo/case/editor/index.js new file mode 100644 index 000000000..684975dd1 --- /dev/null +++ b/packages/demo/src/demo/case/editor/index.js @@ -0,0 +1,5 @@ +export * from "./demo.clear_editor"; +export * from "./demo.shelter_editor"; +export * from "./demo.sign_editor"; +export * from "./demo.simple_state_editor"; +export * from "./demo.state_editor"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/index.js b/packages/demo/src/demo/case/index.js new file mode 100644 index 000000000..5fbb4121f --- /dev/null +++ b/packages/demo/src/demo/case/index.js @@ -0,0 +1,19 @@ +export const meta = { + title: "实例控件 case", + rank: 7 +}; + +export * as combo from "./combo"; +export * as editor from "./editor"; +export * as item from "./item"; +export * as list from "./list"; +export * as pager from "./pager"; +export * as pane from "./pane"; +export * as tree from "./tree"; +export * as triggers from "./triggers"; + +export * from "./demo.calendar"; +export * from "./demo.click.effect"; +export * from "./demo.color_chooser"; +export * from "./demo.color_chooser_popup"; +export * from "./demo.segment"; diff --git a/packages/demo/src/demo/case/item/demo.multi_select_item.js b/packages/demo/src/demo/case/item/demo.multi_select_item.js new file mode 100644 index 000000000..03a1ad362 --- /dev/null +++ b/packages/demo/src/demo/case/item/demo.multi_select_item.js @@ -0,0 +1,29 @@ + +import { VerticalLayout, Label, MultiSelectItem, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class MultiSelectItemDemo extends Widget { + static xtype = "demo.multi_select_item"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "复选item", + }, + { + type: MultiSelectItem.xtype, + text: "复选项", + } + ], + hgap: 300, + }; + } +} + diff --git a/packages/demo/src/demo/case/item/demo.single_select_item.js b/packages/demo/src/demo/case/item/demo.single_select_item.js new file mode 100644 index 000000000..eacea0001 --- /dev/null +++ b/packages/demo/src/demo/case/item/demo.single_select_item.js @@ -0,0 +1,27 @@ + +import { VerticalLayout, Label, SingleSelectItem, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class SingleSelectItemDemo extends Widget { + static xtype = "demo.single_select_item"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "单选item", + }, + { + type: SingleSelectItem.xtype, + text: "单选项", + } + ], + hgap: 300, + }; + } +} + diff --git a/packages/demo/src/demo/case/item/demo.single_select_radio_item.js b/packages/demo/src/demo/case/item/demo.single_select_radio_item.js new file mode 100644 index 000000000..a36de29ce --- /dev/null +++ b/packages/demo/src/demo/case/item/demo.single_select_radio_item.js @@ -0,0 +1,30 @@ +import { + VerticalLayout, + Label, + SingleSelectRadioItem, + Decorators, + Widget +} from "@fui/core"; + +@Decorators.shortcut() +export class SingleSelectRadioItemDemo extends Widget { + static xtype = "demo.single_select_radio_item"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "单选item" + }, + { + type: SingleSelectRadioItem.xtype, + text: "单选项" + } + ], + hgap: 300 + }; + } +} diff --git a/packages/demo/src/demo/case/item/index.js b/packages/demo/src/demo/case/item/index.js new file mode 100644 index 000000000..a5da7036c --- /dev/null +++ b/packages/demo/src/demo/case/item/index.js @@ -0,0 +1,3 @@ +export * from "./demo.multi_select_item"; +export * from "./demo.single_select_item"; +export * from "./demo.single_select_radio_item"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/list/demo.lazy_loader.js b/packages/demo/src/demo/case/list/demo.lazy_loader.js new file mode 100644 index 000000000..e6914637e --- /dev/null +++ b/packages/demo/src/demo/case/list/demo.lazy_loader.js @@ -0,0 +1,37 @@ +import { CONSTANTS } from "@/config/constant"; +import { + LazyLoader, + FloatLeftLayout, + Button, + Decorators, + Widget, + createWidget, + createItems, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class LazyLoaderDemo extends Widget { + static xtype = "demo.lazy_loader"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + createWidget({ + type: LazyLoader.xtype, + element: this, + el: { + layouts: [ + { + type: FloatLeftLayout.xtype, + hgap: 5 + } + ] + }, + items: createItems(deepClone(CONSTANTS.ITEMS), { + type: Button.xtype + }) + }); + } +} diff --git a/packages/demo/src/demo/case/list/demo.select_list.js b/packages/demo/src/demo/case/list/demo.select_list.js new file mode 100644 index 000000000..9dde9066d --- /dev/null +++ b/packages/demo/src/demo/case/list/demo.select_list.js @@ -0,0 +1,39 @@ +import { CONSTANTS } from "@/config/constant"; +import { + SelectList, + MultiSelectBar, + MultiSelectItem, + Decorators, + Widget, + createWidget, + createItems, + deepClone, + Selection +} from "@fui/core"; + +@Decorators.shortcut() +export class SelectListDemo extends Widget { + static xtype = "demo.select_list"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + createWidget({ + type: SelectList.xtype, + toolbar: { + type: MultiSelectBar.xtype, + iconWrapperWidth: 26 + }, + element: this, + el: { + el: { + chooseType: Selection.Multi + } + }, + items: createItems(deepClone(CONSTANTS.SIMPLE_ITEMS), { + type: MultiSelectItem.xtype + }) + }); + } +} diff --git a/packages/demo/src/demo/case/list/index.js b/packages/demo/src/demo/case/list/index.js new file mode 100644 index 000000000..4e008070c --- /dev/null +++ b/packages/demo/src/demo/case/list/index.js @@ -0,0 +1,2 @@ +export * from "./demo.lazy_loader"; +export * from "./demo.select_list"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/pager/demo.all_count_pager.js b/packages/demo/src/demo/case/pager/demo.all_count_pager.js new file mode 100644 index 000000000..fb159af62 --- /dev/null +++ b/packages/demo/src/demo/case/pager/demo.all_count_pager.js @@ -0,0 +1,37 @@ +import { + VerticalLayout, + Label, + AllCountPager, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class AllCountPagerDemo extends Widget { + static xtype = "demo.all_count_pager"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: VerticalLayout.xtype, + hgap: 200, + vgap: 50, + element: this, + items: [ + { + type: Label.xtype, + height: 30, + text: " (测试条件:总页数为3)" + }, + { + type: AllCountPager.xtype, + pages: 3, + curr: 1, + count: 1000 + } + ] + }); + } +} diff --git a/packages/demo/src/demo/case/pager/demo.direction_pager.js b/packages/demo/src/demo/case/pager/demo.direction_pager.js new file mode 100644 index 000000000..e83f76685 --- /dev/null +++ b/packages/demo/src/demo/case/pager/demo.direction_pager.js @@ -0,0 +1,57 @@ + +import { VerticalLayout, DirectionPager, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class DirectionPagerDemo extends Widget { + static xtype = "demo.direction_pager"; + + props = { baseCls: "demo-func" }; + + mounted() { + this.pager.populate(); + } + + render() { + const self = this; + createWidget({ + type: VerticalLayout.xtype, + hgap: 200, + vgap: 50, + element: this, + items: [ + { + type: DirectionPager.xtype, + ref(_ref) { + self.pager = _ref; + }, + horizontal: { + pages: false, // 总页数 + curr: 1, // 初始化当前页, pages为数字时可用 + + hasPrev(v) { + return v > 1; + }, + hasNext() { + return true; + }, + firstPage: 1, + }, + vertical: { + pages: false, // 总页数 + curr: 1, // 初始化当前页, pages为数字时可用 + + hasPrev(v) { + return v > 1; + }, + hasNext() { + return true; + }, + firstPage: 1, + }, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/case/pager/index.js b/packages/demo/src/demo/case/pager/index.js new file mode 100644 index 000000000..c4061c8c6 --- /dev/null +++ b/packages/demo/src/demo/case/pager/index.js @@ -0,0 +1,2 @@ +export * from "./demo.all_count_pager"; +export * from "./demo.direction_pager"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/pane/demo.list_pane.js b/packages/demo/src/demo/case/pane/demo.list_pane.js new file mode 100644 index 000000000..649ed4498 --- /dev/null +++ b/packages/demo/src/demo/case/pane/demo.list_pane.js @@ -0,0 +1,51 @@ +import { CONSTANTS } from "@/config/constant"; +import { + ListPane, + MultiSelectItem, + ButtonGroup, + VerticalLayout, + Decorators, + Widget, + createItems, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class ListPaneDemo extends Widget { + static xtype = "demo.list_pane"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: ListPane.xtype, + ref() { + self.pane = this; + }, + itemsCreator(op, callback) { + setTimeout(() => { + callback( + createItems(deepClone(CONSTANTS.ITEMS), { + type: MultiSelectItem.xtype, + height: 25 + }) + ); + }, 2000); + }, + el: { + type: ButtonGroup.xtype, + layouts: [ + { + type: VerticalLayout.xtype + } + ] + } + }; + } + + mounted() { + this.pane.populate(); + } +} diff --git a/packages/demo/src/demo/case/pane/demo.multi_popup_view.js b/packages/demo/src/demo/case/pane/demo.multi_popup_view.js new file mode 100644 index 000000000..a5cc7d231 --- /dev/null +++ b/packages/demo/src/demo/case/pane/demo.multi_popup_view.js @@ -0,0 +1,59 @@ +import { CONSTANTS } from "@/config/constant"; +import { + AbsoluteLayout, + Combo, + TextButton, + MultiPopupView, + ButtonGroup, + VerticalLayout, + MultiSelectItem, + Decorators, + Widget, + createItems, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiPopupViewDemo extends Widget { + static xtype = "demo.multi_popup_view"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + width: 200, + height: 30, + el: { + type: TextButton.xtype, + text: "点击", + cls: "bi-border", + height: 30 + }, + popup: { + type: MultiPopupView.xtype, + el: { + type: ButtonGroup.xtype, + layouts: [ + { + type: VerticalLayout.xtype + } + ], + items: createItems(deepClone(CONSTANTS.ITEMS), { + type: MultiSelectItem.xtype, + height: 25 + }) + } + } + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/case/pane/demo.panel.js b/packages/demo/src/demo/case/pane/demo.panel.js new file mode 100644 index 000000000..64f1f5d63 --- /dev/null +++ b/packages/demo/src/demo/case/pane/demo.panel.js @@ -0,0 +1,46 @@ +import { CONSTANTS } from "@/config/constant"; +import { + Panel, + Button, + ButtonGroup, + VerticalLayout, + MultiSelectItem, + Decorators, + Widget, + createItems, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class PanelDemo extends Widget { + static xtype = "demo.panel"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: Panel.xtype, + title: "title", + titleButtons: [ + { + type: Button.xtype, + text: "操作" + } + ], + el: { + type: ButtonGroup.xtype, + layouts: [ + { + type: VerticalLayout.xtype + } + ], + items: createItems(deepClone(CONSTANTS.ITEMS), { + type: MultiSelectItem.xtype, + height: 25 + }) + } + }; + } +} diff --git a/packages/demo/src/demo/case/pane/demo.popup_panel.js b/packages/demo/src/demo/case/pane/demo.popup_panel.js new file mode 100644 index 000000000..672e5cfe2 --- /dev/null +++ b/packages/demo/src/demo/case/pane/demo.popup_panel.js @@ -0,0 +1,59 @@ +import { CONSTANTS } from "@/config/constant"; +import { + AbsoluteLayout, + Combo, + TextButton, + PopupPanel, + ButtonGroup, + VerticalLayout, + MultiSelectItem, + Decorators, + Widget, + createItems, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class PopupPanelDemo extends Widget { + static xtype = "demo.popup_panel"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + width: 200, + height: 30, + el: { + type: TextButton.xtype, + text: "点击", + cls: "bi-border", + height: 30 + }, + popup: { + type: PopupPanel.xtype, + el: { + type: ButtonGroup.xtype, + layouts: [ + { + type: VerticalLayout.xtype + } + ], + items: createItems(deepClone(CONSTANTS.ITEMS), { + type: MultiSelectItem.xtype, + height: 25 + }) + } + } + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/case/pane/index.js b/packages/demo/src/demo/case/pane/index.js new file mode 100644 index 000000000..6fd6c64e2 --- /dev/null +++ b/packages/demo/src/demo/case/pane/index.js @@ -0,0 +1,4 @@ +export * from "./demo.list_pane"; +export * from "./demo.multi_popup_view"; +export * from "./demo.panel"; +export * from "./demo.popup_panel"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/tree/demo.display_tree.js b/packages/demo/src/demo/case/tree/demo.display_tree.js new file mode 100644 index 000000000..a7122a533 --- /dev/null +++ b/packages/demo/src/demo/case/tree/demo.display_tree.js @@ -0,0 +1,56 @@ + +import { DisplayTree, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class DisplayTreeDemo extends Widget { + static xtype = "demo.display_tree"; + + props = { baseCls: "demo-func" }; + + render() { + const tree = createWidget({ + type: DisplayTree.xtype, + element: this, + }); + + tree.initTree([ + { + id: 1, + text: "第一项", + open: true, + }, + { + id: 2, + text: "第二项", + }, + { + id: 11, + pId: 1, + text: "子项1(共2个)", + open: true, + }, + { + id: 111, + pId: 11, + text: "子子项1", + }, + { + id: 112, + pId: 11, + text: "子子项2", + }, + { + id: 12, + pId: 1, + text: "子项2", + }, + { + id: 13, + pId: 1, + text: "子项3", + } + ]); + } +} + diff --git a/packages/demo/src/demo/case/tree/demo.level_tree.js b/packages/demo/src/demo/case/tree/demo.level_tree.js new file mode 100644 index 000000000..564ff16ca --- /dev/null +++ b/packages/demo/src/demo/case/tree/demo.level_tree.js @@ -0,0 +1,114 @@ + +import { createWidget, Msg, LevelTree, VTapeLayout, Button, Decorators, Widget } from "@fui/core" + + + +@Decorators.shortcut() +export class LevelTreeDemo extends Widget { + static xtype = "demo.level_tree"; + + props = { baseCls: "demo-func" }; + + render() { + const tree = createWidget({ + type: LevelTree.xtype, + chooseType: 0, + items: [ + { + id: 1, + text: "第一项", + value: 1, + isParent: true, + }, + { + id: 2, + text: "第二项", + value: 2, + isParent: true, + }, + { + id: 3, + text: "第三项", + value: 1, + isParent: true, + open: true, + }, + { + id: 4, + text: "第四项", + value: 1, + }, + { + id: 11, + pId: 1, + text: "子项1", + value: 11, + }, + { + id: 12, + pId: 1, + text: "子项2", + value: 12, + }, + { + id: 13, + pId: 1, + text: "子项3", + value: 13, + }, + { + id: 111, + pId: 11, + text: "子项1-1", + value: 111, + }, + { + id: 21, + pId: 2, + text: "子项1", + value: 21, + }, + { + id: 31, + pId: 3, + text: "子项1", + value: 31, + }, + { + id: 32, + pId: 3, + text: "子项2", + value: 32, + }, + { + id: 33, + pId: 3, + text: "子项3", + value: 33, + } + ], + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + el: tree, + }, + { + height: 30, + el: { + type: Button.xtype, + height: 30, + text: "getValue", + handler() { + Msg.alert("", tree.getValue()); + }, + }, + } + ], + }); + } +} + diff --git a/packages/demo/src/demo/case/tree/demo.simple_tree.js b/packages/demo/src/demo/case/tree/demo.simple_tree.js new file mode 100644 index 000000000..67ced9ce9 --- /dev/null +++ b/packages/demo/src/demo/case/tree/demo.simple_tree.js @@ -0,0 +1,154 @@ +import { + SimpleTreeView, + VTapeLayout, + Button, + Decorators, + Widget, + createWidget, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class SimpleTreeDemo extends Widget { + static xtype = "demo.simple_tree"; + + props = { baseCls: "demo-func" }; + + render() { + // value值一定要是字符串 + const tree = createWidget({ + type: SimpleTreeView.xtype, + items: [ + { + id: 1, + text: "第一项", + value: "1" + }, + { + id: 2, + text: "第二项", + value: "2" + }, + { + id: 3, + text: "第三项", + value: "3", + open: true + }, + { + id: 11, + pId: 1, + text: "子项1", + value: "11" + }, + { + id: 12, + pId: 1, + text: "子项2", + value: "12" + }, + { + id: 13, + pId: 1, + text: "子项3", + value: "13" + }, + { + id: 31, + pId: 3, + text: "子项1", + value: "31" + }, + { + id: 32, + pId: 3, + text: "子项2", + value: "32" + }, + { + id: 33, + pId: 3, + text: "子项3", + value: "33" + } + ], + value: ["31", "32", "33"] + }); + + // tree.populate([{ + // id: 1, + // text: "第一项", + // value: "1" + // }, { + // id: 2, + // text: "第二项", + // value: "2" + // }, { + // id: 3, + // text: "第三项", + // value: "3", + // open: true + // }, { + // id: 11, + // pId: 1, + // text: "子项1", + // value: "11" + // }, { + // id: 12, + // pId: 1, + // text: "子项2", + // value: "12" + // }, { + // id: 13, + // pId: 1, + // text: "子项3", + // value: "13" + // }, { + // id: 31, + // pId: 3, + // text: "子项1", + // value: "31" + // }, { + // id: 32, + // pId: 3, + // text: "子项2", + // value: "32" + // }, { + // id: 33, + // pId: 3, + // text: "子项3", + // value: "33" + // }], "z"); + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + el: tree + }, + { + height: 30, + el: { + type: Button.xtype, + height: 30, + text: "setValue(['31', '32', '33'])", + handler() { + tree.setValue(["31", "32", "33"]); + } + } + }, + { + height: 30, + el: { + type: Button.xtype, + height: 30, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(tree.getValue())); + } + } + } + ] + }); + } +} diff --git a/packages/demo/src/demo/case/tree/index.js b/packages/demo/src/demo/case/tree/index.js new file mode 100644 index 000000000..8180d07ab --- /dev/null +++ b/packages/demo/src/demo/case/tree/index.js @@ -0,0 +1,3 @@ +export * from "./demo.display_tree"; +export * from "./demo.level_tree"; +export * from "./demo.simple_tree"; \ No newline at end of file diff --git a/packages/demo/src/demo/case/triggers/demo.editor_trigger.js b/packages/demo/src/demo/case/triggers/demo.editor_trigger.js new file mode 100644 index 000000000..07a869ade --- /dev/null +++ b/packages/demo/src/demo/case/triggers/demo.editor_trigger.js @@ -0,0 +1,36 @@ +import { + VerticalLayout, + Label, + EditorTrigger, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class EditorTriggerDemo extends Widget { + static xtype = "demo.editor_trigger"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [ + { + type: Label.xtype, + text: "输入框加图标的trigger" + }, + { + type: EditorTrigger.xtype, + watermark: "这是水印", + width: 200, + height: 24 + } + ], + hgap: 20, + vgap: 20 + }); + } +} diff --git a/packages/demo/src/demo/case/triggers/demo.icon_trigger.js b/packages/demo/src/demo/case/triggers/demo.icon_trigger.js new file mode 100644 index 000000000..fc53a5b1c --- /dev/null +++ b/packages/demo/src/demo/case/triggers/demo.icon_trigger.js @@ -0,0 +1,35 @@ +import { + VerticalLayout, + Label, + IconTrigger, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class IconTriggerDemo extends Widget { + static xtype = "demo.icon_trigger"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [ + { + type: Label.xtype, + text: "只有一个图标的trigger" + }, + { + type: IconTrigger.xtype, + width: 30, + height: 24 + } + ], + hgap: 20, + vgap: 20 + }); + } +} diff --git a/packages/demo/src/demo/case/triggers/demo.select_text_trigger.js b/packages/demo/src/demo/case/triggers/demo.select_text_trigger.js new file mode 100644 index 000000000..a34b2c0c2 --- /dev/null +++ b/packages/demo/src/demo/case/triggers/demo.select_text_trigger.js @@ -0,0 +1,36 @@ +import { + VerticalLayout, + Label, + SelectTextTrigger, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class SelectTextTriggerDemo extends Widget { + static xtype = "demo.select_text_trigger"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [ + { + type: Label.xtype, + text: "可被选择的trigger" + }, + { + type: SelectTextTrigger.xtype, + text: "这是一个简单的trigger", + width: 200, + height: 24 + } + ], + hgap: 20, + vgap: 20 + }); + } +} diff --git a/packages/demo/src/demo/case/triggers/demo.text_trigger.js b/packages/demo/src/demo/case/triggers/demo.text_trigger.js new file mode 100644 index 000000000..f7a3a2317 --- /dev/null +++ b/packages/demo/src/demo/case/triggers/demo.text_trigger.js @@ -0,0 +1,36 @@ +import { + VerticalLayout, + Label, + TextTrigger, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class TextTriggerDemo extends Widget { + static xtype = "demo.text_trigger"; + + props = { baseCls: "demo-func" }; + + render() { + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [ + { + type: Label.xtype, + text: "文本加图标的trigger" + }, + { + type: TextTrigger.xtype, + text: "这是一个简单的trigger", + width: 200, + height: 24 + } + ], + hgap: 20, + vgap: 20 + }); + } +} diff --git a/packages/demo/src/demo/case/triggers/index.js b/packages/demo/src/demo/case/triggers/index.js new file mode 100644 index 000000000..0ef8e8a04 --- /dev/null +++ b/packages/demo/src/demo/case/triggers/index.js @@ -0,0 +1,4 @@ +export * from "./demo.editor_trigger"; +export * from "./demo.icon_trigger"; +export * from "./demo.select_text_trigger"; +export * from "./demo.text_trigger"; \ No newline at end of file diff --git a/packages/demo/src/demo/component/demo.form.js b/packages/demo/src/demo/component/demo.form.js new file mode 100644 index 000000000..b1172775f --- /dev/null +++ b/packages/demo/src/demo/component/demo.form.js @@ -0,0 +1,114 @@ + +import { createWidget, isEmpty, isNotEmptyArray, Form, TextEditor, TextValueCombo, TextAreaEditor, VerticalLayout, Button, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class FormDemo extends Widget { + static xtype = "demo.form"; + + props = { baseCls: "demo-form" }; + + render() { + const widget = createWidget({ + type: Form.xtype, + width: 300, + labelWidth: 100, + items: [ + { + validate(v) { + return v !== "a" && v !== ""; + }, + tip(v) { + if (isEmpty(v)) { + return "不能为空"; + } + + return "不合法格式"; + }, + label: "E-mail", + el: { + type: TextEditor.xtype, + watermark: "输入a报错", + allowBlank: true, + }, + }, + { + validate(v) { + return isNotEmptyArray(v); + }, + tip() { + return "不能为空"; + }, + label: "性别", + el: { + type: TextValueCombo.xtype, + text: "请选择", + items: [ + { + text: "男", + value: 1, + }, + { + text: "女", + value: 2, + } + ], + }, + }, + { + validate(v) { + return v !== ""; + }, + tip() { + return "不能为空"; + }, + label: "姓名", + el: { + type: TextEditor.xtype, + watermark: "输入姓名", + allowBlank: true, + }, + }, + { + validate(v) { + return v !== ""; + }, + tip() { + return "不能为空"; + }, + label: "姓名", + el: { + type: TextAreaEditor.xtype, + cls: "bi-border", + watermark: "输入简介", + allowBlank: true, + height: 200, + }, + } + ], + layout: { + type: VerticalLayout.xtype, + vgap: 30, + }, + }); + + return { + type: VerticalLayout.xtype, + hgap: 200, + vgap: 10, + items: [ + widget, + { + type: Button.xtype, + text: "提交", + handler() { + widget.validate(); + + console.log(widget.getValue()); + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/component/demo.treevaluechoosercombo.js b/packages/demo/src/demo/component/demo.treevaluechoosercombo.js new file mode 100644 index 000000000..92ee248ef --- /dev/null +++ b/packages/demo/src/demo/component/demo.treevaluechoosercombo.js @@ -0,0 +1,30 @@ +import { CONSTANTS } from "@/config/constant"; + +import { TreeValueChooserCombo, VerticalLayout, Decorators, Widget, createWidget, deepClone } from "@fui/core" + + +@Decorators.shortcut() +export class TreeValueChooserDemo extends Widget { + static xtype = "demo.tree_value_chooser_combo"; + + props = { baseCls: "demo-tree-value-chooser-combo" }; + + render() { + const widget = createWidget({ + type: TreeValueChooserCombo.xtype, + width: 300, + itemsCreator(op, callback) { + callback(deepClone(CONSTANTS.TREEITEMS)); + }, + defaultText: "请选择", + }); + + return { + type: VerticalLayout.xtype, + hgap: 200, + vgap: 10, + items: [widget], + }; + } +} + diff --git a/packages/demo/src/demo/component/demo.treevaluechooserpane.js b/packages/demo/src/demo/component/demo.treevaluechooserpane.js new file mode 100644 index 000000000..f2a5a4809 --- /dev/null +++ b/packages/demo/src/demo/component/demo.treevaluechooserpane.js @@ -0,0 +1,19 @@ +import { CONSTANTS } from "@/config/constant"; +import { TreeValueChooserPane, Decorators, Widget, deepClone } from "@fui/core"; + +@Decorators.shortcut() +export class TreeValueChooserPaneDemo extends Widget { + static xtype = "demo.tree_value_chooser_pane"; + + props = { baseCls: "demo-tree-value-chooser" }; + + render() { + return { + type: TreeValueChooserPane.xtype, + items: deepClone(CONSTANTS.TREEITEMS) + // itemsCreator: function (op, callback) { + // callback(tree); + // } + }; + } +} diff --git a/packages/demo/src/demo/component/demo.valuechoosercombo.js b/packages/demo/src/demo/component/demo.valuechoosercombo.js new file mode 100644 index 000000000..c14cd4462 --- /dev/null +++ b/packages/demo/src/demo/component/demo.valuechoosercombo.js @@ -0,0 +1,28 @@ +import { CONSTANTS } from "@/config/constant"; + +import { ValueChooserCombo, VerticalLayout, Decorators, Widget, createWidget, deepClone } from "@fui/core" + + +@Decorators.shortcut() +export class ValueChooserComboDemo extends Widget { + static xtype = "demo.value_chooser_combo"; + + props = { baseCls: "demo-value-chooser-combo" }; + + render() { + const widget = createWidget({ + type: ValueChooserCombo.xtype, + itemsCreator (op, callback) { + callback(deepClone(CONSTANTS.ITEMS)); + }, + }); + + return { + type: VerticalLayout.xtype, + hgap: 200, + vgap: 10, + items: [widget], + }; + } +} + diff --git a/packages/demo/src/demo/component/demo.valuechooserpane.js b/packages/demo/src/demo/component/demo.valuechooserpane.js new file mode 100644 index 000000000..ce0b2cc24 --- /dev/null +++ b/packages/demo/src/demo/component/demo.valuechooserpane.js @@ -0,0 +1,16 @@ +import { CONSTANTS } from "@/config/constant"; +import { ValueChooserPane, Decorators, Widget, deepClone } from "@fui/core"; + +@Decorators.shortcut() +export class ValueChooserPaneDemo extends Widget { + static xtype = "demo.value_chooser_pane"; + + props = { baseCls: "demo-value-chooser-pane" }; + + render() { + return { + type: ValueChooserPane.xtype, + items: deepClone(CONSTANTS.ITEMS) + }; + } +} diff --git a/packages/demo/src/demo/component/index.js b/packages/demo/src/demo/component/index.js new file mode 100644 index 000000000..b980af9a7 --- /dev/null +++ b/packages/demo/src/demo/component/index.js @@ -0,0 +1,10 @@ +export const meta = { + title: "部件+服务", + rank: 4 +}; + +export * from "./demo.form"; +export * from "./demo.treevaluechoosercombo"; +export * from "./demo.treevaluechooserpane"; +export * from "./demo.valuechoosercombo"; +export * from "./demo.valuechooserpane"; diff --git a/packages/demo/src/demo/core/abstract/combination/demo.combo.js b/packages/demo/src/demo/core/abstract/combination/demo.combo.js new file mode 100644 index 000000000..343865be5 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.combo.js @@ -0,0 +1,487 @@ +import { + ComboGroup, + IconTextIconItem, + SingleSelectItem, + Combo, + Button, + ButtonGroup, + Decorators, + SingleSelectRadioItem, + VerticalLayout, + MultiSelectItem, + Label, + MultiSelectBar, + TextButton, + Loader, + FloatLeftLayout, + ButtonTree, + AdaptiveLayout, + TableLayout, + AbsoluteLayout, + Navigation, + GridLayout, + Widget, + createWidget, + createItems, + deepClone, + map, + delay, + random, + makeArray, + Msg +} from "@fui/core"; + + +@Decorators.shortcut() +export class ComboDemo extends Widget { + static xtype = "demo.combo"; + + props = { baseCls: "demo-func" }; + years = [ + { text: "2010年", value: 2010, iconCls: "close-ha-font" }, + { text: "2011年", value: 2011 }, + { text: "2012年", value: 2012, iconCls: "close-ha-font" }, + { text: "2013年", value: 2013 }, + { text: "2014年", value: 2014, iconCls: "close-ha-font" }, + { text: "2015年", value: 2015, iconCls: "close-ha-font" }, + { text: "2016年", value: 2016, iconCls: "close-ha-font" }, + { text: "2017年", value: 2017, iconCls: "close-ha-font" } + ]; + child = [ + { + type: ComboGroup.xtype, + el: { + type: IconTextIconItem.xtype, + text: "2010年", + value: 2010, + height: 25, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + }, + items: [ + { type: SingleSelectItem.xtype, height: 25, text: "一月", value: 11 }, + { + type: IconTextIconItem.xtype, + height: 25, + text: "二月", + value: 12, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + children: [{ type: SingleSelectItem.xtype, text: "一号", value: 101, height: 25 }], + } + ], + }, + { text: "2011年", value: 2011 }, + { text: "2012年", value: 2012, iconCls: "close-ha-font" }, + { text: "2013年", value: 2013 }, + { text: "2014年", value: 2014, iconCls: "close-ha-font" }, + { text: "2015年", value: 2015, iconCls: "close-ha-font" } + ]; + months = [ + [{ el: { text: "一月", value: 1 } }, { el: { text: "二月", value: 2 } }], + [{ el: { text: "三月", value: 3 } }, { el: { text: "四月", value: 4 } }], + [{ el: { text: "五月", value: 5 } }, { el: { text: "六月", value: 6 } }], + [{ el: { text: "七月", value: 7 } }, { el: { text: "八月", value: 8 } }], + [{ el: { text: "九月", value: 9 } }, { el: { text: "十月", value: 10 } }], + [{ el: { text: "十一月", value: 11 } }, { el: { text: "十二月", value: 12 } }] + ]; + dynamic = [ + { text: "2010年", value: 1 }, + { text: "20112222年", value: 2 }, + { text: "201233333年", value: 3 }, + { text: "2013年", value: 4 }, + { text: "2012324年", value: 5 }, + { text: "2015年", value: 6 }, + { text: "2016年", value: 7 }, + { text: "201744444444444444444444444444444444444年", value: 8 } + ]; + week = [ + { text: "周一", value: 100, iconClsLeft: "close-ha-font", iconClsRight: "close-font" }, + { text: "周二", value: 101, iconClsLeft: "close-ha-font" }, + { text: "周三", value: 102 }, + { text: "周四", value: 103, iconClsRight: "close-ha-font" }, + { text: "周五", value: 104, iconClsLeft: "close-ha-font", iconClsRight: "close-font" }, + { text: "周六", value: 105, iconClsLeft: "close-font", iconClsRight: "close-ha-font" }, + { text: "周日", value: 106, iconClsLeft: "close-font" } + ]; + + _createTop() { + const self = this; + + const yearCombo = createWidget({ + type: Combo.xtype, + el: { + type: Button.xtype, + text: "简单下拉框", + height: 30, + }, + popup: { + el: { + type: ButtonGroup.xtype, + items: createItems(deepClone(this.years), { + type: SingleSelectRadioItem.xtype, + height: 25, + handler(v) { + }, + }), + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + width: 200, + }); + + var multiCombo = createWidget({ + type: Combo.xtype, + el: { + type: Button.xtype, + text: "多选下拉框", + height: 30, + }, + popup: { + el: { + items: createItems(deepClone(this.years), { + type: MultiSelectItem.xtype, + height: 25, + handler(v) { + }, + }), + chooseType: 1, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + tool: { + type: Label.xtype, + text: "这是一个下拉框", + height: 35, + }, + tabs: [ + { + type: MultiSelectBar.xtype, + height: 25, + text: "全选", + onCheck(v) { + if (v) { + multiCombo.setValue(map(deepClone(self.years), "value")); + } else { + multiCombo.setValue([]); + } + }, + isAllCheckedBySelectedValue(selectedValue) { + return selectedValue.length == self.years.length; + // return true; + }, + } + ], + buttons: [ + { + type: TextButton.xtype, + text: "清空", + handler() { + multiCombo.setValue([]); + }, + }, + { + type: TextButton.xtype, + text: "确定", + handler() { + Msg.alert("", multiCombo.getValue()); + }, + } + ], + }, + width: 200, + }); + + const dynamicPopupCombo = createWidget({ + type: Combo.xtype, + isNeedAdjustWidth: false, + offsetStyle: "center", + el: { + type: Button.xtype, + text: "动态调整宽度", + height: 30, + }, + popup: { + el: { + items: createItems(deepClone(this.dynamic), { + type: SingleSelectItem.xtype, + height: 25, + }), + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + width: 200, + }); + + var dynamicCombo = createWidget({ + type: Combo.xtype, + el: { + type: Button.xtype, + text: "搜索", + height: 30, + }, + popup: { + el: { + type: Loader.xtype, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + itemsCreator(options, popuplate) { + const times = options.times; + delay(() => { + if (times == 3) { + popuplate([ + { + type: SingleSelectItem.xtype, + text: "这是最后一个", + value: "这是最后一个", + py: "zszhyg", + height: 25, + } + ]); + + return; + } + + const map = map(makeArray(3, null), (i, v) => { + const val = `${i}_${random(1, 100)}`; + + return { + type: SingleSelectItem.xtype, + text: val, + value: val, + height: 25, + }; + }); + popuplate(map); + }, 1000); + }, + hasNext(options) { + return options.times < 3; + }, + }, + buttons: [ + { + type: TextButton.xtype, + text: "清空", + handler() { + dynamicCombo.setValue([]); + }, + }, + { + type: TextButton.xtype, + text: "确定", + handler() { + Msg.alert("", dynamicCombo.getValue()); + }, + } + ], + }, + width: 200, + }); + + return createWidget({ + type: FloatLeftLayout.xtype, + items: [yearCombo, multiCombo, dynamicPopupCombo, dynamicCombo], + hgap: 20, + vgap: 20, + }); + } + + _createBottom() { + const combo = createWidget({ + type: Combo.xtype, + el: { + type: TextButton.xtype, + cls: "button-combo", + height: 30, + }, + popup: { + el: { + type: ButtonGroup.xtype, + items: createItems(deepClone(this.years), { + type: SingleSelectItem.xtype, + iconWidth: 25, + height: 25, + handler(v) { + }, + }), + chooseType: 1, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + width: 200, + }); + combo.setValue(deepClone(this.years)[0].value); + + const childCombo = createWidget({ + type: Combo.xtype, + el: { + type: TextButton.xtype, + cls: "button-combo", + height: 30, + }, + popup: { + el: { + type: ButtonTree.xtype, + items: createItems(deepClone(this.child), { + type: SingleSelectItem.xtype, + height: 25, + handler(v) { + }, + }), + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + width: 200, + }); + childCombo.setValue(deepClone(this.child)[0].items[0].value); + + const monthCombo = createWidget({ + type: Combo.xtype, + el: { + type: Button.xtype, + text: "多层样式下拉框", + height: 30, + }, + popup: { + el: { + items: createItems(deepClone(this.months), { + type: SingleSelectItem.xtype, + cls: "button-combo", + handler(v) { + }, + }), + layouts: [ + { + type: AdaptiveLayout.xtype, + items: [ + { + el: { + type: TableLayout.xtype, + columns: 2, + rows: 6, + columnSize: [0.5, "fill"], + rowSize: 30, + }, + left: 4, + right: 4, + top: 2, + bottom: 2, + } + ], + }, + { + type: AbsoluteLayout.xtype, + el: { left: 4, top: 2, right: 4, bottom: 2 }, + } + ], + }, + }, + width: 200, + }); + + const yearCombo = createWidget({ + type: Combo.xtype, + el: { + type: Button.xtype, + text: "自定义控件", + height: 30, + }, + popup: { + el: { + type: Navigation.xtype, + direction: "bottom", + logic: { + dynamic: true, + }, + tab: { + height: 30, + items: [ + { + once: false, + text: "后退", + value: -1, + cls: "mvc-button layout-bg3", + }, + { + once: false, + text: "前进", + value: 1, + cls: "mvc-button layout-bg4", + } + ], + }, + cardCreator(v) { + return createWidget({ + type: TextButton.xtype, + whiteSpace: "normal", + text: new Date().getFullYear() + v, + }); + }, + }, + }, + width: 200, + }); + + return createWidget({ + type: FloatLeftLayout.xtype, + items: [combo, childCombo, monthCombo, yearCombo], + hgap: 20, + vgap: 20, + }); + } + + render() { + return { + type: GridLayout.xtype, + columns: 1, + rows: 2, + items: [ + { + column: 0, + row: 0, + el: this._createTop(), + }, + { + column: 0, + row: 1, + el: this._createBottom(), + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/abstract/combination/demo.combo2.js b/packages/demo/src/demo/core/abstract/combination/demo.combo2.js new file mode 100644 index 000000000..5acd394d5 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.combo2.js @@ -0,0 +1,175 @@ +import { + Button, + Combo, + Layout, + GridLayout, + Widget, + createWidget, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class Combo2Demo extends Widget { + static xtype = "demo.combo2"; + + props = { baseCls: "demo-func" }; + + _createEl() { + return { + type: Button.xtype, + height: 25, + text: "点击" + }; + } + + oneCombo() { + return createWidget({ + type: Combo.xtype, + adjustLength: 5, + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + height: 500 + }, + maxHeight: 400 + } + }); + } + + twoCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "bottom,left", + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + height: 1200 + } + } + }); + } + + threeCombo() { + return createWidget({ + type: Combo.xtype, + adjustYOffset: 5, + el: this._createEl(), + isNeedAdjustHeight: false, + popup: { + el: { + type: Layout.xtype, + height: 1200 + } + } + }); + } + + fourCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "left", + el: this._createEl(), + isNeedAdjustHeight: true, + popup: { + el: { + type: Layout.xtype, + height: 1200 + } + } + }); + } + + fiveCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "left,top", + el: this._createEl(), + isNeedAdjustHeight: true, + popup: { + el: { + type: Layout.xtype, + height: 1200 + }, + maxHeight: 2000 + } + }); + } + + sixCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "top,left", + el: this._createEl(), + isNeedAdjustHeight: true, + popup: { + el: { + type: Layout.xtype, + height: 1200 + } + } + }); + } + + sevenCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "bottom", + isNeedAdjustWidth: false, + // isNeedAdjustHeight: false, + offsetStyle: "center", + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + width: 200, + height: 1200 + } + } + }); + } + + eightCombo() { + return createWidget({ + type: Combo.xtype, + adjustXOffset: 25, + adjustYOffset: 5, + direction: "right", + isNeedAdjustWidth: false, + // isNeedAdjustHeight: false, + offsetStyle: "middle", + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + width: 200, + height: 200 + } + } + }); + } + + render() { + return { + type: GridLayout.xtype, + hgap: 10, + vgap: 5, + items: [ + [this.oneCombo(), this.twoCombo(), this.threeCombo()], + [this.fourCombo(), this.fiveCombo(), this.sixCombo()], + [this.sevenCombo(), this.eightCombo()] + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.combo3.js b/packages/demo/src/demo/core/abstract/combination/demo.combo3.js new file mode 100644 index 000000000..80078e7a8 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.combo3.js @@ -0,0 +1,85 @@ +import { + Label, + Combo, + Layout, + GridLayout, + Widget, + createWidget, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class Combo3Demo extends Widget { + static xtype = "demo.combo3"; + + props = { baseCls: "demo-func" }; + + _createEl() { + return { + type: Label.xtype, + cls: "bi-border", + height: "100%", + text: "点击" + }; + } + + oneCombo() { + return createWidget({ + type: Combo.xtype, + direction: "right,innerRight", + isNeedAdjustWidth: false, + isNeedAdjustHeight: false, + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + width: 200, + height: 200 + } + } + }); + } + + twoCombo() { + return createWidget({ + type: Combo.xtype, + direction: "right,innerRight", + isNeedAdjustWidth: false, + isNeedAdjustHeight: false, + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + width: 1000, + height: 200 + } + } + }); + } + + threeCombo() { + return createWidget({ + type: Combo.xtype, + direction: "right,innerRight", + isNeedAdjustWidth: false, + isNeedAdjustHeight: false, + el: this._createEl(), + popup: { + el: { + type: Layout.xtype, + width: 400, + height: 200 + } + } + }); + } + + render() { + return { + type: GridLayout.xtype, + hgap: 10, + vgap: 5, + items: [[this.oneCombo()], [this.twoCombo()], [this.threeCombo()]] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.combo_group.js b/packages/demo/src/demo/core/abstract/combination/demo.combo_group.js new file mode 100644 index 000000000..925f36fc7 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.combo_group.js @@ -0,0 +1,114 @@ +import { + ComboGroup, + IconTextIconItem, + SingleSelectItem, + Combo, + TextButton, + ButtonTree, + VerticalLayout, + FloatLeftLayout, + GridLayout, + Widget, + createWidget, + createItems, + deepClone, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class ComboGroupDemo extends Widget { + static xtype = "demo.combo.group"; + + props = { baseCls: "demo-func" }; + child = [ + { + type: ComboGroup.xtype, + el: { + type: IconTextIconItem.xtype, + text: "2010年", + value: 2010, + height: 25, + iconCls: "close-ha-font" + }, + items: [ + { + type: SingleSelectItem.xtype, + height: 25, + text: "一月", + value: 11 + }, + { + type: IconTextIconItem.xtype, + height: 25, + text: "二月", + value: 12, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + children: [ + { + type: SingleSelectItem.xtype, + text: "一号", + value: 101, + height: 25 + } + ] + } + ] + }, + { text: "2011年", value: 2011 }, + { text: "2012年", value: 2012, iconCls: "close-ha-font" }, + { text: "2013年", value: 2013 }, + { text: "2014年", value: 2014, iconCls: "close-ha-font" }, + { text: "2015年", value: 2015, iconCls: "close-ha-font" } + ]; + + _createBottom() { + const childCombo = createWidget({ + type: Combo.xtype, + el: { + type: TextButton.xtype, + cls: "button-combo", + height: 30 + }, + popup: { + el: { + type: ButtonTree.xtype, + items: createItems(deepClone(this.child), { + type: SingleSelectItem.xtype, + height: 25, + handler(v) {} + }), + layouts: [ + { + type: VerticalLayout.xtype + } + ] + } + }, + width: 200 + }); + childCombo.setValue(deepClone(this.child)[0].items[0].value); + + return createWidget({ + type: FloatLeftLayout.xtype, + items: [childCombo], + hgap: 20, + vgap: 20 + }); + } + + render() { + return { + type: GridLayout.xtype, + columns: 1, + rows: 1, + items: [ + { + column: 0, + row: 0, + el: this._createBottom() + } + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.expander.js b/packages/demo/src/demo/core/abstract/combination/demo.expander.js new file mode 100644 index 000000000..2316adfa5 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.expander.js @@ -0,0 +1,62 @@ +import { + VerticalLayout, + Expander, + IconTextNode, + SingleSelectItem, + Widget, + createItems, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class ExpanderDemo extends Widget { + static xtype = "demo.expander"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: VerticalLayout.xtype, + hgap: 30, + vgap: 20, + items: [ + { + type: Expander.xtype, + el: { + type: IconTextNode.xtype, + cls: "pull-right-ha-font mvc-border", + height: 25, + text: "Expander" + }, + popup: { + cls: "mvc-border", + items: createItems( + [ + { + text: "项目1", + value: 1 + }, + { + text: "项目2", + value: 2 + }, + { + text: "项目3", + value: 3 + }, + { + text: "项目4", + value: 4 + } + ], + { + type: SingleSelectItem.xtype, + height: 25 + } + ) + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.loader.js b/packages/demo/src/demo/core/abstract/combination/demo.loader.js new file mode 100644 index 000000000..53d9044e6 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.loader.js @@ -0,0 +1,34 @@ +import { Loader,Decorators, SingleSelectItem, Widget, deepClone, map, extend } from '@fui/core'; +import { CONSTANTS } from '@/config/constant'; + +@Decorators.shortcut() +export class LoaderDemo extends Widget { + static xtype = 'demo.loader'; + + props = { baseCls: 'demo-func' }; + + render() { + const self = this; + this.all = 0; + const items = deepClone(CONSTANTS.ITEMS); + + return { + type: Loader.xtype, + itemsCreator(options, populate) { + setTimeout(() => { + populate( + map(items.slice((options.times - 1) * 10, options.times * 10), (i, v) => + extend(v, { + type: SingleSelectItem.xtype, + height: 25, + }) + ) + ); + }, 1000); + }, + hasNext(options) { + return options.times * 10 < items.length; + }, + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.navigation.js b/packages/demo/src/demo/core/abstract/combination/demo.navigation.js new file mode 100644 index 000000000..aa0d398c8 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.navigation.js @@ -0,0 +1,49 @@ +import { + Label, + Navigation, + Widget, + createWidget, + random, + bind, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class NagvigationDemo extends Widget { + static xtype = "demo.navigation"; + + props = { baseCls: "demo-func" }; + + _createNav(v) { + return createWidget({ + type: Label.xtype, + cls: `layout-bg${random(1, 8)}`, + text: `第${v}页` + }); + } + + render() { + return { + type: Navigation.xtype, + showIndex: 0, + tab: { + height: 30, + items: [ + { + once: false, + text: "后退", + value: -1, + cls: "mvc-button layout-bg3" + }, + { + once: false, + text: "前进", + value: 1, + cls: "mvc-button layout-bg4" + } + ] + }, + cardCreator: bind(this._createNav, this) + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.sercher.js b/packages/demo/src/demo/core/abstract/combination/demo.sercher.js new file mode 100644 index 000000000..0c1792d6f --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.sercher.js @@ -0,0 +1,135 @@ +import { + MultiSelectItem, + ButtonGroup, + VerticalLayout, + AbsoluteLayout, + Searcher, + Widget, + createItems, + createWidget, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class SearcherDemo extends Widget { + static xtype = "demo.searcher"; + + props = { baseCls: "demo-func" }; + + _createItems(items) { + return createItems(items, { + type: MultiSelectItem.xtype, + height: 25, + handler(v) {} + }); + } + + render() { + const self = this; + const items = [ + { + text: "2010年", + value: 2010, + py: "2010n", + title: "1111111111111111111111111111111111" + }, + { + text: "2011年", + value: 2011, + py: "2011n", + title: "1111111111111111111111111111111111" + }, + { + text: "2012年", + value: 2012, + py: "2012n", + title: "1111111111111111111111111111111111" + }, + { + text: "2013年", + value: 2013, + py: "2013n", + title: "1111111111111111111111111111111111" + }, + { + text: "2014年", + value: 2014, + py: "2014n", + title: "1111111111111111111111111111111111" + }, + { + text: "2015年", + value: 2015, + py: "2015n", + title: "1111111111111111111111111111111111" + }, + { + text: "2016年", + value: 2016, + py: "2016n", + title: "1111111111111111111111111111111111" + }, + { + text: "2017年", + value: 2017, + py: "2017n", + title: "1111111111111111111111111111111111" + } + ]; + + const adapter = createWidget({ + type: ButtonGroup.xtype, + cls: "layout-bg1", + items: this._createItems(items), + chooseType: 1, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype + } + ] + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: adapter, + top: 50, + left: 50, + width: 200, + height: 100 + } + ] + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: AbsoluteLayout.xtype, + width: 200, + height: 30, + items: [ + { + el: { + type: Searcher.xtype, + adapter, + width: 200, + height: 30 + }, + left: 0, + right: 0, + top: 0, + bottom: 0 + } + ] + }, + top: 100, + left: 300 + } + ] + }); + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.switcher.js b/packages/demo/src/demo/core/abstract/combination/demo.switcher.js new file mode 100644 index 000000000..af833c03c --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.switcher.js @@ -0,0 +1,84 @@ +import { + Label, + AbsoluteLayout, + VerticalLayout, + Switcher, + Button, + SingleSelectItem, + Widget, + createWidget, + createItems, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class SwitcherDemo extends Widget { + static xtype = "demo.switcher"; + + props = { baseCls: "demo-func" }; + + render() { + const adapter = createWidget({ + type: Label.xtype, + cls: "layout-bg2", + text: "将在该处弹出switcher" + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: adapter, + top: 50, + left: 20, + width: 200, + height: 300 + } + ] + }); + createWidget({ + type: VerticalLayout.xtype, + element: this, + hgap: 30, + vgap: 20, + items: [ + { + type: Switcher.xtype, + el: { + type: Button.xtype, + height: 25, + text: "Switcher" + }, + popup: { + cls: "mvc-border layout-bg5", + items: createItems( + [ + { + text: "项目1", + value: 1 + }, + { + text: "项目2", + value: 2 + }, + { + text: "项目3", + value: 3 + }, + { + text: "项目4", + value: 4 + } + ], + { + type: SingleSelectItem.xtype, + height: 25 + } + ) + }, + adapter + } + ] + }); + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/demo.tab.js b/packages/demo/src/demo/core/abstract/combination/demo.tab.js new file mode 100644 index 000000000..5867d8a0b --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/demo.tab.js @@ -0,0 +1,91 @@ +import { + Label, + ButtonGroup, + CenterAdaptLayout, + HorizontalLayout, + Tab, + AbsoluteLayout, + Widget, + createWidget, + bind, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class TabDemo extends Widget { + static xtype = "demo.tab"; + + props = { baseCls: "demo-func" }; + + _createTabs(v) { + switch (v) { + case 1: + return createWidget({ + type: Label.xtype, + cls: "layout-bg1", + text: "面板1" + }); + case 2: + return createWidget({ + type: Label.xtype, + cls: "layout-bg2", + text: "面板2" + }); + } + } + + render() { + this.tab = createWidget({ + type: ButtonGroup.xtype, + height: 30, + items: [ + { + text: "Tab1", + value: 1, + width: 50, + cls: "mvc-button layout-bg3" + }, + { + text: "Tab2", + value: 2, + width: 50, + cls: "mvc-button layout-bg4" + } + ], + layouts: [ + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: { + type: HorizontalLayout.xtype, + width: 100 + } + } + ] + } + ] + }); + + const tab = createWidget({ + direction: "custom", + type: Tab.xtype, + element: this, + tab: this.tab, + cardCreator: bind(this._createTabs, this) + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.tab, + left: 200, + top: 200 + } + ] + }); + + tab.setSelect(2); + } +} diff --git a/packages/demo/src/demo/core/abstract/combination/index.js b/packages/demo/src/demo/core/abstract/combination/index.js new file mode 100644 index 000000000..35bc7e148 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/combination/index.js @@ -0,0 +1,10 @@ +export * from "./demo.combo"; +export * from "./demo.combo2"; +export * from "./demo.combo3"; +export * from "./demo.combo_group"; +export * from "./demo.expander"; +export * from "./demo.loader"; +export * from "./demo.navigation"; +export * from "./demo.sercher"; +export * from "./demo.switcher"; +export * from "./demo.tab"; \ No newline at end of file diff --git a/packages/demo/src/demo/core/abstract/demo.button_group.js b/packages/demo/src/demo/core/abstract/demo.button_group.js new file mode 100644 index 000000000..1d679c10c --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.button_group.js @@ -0,0 +1,87 @@ +import { + VerticalLayout, + ButtonGroup, + VTapeLayout, + Label, + Button, + Decorators, + Widget +} from "@fui/core"; + +@Decorators.shortcut() +export class ButtonGroupDemo extends Widget { + static xtype = "demo.button_group"; + + props = { baseCls: "demo-func" }; + + render() { + let ref; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: ButtonGroup.xtype, + ref(_ref) { + ref = _ref; + }, + chooseType: ButtonGroup.CHOOSE_TYPE_NONE, + layouts: [ + { + type: VerticalLayout.xtype, + items: [ + { + type: VTapeLayout.xtype, + height: 200 + } + ] + } + ], + items: [ + { + el: { + type: Label.xtype, + text: "button_group是一类具有相同属性或相似属性的抽象, 本案例实现的是布局的嵌套(vertical布局下内嵌center_adapt布局)" + }, + height: 150 + }, + { + el: { + type: Button.xtype, + text: "1" + } + } + ] + }, + { + type: Button.xtype, + text: "populate", + handler() { + ref.populate([ + { + el: { + type: Label.xtype, + text: "1" + }, + height: 50 + }, + { + el: { + type: Button.xtype, + text: "2" + }, + height: 50 + }, + { + el: { + type: Label.xtype, + text: "3" + } + } + ]); + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.button_tree.js b/packages/demo/src/demo/core/abstract/demo.button_tree.js new file mode 100644 index 000000000..1da884922 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.button_tree.js @@ -0,0 +1,44 @@ +import { + ButtonTree, + VerticalLayout, + CenterAdaptLayout, + Label, + Button, + Decorators, + Widget, + ButtonGroup +} from "@fui/core"; + +@Decorators.shortcut() +export class ButtonTreeDemo extends Widget { + static xtype = "demo.button_tree"; + + props = { baseCls: "demo-func" }; + + render() { + return { + type: ButtonTree.xtype, + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + layouts: [ + { + type: VerticalLayout.xtype + }, + { + type: CenterAdaptLayout.xtype + } + ], + items: [ + { + type: Label.xtype, + text: "0", + value: 0 + }, + { + type: Button.xtype, + text: "1", + value: 1 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.collection_view.js b/packages/demo/src/demo/core/abstract/demo.collection_view.js new file mode 100644 index 000000000..eef001c9a --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.collection_view.js @@ -0,0 +1,53 @@ +import { + Label, + CollectionView, + AbsoluteLayout, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class CollectionViewDemo extends Widget { + static xtype = "demo.collection_view"; + + props = { baseCls: "demo-func" }; + + render() { + const items = []; + const cellCount = 100; + for (let i = 0; i < cellCount; i++) { + items[i] = { + type: Label.xtype, + text: i + }; + } + const grid = createWidget({ + type: CollectionView.xtype, + width: 400, + height: 300, + items, + cellSizeAndPositionGetter(index) { + return { + x: (index % 10) * 50, + y: Math.floor(index / 10) * 50, + width: 50, + height: 50 + }; + } + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: grid, + left: 10, + right: 10, + top: 10, + bottom: 10 + } + ] + }); + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.custom_tree.js b/packages/demo/src/demo/core/abstract/demo.custom_tree.js new file mode 100644 index 000000000..9e130db06 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.custom_tree.js @@ -0,0 +1,408 @@ +import { + PlusGroupNode, + SingleSelectItem, + CustomTree, + ButtonTree, + VerticalLayout, + Loader, + GridLayout, + VTapeLayout, + CenterLayout, + TextButton, + Label, + Decorators, + Widget, + createWidget, + deepClone, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class CustomTreeDemo extends Widget { + static xtype = "demo.custom_tree"; + + props = { baseCls: "demo-func" }; + + _createDefaultTree() { + const TREEITEMS = [ + { + id: -1, + pId: -2, + value: "根目录", + open: true, + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 1, + pId: -1, + value: "第一级目录1", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 11, + pId: 1, + value: "第二级文件1", + type: SingleSelectItem.xtype, + height: 25 + }, + { + id: 12, + pId: 1, + value: "第二级目录2", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 121, + pId: 12, + value: "第三级目录1", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 122, + pId: 12, + value: "第三级文件1", + type: SingleSelectItem.xtype, + height: 25 + }, + { + id: 1211, + pId: 121, + value: "第四级目录1", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 12111, + pId: 1211, + value: "第五级文件1", + type: SingleSelectItem.xtype, + height: 25 + }, + { + id: 2, + pId: -1, + value: "第一级目录2", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 21, + pId: 2, + value: "第二级目录3", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 22, + pId: 2, + value: "第二级文件2", + type: SingleSelectItem.xtype, + height: 25 + }, + { + id: 211, + pId: 21, + value: "第三级目录2", + type: PlusGroupNode.xtype, + height: 25 + }, + { + id: 212, + pId: 21, + value: "第三级文件2", + type: SingleSelectItem.xtype, + height: 25 + }, + { + id: 2111, + pId: 211, + value: "第四级文件1", + type: SingleSelectItem.xtype, + height: 25 + } + ]; + this.tree = createWidget({ + type: CustomTree.xtype, + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + hgap: 30 + } + ] + }, + items: deepClone(TREEITEMS) + }); + + return this.tree; + } + + _createAsyncTree() { + this.asyncTree = createWidget({ + type: CustomTree.xtype, + itemsCreator(op, callback) { + if (!op.node) { + // 根节点 + callback([ + { + id: 1, + pId: 0, + type: PlusGroupNode.xtype, + text: "test1", + value: 1, + height: 25, + isParent: true + }, + { + id: 2, + pId: 0, + type: PlusGroupNode.xtype, + text: "test2", + value: 1, + isParent: true, + open: true, + height: 25 + } + ]); + } else { + if (op.node.id == 1) { + callback([ + { + id: 11, + pId: 1, + type: PlusGroupNode.xtype, + text: "test11", + value: 11, + height: 25, + isParent: true + }, + { + id: 12, + pId: 1, + type: SingleSelectItem.xtype, + text: "test12", + value: 12, + height: 35 + }, + { + id: 13, + pId: 1, + type: SingleSelectItem.xtype, + text: "test13", + value: 13, + height: 35 + }, + { + id: 14, + pId: 1, + type: SingleSelectItem.xtype, + text: "test14", + value: 14, + height: 35 + }, + { + id: 15, + pId: 1, + type: SingleSelectItem.xtype, + text: "test15", + value: 15, + height: 35 + }, + { + id: 16, + pId: 1, + type: SingleSelectItem.xtype, + text: "test16", + value: 16, + height: 35 + }, + { + id: 17, + pId: 1, + type: SingleSelectItem.xtype, + text: "test17", + value: 17, + height: 35 + } + ]); + } else if (op.node.id == 2) { + callback([ + { + id: 21, + pId: 2, + type: SingleSelectItem.xtype, + text: "test21", + value: 21, + height: 35 + }, + { + id: 22, + pId: 2, + type: SingleSelectItem.xtype, + text: "test22", + value: 22, + height: 35 + } + ]); + } else if (op.node.id == 11) { + callback([ + { + id: 111, + pId: 11, + type: SingleSelectItem.xtype, + text: "test111", + value: 111, + height: 35 + } + ]); + } + } + }, + el: { + type: Loader.xtype, + next: false, + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + hgap: 30, + vgap: 0 + } + ] + } + } + }); + + return this.asyncTree; + } + + render() { + const self = this; + createWidget({ + type: GridLayout.xtype, + columns: 2, + rows: 1, + element: this, + items: [ + { + column: 0, + row: 0, + el: { + type: VTapeLayout.xtype, + items: [ + { + el: this._createDefaultTree() + }, + { + el: { + type: CenterLayout.xtype, + hgap: 10, + items: [ + { + type: TextButton.xtype, + cls: "mvc-button layout-bg2", + text: "getValue", + height: 30, + handler() { + Msg.alert( + "", + JSON.stringify( + self.tree.getValue() + ) + ); + } + }, + { + type: TextButton.xtype, + cls: "mvc-button layout-bg2", + text: "getNodeByValue(第一级目录1)", + height: 30, + handler() { + Msg.alert( + "", + `节点名称为: ${self.tree + .getNodeByValue( + "第一级目录1" + ) + .getValue()}` + ); + } + } + ] + }, + height: 30 + } + ] + } + }, + { + column: 1, + row: 0, + el: { + type: VTapeLayout.xtype, + items: [ + { + type: Label.xtype, + text: "异步加载数据", + height: 30 + }, + { + el: this._createAsyncTree() + }, + { + el: { + type: CenterLayout.xtype, + hgap: 10, + items: [ + { + type: TextButton.xtype, + cls: "mvc-button layout-bg2", + text: "getValue", + height: 30, + handler() { + Msg.alert( + "", + JSON.stringify( + self.asyncTree.getValue() + ) + ); + } + }, + { + type: TextButton.xtype, + cls: "mvc-button layout-bg2", + text: "getNodeById(11)", + height: 30, + handler() { + Msg.alert( + "", + `节点名称为: ${ + self.asyncTree.getNodeById( + 11 + ) && + self.asyncTree + .getNodeById(11) + .getText() + }` + ); + } + } + ] + }, + height: 30 + } + ] + } + } + ] + }); + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.grid_view.js b/packages/demo/src/demo/core/abstract/demo.grid_view.js new file mode 100644 index 000000000..53b28cf80 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.grid_view.js @@ -0,0 +1,70 @@ +import { + Label, + GridView, + AbsoluteLayout, + GridLayout, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class GridViewDemo extends Widget { + static xtype = "demo.grid_view"; + + props = { baseCls: "demo-func" }; + + render() { + const items = []; + const rowCount = 10000, + columnCount = 100; + for (let i = 0; i < rowCount; i++) { + items[i] = []; + for (let j = 0; j < columnCount; j++) { + items[i][j] = { + type: Label.xtype, + text: `${i}-${j}` + }; + } + } + const grid = createWidget({ + type: GridView.xtype, + width: 400, + height: 300, + estimatedRowSize: 30, + estimatedColumnSize: 100, + items, + scrollTop: 100, + rowHeightGetter() { + return 30; + }, + columnWidthGetter() { + return 100; + } + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: GridLayout.xtype, + columns: 1, + rows: 1, + items: [ + { + column: 0, + row: 0, + el: grid + } + ] + }, + left: 10, + right: 10, + top: 10, + bottom: 10 + } + ] + }); + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.list_view.js b/packages/demo/src/demo/core/abstract/demo.list_view.js new file mode 100644 index 000000000..4b37a32ff --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.list_view.js @@ -0,0 +1,26 @@ +import { ListView, FloatLeftLayout, Label, Decorators, Widget, map, extend } from '@fui/core'; +import { CONSTANTS } from '@/config/constant'; + +@Decorators.shortcut() +export class ListViewDemo extends Widget { + static xtype = 'demo.list_view'; + + props = { baseCls: 'demo-func' }; + + render() { + return { + type: ListView.xtype, + el: { + type: FloatLeftLayout.xtype, + }, + items: map(CONSTANTS.ITEMS, (i, item) => + extend({}, item, { + type: Label.xtype, + width: 200, + height: 200, + text: `${i + 1}.${item.text}`, + }) + ), + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.virtual_group.js b/packages/demo/src/demo/core/abstract/demo.virtual_group.js new file mode 100644 index 000000000..07467ead0 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.virtual_group.js @@ -0,0 +1,98 @@ +import { + VerticalLayout, + Label, + ButtonGroup, + Button, + VirtualGroup, + Decorators, + Widget, + map, + range, + deepClone +} from "@fui/core"; + +@Decorators.shortcut() +export class VirtualGroupDemo extends Widget { + static xtype = "demo.virtual_group"; + + props = { baseCls: "demo-func" }; + + _createItems() { + const items = map(range(1000), (i) => { + return { + type: "demo.virtual_group_item", + value: i, + key: i + 1 + }; + }); + + return items; + } + + render() { + const self = this; + const buttonGroupItems = self._createItems(); + const virtualGroupItems = self._createItems(); + + return { + type: VerticalLayout.xtype, + vgap: 20, + items: [ + { + type: Label.xtype, + cls: "layout-bg5", + height: 50, + text: "共1000个元素,演示button_group和virtual_group每次删除第一个元素,打开控制台看输出" + }, + { + type: ButtonGroup.xtype, + width: 500, + height: 300, + ref() { + self.buttonGroup = this; + }, + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + layouts: [ + { + type: VerticalLayout.xtype + } + ], + items: this._createItems() + }, + { + type: Button.xtype, + text: "演示button_group的刷新", + handler() { + buttonGroupItems.shift(); + self.buttonGroup.populate(deepClone(buttonGroupItems)); + } + }, + { + type: VirtualGroup.xtype, + width: 500, + height: 300, + ref() { + self.virtualGroup = this; + }, + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + layouts: [ + { + type: VerticalLayout.xtype + } + ], + items: this._createItems() + }, + { + type: Button.xtype, + text: "演示virtual_group的刷新", + handler() { + virtualGroupItems.shift(); + self.virtualGroup.populate( + deepClone(virtualGroupItems) + ); + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.virtual_group_item.js b/packages/demo/src/demo/core/abstract/demo.virtual_group_item.js new file mode 100644 index 000000000..35a8ef699 --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.virtual_group_item.js @@ -0,0 +1,47 @@ +import { Label, Decorators, Widget, UUID } from "@fui/core"; + +@Decorators.shortcut() +export class VirtualGroupItemDemo extends Widget { + static xtype = "demo.virtual_group_item"; + + props = { baseCls: "demo-item", height: 30 }; + + render() { + const self = this, + o = this.options; + + return { + type: Label.xtype, + ref() { + self.label = this; + }, + height: this.options.height, + text: `key:${o.key},随机数${UUID()}` + }; + } + + shouldUpdate(nextProps) { + const o = this.options; + + return ( + o.type !== nextProps.type || + o.key !== nextProps.key || + o.value !== nextProps.value + ); + } + + update(item) { + this.label.setText(item.value); + console.log("更新了一项"); + + return true; // 返回是不是更新成功 + } + + created() { + console.log("创建了一项"); + } + + destroyed() { + console.log("删除了一项"); + } +} diff --git a/packages/demo/src/demo/core/abstract/demo.virtual_list.js b/packages/demo/src/demo/core/abstract/demo.virtual_list.js new file mode 100644 index 000000000..0545d449d --- /dev/null +++ b/packages/demo/src/demo/core/abstract/demo.virtual_list.js @@ -0,0 +1,22 @@ +import { VirtualList, Label, Decorators, Widget, map, extend } from '@fui/core'; +import { CONSTANTS } from '@/config/constant'; + +@Decorators.shortcut() +export class VirtualListDemo extends Widget { + static xtype = 'demo.virtual_list'; + + props = { baseCls: 'demo-func' }; + + render() { + return { + type: VirtualList.xtype, + items: map(CONSTANTS.ITEMS, (i, item) => + extend({}, item, { + type: Label.xtype, + height: 30, + text: `${i + 1}.${item.text}`, + }) + ), + }; + } +} diff --git a/packages/demo/src/demo/core/abstract/index.js b/packages/demo/src/demo/core/abstract/index.js new file mode 100644 index 000000000..8d976634f --- /dev/null +++ b/packages/demo/src/demo/core/abstract/index.js @@ -0,0 +1,16 @@ +export const meta = { + title: "抽象控件 core", + rank: 9999 +}; + +export * as combination from "./combination"; + +export * from "./demo.button_group"; +export * from "./demo.button_tree"; +export * from "./demo.collection_view"; +export * from "./demo.custom_tree"; +export * from "./demo.grid_view"; +export * from "./demo.list_view"; +export * from "./demo.virtual_group"; +export * from "./demo.virtual_group_item"; +export * from "./demo.virtual_list"; diff --git a/packages/demo/src/demo/core/index.js b/packages/demo/src/demo/core/index.js new file mode 100644 index 000000000..0136c7f8e --- /dev/null +++ b/packages/demo/src/demo/core/index.js @@ -0,0 +1,8 @@ +export const meta = { + title: "核心控件 core", + rank: 9999 +}; + +export * as layout from "./layout"; +export * as abstract from "./abstract"; +export * as popup from "./popup"; diff --git a/packages/demo/src/demo/core/layout/demo.absolute.js b/packages/demo/src/demo/core/layout/demo.absolute.js new file mode 100644 index 000000000..65d4a4ea6 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.absolute.js @@ -0,0 +1,30 @@ + +import { AbsoluteLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class AbsoluteLayoutDemo extends Widget { + static xtype = "demo.absolute"; + + props = { baseCls: "demo-absolute" }; + + render() { + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Label.xtype, + text: "绝对布局", + cls: "layout-bg1", + width: 300, + height: 200, + }, + left: 100, + top: 100, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.border.js b/packages/demo/src/demo/core/layout/demo.border.js new file mode 100644 index 000000000..f5c58c715 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.border.js @@ -0,0 +1,105 @@ + +import { Label, CenterLayout, BorderLayout, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class BorderLayoutDemo extends Widget { + static xtype = "demo.border"; + + props = { baseCls: "demo-border" }; + + _createNorth() { + return createWidget({ + type: Label.xtype, + text: "North", + cls: "layout-bg1", + height: 30, + }); + } + + _createWest() { + return createWidget({ + type: CenterLayout.xtype, + cls: "layout-bg2", + items: [ + { + type: Label.xtype, + text: "West", + whiteSpace: "normal", + } + ], + }); + } + + _createCenter() { + return createWidget({ + type: CenterLayout.xtype, + cls: "layout-bg3", + items: [ + { + type: Label.xtype, + text: "Center", + whiteSpace: "normal", + } + ], + }); + } + + _createEast() { + return createWidget({ + type: CenterLayout.xtype, + cls: "layout-bg5", + items: [ + { + type: Label.xtype, + text: "East", + whiteSpace: "normal", + } + ], + }); + } + + _createSouth() { + return createWidget({ + type: Label.xtype, + text: "South", + cls: "layout-bg6", + height: 50, + }); + } + + render() { + return { + type: BorderLayout.xtype, + cls: "", + items: { + north: { + el: this._createNorth(), + height: 30, + top: 20, + left: 20, + right: 20, + }, + south: { + el: this._createSouth(), + height: 50, + bottom: 20, + left: 20, + right: 20, + }, + west: { + el: this._createWest(), + width: 200, + left: 20, + }, + east: { + el: this._createEast(), + width: 300, + right: 20, + }, + center: this._createCenter(), + }, + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.center_adapt.js b/packages/demo/src/demo/core/layout/demo.center_adapt.js new file mode 100644 index 000000000..52ae2d035 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.center_adapt.js @@ -0,0 +1,26 @@ + +import { CenterAdaptLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class CenterAdaptDemo extends Widget { + static xtype = "demo.center_adapt"; + + props = { baseCls: "demo-absolute" }; + + render() { + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: Label.xtype, + text: "水平垂直居中", + width: 300, + height: 200, + cls: "layout-bg1", + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.float_center.js b/packages/demo/src/demo/core/layout/demo.float_center.js new file mode 100644 index 000000000..a4ea3684a --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.float_center.js @@ -0,0 +1,33 @@ + +import { FloatCenterLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class FloatCenterLayoutDemo extends Widget { + static xtype = "demo.float_center"; + + props = { baseCls: "demo-float-center" }; + + render() { + return { + type: FloatCenterLayout.xtype, + items: [ + { + type: Label.xtype, + text: "floatCenter与center的不同在于,它可以控制最小宽度和最大宽度", + cls: "layout-bg1", + whiteSpace: "normal", + }, + { + type: Label.xtype, + text: "浮动式的中间布局", + cls: "layout-bg2", + whiteSpace: "normal", + } + ], + hgap: 20, + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.flow.js b/packages/demo/src/demo/core/layout/demo.flow.js new file mode 100644 index 000000000..3f95628c1 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.flow.js @@ -0,0 +1,92 @@ + +import { CenterAdaptLayout, FloatLeftLayout, Label, FloatRightLayout, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class FlowLayoutDemo extends Widget { + static xtype = "demo.flow"; + + props = { baseCls: "demo-flow" }; + + render() { + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: FloatLeftLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "Left-1", + cls: "layout-bg1", + }, + { + type: Label.xtype, + height: 30, + text: "Left-2", + cls: "layout-bg2", + }, + { + type: Label.xtype, + height: 30, + text: "Left-3", + cls: "layout-bg3", + }, + { + type: Label.xtype, + height: 30, + text: "Left-4", + cls: "layout-bg4", + }, + { + type: Label.xtype, + height: 30, + text: "Left-5", + cls: "layout-bg5", + } + ], + hgap: 20, + }, + { + type: FloatRightLayout.xtype, + hgap: 20, + items: [ + { + type: Label.xtype, + height: 30, + text: "Right-1", + cls: "layout-bg1", + }, + { + type: Label.xtype, + height: 30, + text: "Right-2", + cls: "layout-bg2", + }, + { + type: Label.xtype, + height: 30, + text: "Right-3", + cls: "layout-bg3", + }, + { + type: Label.xtype, + height: 30, + text: "Right-4", + cls: "layout-bg4", + }, + { + type: Label.xtype, + height: 30, + text: "Right-5", + cls: "layout-bg5", + } + ], + vgap: 20, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.grid.js b/packages/demo/src/demo/core/layout/demo.grid.js new file mode 100644 index 000000000..e22805f04 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.grid.js @@ -0,0 +1,156 @@ + +import { GridLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class GridLayoutDemo extends Widget { + static xtype = "demo.grid"; + + props = { baseCls: "demo-grid" }; + + render() { + return { + type: GridLayout.xtype, + columns: 5, + rows: 3, + items: [ + { + column: 0, + row: 0, + el: { + type: Label.xtype, + text: "column-0, row-0", + cls: "layout-bg1", + }, + }, + { + column: 1, + row: 0, + el: { + type: Label.xtype, + text: "column-1, row-0", + cls: "layout-bg2", + }, + }, + { + column: 2, + row: 0, + el: { + type: Label.xtype, + text: "column-2, row-0", + cls: "layout-bg6", + }, + }, + { + column: 3, + row: 0, + el: { + type: Label.xtype, + text: "column-3, row-0", + cls: "layout-bg3", + }, + }, + { + column: 4, + row: 0, + el: { + type: Label.xtype, + text: "column-4, row-0", + cls: "layout-bg4", + }, + }, + { + column: 0, + row: 1, + el: { + type: Label.xtype, + text: "column-0, row-1", + cls: "layout-bg5", + }, + }, + { + column: 1, + row: 1, + el: { + type: Label.xtype, + text: "column-1, row-1", + cls: "layout-bg6", + }, + }, + { + column: 2, + row: 1, + el: { + type: Label.xtype, + text: "column-2, row-1", + cls: "layout-bg7", + }, + }, + { + column: 3, + row: 1, + el: { + type: Label.xtype, + text: "column-3, row-1", + cls: "layout-bg1", + }, + }, + { + column: 4, + row: 1, + el: { + type: Label.xtype, + text: "column-4, row-1", + cls: "layout-bg3", + }, + }, + { + column: 0, + row: 2, + el: { + type: Label.xtype, + text: "column-0, row-2", + cls: "layout-bg2", + }, + }, + { + column: 1, + row: 2, + el: { + type: Label.xtype, + text: "column-1, row-2", + cls: "layout-bg3", + }, + }, + { + column: 2, + row: 2, + el: { + type: Label.xtype, + text: "column-2, row-2", + cls: "layout-bg4", + }, + }, + { + column: 3, + row: 2, + el: { + type: Label.xtype, + text: "column-3, row-2", + cls: "layout-bg5", + }, + }, + { + column: 4, + row: 2, + el: { + type: Label.xtype, + text: "column-4, row-2", + cls: "layout-bg6", + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.horizontal.js b/packages/demo/src/demo/core/layout/demo.horizontal.js new file mode 100644 index 000000000..de2205257 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.horizontal.js @@ -0,0 +1,156 @@ + +import { VerticalLayout, HorizontalLayout, Label, Layout, CenterAdaptLayout, Decorators, Widget, VerticalAlign, HorizontalAlign } from "@fui/core" + + + +@Decorators.shortcut() +export class HorizontalDemo extends Widget { + static xtype = "demo.horizontal"; + + props = { baseCls: "demo-horizontal" }; + + render() { + return { + type: VerticalLayout.xtype, + vgap: 10, + items: [ + { + type: HorizontalLayout.xtype, + height: 150, + hgap: 10, + items: [ + { + type: Label.xtype, + whiteSpace: "normal", + text: "因为大多数场景下都需要垂直居中,所以这个布局一般会被vertical_adapt布局设置scrollx=true取代", + cls: "layout-bg3", + width: 500, + height: 50, + }, + { + type: Label.xtype, + text: "水平布局", + cls: "layout-bg4", + width: 300, + height: 30, + }, + { + type: Label.xtype, + text: "水平布局", + cls: "layout-bg5", + width: 300, + height: 30, + }, + { + type: Label.xtype, + text: "水平布局", + cls: "layout-bg6", + width: 300, + height: 30, + } + ], + }, + { + type: Layout.xtype, + height: 1, + cls: "bi-border-bottom bi-high-light-border", + }, + { + type: HorizontalLayout.xtype, + height: 150, + verticalAlign: VerticalAlign.Middle, + horizontalAlign: HorizontalAlign.Left, + vgap: 10, + items: [ + { + type: Label.xtype, + text: "以horizontal实现的vertical_adapt垂直居中", + cls: "layout-bg1", + width: 300, + height: 30, + }, + { + type: Label.xtype, + text: "以horizontal实现的vertical_adapt垂直居中", + cls: "layout-bg2", + width: 300, + height: 30, + } + ], + }, + { + type: Layout.xtype, + height: 1, + cls: "bi-border-bottom bi-high-light-border", + }, + { + type: HorizontalLayout.xtype, + height: 150, + verticalAlign: VerticalAlign.Top, + horizontalAlign: HorizontalAlign.Center, + items: [ + { + type: Label.xtype, + text: "以horizontal代替horizontal_adapt实现的水平居中(单元素)", + cls: "layout-bg1", + width: 300, + height: 30, + } + ], + }, + { + type: Layout.xtype, + height: 1, + cls: "bi-border-bottom bi-high-light-border", + }, + { + type: HorizontalLayout.xtype, + height: 150, + verticalAlign: VerticalAlign.Top, + horizontalAlign: HorizontalAlign.Center, + columnSize: [300, "fill"], + items: [ + { + type: Label.xtype, + text: "以horizontal代替horizontal_adapt实现的用于水平适应布局", + cls: "layout-bg1", + height: 30, + }, + { + type: Label.xtype, + text: "以horizontal代替horizontal_adapt实现的水平自适应列", + cls: "layout-bg2", + height: 30, + } + ], + }, + { + type: Layout.xtype, + height: 1, + cls: "bi-border-bottom bi-high-light-border", + }, + { + type: CenterAdaptLayout.xtype, + height: 150, + verticalAlign: VerticalAlign.Middle, + horizontalAlign: HorizontalAlign.Center, + items: [ + { + type: Label.xtype, + text: "以horizontal代替center_adapt实现的水平垂直居中", + width: 300, + height: 100, + cls: "layout-bg1", + } + ], + }, + { + type: Layout.xtype, + height: 1, + cls: "bi-border-bottom bi-high-light-border", + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.horizontal_adapt.js b/packages/demo/src/demo/core/layout/demo.horizontal_adapt.js new file mode 100644 index 000000000..ed122355e --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.horizontal_adapt.js @@ -0,0 +1,67 @@ + +import { HorizontalAdaptLayout, Label, GridLayout, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class HorizontalAdaptDemo extends Widget { + static xtype = "demo.horizontal_adapt"; + + props = { baseCls: "demo-horizontal-adapt" }; + + _createLayout() { + return createWidget({ + type: HorizontalAdaptLayout.xtype, + items: [ + { + type: Label.xtype, + text: "例子1:可用做水平居中", + cls: "layout-bg1", + width: 300, + height: 30, + } + ], + }); + } + + _createAdaptLayout() { + return createWidget({ + type: HorizontalAdaptLayout.xtype, + columnSize: [300, "fill"], + items: [ + { + type: Label.xtype, + text: "例子2:用于水平适应布局", + cls: "layout-bg1", + height: 30, + }, + { + type: Label.xtype, + text: "水平自适应列", + cls: "layout-bg2", + height: 30, + } + ], + }); + } + + render() { + return { + type: GridLayout.xtype, + columns: 1, + rows: 2, + items: [ + { + column: 0, + row: 0, + el: this._createLayout(), + }, + { + column: 0, + row: 1, + el: this._createAdaptLayout(), + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.horizontal_auto.js b/packages/demo/src/demo/core/layout/demo.horizontal_auto.js new file mode 100644 index 000000000..7981937b8 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.horizontal_auto.js @@ -0,0 +1,48 @@ + +import { HorizontalAutoLayout, Label, GridLayout, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class HorizontalAutoDemo extends Widget { + static xtype = "demo.horizontal_auto"; + + props = { baseCls: "demo-horizontal-auto" }; + + _createLayout() { + return createWidget({ + type: HorizontalAutoLayout.xtype, + items: [ + { + type: Label.xtype, + text: "水平居中", + cls: "layout-bg1", + width: 300, + height: 30, + }, + { + type: Label.xtype, + text: "水平居中优先使用该布局", + cls: "layout-bg2", + width: 300, + height: 30, + } + ], + }); + } + + render() { + return { + type: GridLayout.xtype, + columns: 1, + rows: 2, + items: [ + { + column: 0, + row: 0, + el: this._createLayout(), + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.horizontal_float.js b/packages/demo/src/demo/core/layout/demo.horizontal_float.js new file mode 100644 index 000000000..135137825 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.horizontal_float.js @@ -0,0 +1,25 @@ + +import { FloatHorizontalLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class HorizontalFloatDemo extends Widget { + static xtype = "demo.horizontal_float"; + + props = { baseCls: "demo-horizontal-float" }; + + render() { + return { + type: FloatHorizontalLayout.xtype, + items: [ + { + type: Label.xtype, + text: "浮动式水平居中布局方案,用于宽度未知的情况", + cls: "layout-bg1", + height: 30, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.htape.js b/packages/demo/src/demo/core/layout/demo.htape.js new file mode 100644 index 000000000..7ea214d7a --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.htape.js @@ -0,0 +1,43 @@ + +import { HTapeLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class HtapeLayoutDemo extends Widget { + static xtype = "demo.htape"; + + props = { baseCls: "demo-htape" }; + + render() { + return { + type: HTapeLayout.xtype, + items: [ + { + width: 100, + el: { + type: Label.xtype, + text: "1", + cls: "bi-background", + }, + }, + { + width: 200, + el: { + type: Label.xtype, + text: "2", + cls: "layout-bg2", + }, + }, + { + width: "fill", + el: { + type: Label.xtype, + text: "3", + cls: "layout-bg3", + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.left_right_vertical_adapt.js b/packages/demo/src/demo/core/layout/demo.left_right_vertical_adapt.js new file mode 100644 index 000000000..522c76757 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.left_right_vertical_adapt.js @@ -0,0 +1,53 @@ + +import { LeftRightVerticalAdaptLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class LeftRightVerticalAdaptLayoutDemo extends Widget { + static xtype = "demo.left_right_vertical_adapt"; + + props = { baseCls: "demo-left-right-vertical-adapt" }; + + render() { + return { + type: LeftRightVerticalAdaptLayout.xtype, + lhgap: 10, + rhgap: 30, + items: { + left: [ + { + type: Label.xtype, + text: "左边的垂直居中", + cls: "layout-bg1", + width: 100, + height: 30, + }, + { + type: Label.xtype, + text: "左边的垂直居中", + cls: "layout-bg2", + width: 100, + height: 30, + } + ], + right: [ + { + type: Label.xtype, + text: "右边的垂直居中", + cls: "layout-bg1", + width: 100, + height: 30, + }, + { + type: Label.xtype, + text: "右边的垂直居中", + cls: "layout-bg2", + width: 100, + height: 30, + } + ], + }, + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.table.js b/packages/demo/src/demo/core/layout/demo.table.js new file mode 100644 index 000000000..cdb546894 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.table.js @@ -0,0 +1,167 @@ + +import { TableLayout, Layout, GridLayout, Decorators, Widget, createItems } from "@fui/core" + + +@Decorators.shortcut() +export class TableLayoutDemo extends Widget { + static xtype = "demo.table_layout"; + + props = { baseCls: "demo-table-layout" }; + + _createTable1() { + return { + type: TableLayout.xtype, + items: createItems( + [ + [ + { + el: { + cls: "layout-bg1", + }, + }, + { + el: { + cls: "layout-bg2", + }, + }, + { + el: { + cls: "layout-bg3", + }, + } + ], + [ + { + el: { + cls: "layout-bg4", + }, + }, + { + el: { + cls: "layout-bg5", + }, + }, + { + el: { + cls: "layout-bg6", + }, + } + ], + [ + { + el: { + cls: "layout-bg7", + }, + }, + { + el: { + cls: "layout-bg8", + }, + }, + { + el: { + cls: "layout-bg1", + }, + } + ], + [ + { + el: { + cls: "layout-bg2", + }, + }, + { + el: { + cls: "layout-bg3", + }, + }, + { + el: { + cls: "layout-bg4", + }, + } + ], + [ + { + el: { + cls: "layout-bg5", + }, + }, + { + el: { + cls: "layout-bg6", + }, + }, + { + el: { + cls: "layout-bg7", + }, + } + ], + [ + { + el: { + cls: "layout-bg8", + }, + }, + { + el: { + cls: "layout-bg1", + }, + }, + { + el: { + cls: "layout-bg2", + }, + } + ], + [ + { + el: { + cls: "layout-bg6", + }, + }, + { + el: { + cls: "layout-bg7", + }, + }, + { + el: { + cls: "layout-bg8", + }, + } + ] + ], + { + type: Layout.xtype, + } + ), + columnSize: [100, "fill", 200], + rowSize: [10, 30, 50, 70, 90, 110, 130], + hgap: 20, + vgap: 10, + }; + } + + render() { + return { + type: GridLayout.xtype, + columns: 1, + rows: 1, + items: [ + { + column: 0, + row: 0, + el: this._createTable1(), + } + // , { + // column: 0, + // row: 1, + // el: this._createTable2() + // } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.td.js b/packages/demo/src/demo/core/layout/demo.td.js new file mode 100644 index 000000000..e36d535c4 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.td.js @@ -0,0 +1,76 @@ + +import { VerticalLayout, TdLayout, Label, Decorators, Widget, createItems } from "@fui/core" + + +@Decorators.shortcut() +export class TdLayoutDemo extends Widget { + static xtype = "demo.td"; + + props = { baseCls: "demo-td" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: TdLayout.xtype, + columnSize: [100, 100, ""], + items: createItems( + [ + [ + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg1", + }, + }, + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg2", + }, + }, + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg3", + }, + } + ], + [ + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg5", + }, + }, + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg6", + }, + }, + { + el: { + type: Label.xtype, + text: "这是一段可以换行的文字,为了使它换行我要多写几个字,但是我又凑不够这么多的字,万般焦急下,只能随便写写", + cls: "layout-bg7", + }, + } + ] + ], + { + whiteSpace: "normal", + } + ), + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.vertical.js b/packages/demo/src/demo/core/layout/demo.vertical.js new file mode 100644 index 000000000..7ff15d4a0 --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.vertical.js @@ -0,0 +1,32 @@ + +import { VerticalLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class VerticalLayoutDemo extends Widget { + static xtype = "demo.vertical"; + + props = { baseCls: "demo-vertical" }; + + render() { + return { + type: VerticalLayout.xtype, + vgap: 10, + items: [ + { + type: Label.xtype, + cls: "layout-bg3", + text: "垂直布局", + height: 30, + }, + { + type: Label.xtype, + cls: "layout-bg4", + text: "垂直布局", + height: 30, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.vertical_adapt.js b/packages/demo/src/demo/core/layout/demo.vertical_adapt.js new file mode 100644 index 000000000..061624a0b --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.vertical_adapt.js @@ -0,0 +1,49 @@ + +import { VerticalAdaptLayout, Label, GridLayout, Decorators, Widget, createWidget } from "@fui/core" + + +@Decorators.shortcut() +export class VerticalAdaptLayoutDemo extends Widget { + static xtype = "demo.vertical_adapt"; + + props = { baseCls: "demo-vertical-adapt" }; + + _createLayout() { + return createWidget({ + type: VerticalAdaptLayout.xtype, + vgap: 10, + items: [ + { + type: Label.xtype, + text: "垂直居中", + cls: "layout-bg1", + width: 300, + height: 30, + }, + { + type: Label.xtype, + text: "垂直居中", + cls: "layout-bg2", + width: 300, + height: 30, + } + ], + }); + } + + render() { + return { + type: GridLayout.xtype, + columns: 2, + rows: 1, + items: [ + { + column: 0, + row: 0, + el: this._createLayout(), + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/demo.vtape.js b/packages/demo/src/demo/core/layout/demo.vtape.js new file mode 100644 index 000000000..8023e193b --- /dev/null +++ b/packages/demo/src/demo/core/layout/demo.vtape.js @@ -0,0 +1,46 @@ + +import { VTapeLayout, Label, Decorators, Widget } from "@fui/core" + + +@Decorators.shortcut() +export class VtapeLayoutDemo extends Widget { + static xtype = "demo.vtape"; + + props = { baseCls: "demo-vtape" }; + + render() { + return { + type: VTapeLayout.xtype, + vgap: 10, + items: [ + { + height: 100, + el: { + type: Label.xtype, + text: "1", + cls: "layout-bg1", + }, + tgap: 10, + vgap: 10, + }, + { + height: 200, + el: { + type: Label.xtype, + text: "2", + cls: "layout-bg2", + }, + }, + { + height: "fill", + el: { + type: Label.xtype, + text: "3", + cls: "layout-bg3", + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/layout/index.js b/packages/demo/src/demo/core/layout/index.js new file mode 100644 index 000000000..151ed390b --- /dev/null +++ b/packages/demo/src/demo/core/layout/index.js @@ -0,0 +1,22 @@ +export const meta = { + title: "布局组件", + rank: 9999 +}; + +export * from "./demo.absolute"; +export * from "./demo.border"; +export * from "./demo.center_adapt"; +export * from "./demo.float_center"; +export * from "./demo.flow"; +export * from "./demo.grid"; +export * from "./demo.horizontal"; +export * from "./demo.horizontal_adapt"; +export * from "./demo.horizontal_auto"; +export * from "./demo.horizontal_float"; +export * from "./demo.htape"; +export * from "./demo.left_right_vertical_adapt"; +export * from "./demo.table"; +export * from "./demo.td"; +export * from "./demo.vertical"; +export * from "./demo.vertical_adapt"; +export * from "./demo.vtape"; diff --git a/packages/demo/src/demo/core/popup/demo.layer.js b/packages/demo/src/demo/core/popup/demo.layer.js new file mode 100644 index 000000000..dcecd9ef4 --- /dev/null +++ b/packages/demo/src/demo/core/popup/demo.layer.js @@ -0,0 +1,81 @@ + +import { VerticalLayout, Button, CenterAdaptLayout, Decorators, Widget, UUID, Layers } from "@fui/core" + + + +@Decorators.shortcut() +export class LayerDemo extends Widget { + static xtype = "demo.layer"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this, + id1 = UUID(), + id2 = UUID(); + + return { + type: VerticalLayout.xtype, + vgap: 10, + items: [ + { + type: Button.xtype, + text: "create形式创建layer, 遮住当前面板, 返回创建的面板对象", + height: 30, + handler() { + Layers.create(id1, self, { + // 偏移量 + offset: { + left: 10, + right: 10, + top: 10, + bottom: 10, + }, + type: CenterAdaptLayout.xtype, + cls: "bi-card", + items: [ + { + type: Button.xtype, + text: "点击关闭", + handler() { + Layers.hide(id1); + }, + } + ], + }); + Layers.show(id1); + }, + }, + { + type: Button.xtype, + text: "make形式创建layer,可以指定放到哪个面板内,这里指定当前面板(默认放在body下撑满), 返回创建的面板对象", + height: 30, + handler() { + Layers.make(id2, self, { + // 偏移量 + offset: { + left: 10, + right: 10, + top: 10, + bottom: 10, + }, + type: CenterAdaptLayout.xtype, + cls: "bi-card", + items: [ + { + type: Button.xtype, + text: "点击关闭", + handler() { + Layers.remove(id2); + }, + } + ], + }); + Layers.show(id2); + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/popup/demo.popover.js b/packages/demo/src/demo/core/popup/demo.popover.js new file mode 100644 index 000000000..cf8211daa --- /dev/null +++ b/packages/demo/src/demo/core/popup/demo.popover.js @@ -0,0 +1,222 @@ + +import { VerticalLayout, TextButton, BarPopover, Label, ButtonGroup, Decorators, Widget, UUID, map, range, Popovers } from "@fui/core" + + + +@Decorators.shortcut() +export class PopoverDemo extends Widget { + static xtype = "demo.popover"; + + props = { baseCls: "demo-func" }; + + render() { + const id = UUID(); + let body; + + return { + type: VerticalLayout.xtype, + vgap: 10, + items: [ + { + type: TextButton.xtype, + text: "点击弹出Popover(normal size & fixed)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + type: BarPopover.xtype, + size: "normal", + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: Label.xtype, + text: "这个是body", + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + text: "点击弹出Popover(small size & fixed)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + type: BarPopover.xtype, + size: "small", + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: Label.xtype, + text: "这个是body", + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + text: "点击弹出Popover(big size & fixed)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + type: BarPopover.xtype, + size: "big", + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: Label.xtype, + text: "这个是body", + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + text: "点击弹出Popover(normal size & adapt body区域高度是300)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + type: BarPopover.xtype, + size: "normal", + logic: { + dynamic: true, + }, + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: VerticalLayout.xtype, + items: [ + { + type: ButtonGroup.xtype, + ref() { + body = this; + }, + items: map(range(0, 10), () => { + return { + type: Label.xtype, + text: "1", + height: 30, + }; + }), + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + } + ], + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + text: "点击弹出Popover(small size & adapt body区域高度是900)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + type: BarPopover.xtype, + size: "small", + logic: { + dynamic: true, + }, + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: VerticalLayout.xtype, + items: [ + { + type: ButtonGroup.xtype, + ref() { + body = this; + }, + items: map(range(0, 30), () => { + return { + type: Label.xtype, + text: "1", + height: 30, + }; + }), + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + } + ], + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + text: "点击弹出Popover(custom)", + height: 30, + handler() { + Popovers.remove(id); + Popovers.create(id, { + width: 400, + height: 300, + header: { + type: Label.xtype, + text: "这个是header", + }, + body: { + type: Label.xtype, + text: "这个是body", + }, + footer: { + type: Label.xtype, + text: "这个是footer", + }, + }).open(id); + }, + }, + { + type: TextButton.xtype, + height: 30, + text: "弹出一个高度动态的popover层, 此弹出层指定size为small, 但是高度随内容自适应,自适应支持的最大高度为默认为600px", + handler() { + const id = "弹出层id1"; + Popovers.create(id, { + // String或者是json都行 + header: "弹出层标题", + logic: { + dynamic: true, + maxHeight: 700, + }, + size: "small", + body: { + type: VerticalLayout.xtype, + items: map(range(0, 50), (idx, v) => { + return { + type: Label.xtype, + text: "弹出层内容", + }; + }), + }, + footer: { + type: Label.xtype, + text: "这个是footer", + }, + }).open(id); + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/popup/demo.popup_view.js b/packages/demo/src/demo/core/popup/demo.popup_view.js new file mode 100644 index 000000000..833177f50 --- /dev/null +++ b/packages/demo/src/demo/core/popup/demo.popup_view.js @@ -0,0 +1,50 @@ + +import { AbsoluteLayout, Combo, TextButton, PopupView, ButtonGroup, VerticalLayout, MultiSelectItem, Decorators, Widget, createItems, deepClone } from "@fui/core" +import { CONSTANTS } from "@/config/constant"; + + +@Decorators.shortcut() +export class PopupViewDemo extends Widget { + static xtype = "demo.popup_view"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + width: 200, + height: 30, + el: { + type: TextButton.xtype, + text: "点击", + cls: "bi-border", + height: 30, + }, + popup: { + type: PopupView.xtype, + el: { + type: ButtonGroup.xtype, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + items: createItems(deepClone(CONSTANTS.ITEMS), { + type: MultiSelectItem.xtype, + height: 25, + }), + }, + }, + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/core/popup/demo.searcher_view.js b/packages/demo/src/demo/core/popup/demo.searcher_view.js new file mode 100644 index 000000000..d8fd1858f --- /dev/null +++ b/packages/demo/src/demo/core/popup/demo.searcher_view.js @@ -0,0 +1,68 @@ +import { + AbsoluteLayout, + SearcherView, + Label, + Decorators, + Widget, + createItems +} from "@fui/core"; + +@Decorators.shortcut() +export class SearcherViewDemo extends Widget { + static xtype = "demo.searcher_view"; + + props = { baseCls: "demo-func" }; + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: SearcherView.xtype, + ref() { + self.searcherView = this; + } + }, + left: 100, + top: 20, + width: 230 + } + ] + }; + } + + mounted() { + this.searcherView.populate( + createItems( + [ + { + text: 2012 + }, + { + text: 2013 + }, + { + text: 2014 + }, + { + text: 2015 + } + ], + { + type: Label.xtype, + textHeight: 24, + height: 24 + } + ), + [ + { + text: 2 + } + ], + "2" + ); + } +} diff --git a/packages/demo/src/demo/core/popup/index.js b/packages/demo/src/demo/core/popup/index.js new file mode 100644 index 000000000..d6f2c44b0 --- /dev/null +++ b/packages/demo/src/demo/core/popup/index.js @@ -0,0 +1,4 @@ +export * from "./demo.layer"; +export * from "./demo.popover"; +export * from "./demo.popup_view"; +export * from "./demo.searcher_view"; diff --git a/packages/demo/src/demo/fix-2.0/context.js b/packages/demo/src/demo/fix-2.0/context.js new file mode 100644 index 000000000..376877ff2 --- /dev/null +++ b/packages/demo/src/demo/fix-2.0/context.js @@ -0,0 +1,81 @@ +import { Decorators, Widget, AbsoluteLayout, Button, Fix, model, Models } from '@fui/core'; + +@model() +class ParentStore extends Fix.Model { + static xtype = 'demo.model.context.parent_store'; + + state() { + return { + context: '默认context', + }; + } + childContext = ['context']; +} + +@model() +class ChildStore extends Fix.Model { + static xtype = 'demo.model.context.child_store'; + + context = ['context']; + computed = { + currContext: function () { + return this.model.context; + }, + }; + actions = { + changeContext: function () { + this.model.context = '改变后的context'; + }, + }; +} + +@Decorators.shortcut() +class Child extends Widget { + static xtype = 'demo.fix_context_child'; + + _store() { + return Models.getModel(ChildStore.xtype); + } + + watch = { + currContext(val) { + this.button.setText(val); + }, + }; + + render() { + var self = this; + return { + type: Button.xtype, + ref() { + self.button = this; + }, + text: this.model.context, + handler() { + self.store.changeContext(); + }, + }; + } +} + +@Decorators.shortcut() +export class FixContextDemo extends Widget { + static xtype = 'demo.fix_context'; + + _store() { + return Models.getModel(ParentStore.xtype); + } + + render() { + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Child.xtype, + }, + }, + ], + }; + } +} diff --git a/packages/demo/src/demo/fix-2.0/define.js b/packages/demo/src/demo/fix-2.0/define.js new file mode 100644 index 000000000..f16152fbb --- /dev/null +++ b/packages/demo/src/demo/fix-2.0/define.js @@ -0,0 +1,40 @@ +import { Decorators, AbsoluteLayout, Button, Widget, Fix } from '@fui/core'; + +@Decorators.shortcut() +export class DefineDemo extends Widget { + static xtype = 'demo.fix2.define'; + + watch = { + name() { + this.button.setText(this.model.name); + }, + }; + + _store() { + return Fix.define({ + name: '原始属性', + }); + } + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Button.xtype, + ref() { + self.button = this; + }, + handler() { + self.model.name = '这是改变后的属性'; + }, + text: this.model.name, + }, + }, + ], + }; + } +} diff --git a/packages/demo/src/demo/fix-2.0/index.js b/packages/demo/src/demo/fix-2.0/index.js new file mode 100644 index 000000000..6d259a331 --- /dev/null +++ b/packages/demo/src/demo/fix-2.0/index.js @@ -0,0 +1,7 @@ +export const meta = { + title: '数据流框架 fix-2.0', + rank: 0, +}; + +export * from './define'; +export * from './context'; diff --git a/packages/demo/src/demo/index.js b/packages/demo/src/demo/index.js new file mode 100644 index 000000000..7a777eea5 --- /dev/null +++ b/packages/demo/src/demo/index.js @@ -0,0 +1,6 @@ +export * as base from "./base"; +export * as core from "./core"; +export * as caseModule from "./case"; +export * as widget from "./widget"; +export * as component from "./component"; +export * as fix from "./fix-2.0"; diff --git a/packages/demo/src/demo/widget/basewidget/demo.buttons.js b/packages/demo/src/demo/widget/basewidget/demo.buttons.js new file mode 100644 index 000000000..cf92caae7 --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/demo.buttons.js @@ -0,0 +1,94 @@ +import { + Button, + MultiSelectBar, + FloatLeftLayout, + Widget, + each, + Msg, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class ButtonsDemo extends Widget { + static xtype = "demo.buttons"; + + props = { baseCls: "demo-button" }; + + render() { + const items = [ + { + el: { + type: Button.xtype, + text: "一般按钮", + level: "common", + height: 30 + } + }, + { + el: { + type: Button.xtype, + text: "带图标的按钮", + // level: 'ignore', + iconCls: "close-font", + height: 30 + } + }, + { + el: { + type: Button.xtype, + text: "一般按钮", + block: true, + level: "common", + height: 30 + } + }, + { + el: { + type: Button.xtype, + text: "一般按钮", + clear: true, + level: "common", + height: 30 + } + }, + { + el: { + type: MultiSelectBar.xtype, + selected: true, + halfSelected: true + } + }, + { + el: { + type: MultiSelectBar.xtype, + selected: true, + halfSelected: false + } + }, + { + el: { + type: MultiSelectBar.xtype, + selected: false, + halfSelected: true + } + }, + { + el: { + type: MultiSelectBar.xtype + } + } + ]; + each(items, (i, item) => { + item.el.handler = function () { + Msg.alert("按钮", this.options.text); + }; + }); + + return { + type: FloatLeftLayout.xtype, + vgap: 100, + hgap: 20, + items + }; + } +} diff --git a/packages/demo/src/demo/widget/basewidget/demo.items.js b/packages/demo/src/demo/widget/basewidget/demo.items.js new file mode 100644 index 000000000..0a9f8780b --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/demo.items.js @@ -0,0 +1,53 @@ +import { + Widget, + VerticalLayout, + TextButton, + SingleSelectItem, + SingleSelectRadioItem, + Label, + MultiSelectItem, + Switch, + Decorators +} from "@fui/core"; + +@Decorators.shortcut() +export class Items extends Widget { + static xtype = "demo.items"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: TextButton.xtype, + cls: "bi-list-item-select bi-high-light-border bi-border", + height: 30, + level: "warning", + text: "单选item" + }, + { + type: SingleSelectItem.xtype, + text: "单选项" + }, + { + type: SingleSelectRadioItem.xtype, + text: "单选项" + }, + { + type: Label.xtype, + height: 30, + text: "复选item" + }, + { + type: MultiSelectItem.xtype, + text: "复选项" + }, + { + type: Switch.xtype, + selected: true + } + ], + hgap: 300 + }; + } +} diff --git a/packages/demo/src/demo/widget/basewidget/demo.nodes.js b/packages/demo/src/demo/widget/basewidget/demo.nodes.js new file mode 100644 index 000000000..8392f6659 --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/demo.nodes.js @@ -0,0 +1,50 @@ +import { + Widget, + VerticalLayout, + Label, + PlusGroupNode, + ArrowNode, + IconArrowNode, + MultiLayerIconArrowNode, + Decorators, +} from "@fui/core"; + +@Decorators.shortcut() +export class NodesDemo extends Widget { + static xtype = "demo.nodes"; + + render(vessel) { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "十字形的节点" + }, + { + type: PlusGroupNode.xtype, + text: "十字形的节点" + }, + { + type: Label.xtype, + height: 30, + text: "箭头节点" + }, + { + type: ArrowNode.xtype, + text: "箭头节点" + }, + { + type: IconArrowNode.xtype, + iconCls: "search-font", + text: "箭头图标节点" + }, + { + type: MultiLayerIconArrowNode.xtype, + layer: 2 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/basewidget/demo.sagments.js b/packages/demo/src/demo/widget/basewidget/demo.sagments.js new file mode 100644 index 000000000..fe36cbc68 --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/demo.sagments.js @@ -0,0 +1,40 @@ +import { VerticalLayout, Label, Segment, Decorators, Widget } from "@fui/core"; + +@Decorators.shortcut() +export class SegmentsDemo extends Widget { + static xtype = "demo.segments"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + height: 30, + text: "默认风格" + }, + { + type: Segment.xtype, + items: [ + { + text: "tab1", + value: 1, + selected: true + }, + { + text: "tab2", + value: 2 + }, + { + text: "tab3 disabled", + disabled: true, + value: 3 + } + ] + } + ], + hgap: 50, + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/basewidget/demo.tips.js b/packages/demo/src/demo/widget/basewidget/demo.tips.js new file mode 100644 index 000000000..fd519dc0a --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/demo.tips.js @@ -0,0 +1,175 @@ +import { + Bubbles, + Msg, + Widget, + createWidget, + each, + FloatLeftLayout, + Button, + VerticalLayout, + Label, + Decorators, + HorizontalAutoLayout +} from "@fui/core"; + +@Decorators.shortcut() +export class TipsDemo extends Widget { + static xtype = "demo.tips"; + + props = { baseCls: "demo-tips" }; + + render() { + const btns = []; + const bubble = createWidget({ + type: FloatLeftLayout.xtype, + items: [ + { + el: { + type: Button.xtype, + text: "bubble测试", + height: 30, + handler() { + Bubbles.show("singleBubble1", "bubble测试", this); + btns.push("singleBubble1"); + } + } + }, + { + el: { + type: Button.xtype, + text: "bubble测试(居中显示)", + height: 30, + handler() { + Bubbles.show("singleBubble2", "bubble测试", this, { + offsetStyle: "center" + }); + btns.push("singleBubble2"); + } + } + }, + { + el: { + type: Button.xtype, + text: "bubble测试(右边显示)", + height: 30, + handler() { + Bubbles.show("singleBubble3", "bubble测试", this, { + offsetStyle: "right" + }); + btns.push("singleBubble3"); + } + } + }, + { + el: { + type: Button.xtype, + text: "隐藏所有 bubble", + height: 30, + cls: "layout-bg2", + handler() { + each(btns, (index, value) => { + Bubbles.hide(value); + }); + } + } + } + ], + hgap: 20 + }); + + const title = createWidget({ + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + cls: "layout-bg1", + height: 50, + title: "title提示", + text: "移上去有title提示", + textAlign: "center" + }, + { + type: Label.xtype, + cls: "layout-bg6", + height: 50, + disabled: true, + warningTitle: "title错误提示", + text: "移上去有title错误提示", + textAlign: "center" + }, + { + type: Label.xtype, + cls: "layout-bg2", + height: 50, + disabled: true, + tipType: "success", + title: "自定义title提示效果", + warningTitle: "自定义title提示效果", + text: "自定义title提示效果", + textAlign: "center" + } + ], + hgap: 20, + vgap: 20 + }); + + const toast = createWidget({ + type: VerticalLayout.xtype, + items: [ + { + el: { + type: Button.xtype, + text: "简单Toast测试", + height: 30, + handler() { + Msg.toast("这是一条简单的数据"); + } + } + }, + { + el: { + type: Button.xtype, + text: "很长的Toast测试", + height: 30, + handler() { + Msg.toast( + "这是一条很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的数据" + ); + } + } + }, + { + el: { + type: Button.xtype, + text: "非常长的Toast测试", + height: 30, + handler() { + Msg.toast( + "这是一条非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长非常长的数据" + ); + } + } + }, + { + el: { + type: Button.xtype, + text: "错误提示Toast测试", + level: "warning", + height: 30, + handler() { + Msg.toast("错误提示Toast测试", "warning"); + } + } + } + ], + vgap: 20 + }); + + return { + type: HorizontalAutoLayout.xtype, + vgap: 20, + hgap: 20, + items: [bubble, title, toast] + }; + } +} diff --git a/packages/demo/src/demo/widget/basewidget/index.js b/packages/demo/src/demo/widget/basewidget/index.js new file mode 100644 index 000000000..74e1099d2 --- /dev/null +++ b/packages/demo/src/demo/widget/basewidget/index.js @@ -0,0 +1,9 @@ +export const meta = { + title: "各种小控件" +}; + +export * from "./demo.buttons"; +export * from "./demo.items"; +export * from "./demo.nodes"; +export * from "./demo.sagments"; +export * from "./demo.tips"; diff --git a/packages/demo/src/demo/widget/collapase/demo.collapse.js b/packages/demo/src/demo/widget/collapase/demo.collapse.js new file mode 100644 index 000000000..0558523f1 --- /dev/null +++ b/packages/demo/src/demo/widget/collapase/demo.collapse.js @@ -0,0 +1,82 @@ +import { + Widget, + createItems, + SingleSelectItem, + Label, + VerticalLayout, + Decorators, + Collapse +} from "@fui/core"; + +@Decorators.shortcut() +export class CollapseDemo extends Widget { + static xtype = "demo.collapse"; + + props = { baseCls: "demo-collapse" }; + + render() { + const self = this; + + const items = [ + { + value: "test", + popup: { + cls: "mvc-border", + items: createItems( + [ + { + text: "项目1", + value: 1 + }, + { + text: "项目2", + value: 2 + }, + { + text: "项目3", + value: 3 + }, + { + text: "项目4", + value: 4 + } + ], + { + type: SingleSelectItem.xtype, + height: 25 + } + ) + } + }, + { + value: 2, + popup: { + type: Label.xtype, + value: "给岁月以文明,而不是给文明以岁月" + } + }, + { + value: 3, + popup: { + type: Label.xtype, + value: "漂流瓶隐没于黑暗里,在一千米见方的宇宙中,只有生态球里的小太阳发出一点光芒。在这个小小的生命世界中,几只清澈的水球在零重力环境中静静地飘浮着,有一条小鱼从一只水球中蹦出,跃入另一只水球,轻盈地穿游于绿藻之间。" + } + } + ]; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: Collapse.xtype, + accordion: true, + items, + value: [2] + } + ], + width: "60%", + tgap: 100, + hgap: 100 + }; + } +} diff --git a/packages/demo/src/demo/widget/collapase/index.js b/packages/demo/src/demo/widget/collapase/index.js new file mode 100644 index 000000000..874481a67 --- /dev/null +++ b/packages/demo/src/demo/widget/collapase/index.js @@ -0,0 +1,5 @@ +export const meta = { + title: "collapase" +}; + +export * from "./demo.collapse"; diff --git a/packages/demo/src/demo/widget/date/demo.datepane.js b/packages/demo/src/demo/widget/date/demo.datepane.js new file mode 100644 index 000000000..14c092a32 --- /dev/null +++ b/packages/demo/src/demo/widget/date/demo.datepane.js @@ -0,0 +1,104 @@ +import { + Decorators, + Widget, + Msg, + HorizontalAutoLayout, + VerticalLayout, + DynamicDatePane, + Button, + DynamicDateTimePane +} from "@fui/core"; + +@Decorators.shortcut() +export class DatePane extends Widget { + static xtype = "demo.date_pane"; + + props = { baseCls: "demo-datepane" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: VerticalLayout.xtype, + vgap: 10, + items: [ + { + type: DynamicDatePane.xtype, + // value: { + // type: 1, + // value: { + // year: 2017, + // month: 12, + // day: 11 + // } + // }, + ref(_ref) { + self.datepane = _ref; + }, + height: 300 + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast( + `date${JSON.stringify( + self.datepane.getValue() + )}` + ); + } + }, + { + type: DynamicDateTimePane.xtype, + value: { + type: 1, + value: { + year: 2017, + month: 12, + day: 11, + hour: 12, + minute: 12, + second: 12 + } + }, + ref(_ref) { + self.dateTimePane = _ref; + }, + height: 340 + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast( + `date${JSON.stringify( + self.dateTimePane.getValue() + )}` + ); + } + }, + { + type: Button.xtype, + text: "setValue '2017-12-31'", + handler() { + self.datepane.setValue({ + year: 2017, + month: 12, + day: 31 + }); + } + } + ], + width: "50%" + } + ] + }; + } + + mounted() { + this.datepane.setValue(); // 不设value值表示当前时间 + } +} diff --git a/packages/demo/src/demo/widget/date/demo.multidate_combo.js b/packages/demo/src/demo/widget/date/demo.multidate_combo.js new file mode 100644 index 000000000..5ebe494d3 --- /dev/null +++ b/packages/demo/src/demo/widget/date/demo.multidate_combo.js @@ -0,0 +1,124 @@ +import { + Decorators, + Widget, + Msg, + HorizontalAutoLayout, + DynamicDateCombo, + Button, + DynamicDateTimeCombo +} from "@fui/core"; + +@Decorators.shortcut() +export class Date extends Widget { + static xtype = "demo.multidate_combo"; + + props = { baseCls: "demo-date" }; + + _init(...args) { + super._init(...args); + } + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + vgap: 20, + items: [ + { + type: DynamicDateCombo.xtype, + ref() { + self.datecombo = this; + }, + width: 300, + // allowEdit: false, + // format: "%Y-%X-%d", // yyyy-MM-dd + // format: "%Y/%X/%d", // yyyy/MM/dd + // format: "%Y-%x-%e", // yyyy-M-d + // format: "%Y/%x/%e", // yyyy/M/d + // format: "%X/%d/%Y", // MM/dd/yyyy + // format: "%X/%e/%y", // MM/d/yy + // format: "%X.%d.%Y", // MM.dd.yyyy + // format: "%X.%e.%Y", // MM.d.yyyy + // format: "%X-%e-%y", // MM.d.yyyy + value: { + type: 1, + value: { + year: 2018, + month: 2, + day: 23 + } + } + }, + { + type: Button.xtype, + text: "getValue", + width: 300, + handler() { + Msg.alert( + "date", + JSON.stringify(self.datecombo.getValue()) + ); + } + }, + { + type: DynamicDateTimeCombo.xtype, + ref() { + self.datetimecombo = this; + }, + width: 300, + // allowEdit: false, + // format: "%Y-%X-%d %H:%M:%S", // yyyy-MM-dd HH:mm:ss + // format: "%Y/%X/%d %H:%M:%S", // yyyy/MM/dd HH:mm:ss + // format: "%Y-%X-%d %I:%M:%S", // yyyy-MM-dd hh:mm:ss + // format: "%Y/%X/%d %I:%M:%S", // yyyy/MM/dd hh:mm:ss + // format: "%Y-%X-%d %H:%M:%S %p", // yyyy-MM-dd HH:mm:ss a + // format: "Y/%X/%d %H:%M:%S %p", // yyyy/MM/dd HH:mm:ss a + // format: "%Y-%X-%d %I:%M:%S %p", // yyyy-MM-dd hh:mm:ss a + // format: "%Y/%X/%d %I:%M:%S %p", // yyyy/MM/dd hh:mm:ss a + // format: "%X/%d/%Y %I:%M:%S", // MM/dd/yyyy hh:mm:ss + // format: "%X/%d/%Y %H:%M:%S", // MM/dd/yyyy HH:mm:ss + // format: "%X/%d/%Y %I:%M:%S", // MM/dd/yyyy hh:mm:ss a + // format: "%X/%d/%Y %H:%M:%S %p", // MM/dd/yyyy HH:mm:ss a + // format: "%X/%d/%Y %I:%M:%S %p", // MM/dd/yyyy hh:mm:ss a + // format: "%X/%d/%Y %H:%M:%S %p", // MM/dd/yyyy HH:mm:ss a + // format: "%X/%d/%Y %l:%M %p", // MM/dd/yyyy h:mm a + // format: "%X-%d-%Y %k:%M %p", // MM/dd/yyyy H:mm a + // format: "%Y-%x-%e %l:%M", // yyyy-M-d h:mm + // format: "%Y-%x-%e %k:%M", // yyyy-M-d H:mm + value: { + type: 1, + value: { + year: 2018, + month: 2, + day: 23 + } + } + }, + { + type: Button.xtype, + text: "getValue", + width: 300, + handler() { + Msg.alert( + "date", + JSON.stringify(self.datetimecombo.getValue()) + ); + } + }, + { + type: Button.xtype, + text: "setValue '2017-12-31'", + width: 300, + handler() { + self.datecombo.setValue({ + year: 2017, + month: 11, + day: 31 + }); + } + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/date/index.js b/packages/demo/src/demo/widget/date/index.js new file mode 100644 index 000000000..379827fba --- /dev/null +++ b/packages/demo/src/demo/widget/date/index.js @@ -0,0 +1,2 @@ +export * from "./demo.datepane"; +export * from "./demo.multidate_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/datetime/demo.datetime.js b/packages/demo/src/demo/widget/datetime/demo.datetime.js new file mode 100644 index 000000000..62c484409 --- /dev/null +++ b/packages/demo/src/demo/widget/datetime/demo.datetime.js @@ -0,0 +1,65 @@ +import { + AbsoluteLayout, + DateTimeCombo, + Decorators, + Widget, + print, + Msg, +} from "@fui/core"; + +@Decorators.shortcut() +export class CustomDateTimeDemo extends Widget { + static xtype = "demo.date_time"; + + props = {}; + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: DateTimeCombo.xtype, + listeners: [ + { + eventName: DateTimeCombo.EVENT_CONFIRM, + action() { + const value = this.getValue(); + const date = new Date( + value.year, + value.month - 1, + value.day, + value.hour, + value.minute, + value.second + ); + const dateStr = print( + date, + "%Y-%X-%d %H:%M:%S" + ); + Msg.alert("日期", dateStr); + } + }, + { + eventName: DateTimeCombo.EVENT_CANCEL, + action() {} + } + ], + value: { + year: 2017, + month: 2, + day: 23, + hour: 12, + minute: 11, + second: 1 + } + }, + top: 200, + left: 200 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/datetime/index.js b/packages/demo/src/demo/widget/datetime/index.js new file mode 100644 index 000000000..a8f8094c4 --- /dev/null +++ b/packages/demo/src/demo/widget/datetime/index.js @@ -0,0 +1 @@ +export * from "./demo.datetime"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/downlist/demo.downlist.icon.js b/packages/demo/src/demo/widget/downlist/demo.downlist.icon.js new file mode 100644 index 000000000..8905caf28 --- /dev/null +++ b/packages/demo/src/demo/widget/downlist/demo.downlist.icon.js @@ -0,0 +1,16 @@ + +import { Label, Decorators, Widget } from "@fui/core" + +@Decorators.shortcut() +export class CustomIcon extends Widget { + static xtype = "demo.downlist.icon"; + + render() { + return { + type: Label.xtype, + text: "✨", + }; + } +} + + diff --git a/packages/demo/src/demo/widget/downlist/demo.downlist.js b/packages/demo/src/demo/widget/downlist/demo.downlist.js new file mode 100644 index 000000000..9d92558cd --- /dev/null +++ b/packages/demo/src/demo/widget/downlist/demo.downlist.js @@ -0,0 +1,278 @@ +import { + Decorators, + Widget, + i18nText, + DownListCombo, + FloatLeftLayout, + Button, + MultiLayerDownListCombo, + Label +} from "@fui/core"; + +@Decorators.shortcut() +export class DownlistDemo extends Widget { + static xtype = "demo.down_list"; + + props = { baseCls: "demo-downlist" }; + + mounted() { + const downlist = this.downlist; + const label = this.label; + this.downlist.setValue([ + { + value: [11, 6], + childValue: 67 + } + ]); + downlist.on(DownListCombo.EVENT_CHANGE, (value, fatherValue) => { + label.setValue(JSON.stringify(downlist.getValue())); + }); + + this.downlist.on( + DownListCombo.EVENT_SON_VALUE_CHANGE, + (value, fatherValue) => { + label.setValue(JSON.stringify(downlist.getValue())); + } + ); + } + + render() { + const self = this; + + return { + type: FloatLeftLayout.xtype, + items: [ + { + type: DownListCombo.xtype, + ref(_ref) { + self.downlist = _ref; + }, + // value: [{"childValue":22,"value":11},{"value":18},{"value":20}], + height: 30, + width: 100, + items: [ + [ + { + text: "column 1111", + iconCls1: "dot-e-font", + value: 12, + children: [ + { + text: "column 1.1", + value: 21, + cls: "dot-e-font" + }, + { + text: "column 1.2", + value: 22, + cls: "dot-e-font" + } + ] + } + ], + [ + { + el: { + text: "column 1111", + iconCls1: "dot-e-font", + value: 11 + }, + children: [ + { + text: "column 1.1", + value: 21, + cls: "dot-e-font" + }, + { + text: "column 1.2", + value: 22, + cls: "dot-e-font" + } + ] + // children: [{ + // text: i18nText("BI-Basic_None"), + // cls: "dot-e-font", + // value: 1 + // }, { + // text: i18nText("BI-Basic_Calculate_Same_Period"), + // cls: "dot-e-font", + // value: 2 + // }, { + // text: i18nText("BI-Basic_Calculate_Same_Ring"), + // cls: "dot-e-font", + // value: 3 + // }, { + // text: i18nText("BI-Basic_Calculate_Same_Period_Rate"), + // cls: "dot-e-font", + // value: 4 + // }, { + // text: i18nText("BI-Basic_Calculate_Same_Ring_Rate"), + // cls: "dot-e-font", + // value: 5 + // }, { + // el: { + // text: i18nText("BI-Basic_Rank"), + // iconCls1: "dot-e-font", + // value: 6 + // }, + // children: [{ + // text: "test1", + // cls: "dot-e-font", + // value: 67 + // }, { + // text: "test2", + // cls: "dot-e-font", + // value: 68 + // }] + // }, { + // text: i18nText("BI-Basic_Rank_In_Group"), + // cls: "dot-e-font", + // value: 7 + // }, { + // text: i18nText("BI-Basic_Sum_Of_All"), + // cls: "dot-e-font", + // value: 8 + // }, { + // text: i18nText("BI-Basic_Sum_Of_All_In_Group"), + // cls: "dot-e-font", + // value: 9 + // }, { + // text: i18nText("BI-Basic_Sum_Of_Above"), + // cls: "dot-e-font", + // value: 10 + // }, { + // text: i18nText("BI-Basic_Sum_Of_Above_In_Group"), + // cls: "dot-e-font", + // value: 11 + // }, { + // text: i18nText("BI-Design_Current_Dimension_Percent"), + // cls: "dot-e-font", + // value: 12 + // }, { + // text: i18nText("BI-Design_Current_Target_Percent"), + // cls: "dot-e-font", + // value: 13 + // }] + } + ] + ] + }, + { + type: DownListCombo.xtype, + el: { + type: Button.xtype, + ghost: true, + iconPosition: "right", + icon: "column-next-page-h-font", + text: "自定义 trigger 和 icon 的级联下拉框" + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action(v) { + console.log("触发值", v); + } + }, + { + eventName: "EVENT_SON_VALUE_CHANGE", + action(v) { + console.log("二级菜单触发值", v); + } + } + ], + items: [ + [ + { + text: "选项一", + value: 1, + icon: { + type: "demo.downlist.icon" + }, + children: [ + { + text: "选项一", + value: 11, + icon: { + type: "demo.downlist.icon" + } + }, + { + text: "选项二", + value: 12 + } + ] + }, + { + text: "选项二", + value: 2 + } + ] + ] + }, + { + type: MultiLayerDownListCombo.xtype, + ref(_ref) { + self.downlist = _ref; + }, + // value: [{"childValue":22,"value":11},{"value":18},{"value":20}], + height: 30, + width: 100, + items: [ + [ + { + el: { + text: "column 1111", + iconCls1: "dot-e-font", + value: 12 + }, + children: [ + { + text: "column 1.1", + value: 21, + cls: "dot-e-font" + }, + { + text: "column 1.2", + value: 22, + cls: "dot-e-font" + } + ] + } + ], + [ + { + el: { + text: "column 1111", + iconCls1: "dot-e-font", + value: 11 + }, + children: [ + { + text: "column 1.1", + value: 21, + cls: "dot-e-font" + }, + { + text: "column 1.2", + value: 22, + cls: "dot-e-font" + } + ] + } + ] + ] + }, + { + type: Label.xtype, + text: "显示选择值", + width: 500, + cls: "layout-bg3", + ref(_ref) { + self.label = _ref; + } + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/downlist/index.js b/packages/demo/src/demo/widget/downlist/index.js new file mode 100644 index 000000000..3636f3654 --- /dev/null +++ b/packages/demo/src/demo/widget/downlist/index.js @@ -0,0 +1,2 @@ +export * from "./demo.downlist"; +export * from "./demo.downlist.icon"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/editor/demo.search_editor.js b/packages/demo/src/demo/widget/editor/demo.search_editor.js new file mode 100644 index 000000000..6a64bba16 --- /dev/null +++ b/packages/demo/src/demo/widget/editor/demo.search_editor.js @@ -0,0 +1,37 @@ +import { + HorizontalAutoLayout, + SearchEditor, + SmallSearchEditor, + Decorators, + Widget +} from "@fui/core"; + +@Decorators.shortcut() +export class SearchEditorDemo extends Widget { + static xtype = "demo.search_editor"; + + props = { baseCls: "demo-exceltable" }; + + render() { + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: SearchEditor.xtype, + width: 300, + watermark: "添加合法性判断", + errorText: "长度必须大于4", + validationChecker() { + return this.getValue().length > 4; + } + }, + { + type: SmallSearchEditor.xtype, + width: 300, + watermark: "这个是 small,小一号" + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/editor/demo.text_editor.js b/packages/demo/src/demo/widget/editor/demo.text_editor.js new file mode 100644 index 000000000..cfab878ab --- /dev/null +++ b/packages/demo/src/demo/widget/editor/demo.text_editor.js @@ -0,0 +1,29 @@ +import { HorizontalAutoLayout, TextEditor, Decorators, Widget } from "@fui/core"; + +@Decorators.shortcut() +export class TextEditorDemo extends Widget { + static xtype = "demo.text_editor"; + + props = { baseCls: "demo-exceltable" }; + + render() { + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: TextEditor.xtype, + watermark: "这是水印,watermark", + width: 300 + }, + { + type: TextEditor.xtype, + watermark: "这个不予许空", + allowBlank: false, + errorText: "非空!", + width: 300 + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/editor/index.js b/packages/demo/src/demo/widget/editor/index.js new file mode 100644 index 000000000..fe266fb31 --- /dev/null +++ b/packages/demo/src/demo/widget/editor/index.js @@ -0,0 +1,2 @@ +export * from "./demo.search_editor"; +export * from "./demo.text_editor"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/index.js b/packages/demo/src/demo/widget/index.js new file mode 100644 index 000000000..5d6c985fc --- /dev/null +++ b/packages/demo/src/demo/widget/index.js @@ -0,0 +1,30 @@ +export const meta = { + title: "详细控件 widget", + rank: 6 +}; + +export * as basewiget from "./basewidget"; +export * as collapase from "./collapase"; +export * as date from "./date"; +export * as datetime from "./datetime"; +export * as downlist from "./downlist"; +export * as editor from "./editor"; +export * as multiselect from "./multiselect"; +export * as multitree from "./multitree"; +export * as numbereditor from "./numbereditor"; +export * as numberinterval from "./numberinterval"; +export * as selecttree from "./selecttree"; +export * as singleselct from "./singleselct"; + +export * as singletree from "./singletree"; +export * as slider from "./slider"; +export * as timecombo from "./timecombo"; +export * as timeinterval from "./timeinterval"; +export * as tree from "./tree"; +export * as year from "./year"; +export * as yearinterval from "./yearinterval"; + +export * as yearmonth from "./yearmonth"; +export * as yearmonthinterval from "./yearmonthinterval"; +export * as yearquarter from "./yearquarter"; +export * as yearquarterinterval from "./yearquarterinterval"; diff --git a/packages/demo/src/demo/widget/multiselect/demo.multi_select_combo.js b/packages/demo/src/demo/widget/multiselect/demo.multi_select_combo.js new file mode 100644 index 000000000..a9e35b6e5 --- /dev/null +++ b/packages/demo/src/demo/widget/multiselect/demo.multi_select_combo.js @@ -0,0 +1,110 @@ +import { CONSTANTS } from "@/config/constant"; +import { + MultiSelectInsertCombo, + AbsoluteLayout, + Decorators, + Widget, + Func, + createWidget, + bind, + each, + makeObject, + filter, + delay, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiSelectComboDemo extends Widget { + static xtype = "demo.multi_select_combo"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + props = { baseCls: "demo-multi-select-combo" }; + + _createMultiSelectCombo() { + const self = this; + const widget = createWidget({ + type: MultiSelectInsertCombo.xtype, + // allowEdit: false, + itemsCreator: bind(this._itemsCreator, this), + width: 200, + value: { + type: 1, + value: [ + "柳州市城贸金属材料有限责任公司", + "柳州市建福房屋租赁有限公司", + "柳州市迅昌数码办公设备有限责任公司" + ] + } + }); + + widget.on(MultiSelectComboDemo.EVENT_CONFIRM, function () { + Msg.toast(JSON.stringify(this.getValue())); + }); + + return widget; + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * 100; items[i] && i < times * 100; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * 100 < items.length; + } + + _itemsCreator(options, callback) { + const self = this; + let items = CONSTANTS.ITEMS; + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + items = search.match.concat(search.find); + }); + if (options.selectedValues) { + // 过滤 + const filter = makeObject(options.selectedValues, true); + items = filter(items, (i, ob) => !filter[ob.value]); + } + if (options.type == MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items + }); + + return; + } + if (options.type == MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: items.length }); + + return; + } + delay(() => { + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + }, 1000); + } + + render() { + return { + type: AbsoluteLayout.xtype, + scrolly: false, + items: [ + { + el: this._createMultiSelectCombo(), + right: "50%", + top: 10 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/multiselect/demo.multi_select_list.js b/packages/demo/src/demo/widget/multiselect/demo.multi_select_list.js new file mode 100644 index 000000000..3ae93b7dd --- /dev/null +++ b/packages/demo/src/demo/widget/multiselect/demo.multi_select_list.js @@ -0,0 +1,117 @@ +import { CONSTANTS } from "@/config/constant"; +import { + MultiSelectInsertList, + AbsoluteLayout, + Decorators, + Widget, + createWidget, + Func, + bind, + each, + makeObject, + filter, + delay, + Msg, + MultiSelectCombo +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiSelectListDemo extends Widget { + static xtype = "demo.multi_select_list"; + + props = { baseCls: "demo-multi-select-combo" }; + + mounted() { + this.list.populate(); + } + + _createMultiSelectCombo() { + const self = this; + const widget = createWidget({ + type: MultiSelectInsertList.xtype, + ref(ref) { + self.list = ref; + }, + itemsCreator: bind(this._itemsCreator, this), + value: { + type: 1, + value: [ + "柳州市城贸金属材料有限责任公司", + "柳州市建福房屋租赁有限公司", + "柳州市迅昌数码办公设备有限责任公司" + ] + } + }); + + widget.on(MultiSelectCombo.EVENT_CONFIRM, function () { + Msg.toast(JSON.stringify(this.getValue())); + }); + + return widget; + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * 10; items[i] && i < times * 10; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * 10 < items.length; + } + + _itemsCreator(options, callback) { + const self = this; + let items = CONSTANTS.ITEMS; + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + items = search.match.concat(search.find); + }); + if (options.selectedValues) { + // 过滤 + const filterItems = makeObject(options.selectedValues, true); + items = filter(items, (i, ob) => !filterItems[ob.value]); + } + if (options.type == MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items + }); + + return; + } + if (options.type == MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: items.length }); + + return; + } + delay(() => { + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + }, 1000); + } + + render() { + return { + type: AbsoluteLayout.xtype, + scrolly: false, + items: [ + { + el: this._createMultiSelectCombo(), + top: 50, + left: 50, + right: 50, + bottom: 50 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/multiselect/index.js b/packages/demo/src/demo/widget/multiselect/index.js new file mode 100644 index 000000000..36754a3c9 --- /dev/null +++ b/packages/demo/src/demo/widget/multiselect/index.js @@ -0,0 +1,2 @@ +export * from "./demo.multi_select_combo"; +export * from "./demo.multi_select_list"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/multitree/demo.multi_tree_combo.js b/packages/demo/src/demo/widget/multitree/demo.multi_tree_combo.js new file mode 100644 index 000000000..8cd5fac45 --- /dev/null +++ b/packages/demo/src/demo/widget/multitree/demo.multi_tree_combo.js @@ -0,0 +1,75 @@ +import { CONSTANTS } from "@/config/constant"; +import { + HorizontalAutoLayout, + MultiTreeCombo, + Button, + Decorators, + Widget, + deepClone, + Msg, + TreeView +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiTreeComboDemo extends Widget { + static xtype = "demo.multi_tree_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.TREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: MultiTreeCombo.xtype, + ref(_ref) { + self.tree = _ref; + }, + itemsCreator(options, callback) { + console.log(options); + // 根据不同的类型处理相应的结果 + switch (options.type) { + case TreeView.REQ_TYPE_INIT_DATA: + break; + case TreeView.REQ_TYPE_ADJUST_DATA: + break; + case TreeView.REQ_TYPE_SELECT_DATA: + break; + case TreeView.REQ_TYPE_GET_SELECTED_DATA: + break; + default: + break; + } + callback({ + items + }); + }, + width: 300, + value: { + 根目录: {} + }, + listeners: [ + { + eventName: "EVENT_CONFIRM", + action() { + console.log("EVENT_CONFIRM", this.getValue()); + } + } + ] + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.tree.getValue())); + }, + width: 300 + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/multitree/demo.multi_tree_list.js b/packages/demo/src/demo/widget/multitree/demo.multi_tree_list.js new file mode 100644 index 000000000..b92934144 --- /dev/null +++ b/packages/demo/src/demo/widget/multitree/demo.multi_tree_list.js @@ -0,0 +1,81 @@ +import { CONSTANTS } from "@/config/constant"; +import { + AbsoluteLayout, + MultiSelectTree, + Button, + Decorators, + Widget, + deepClone, + Msg, + TreeView +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiSelectTreeDemo extends Widget { + static xtype = "demo.multi_select_tree"; + + props = { baseCls: "" }; + + mounted() { + this.tree.populate(); + } + + render() { + const self = this; + const items = deepClone(CONSTANTS.TREE); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: MultiSelectTree.xtype, + ref(_ref) { + self.tree = _ref; + }, + itemsCreator(options, callback) { + console.log(options); + // 根据不同的类型处理相应的结果 + switch (options.type) { + case TreeView.REQ_TYPE_INIT_DATA: + break; + case TreeView.REQ_TYPE_ADJUST_DATA: + break; + case TreeView.REQ_TYPE_SELECT_DATA: + break; + case TreeView.REQ_TYPE_GET_SELECTED_DATA: + break; + default: + break; + } + callback({ + items: deepClone(items) + }); + }, + width: 300, + value: { + 根目录: {} + } + }, + top: 50, + bottom: 50, + left: 50, + right: 50 + }, + { + el: { + type: Button.xtype, + height: 30, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.tree.getValue())); + } + }, + left: 50, + right: 50, + bottom: 20 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/multitree/index.js b/packages/demo/src/demo/widget/multitree/index.js new file mode 100644 index 000000000..af21d372d --- /dev/null +++ b/packages/demo/src/demo/widget/multitree/index.js @@ -0,0 +1,2 @@ +export * from "./demo.multi_tree_combo"; +export * from "./demo.multi_tree_list"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/numbereditor/demo.number_editor.js b/packages/demo/src/demo/widget/numbereditor/demo.number_editor.js new file mode 100644 index 000000000..63a8ab40f --- /dev/null +++ b/packages/demo/src/demo/widget/numbereditor/demo.number_editor.js @@ -0,0 +1,73 @@ +import { + NumberEditor, + VerticalLayout, + Decorators, + Widget, + createWidget, + parseFloat, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class FileManagerDemo extends Widget { + static xtype = "demo.number_editor"; + + props = { baseCls: "" }; + + render() { + const editor1 = createWidget({ + type: NumberEditor.xtype, + validationChecker(v) { + return parseFloat(v) <= 100 && parseFloat(v) >= 0; + }, + height: 24, + width: 150, + errorText: "hahah", + watermark: "每个人都是自己健康的第一责任人" + }); + editor1.on(NumberEditor.EVENT_CHANGE, function () { + if (parseFloat(this.getValue()) < 1) { + editor1.setDownEnable(false); + } else { + editor1.setDownEnable(true); + } + Msg.toast(editor1.getValue()); + }); + + const editor2 = createWidget({ + type: NumberEditor.xtype, + validationChecker(v) { + return parseFloat(v) <= 100 && parseFloat(v) >= 0; + }, + valueFormatter: (v) => `${v}$`, + valueParser: (v) => v.replace(/\$\s?|(,*)/g, ""), + height: 24, + width: 150, + errorText: "hahah" + }); + editor2.on(NumberEditor.EVENT_CHANGE, function () { + if (parseFloat(this.getValue()) < 1) { + editor2.setDownEnable(false); + } else { + editor2.setDownEnable(true); + } + Msg.toast(editor2.getValue()); + }); + + return { + type: VerticalLayout.xtype, + hgap: 20, + vgap: 20, + items: [ + { + el: editor1, + height: 24 + }, + { + el: editor2, + height: 24 + } + ] + }; + } +} diff --git a/packages/demo/src/demo/widget/numbereditor/index.js b/packages/demo/src/demo/widget/numbereditor/index.js new file mode 100644 index 000000000..368c8e49d --- /dev/null +++ b/packages/demo/src/demo/widget/numbereditor/index.js @@ -0,0 +1 @@ +export * from "./demo.number_editor"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/numberinterval/demo.number_interval.js b/packages/demo/src/demo/widget/numberinterval/demo.number_interval.js new file mode 100644 index 000000000..aa11c27ae --- /dev/null +++ b/packages/demo/src/demo/widget/numberinterval/demo.number_interval.js @@ -0,0 +1,56 @@ +import { + HorizontalAutoLayout, + NumberInterval, + Label, + Decorators, + Widget +} from "@fui/core"; + +@Decorators.shortcut() +export class NumericalIntervalDemo extends Widget { + static xtype = "demo.number_interval"; + + props = { baseCls: "demo-exceltable" }; + + mounted() { + const numerical = this.numerical; + const label = this.label; + numerical.on(NumberInterval.EVENT_CONFIRM, () => { + const temp = numerical.getValue(); + const res = `大于${temp.closemin ? "等于 " : " "}${temp.min} 小于${ + temp.closemax ? "等于 " : " " + }${temp.max}`; + label.setValue(res); + }); + } + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: NumberInterval.xtype, + ref(_ref) { + self.numerical = _ref; + }, + width: 500, + value: { + max: 300, + closeMax: true, + closeMin: false + } + }, + { + type: Label.xtype, + ref(_ref) { + self.label = _ref; + }, + text: "显示结果" + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/numberinterval/index.js b/packages/demo/src/demo/widget/numberinterval/index.js new file mode 100644 index 000000000..9f891df71 --- /dev/null +++ b/packages/demo/src/demo/widget/numberinterval/index.js @@ -0,0 +1 @@ +export * from "./demo.number_interval"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/selecttree/demo.multilayer_select_tree_combo.js b/packages/demo/src/demo/widget/selecttree/demo.multilayer_select_tree_combo.js new file mode 100644 index 000000000..eb0736b77 --- /dev/null +++ b/packages/demo/src/demo/widget/selecttree/demo.multilayer_select_tree_combo.js @@ -0,0 +1,51 @@ +import { CONSTANTS } from "@/config/constant"; + +import { HorizontalAutoLayout, MultiLayerSelectTreeCombo, Button, Decorators, Widget, deepClone, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class MultiLayerSelectTreeComboDemo extends Widget { + static xtype = "demo.multilayer_select_tree_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.TREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: MultiLayerSelectTreeCombo.xtype, + ref(_ref) { + self.tree = _ref; + }, + defaultText: "请选择", + items, + width: 300, + value: ["第五级文件1"], + }, + { + type: Button.xtype, + text: "getVlaue", + handler() { + Msg.toast(self.tree.getValue()[0]); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setVlaue (第二级文件1)", + handler() { + self.tree.setValue(["11"]); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/selecttree/demo.select_tree_combo.js b/packages/demo/src/demo/widget/selecttree/demo.select_tree_combo.js new file mode 100644 index 000000000..3fcaf900a --- /dev/null +++ b/packages/demo/src/demo/widget/selecttree/demo.select_tree_combo.js @@ -0,0 +1,55 @@ +import { CONSTANTS } from "@/config/constant"; +import { + HorizontalAutoLayout, + SelectTreeCombo, + Button, + Decorators, + Widget, + deepClone, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class SelectTreeComboDemo extends Widget { + static xtype = "demo.select_tree_combo"; + + props = { baseCls: "demo-exceltable" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.LEVELTREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: SelectTreeCombo.xtype, + ref(_ref) { + self.tree = _ref; + }, + value: "11", + text: "默认值", + items, + width: 300 + }, + { + type: Button.xtype, + text: "getVlaue", + handler() { + Msg.toast(self.tree.getValue()[0]); + }, + width: 300 + }, + { + type: Button.xtype, + text: "setVlaue (11)", + handler() { + self.tree.setValue(["2"]); + }, + width: 300 + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/selecttree/index.js b/packages/demo/src/demo/widget/selecttree/index.js new file mode 100644 index 000000000..a9bb935f3 --- /dev/null +++ b/packages/demo/src/demo/widget/selecttree/index.js @@ -0,0 +1,2 @@ +export * from "./demo.multilayer_select_tree_combo"; +export * from "./demo.select_tree_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/singleselct/demo.single_select_combo.js b/packages/demo/src/demo/widget/singleselct/demo.single_select_combo.js new file mode 100644 index 000000000..d4c9fc97f --- /dev/null +++ b/packages/demo/src/demo/widget/singleselct/demo.single_select_combo.js @@ -0,0 +1,107 @@ +import { CONSTANTS } from "@/config/constant"; + +import { SingleSelectCombo, AbsoluteLayout, Button, Decorators, Widget, Func, createWidget, bind, each, makeObject, filter, delay } from "@fui/core" + + +@Decorators.shortcut() +export class SingleSelectComboDemo extends Widget { + static xtype = "demo.single_select_combo"; + + props = { baseCls: "demo-single-select-combo" }; + + _createSingleSelectCombo() { + const self = this; + const widget = createWidget({ + type: SingleSelectCombo.xtype, + itemsCreator: bind(this._itemsCreator, this), + width: 200, + ref() { + self.SingleSelectCombo = this; + }, + value: "柳州市针织总厂", + }); + + widget.populate(); + + widget.on(SingleSelectCombo.EVENT_CONFIRM, function () { + Msg.toast(JSON.stringify(this.getValue())); + }); + + return widget; + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * 100; items[i] && i < times * 100; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * 100 < items.length; + } + + _itemsCreator(options, callback) { + const self = this; + let items = CONSTANTS.ITEMS; + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + items = search.match.concat(search.find); + }); + if (options.selectedValues) { + // 过滤 + const filterItems = makeObject(options.selectedValues, true); + items = filter(items, (i, ob) => !filterItems[ob.value]); + } + if (options.type == SingleSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items, + }); + + return; + } + if (options.type == SingleSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: items.length }); + + return; + } + delay(() => { + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times), + }); + }, 1000); + } + + render() { + const self = this; + + return { + type: AbsoluteLayout.xtype, + scrolly: false, + items: [ + { + el: this._createSingleSelectCombo(), + right: "50%", + top: 10, + }, + { + el: { + type: Button.xtype, + text: "setValue(\"柳州市针织总厂\")", + handler() { + self.SingleSelectCombo.setValue("柳州市针织总厂"); + }, + }, + } + ], + }; + } +} + diff --git a/packages/demo/src/demo/widget/singleselct/index.js b/packages/demo/src/demo/widget/singleselct/index.js new file mode 100644 index 000000000..8e8739954 --- /dev/null +++ b/packages/demo/src/demo/widget/singleselct/index.js @@ -0,0 +1 @@ +export * from "./demo.single_select_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/singletree/demo.multilayer_single_tree_combo.js b/packages/demo/src/demo/widget/singletree/demo.multilayer_single_tree_combo.js new file mode 100644 index 000000000..8f4bcd926 --- /dev/null +++ b/packages/demo/src/demo/widget/singletree/demo.multilayer_single_tree_combo.js @@ -0,0 +1,50 @@ +import { CONSTANTS } from "@/config/constant"; + +import { HorizontalAutoLayout, MultiLayerSingleTreeCombo, Button, Decorators, Widget, deepClone, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class MultiLayerSingleTreeComboDemo extends Widget { + static xtype = "demo.multilayer_single_tree_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.TREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: MultiLayerSingleTreeCombo.xtype, + ref(_ref) { + self.tree = _ref; + }, + defaultText: "请选择", + items, + width: 300, + }, + { + type: Button.xtype, + text: "getVlaue", + handler() { + Msg.toast(self.tree.getValue()[0]); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setVlaue (11)", + handler() { + self.tree.setValue(["11"]); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/singletree/demo.single_tree_combo.js b/packages/demo/src/demo/widget/singletree/demo.single_tree_combo.js new file mode 100644 index 000000000..932a4ffc9 --- /dev/null +++ b/packages/demo/src/demo/widget/singletree/demo.single_tree_combo.js @@ -0,0 +1,51 @@ +import { CONSTANTS } from "@/config/constant"; + +import { HorizontalAutoLayout, SingleTreeCombo, Button, Decorators, Widget, deepClone, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class SingleTreeComboDemo extends Widget { + static xtype = "demo.single_tree_combo"; + + props = { baseCls: "demo-exceltable" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.LEVELTREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: SingleTreeCombo.xtype, + ref(_ref) { + self.tree = _ref; + }, + defaultText: "请选择", + items, + width: 300, + value: "11", + }, + { + type: Button.xtype, + text: "getVlaue", + handler() { + Msg.toast(self.tree.getValue()[0]); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setVlaue (第二级文件1)", + handler() { + self.tree.setValue(["2"]); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/singletree/index.js b/packages/demo/src/demo/widget/singletree/index.js new file mode 100644 index 000000000..992531fa9 --- /dev/null +++ b/packages/demo/src/demo/widget/singletree/index.js @@ -0,0 +1,2 @@ +export * from "./demo.multilayer_single_tree_combo"; +export * from "./demo.single_tree_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/slider/demo.slider.js b/packages/demo/src/demo/widget/slider/demo.slider.js new file mode 100644 index 000000000..681f9f633 --- /dev/null +++ b/packages/demo/src/demo/widget/slider/demo.slider.js @@ -0,0 +1,142 @@ +import { + SingleSlider, + SingleSliderNormal, + SingleSliderLabel, + IntervalSlider, + VerticalLayout, + CenterAdaptLayout, + Decorators, + Widget, + createWidget +} from "@fui/core"; + +@Decorators.shortcut() +export class SliderDemo extends Widget { + static xtype = "demo.slider"; + + props = { + baseCls: "demo-slider", + width: 300, + height: 50, + min: 0, + max: 100 + }; + + render() { + const self = this, + o = this.options; + const singleSlider = createWidget({ + type: SingleSlider.xtype, + digit: 0, + width: o.width, + height: o.height, + cls: "layout-bg-white", + value: 30, + min: 10, + max: 100 + }); + singleSlider.on(SingleSlider.EVENT_CHANGE, function () { + console.log(this.getValue()); + }); + + const normalSingleSlider = createWidget({ + type: SingleSliderNormal.xtype, + width: o.width, + height: 30, + cls: "layout-bg-white", + min: o.min, + max: o.max, + value: 30 + }); + normalSingleSlider.on(SingleSliderNormal.EVENT_DRAG, function () { + console.log(this.getValue()); + }); + + const singleSliderLabel = createWidget({ + type: SingleSliderLabel.xtype, + width: o.width, + height: o.height, + digit: 0, + unit: "个", + cls: "layout-bg-white", + min: o.min, + max: o.max, + value: 10 + }); + + const intervalSlider = createWidget({ + type: IntervalSlider.xtype, + width: o.width, + digit: 0, + cls: "layout-bg-white", + min: o.min, + max: o.max, + value: { + min: 10, + max: 70 + } + }); + + const intervalSliderLabel = createWidget({ + type: IntervalSlider.xtype, + width: o.width, + unit: "px", + cls: "layout-bg-white", + digit: 1, + min: 0, + max: 120, + value: { + min: 60, + max: 120 + } + }); + + return { + type: VerticalLayout.xtype, + element: this, + items: [ + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: singleSlider + } + ] + }, + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: normalSingleSlider + } + ] + }, + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: singleSliderLabel + } + ] + }, + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: intervalSlider + } + ] + }, + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: intervalSliderLabel + } + ] + } + ], + vgap: 20 + }; + } +} diff --git a/packages/demo/src/demo/widget/slider/index.js b/packages/demo/src/demo/widget/slider/index.js new file mode 100644 index 000000000..462bc1ee8 --- /dev/null +++ b/packages/demo/src/demo/widget/slider/index.js @@ -0,0 +1 @@ +export * from "./demo.slider"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/timecombo/demo.timecombo.js b/packages/demo/src/demo/widget/timecombo/demo.timecombo.js new file mode 100644 index 000000000..6d795b00b --- /dev/null +++ b/packages/demo/src/demo/widget/timecombo/demo.timecombo.js @@ -0,0 +1,54 @@ + +import { HorizontalAutoLayout, TimeCombo, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class TimeComboDemo extends Widget { + static xtype = "demo.time_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: TimeCombo.xtype, + ref(_ref) { + self.timeCombo = _ref; + }, + // allowEdit: true, + // format: "%H:%M:%S", // HH:mm:ss + // format: "%I:%M:%S", // hh:mm:ss + // format: "%l:%M:%S", // h:mm:ss + // format: "%k:%M:%S", // H:mm:ss + // format: "%l:%M:%S %p", // h:mm:ss a + // format: "%l:%M", // h:mm + // format: "%k:%M", // H:mm + // format: "%I:%M", // hh:mm + // format: "%H:%M", // HH:mm + // format: "%M:%S", // mm:ss + value: { + hour: 12, + minute: 0, + second: 0, + }, + width: 300, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.timeCombo.getValue())); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/timecombo/index.js b/packages/demo/src/demo/widget/timecombo/index.js new file mode 100644 index 000000000..4a6bd372e --- /dev/null +++ b/packages/demo/src/demo/widget/timecombo/index.js @@ -0,0 +1 @@ +export * from "./demo.timecombo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/timeinterval/demo.time_interval.js b/packages/demo/src/demo/widget/timeinterval/demo.time_interval.js new file mode 100644 index 000000000..184f33173 --- /dev/null +++ b/packages/demo/src/demo/widget/timeinterval/demo.time_interval.js @@ -0,0 +1,115 @@ +import { CONSTANTS } from "@/config/constant"; + +import { HorizontalAutoLayout, DateInterval, Button, TimeInterval, TimePeriods, Decorators, Widget, deepClone, Msg } from "@fui/core" + + +@Decorators.shortcut() +export class TimeIntervalDemo extends Widget { + static xtype = "demo.time_interval"; + + props = { baseCls: "" }; + + render() { + const self = this; + const items = deepClone(CONSTANTS.TREE); + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: DateInterval.xtype, + ref(_ref) { + self.dateInterval = _ref; + }, + value: { + start: { + type: 2, + value: { + year: -1, + position: 2, + }, + }, + end: { + type: 1, + value: { + year: 2018, + month: 1, + day: 12, + }, + }, + }, + width: 300, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.dateInterval.getValue())); + }, + width: 300, + }, + { + type: TimeInterval.xtype, + ref(_ref) { + self.interval = _ref; + }, + value: { + start: { + type: 2, + value: { + year: -1, + position: 2, + }, + }, + end: { + type: 1, + value: { + year: 2018, + month: 1, + day: 12, + }, + }, + }, + width: 400, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.interval.getValue())); + }, + width: 300, + }, + { + type: TimePeriods.xtype, + value: { + start: { + hour: 7, + minute: 23, + second: 14, + }, + end: { + hour: 23, + minute: 34, + second: 32, + }, + }, + ref(_ref) { + self.periods = _ref; + }, + width: 180, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.periods.getValue())); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/timeinterval/index.js b/packages/demo/src/demo/widget/timeinterval/index.js new file mode 100644 index 000000000..76ce2e430 --- /dev/null +++ b/packages/demo/src/demo/widget/timeinterval/index.js @@ -0,0 +1 @@ +export * from "./demo.time_interval"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/tree/demo.multilayer_select_level_tree.js b/packages/demo/src/demo/widget/tree/demo.multilayer_select_level_tree.js new file mode 100644 index 000000000..b9d5b48de --- /dev/null +++ b/packages/demo/src/demo/widget/tree/demo.multilayer_select_level_tree.js @@ -0,0 +1,58 @@ +import { CONSTANTS } from "@/config/constant"; +import { + MultiLayerSelectLevelTree, + VTapeLayout, + Button, + Decorators, + Widget, + createWidget, + deepClone, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class MultiLayerSelectLevelTreeDemo extends Widget { + static xtype = "demo.multilayer_select_level_tree"; + + render() { + const self = this; + const tree = createWidget({ + type: MultiLayerSelectLevelTree.xtype, + items: deepClone(CONSTANTS.TREE), + value: "第五级文件1" + }); + + return { + type: VTapeLayout.xtype, + items: [ + { + el: tree + }, + { + el: { + type: Button.xtype, + height: 25, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(tree.getValue())); + } + }, + height: 25 + }, + { + el: { + type: Button.xtype, + height: 25, + text: "setValue (第二级文件1)", + handler() { + tree.setValue(["11"]); + } + }, + height: 25 + } + ], + width: 500, + hgap: 300 + }; + } +} diff --git a/packages/demo/src/demo/widget/tree/demo.multilayer_single_level_tree.js b/packages/demo/src/demo/widget/tree/demo.multilayer_single_level_tree.js new file mode 100644 index 000000000..3b1140430 --- /dev/null +++ b/packages/demo/src/demo/widget/tree/demo.multilayer_single_level_tree.js @@ -0,0 +1,77 @@ + +import { MultiLayerSingleLevelTree, VTapeLayout, Button, Decorators, Widget, createWidget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class MultiLayerSingleLevelTreeDemo extends Widget { + static xtype = "demo.multilayer_single_level_tree"; + + render() { + const self = this; + this.tree = createWidget({ + type: MultiLayerSingleLevelTree.xtype, + items: [], + value: "第二级文件1", + }); + + return { + type: VTapeLayout.xtype, + items: [ + { + el: this.tree, + }, + { + el: { + type: Button.xtype, + height: 25, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(self.tree.getValue())); + }, + }, + height: 25, + }, + { + el: { + type: Button.xtype, + height: 25, + text: "setValue (第二级文件1)", + handler() { + self.tree.setValue(["第二级文件1"]); + }, + }, + height: 25, + } + ], + width: 500, + hgap: 300, + }; + } + + mounted() { + const tree = [ + // {id: -2, pId: 0, value: "根目录1", text: "根目录1"}, + { id: -1, pId: 0, value: "根目录", text: "根目录" }, + { id: 1, pId: -1, value: "第一级目录1", text: "第一级目录1" }, + { id: 11, pId: 1, value: "第二级文件1", text: "第二级文件1" }, + { id: 12, pId: 1, value: "第二级目录2", text: "第二级目录2", disabled: true }, + { id: 121, pId: 12, value: "第三级目录1", text: "第三级目录1" }, + { id: 122, pId: 12, value: "第三级文件1", text: "第三级文件1" }, + { id: 1211, pId: 121, value: "第四级目录1", text: "第四级目录1" }, + { id: 2, pId: -1, value: "第一级目录2", text: "第一级目录2" }, + { id: 21, pId: 2, value: "第二级目录3", text: "第二级目录3" }, + { id: 22, pId: 2, value: "第二级文件2", text: "第二级文件2" }, + { id: 211, pId: 21, value: "第三级目录2", text: "第三级目录2" }, + { id: 212, pId: 21, value: "第三级文件2", text: "第三级文件2" }, + { id: 2111, pId: 211, value: "第四级文件1", text: "第四级文件1" }, + { id: 3, pId: -1, value: "第一级目录3", text: "第一级目录3" }, + { id: 31, pId: 3, value: "第二级文件2", text: "第二级文件2" }, + { id: 33, pId: 3, value: "第二级目录3", text: "第二级目录1" }, + { id: 32, pId: 3, value: "第二级文件3", text: "第二级文件3" }, + { id: 331, pId: 33, value: "第三级文件1", text: "第三级文件1" } + ]; + this.tree.populate(tree); + } +} + diff --git a/packages/demo/src/demo/widget/tree/demo.select_level_tree.js b/packages/demo/src/demo/widget/tree/demo.select_level_tree.js new file mode 100644 index 000000000..bc7b1f01c --- /dev/null +++ b/packages/demo/src/demo/widget/tree/demo.select_level_tree.js @@ -0,0 +1,58 @@ +import { CONSTANTS } from "@/config/constant"; +import { + SelectTreePopup, + VTapeLayout, + Button, + Decorators, + Widget, + createWidget, + deepClone, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class SelectLevelTreeDemo extends Widget { + static xtype = "demo.select_level_tree"; + + render() { + const self = this; + const tree = createWidget({ + type: SelectTreePopup.xtype, + items: deepClone(CONSTANTS.LEVELTREE), + value: "11" + }); + + return { + type: VTapeLayout.xtype, + items: [ + { + el: tree + }, + { + el: { + type: Button.xtype, + height: 25, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(tree.getValue())); + } + }, + height: 25 + }, + { + el: { + type: Button.xtype, + height: 25, + text: "setValue (第二级文件1)", + handler() { + tree.setValue(["2"]); + } + }, + height: 25 + } + ], + width: 500, + hgap: 300 + }; + } +} diff --git a/packages/demo/src/demo/widget/tree/demo.single_level_tree.js b/packages/demo/src/demo/widget/tree/demo.single_level_tree.js new file mode 100644 index 000000000..8014ac46e --- /dev/null +++ b/packages/demo/src/demo/widget/tree/demo.single_level_tree.js @@ -0,0 +1,58 @@ +import { CONSTANTS } from "../../../config/constant"; +import { + SingleTreePopup, + VTapeLayout, + Button, + Decorators, + Widget, + createWidget, + deepClone, + Msg +} from "@fui/core"; + +@Decorators.shortcut() +export class SingleLevelTreeDemo extends Widget { + static xtype = "demo.single_level_tree"; + + render() { + const self = this; + const tree = createWidget({ + type: SingleTreePopup.xtype, + items: deepClone(CONSTANTS.LEVELTREE), + value: "11" + }); + + return { + type: VTapeLayout.xtype, + items: [ + { + el: tree + }, + { + el: { + type: Button.xtype, + height: 25, + text: "getValue", + handler() { + Msg.alert("", JSON.stringify(tree.getValue())); + } + }, + height: 25 + }, + { + el: { + type: Button.xtype, + height: 25, + text: "setValue (第二级文件1)", + handler() { + tree.setValue(["2"]); + } + }, + height: 25 + } + ], + width: 500, + hgap: 300 + }; + } +} diff --git a/packages/demo/src/demo/widget/tree/index.js b/packages/demo/src/demo/widget/tree/index.js new file mode 100644 index 000000000..f4880f1e6 --- /dev/null +++ b/packages/demo/src/demo/widget/tree/index.js @@ -0,0 +1,4 @@ +export * from "./demo.multilayer_select_level_tree"; +export * from "./demo.multilayer_single_level_tree"; +export * from "./demo.select_level_tree"; +export * from "./demo.single_level_tree"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/year/demo.year.js b/packages/demo/src/demo/widget/year/demo.year.js new file mode 100644 index 000000000..d4dc87658 --- /dev/null +++ b/packages/demo/src/demo/widget/year/demo.year.js @@ -0,0 +1,53 @@ + +import { HorizontalAutoLayout, DynamicYearCombo, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearDemo extends Widget { + static xtype = "demo.year"; + + props = { baseCls: "demo-exceltable" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + vgap: 10, + items: [ + { + type: DynamicYearCombo.xtype, + width: 300, + ref() { + self.yearcombo = this; + }, + value: { + type: 1, + value: { + year: 2017, + }, + }, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.yearcombo.getValue())); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setValue : 2018", + handler() { + self.yearcombo.setValue(2018); + }, + width: 300, + } + ], + vgap: 10, + }; + } +} + diff --git a/packages/demo/src/demo/widget/year/index.js b/packages/demo/src/demo/widget/year/index.js new file mode 100644 index 000000000..3014c849c --- /dev/null +++ b/packages/demo/src/demo/widget/year/index.js @@ -0,0 +1 @@ +export * from "./demo.year"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/yearinterval/demo.year_interval.js b/packages/demo/src/demo/widget/yearinterval/demo.year_interval.js new file mode 100644 index 000000000..4899bb8f4 --- /dev/null +++ b/packages/demo/src/demo/widget/yearinterval/demo.year_interval.js @@ -0,0 +1,56 @@ + +import { HorizontalAutoLayout, YearInterval, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearIntervalDemo extends Widget { + static xtype = "demo.year_interval"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: YearInterval.xtype, + ref(_ref) { + self.widget = _ref; + }, + width: 300, + minDate: "2012-01-01", + maxDate: "2013-12-31", + value: { + type: 1, + value: { + year: 2012, + }, + }, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.widget.getValue())); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setValue '2017-12'", + width: 300, + handler() { + self.widget.setValue({ + year: 2017, + }); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/yearinterval/index.js b/packages/demo/src/demo/widget/yearinterval/index.js new file mode 100644 index 000000000..7fb068008 --- /dev/null +++ b/packages/demo/src/demo/widget/yearinterval/index.js @@ -0,0 +1 @@ +export * from "./demo.year_interval"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/yearmonth/demo.year_month_combo.js b/packages/demo/src/demo/widget/yearmonth/demo.year_month_combo.js new file mode 100644 index 000000000..86fd00651 --- /dev/null +++ b/packages/demo/src/demo/widget/yearmonth/demo.year_month_combo.js @@ -0,0 +1,56 @@ + +import { HorizontalAutoLayout, DynamicYearMonthCombo, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearMonthComboDemo extends Widget { + static xtype = "demo.year_month_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: DynamicYearMonthCombo.xtype, + ref(_ref) { + self.widget = _ref; + }, + width: 300, + // value: { + // type: 1, + // value: { + // year: 2018, + // month: 1 + // } + // } + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.widget.getValue())); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setValue '2017-12'", + width: 300, + handler() { + self.widget.setValue({ + year: 2017, + month: 12, + }); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/yearmonth/index.js b/packages/demo/src/demo/widget/yearmonth/index.js new file mode 100644 index 000000000..9a7f8343d --- /dev/null +++ b/packages/demo/src/demo/widget/yearmonth/index.js @@ -0,0 +1 @@ +export * from "./demo.year_month_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/yearmonthinterval/demo.year_month_interval.js b/packages/demo/src/demo/widget/yearmonthinterval/demo.year_month_interval.js new file mode 100644 index 000000000..014c80565 --- /dev/null +++ b/packages/demo/src/demo/widget/yearmonthinterval/demo.year_month_interval.js @@ -0,0 +1,54 @@ + +import { HorizontalAutoLayout, YearMonthInterval, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearMonthIntervalDemo extends Widget { + static xtype = "demo.year_month_interval"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: YearMonthInterval.xtype, + ref(_ref) { + self.interval = _ref; + }, + value: { + start: { + type: 2, + value: { + year: -1, + month: 1, + }, + }, + end: { + type: 1, + value: { + year: 2018, + month: 1, + }, + }, + }, + width: 400, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.interval.getValue())); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/yearmonthinterval/index.js b/packages/demo/src/demo/widget/yearmonthinterval/index.js new file mode 100644 index 000000000..13b3e3eeb --- /dev/null +++ b/packages/demo/src/demo/widget/yearmonthinterval/index.js @@ -0,0 +1 @@ +export * from "./demo.year_month_interval"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/yearquarter/demo.year_quarter_combo.js b/packages/demo/src/demo/widget/yearquarter/demo.year_quarter_combo.js new file mode 100644 index 000000000..c3cef10d5 --- /dev/null +++ b/packages/demo/src/demo/widget/yearquarter/demo.year_quarter_combo.js @@ -0,0 +1,58 @@ + +import { HorizontalAutoLayout, DynamicYearQuarterCombo, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearQuarterComboDemo extends Widget { + static xtype = "demo.year_quarter_combo"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: DynamicYearQuarterCombo.xtype, + width: 300, + ref(_ref) { + self.widget = _ref; + }, + yearBehaviors: {}, + quarterBehaviors: {}, + value: { + type: 1, + value: { + year: 2018, + quarter: 1, + }, + }, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.widget.getValue())); + }, + width: 300, + }, + { + type: Button.xtype, + text: "setVlaue '2017 季度3'", + width: 300, + handler() { + self.widget.setValue({ + year: 2017, + quarter: 3, + }); + }, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/yearquarter/index.js b/packages/demo/src/demo/widget/yearquarter/index.js new file mode 100644 index 000000000..53d2ff1bf --- /dev/null +++ b/packages/demo/src/demo/widget/yearquarter/index.js @@ -0,0 +1 @@ +export * from "./demo.year_quarter_combo"; \ No newline at end of file diff --git a/packages/demo/src/demo/widget/yearquarterinterval/demo.yearquarterinterval.js b/packages/demo/src/demo/widget/yearquarterinterval/demo.yearquarterinterval.js new file mode 100644 index 000000000..f21b2acc8 --- /dev/null +++ b/packages/demo/src/demo/widget/yearquarterinterval/demo.yearquarterinterval.js @@ -0,0 +1,56 @@ + +import { HorizontalAutoLayout, YearQuarterInterval, Button, Decorators, Widget, Msg } from "@fui/core" + + + +@Decorators.shortcut() +export class YearQuarterIntervalDemo extends Widget { + static xtype = "demo.year_quarter_interval"; + + props = { baseCls: "" }; + + render() { + const self = this; + + return { + type: HorizontalAutoLayout.xtype, + items: [ + { + type: YearQuarterInterval.xtype, + ref(_ref) { + self.interval = _ref; + }, + minDate: "2012-07-01", + maxDate: "2012-12-31", + value: { + start: { + type: 2, + value: { + year: -1, + month: 1, + }, + }, + end: { + type: 1, + value: { + year: 2018, + month: 1, + }, + }, + }, + width: 400, + }, + { + type: Button.xtype, + text: "getValue", + handler() { + Msg.toast(JSON.stringify(self.interval.getValue())); + }, + width: 300, + } + ], + vgap: 20, + }; + } +} + diff --git a/packages/demo/src/demo/widget/yearquarterinterval/index.js b/packages/demo/src/demo/widget/yearquarterinterval/index.js new file mode 100644 index 000000000..36d6ee029 --- /dev/null +++ b/packages/demo/src/demo/widget/yearquarterinterval/index.js @@ -0,0 +1 @@ +export * from "./demo.yearquarterinterval"; \ No newline at end of file diff --git a/packages/demo/src/face.js b/packages/demo/src/face.js new file mode 100644 index 000000000..31be872f6 --- /dev/null +++ b/packages/demo/src/face.js @@ -0,0 +1,877 @@ +import { + Widget, + Label, + Decorators, + each, + Msg, + StyleLoaders, + ColorChooser, + VerticalAdaptLayout, + HTapeLayout, + TextButton, + IconTextItem, + VerticalLayout, + Button, + DownListCombo, + IconTextIconItem, + GridLayout, + Layout, + Fix, +} from "@fui/core"; + +@Decorators.shortcut() +export class Face extends Widget { + static xtype = "demo.face"; + + props = { + baseCls: "demo-face", + }; + + _createLabel(text) { + return { + width: 200, + el: { + type: Label.xtyp, + text: text, + textAlign: "left", + hgap: 5, + height: 40, + cls: "config-label", + }, + }; + } + + _createColorPicker(ref, action) { + return { + el: { + type: VerticalAdaptLayout.xtype, + items: [ + { + type: ColorChooser.xtype, + listeners: [ + { + eventName: ColorChooser.EVENT_CHANGE, + action: action, + }, + ], + ref: ref, + width: 24, + height: 24, + }, + ], + }, + }; + } + + _createBackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("背景色:"), + this._createColorPicker( + function() { + self.backgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createFontConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("字体颜色:"), + this._createColorPicker( + function() { + self.fontColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createActiveFontConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("激活状态字体颜色:"), + this._createColorPicker( + function() { + self.activeFontColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + cls: "bi-list-item-active", + text: "测试激活状态", + }, + }, + ], + }; + } + + _createSelectFontConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("选中状态字体颜色:"), + this._createColorPicker( + function() { + self.selectFontColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + cls: "bi-list-item-active", + text: "测试选中状态", + }, + }, + ], + }; + } + + _createGrayFontConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("tip提示字体颜色:"), + this._createColorPicker( + function() { + self.grayFontColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: IconTextItem.xtype, + cls: "bi-tips copy-font", + height: 40, + text: "测试提示文字", + }, + }, + ], + }; + } + + _createDisableFontConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("灰化字体颜色:"), + this._createColorPicker( + function() { + self.disabledFontColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + text: "这个按钮是灰化的", + disabled: true, + }, + }, + ], + }; + } + + _createCardBackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("Card背景颜色:"), + this._createColorPicker( + function() { + self.cardBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createHoverBackgroundColor() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("悬浮状态背景颜色:"), + this._createColorPicker( + function() { + self.hoverBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + cls: "bi-list-item-active", + text: "测试悬浮状态", + }, + }, + ], + }; + } + + _createActiveBackgroundColor() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("激活状态背景颜色:"), + this._createColorPicker( + function() { + self.activeBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + cls: "bi-list-item-active", + text: "测试激活状态", + }, + }, + ], + }; + } + + _createSelectBackgroundColor() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("选中状态背景颜色:"), + this._createColorPicker( + function() { + self.selectBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: TextButton.xtype, + cls: "bi-list-item-active", + text: "测试选中状态", + }, + }, + ], + }; + } + + _createSlitColor() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("分割线颜色:"), + this._createColorPicker( + function() { + self.slitColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createBaseConfig() { + return { + type: VerticalLayout.xtype, + items: [ + this._createLabel("--通用配色--"), + this._createBackgroundConfig(), + this._createCardBackgroundConfig(), + this._createFontConfig(), + this._createActiveFontConfig(), + this._createSelectFontConfig(), + this._createGrayFontConfig(), + this._createDisableFontConfig(), + this._createHoverBackgroundColor(), + this._createActiveBackgroundColor(), + this._createSelectBackgroundColor(), + this._createSlitColor(), + ], + }; + } + + _createButton1BackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("按钮背景色1:"), + this._createColorPicker( + function() { + self.button1BackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + height: 40, + items: [ + { + type: Button.xtype, + cls: "config-button1", + text: "测试按钮", + }, + ], + }, + }, + ], + }; + } + + _createButton2BackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("按钮背景色2:"), + this._createColorPicker( + function() { + self.button2BackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + height: 40, + items: [ + { + type: Button.xtype, + level: "success", + cls: "config-button2", + text: "测试按钮", + }, + ], + }, + }, + ], + }; + } + + _createButton3BackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("按钮背景色3:"), + this._createColorPicker( + function() { + self.button3BackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + height: 40, + items: [ + { + type: Button.xtype, + level: "warning", + cls: "config-button3", + text: "测试按钮", + }, + ], + }, + }, + ], + }; + } + + _createButton4BackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("按钮背景色4:"), + this._createColorPicker( + function() { + self.button4BackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + height: 40, + items: [ + { + type: Button.xtype, + level: "ignore", + cls: "config-button4", + text: "测试按钮", + }, + ], + }, + }, + ], + }; + } + + _createScrollBackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("滚动条底色:"), + this._createColorPicker( + function() { + self.scrollBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createScrollThumbConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("滚动条thumb颜色:"), + this._createColorPicker( + function() { + self.scrollThumbColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + ], + }; + } + + _createPopupBackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("下拉框背景颜色:"), + this._createColorPicker( + function() { + self.popupBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + items: [ + { + type: DownListCombo.xtype, + items: [ + [ + { + el: { + text: "column 1111", + iconCls1: "check-mark-e-font", + value: 11, + }, + children: [ + { + text: "column 1.1", + value: 21, + cls: "dot-e-font", + selected: true, + }, + { + text: "column 1.222222222222222222222222222222222222", + cls: "dot-e-font", + value: 22, + }, + { + text: "column 1.3", + cls: "dot-e-font", + value: 23, + }, + { + text: "column 1.4", + cls: "dot-e-font", + value: 24, + }, + { + text: "column 1.5", + cls: "dot-e-font", + value: 25, + }, + ], + }, + ], + [ + { + el: { + type: IconTextIconItem.xtype, + text: "column 2", + iconCls1: "chart-type-e-font", + cls: "dot-e-font", + value: 12, + }, + disabled: true, + children: [ + { + type: IconTextItem.xtype, + cls: "dot-e-font", + height: 25, + text: "column 2.1", + value: 11, + }, + { text: "column 2.2", value: 12, cls: "dot-e-font" }, + ], + }, + ], + [ + { + text: "column 33333333333333333333333333333333", + cls: "style-set-e-font", + value: 13, + }, + ], + [ + { + text: "column 4", + cls: "filter-e-font", + value: 14, + }, + ], + [ + { + text: "column 5", + cls: "copy-e-font", + value: 15, + }, + ], + [ + { + text: "column 6", + cls: "delete-e-font", + value: 16, + }, + ], + [ + { + text: "column 7", + cls: "dimension-from-e-font", + value: 17, + disabled: true, + }, + ], + ], + }, + ], + }, + }, + ], + }; + } + + _createMaskBackgroundConfig() { + var self = this; + return { + type: HTapeLayout.xtype, + cls: "config-item bi-border-bottom", + height: 40, + items: [ + this._createLabel("弹出层蒙版颜色:"), + this._createColorPicker( + function() { + self.maskBackgroundColor = this; + }, + function() { + self._runGlobalStyle(); + } + ), + { + width: 100, + el: { + type: VerticalAdaptLayout.xtype, + items: [ + { + type: Button.xtype, + text: "mask测试", + handler() { + Msg.alert("弹出层", "弹出层面板"); + }, + }, + ], + }, + }, + ], + }; + } + + _createCommonConfig() { + return { + type: VerticalLayout.xtype, + items: [ + this._createLabel("--一般配色--"), + this._createButton1BackgroundConfig(), + this._createButton2BackgroundConfig(), + this._createButton3BackgroundConfig(), + this._createButton4BackgroundConfig(), + this._createScrollBackgroundConfig(), + this._createScrollThumbConfig(), + this._createPopupBackgroundConfig(), + this._createMaskBackgroundConfig(), + ], + }; + } + + render() { + var self = this; + return { + type: GridLayout.xtype, + items: [ + [ + { + el: { + type: VerticalLayout.xtype, + cls: "face-config bi-border-right", + items: [this._createBaseConfig(), this._createCommonConfig()], + }, + }, + { + el: { + type: Layout.xtype, + }, + }, + ], + ], + }; + } + + _setStyle(objects) { + var result = ""; + each(objects, function(cls, object) { + result += cls + "{"; + each(object, function(name, value) { + result += name + ":" + value + ";"; + }); + result += "} "; + }); + StyleLoaders.removeStyle("style").loadStyle("style", result); + } + + _runGlobalStyle() { + var backgroundColor = this.backgroundColor.getValue(); + var fontColor = this.fontColor.getValue(); + var activeFontColor = this.activeFontColor.getValue(); + var selectFontColor = this.selectFontColor.getValue(); + var grayFontColor = this.grayFontColor.getValue(); + var disabledFontColor = this.disabledFontColor.getValue(); + var cardBackgroundColor = this.cardBackgroundColor.getValue(); + var hoverBackgroundColor = this.hoverBackgroundColor.getValue(); + var activeBackgroundColor = this.activeBackgroundColor.getValue(); + var selectBackgroundColor = this.selectBackgroundColor.getValue(); + var slitColor = this.slitColor.getValue(); + + var button1BackgroundColor = this.button1BackgroundColor.getValue(); + var button2BackgroundColor = this.button2BackgroundColor.getValue(); + var button3BackgroundColor = this.button3BackgroundColor.getValue(); + var button4BackgroundColor = this.button4BackgroundColor.getValue(); + var scrollBackgroundColor = this.scrollBackgroundColor.getValue(); + var scrollThumbColor = this.scrollThumbColor.getValue(); + var popupBackgroundColor = this.popupBackgroundColor.getValue(); + var maskBackgroundColor = this.maskBackgroundColor.getValue(); + + this._setStyle({ + "body.bi-background, body .bi-background": { + "background-color": backgroundColor, + color: fontColor, + }, + "body .bi-card": { + "background-color": cardBackgroundColor, + color: fontColor, + }, + "body .bi-tips": { + color: grayFontColor, + }, + "div::-webkit-scrollbar,.scrollbar-layout-main": { + "background-color": scrollBackgroundColor + "!important", + }, + "div::-webkit-scrollbar-thumb,.public-scrollbar-face:after": { + "background-color": scrollThumbColor + "!important", + }, + ".base-disabled": { + color: disabledFontColor + "!important", + }, + ".base-disabled .b-font:before": { + color: disabledFontColor + "!important", + }, + ".list-view-outer": { + "background-color": popupBackgroundColor + "!important", + }, + ".bi-z-index-mask": { + "background-color": maskBackgroundColor + "!important", + }, + ".bi-list-item:hover,.bi-list-item-hover:hover,.bi-list-item-active:hover,.bi-list-item-select:hover,.bi-list-item-effect:hover": + { + "background-color": hoverBackgroundColor + "!important", + }, + ".bi-list-item-active:active,.bi-list-item-select:active,.bi-list-item-effect:active": { + "background-color": activeBackgroundColor + "!important", + color: activeFontColor + "!important", + }, + ".bi-list-item-active.active,.bi-list-item-select.active,.bi-list-item-effect.active": { + "background-color": selectBackgroundColor + "!important", + color: selectFontColor + "!important", + }, + "body .bi-button.button-common": { + "background-color": button1BackgroundColor, + "border-color": button1BackgroundColor, + }, + "body .bi-button.button-success": { + "background-color": button2BackgroundColor, + "border-color": button2BackgroundColor, + }, + "body .bi-button.button-warning": { + "background-color": button3BackgroundColor, + "border-color": button3BackgroundColor, + }, + "body .bi-button.button-ignore": { + "background-color": button4BackgroundColor, + }, + // 以下是分割线颜色 + "body .bi-border,body .bi-border-top,#wrapper .bi-border-bottom,body .bi-border-left,body .bi-border-right": + { + "border-color": slitColor, + }, + ".bi-collection-table-cell": { + "border-right-color": slitColor, + "border-bottom-color": slitColor, + }, + ".bi-collection-table-cell.first-col": { + "border-left-color": slitColor, + }, + ".bi-collection-table-cell.first-row": { + "border-top-color": slitColor, + }, + }); + } + + mounted() { + this.backgroundColor.setValue(""); + this.fontColor.setValue(""); + this.activeFontColor.setValue(""); + this.selectFontColor.setValue(""); + this.grayFontColor.setValue(""); + this.disabledFontColor.setValue(""); + this.cardBackgroundColor.setValue(""); + this.hoverBackgroundColor.setValue(""); + this.activeBackgroundColor.setValue(""); + this.selectBackgroundColor.setValue(""); + + this.button1BackgroundColor.setValue(""); + this.button2BackgroundColor.setValue(""); + this.button3BackgroundColor.setValue(""); + this.button4BackgroundColor.setValue(""); + this.scrollBackgroundColor.setValue(""); + this.scrollThumbColor.setValue(""); + this.popupBackgroundColor.setValue(""); + this.maskBackgroundColor.setValue(""); + this.slitColor.setValue(""); + this._runGlobalStyle(); + } +} diff --git a/packages/demo/src/index.js b/packages/demo/src/index.js new file mode 100644 index 000000000..056a80be8 --- /dev/null +++ b/packages/demo/src/index.js @@ -0,0 +1,34 @@ +import './less/index.less'; +import '../i18n/i18n.cn'; +import { createWidget, Layout, RouterWidget } from '@fui/core'; +import { Main } from './main'; +import { RouterDemo } from './center'; + +createWidget({ + type: RouterWidget.xtype, + routes: [ + { + path: '/', + component: function () { + return Promise.resolve({ + type: Layout.xtype, + }); + }, + }, + { + name: 'component', + path: '/component/:componentId', + component() { + return Promise.resolve({ + type: RouterDemo.xtype, + }); + }, + }, + ], + render() { + return { + type: Main.xtype, + element: '#wrapper', + }; + }, +}); diff --git a/packages/demo/src/less/face.less b/packages/demo/src/less/face.less new file mode 100644 index 000000000..041cd31ba --- /dev/null +++ b/packages/demo/src/less/face.less @@ -0,0 +1,11 @@ +@import "fineui.less"; + +.demo-face { + .face-config { + .config-label { + font-size: 1.4rem; + } + .config-item { + } + } +} \ No newline at end of file diff --git a/packages/demo/src/less/fineui.less b/packages/demo/src/less/fineui.less new file mode 100644 index 000000000..77a935b79 --- /dev/null +++ b/packages/demo/src/less/fineui.less @@ -0,0 +1 @@ +@import "../../node_modules/@fui/core/src/less/index.less"; \ No newline at end of file diff --git a/packages/demo/src/less/index.less b/packages/demo/src/less/index.less new file mode 100644 index 000000000..d9e864713 --- /dev/null +++ b/packages/demo/src/less/index.less @@ -0,0 +1,7 @@ +@import "./face.less"; +@import "./index.less"; +@import "./main.less"; +@import "./north.less"; +@import "./preview.less"; +@import "./vm.less"; +@import "./west.less"; diff --git a/packages/demo/src/less/main.less b/packages/demo/src/less/main.less new file mode 100644 index 000000000..ff1f415de --- /dev/null +++ b/packages/demo/src/less/main.less @@ -0,0 +1,103 @@ +@import "fineui.less"; + +.layout-bg-white { + background-color: #ffffff; +} + +.layout-bg-gray { + background-color: #eeeeee; +} + +.layout-bg1 { + color: #ffffff; + background-color: #0088cc; +} + +.layout-bg2 { + color: #ffffff; + background-color: #008B8B; +} + +.layout-bg3 { + color: #ffffff; + background-color: #6495ED; +} + +.layout-bg4 { + color: #ffffff; + background-color: #ff69b4; +} + +.layout-bg5 { + color: #ffffff; + background-color: #B8860B; +} + +.layout-bg6 { + color: #ffffff; + background-color: #d9534f; +} + +.layout-bg7 { + color: #ffffff; + background-color: #ea4738; +} + +.layout-bg8 { + color: #ffffff; + background-color: #6495ed; +} + +.demo-main { + & .bg1 { + background-color: #178cdf; + } +} + +body { + background-color: @color-bi-background-normal; +} + +#wrapper { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + font-size: 1.2rem; +} + +.bi-theme-dark body { + background-color: @color-bi-background-normal-theme-dark; +} + +.demo-editor { + border: 1px solid rgb(204, 204, 204); +} + +.demo-clolor { + color: #1a1a1a; +} + +.bi-progress-bar-processor { + transition: all 0.5s ease; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + background: #3f8ce8; + border-radius: 2rem; + overflow: hidden; + overflow-x: hidden; + overflow-y: hidden; +} + +.bi-progress-text-bar-processor { + transition: all 0.5s ease; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; +} + +.bi-progress-bar-bar { + border-radius: 2rem; +} diff --git a/packages/demo/src/less/north.less b/packages/demo/src/less/north.less new file mode 100644 index 000000000..f174587dd --- /dev/null +++ b/packages/demo/src/less/north.less @@ -0,0 +1,12 @@ +@import "fineui.less"; + +.demo-north { + background-color: #3c8dbc; + & .logo { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color: @color-bi-text; + background-color: #367fa9; + font-size: 2rem; + font-weight: 300; + } +} \ No newline at end of file diff --git a/packages/demo/src/less/preview.less b/packages/demo/src/less/preview.less new file mode 100644 index 000000000..ac267e5a2 --- /dev/null +++ b/packages/demo/src/less/preview.less @@ -0,0 +1,8 @@ +@import "fineui.less"; + +.demo-preview { +} + +#wrapper { + font-size: 12px; +} \ No newline at end of file diff --git a/packages/demo/src/less/vm.less b/packages/demo/src/less/vm.less new file mode 100644 index 000000000..d962e2cc0 --- /dev/null +++ b/packages/demo/src/less/vm.less @@ -0,0 +1,123 @@ +@import "fineui.less"; + +.mvc-button { + &:hover, &.hover { + .opacity(0.5); + } + &.active, &:active { + .opacity(0.5) + } +} + +.bi-set-get { + & .left-title, & .right-title { + background: #0088cc; + color: #ffffff; + } + & .left-nav { + border-bottom: 1px solid #cccccc; + &.active, &:active { + color: #ffffff; + background-color: #d9534f; + } + } +} + +.bi-local { + & .top-button { + background-color: #448eea; + color: #ffffff + } + & .bottom-label { + background-color: #EA4738; + color: #ffffff; + } + & .delete-button { + background-color: #008B8B; + color: #ffffff; + } + & .vessel-border { + border-left: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; + border-right: 1px solid #cccccc; + } +} + +.bi-event { + & .title { + background: #0088cc; + color: #ffffff; + } + & .front { + background: #ADD8E6; + } + & .nav { + border: 1px solid #cccccc; + } +} + +.bi-skip-to { + color: #ffffff; + + & .red-pane { + background-color: #0088cc; + } + & .blue-pane { + background-color: #6495ED; + } + & .green-pane { + background-color: #008B8B; + } + & .yellow-pane { + background-color: #B8860B; + } +} + +.bi-change { + & .outer-text { + background-color: #0088cc; + color: #ffffff; + } + & .inner { + border-left: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; + border-right: 1px solid #cccccc; + } + + & .type-first { + background-color: #008B8B; + } + + & .type-second { + background-color: #6495ED; + } + + & .type-third { + background-color: #0088cc; + } +} + +.bi-tmp { + & .tmp-button { + color: #ffffff; + background: #0088cc; + } +} + +.bi-splice-duplicate { + & .superiors-label { + color: white; + background-color: #008B8B; + } + & .sd-child { + border: 1px solid #cccccc; + & .right-button-add { + color: white; + background-color: #0088cc; + } + & .right-button-del { + color: white; + background-color: #d9534f; + } + } +} \ No newline at end of file diff --git a/packages/demo/src/less/west.less b/packages/demo/src/less/west.less new file mode 100644 index 000000000..920fbc8b8 --- /dev/null +++ b/packages/demo/src/less/west.less @@ -0,0 +1,4 @@ +@import "fineui.less"; + +.demo-west { +} diff --git a/packages/demo/src/main.js b/packages/demo/src/main.js new file mode 100644 index 000000000..a3f8dcccb --- /dev/null +++ b/packages/demo/src/main.js @@ -0,0 +1,36 @@ +import { Decorators, Widget, BorderLayout } from "@fui/core"; +import { West } from "./west"; +import { Center } from "./center"; +import { North } from "./north"; + +@Decorators.shortcut() +export class Main extends Widget { + static xtype = "demo.main"; + + props = { baseCls: "demo-main bi-background" }; + + render() { + return { + type: BorderLayout.xtype, + items: { + north: { + height: 50, + el: { + type: North, + }, + }, + west: { + width: 230, + el: { + type: West.xtype, + }, + }, + center: { + el: { + type: Center.xtype, + }, + }, + }, + }; + } +} diff --git a/packages/demo/src/north.js b/packages/demo/src/north.js new file mode 100644 index 000000000..562dbe313 --- /dev/null +++ b/packages/demo/src/north.js @@ -0,0 +1,66 @@ +import { Widget, Button, $, HTapeLayout, TextButton, FloatRightLayout, } from "@fui/core"; + +export class North extends Widget { + static xtype = "demo.north"; + static EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; + + props = { + baseCls: "demo-north" + }; + + render() { + var self = this; + return { + type: HTapeLayout.xtype, + items: [ + { + width: 230, + el: { + type: TextButton.xtype, + listeners: [ + { + eventName: Button.EVENT_CHANGE, + action: function () { + // self.fireEvent( + // Demo.North.EVENT_VALUE_CHANGE, + // "" + // ); + } + } + ], + cls: "logo", + height: 50, + text: "FineUI2.0" + } + }, + { + el: { + type: FloatRightLayout.xtype, + hgap: 10, + items: [ + { + type: TextButton.xtype, + text: "星空蓝", + handler: function () { + $("html") + .removeClass(undefined.xtype) + .addClass(undefined.xtype); + } + }, + { + type: TextButton.xtype, + text: "典雅白", + handler: function () { + $("html") + .removeClass(undefined.xtype) + .addClass(undefined.xtype); + } + } + ] + } + } + ] + }; + } +} + diff --git a/packages/demo/src/west.js b/packages/demo/src/west.js new file mode 100644 index 000000000..f4ad12737 --- /dev/null +++ b/packages/demo/src/west.js @@ -0,0 +1,101 @@ +import { + Widget, + Decorators, + VTapeLayout, + CenterAdaptLayout, + Searcher, + SearchEditor, + Func, + concat, + each, + Router, + MultiLayerSingleLevelTree, +} from '@fui/core'; +import { demoConfig } from './config'; + +@Decorators.shortcut() +export class West extends Widget { + static xtype = 'demo.west'; + static EVENT_VALUE_CHANGE = 'EVENT_VALUE_CHANGE'; + + props = { + baseCls: 'demo-west bi-border-right bi-card', + }; + + mounted() { + this.searcher.setAdapter(this.tree); + } + + render() { + var self = this; + + // var selectedId = BI.Router.$router.currentRoute.params?.componentId; + + return { + type: VTapeLayout.xtype, + items: [ + { + type: CenterAdaptLayout.xtype, + items: [ + { + type: Searcher.xtype, + el: { + type: SearchEditor.xtype, + watermark: '简单搜索', + }, + width: 200, + isAutoSearch: false, + isAutoSync: false, + ref: function (ref) { + self.searcher = ref; + }, + popup: { + type: MultiLayerSingleLevelTree.xtype, + cls: 'bi-card', + listeners: [ + { + eventName: MultiLayerSingleLevelTree.EVENT_CHANGE, + action: function (v) {}, + }, + ], + }, + onSearch: function (op, callback) { + var result = Func.getSearchResult(Demo.CONFIG, op.keyword, 'text'); + var items = concat(result.match, result.find); + var children = []; + each(items, function (index, item) { + var childList = Func.getSearchResult(Demo.CONFIG, item.id, 'pId'); + each(childList.match, function (index, child) { + if (child.value) { + children.push(child); + } + }); + }); + items = concat(items, children); + callback(items); + }, + }, + ], + height: 40, + }, + { + type: MultiLayerSingleLevelTree.xtype, + listeners: [ + { + eventName: MultiLayerSingleLevelTree.EVENT_CHANGE, + action: function (v) { + Router.$router.push({ + name: 'component', + params: { + componentId: v, + }, + }); + }, + }, + ], + items: demoConfig, + }, + ], + }; + } +} diff --git a/packages/demo/webpack.dev.js b/packages/demo/webpack.dev.js new file mode 100644 index 000000000..4a3743bf1 --- /dev/null +++ b/packages/demo/webpack.dev.js @@ -0,0 +1,38 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const path = require('path'); + +module.exports = { + mode: 'development', + entry: './src/index.js', + devServer: { + port: 3000, + liveReload: true, + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + }, + }, + { + test: /\.less$/i, + use: ['style-loader', 'css-loader', 'less-loader'], + }, + ], + }, + devtool: 'source-map', + resolve: { + extensions: ['.js', '.ts'], + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + plugins: [ + new HtmlWebpackPlugin({ + template: 'index.html', + }), + ], +}; diff --git a/packages/demo/webpack.prod.js b/packages/demo/webpack.prod.js new file mode 100644 index 000000000..20bc06a53 --- /dev/null +++ b/packages/demo/webpack.prod.js @@ -0,0 +1,58 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const path = require('path'); +const TerserPlugin = require("terser-webpack-plugin"); +const webpack = require("webpack"); +const childProcess = require("child_process"); + +function git(command) { + return childProcess.execSync(`git ${command}`).toString().trim(); +} + +module.exports = { + mode: 'production', + entry: { + "demo.min": './src/index.js' + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + }, + }, + { + test: /\.less$/i, + use: ['style-loader', 'css-loader', 'less-loader'], + }, + ], + }, + devtool: 'source-map', + resolve: { + extensions: ['.js', '.ts'], + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + optimization: { + usedExports: false, + minimize: true, + minimizer: [ + new TerserPlugin({ + include: /\.min/, + parallel: true, + terserOptions: { + output: { + comments: false, + }, + }, + }), + new webpack.BannerPlugin({ + banner: `time: ${new Date().toLocaleString("en-US")}; branch: ${git( + "name-rev --name-only HEAD" + )} commit: ${git("rev-parse HEAD")}`, + }) + ], + }, +}; diff --git a/packages/fineui/babel.config.js b/packages/fineui/babel.config.js new file mode 100644 index 000000000..d01a496d7 --- /dev/null +++ b/packages/fineui/babel.config.js @@ -0,0 +1 @@ +module.exports = require('@fui/babel-preset-fineui').configs.base; \ No newline at end of file diff --git a/dist/font/iconfont.eot b/packages/fineui/dist/font/iconfont.eot similarity index 100% rename from dist/font/iconfont.eot rename to packages/fineui/dist/font/iconfont.eot diff --git a/dist/font/iconfont.svg b/packages/fineui/dist/font/iconfont.svg similarity index 100% rename from dist/font/iconfont.svg rename to packages/fineui/dist/font/iconfont.svg diff --git a/dist/font/iconfont.ttf b/packages/fineui/dist/font/iconfont.ttf similarity index 100% rename from dist/font/iconfont.ttf rename to packages/fineui/dist/font/iconfont.ttf diff --git a/dist/font/iconfont.woff b/packages/fineui/dist/font/iconfont.woff similarity index 100% rename from dist/font/iconfont.woff rename to packages/fineui/dist/font/iconfont.woff diff --git a/dist/font/iconfont.woff2 b/packages/fineui/dist/font/iconfont.woff2 similarity index 100% rename from dist/font/iconfont.woff2 rename to packages/fineui/dist/font/iconfont.woff2 diff --git a/dist/images/1x/background/auto_color.png b/packages/fineui/dist/images/1x/background/auto_color.png similarity index 100% rename from dist/images/1x/background/auto_color.png rename to packages/fineui/dist/images/1x/background/auto_color.png diff --git a/dist/images/1x/background/auto_color_disable.png b/packages/fineui/dist/images/1x/background/auto_color_disable.png similarity index 100% rename from dist/images/1x/background/auto_color_disable.png rename to packages/fineui/dist/images/1x/background/auto_color_disable.png diff --git a/dist/images/1x/background/auto_color_normal.png b/packages/fineui/dist/images/1x/background/auto_color_normal.png similarity index 100% rename from dist/images/1x/background/auto_color_normal.png rename to packages/fineui/dist/images/1x/background/auto_color_normal.png diff --git a/dist/images/1x/background/auto_color_normal_disable.png b/packages/fineui/dist/images/1x/background/auto_color_normal_disable.png similarity index 100% rename from dist/images/1x/background/auto_color_normal_disable.png rename to packages/fineui/dist/images/1x/background/auto_color_normal_disable.png diff --git a/dist/images/1x/background/auto_color_normal_select.png b/packages/fineui/dist/images/1x/background/auto_color_normal_select.png similarity index 100% rename from dist/images/1x/background/auto_color_normal_select.png rename to packages/fineui/dist/images/1x/background/auto_color_normal_select.png diff --git a/dist/images/1x/background/auto_color_select.png b/packages/fineui/dist/images/1x/background/auto_color_select.png similarity index 100% rename from dist/images/1x/background/auto_color_select.png rename to packages/fineui/dist/images/1x/background/auto_color_select.png diff --git a/dist/images/1x/background/line_conn.gif b/packages/fineui/dist/images/1x/background/line_conn.gif similarity index 100% rename from dist/images/1x/background/line_conn.gif rename to packages/fineui/dist/images/1x/background/line_conn.gif diff --git a/dist/images/1x/background/trans_color.png b/packages/fineui/dist/images/1x/background/trans_color.png similarity index 100% rename from dist/images/1x/background/trans_color.png rename to packages/fineui/dist/images/1x/background/trans_color.png diff --git a/dist/images/1x/background/trans_disable.png b/packages/fineui/dist/images/1x/background/trans_disable.png similarity index 100% rename from dist/images/1x/background/trans_disable.png rename to packages/fineui/dist/images/1x/background/trans_disable.png diff --git a/dist/images/1x/background/trans_normal.png b/packages/fineui/dist/images/1x/background/trans_normal.png similarity index 100% rename from dist/images/1x/background/trans_normal.png rename to packages/fineui/dist/images/1x/background/trans_normal.png diff --git a/dist/images/1x/background/trans_select.png b/packages/fineui/dist/images/1x/background/trans_select.png similarity index 100% rename from dist/images/1x/background/trans_select.png rename to packages/fineui/dist/images/1x/background/trans_select.png diff --git a/dist/images/1x/icon/auto_no_square_normal.png b/packages/fineui/dist/images/1x/icon/auto_no_square_normal.png similarity index 100% rename from dist/images/1x/icon/auto_no_square_normal.png rename to packages/fineui/dist/images/1x/icon/auto_no_square_normal.png diff --git a/dist/images/1x/icon/auto_square_normal.png b/packages/fineui/dist/images/1x/icon/auto_square_normal.png similarity index 100% rename from dist/images/1x/icon/auto_square_normal.png rename to packages/fineui/dist/images/1x/icon/auto_square_normal.png diff --git a/dist/images/1x/icon/check_box_active.png b/packages/fineui/dist/images/1x/icon/check_box_active.png similarity index 100% rename from dist/images/1x/icon/check_box_active.png rename to packages/fineui/dist/images/1x/icon/check_box_active.png diff --git a/dist/images/1x/icon/check_box_disable.png b/packages/fineui/dist/images/1x/icon/check_box_disable.png similarity index 100% rename from dist/images/1x/icon/check_box_disable.png rename to packages/fineui/dist/images/1x/icon/check_box_disable.png diff --git a/dist/images/1x/icon/check_box_disable2.png b/packages/fineui/dist/images/1x/icon/check_box_disable2.png similarity index 100% rename from dist/images/1x/icon/check_box_disable2.png rename to packages/fineui/dist/images/1x/icon/check_box_disable2.png diff --git a/dist/images/1x/icon/check_box_hover.png b/packages/fineui/dist/images/1x/icon/check_box_hover.png similarity index 100% rename from dist/images/1x/icon/check_box_hover.png rename to packages/fineui/dist/images/1x/icon/check_box_hover.png diff --git a/dist/images/1x/icon/check_box_normal.png b/packages/fineui/dist/images/1x/icon/check_box_normal.png similarity index 100% rename from dist/images/1x/icon/check_box_normal.png rename to packages/fineui/dist/images/1x/icon/check_box_normal.png diff --git a/dist/images/1x/icon/dark/auto_square_normal.png b/packages/fineui/dist/images/1x/icon/dark/auto_square_normal.png similarity index 100% rename from dist/images/1x/icon/dark/auto_square_normal.png rename to packages/fineui/dist/images/1x/icon/dark/auto_square_normal.png diff --git a/dist/images/1x/icon/dark/trans_normal.png b/packages/fineui/dist/images/1x/icon/dark/trans_normal.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/1x/icon/dark/trans_normal.png rename to packages/fineui/dist/images/1x/icon/dark/trans_normal.png diff --git a/dist/images/1x/icon/dark/trans_select.png b/packages/fineui/dist/images/1x/icon/dark/trans_select.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/1x/icon/dark/trans_select.png rename to packages/fineui/dist/images/1x/icon/dark/trans_select.png diff --git a/dist/images/1x/icon/dark/tree_collapse_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_collapse_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_collapse_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_collapse_1.png diff --git a/dist/images/1x/icon/dark/tree_collapse_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_collapse_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_collapse_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_collapse_2.png diff --git a/dist/images/1x/icon/dark/tree_collapse_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_collapse_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_collapse_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_collapse_3.png diff --git a/dist/images/1x/icon/dark/tree_collapse_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_collapse_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_collapse_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_collapse_4.png diff --git a/dist/images/1x/icon/dark/tree_expand_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_expand_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_expand_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_expand_1.png diff --git a/dist/images/1x/icon/dark/tree_expand_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_expand_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_expand_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_expand_2.png diff --git a/dist/images/1x/icon/dark/tree_expand_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_expand_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_expand_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_expand_3.png diff --git a/dist/images/1x/icon/dark/tree_expand_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_expand_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_expand_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_expand_4.png diff --git a/dist/images/1x/icon/dark/tree_solid_collapse_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_collapse_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_1.png diff --git a/dist/images/1x/icon/dark/tree_solid_collapse_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_collapse_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_2.png diff --git a/dist/images/1x/icon/dark/tree_solid_collapse_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_collapse_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_3.png diff --git a/dist/images/1x/icon/dark/tree_solid_collapse_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_collapse_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_4.png diff --git a/dist/images/1x/icon/dark/tree_solid_collapse_5.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_5.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_collapse_5.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_collapse_5.png diff --git a/dist/images/1x/icon/dark/tree_solid_expand_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_expand_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_1.png diff --git a/dist/images/1x/icon/dark/tree_solid_expand_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_expand_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_2.png diff --git a/dist/images/1x/icon/dark/tree_solid_expand_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_expand_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_3.png diff --git a/dist/images/1x/icon/dark/tree_solid_expand_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_expand_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_4.png diff --git a/dist/images/1x/icon/dark/tree_solid_expand_5.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_5.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_expand_5.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_expand_5.png diff --git a/dist/images/1x/icon/dark/tree_solid_vertical_line_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_vertical_line_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_1.png diff --git a/dist/images/1x/icon/dark/tree_solid_vertical_line_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_vertical_line_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_2.png diff --git a/dist/images/1x/icon/dark/tree_solid_vertical_line_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_vertical_line_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_3.png diff --git a/dist/images/1x/icon/dark/tree_solid_vertical_line_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_solid_vertical_line_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_solid_vertical_line_4.png diff --git a/dist/images/1x/icon/dark/tree_vertical_line_1.png b/packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_1.png similarity index 100% rename from dist/images/1x/icon/dark/tree_vertical_line_1.png rename to packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_1.png diff --git a/dist/images/1x/icon/dark/tree_vertical_line_2.png b/packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_2.png similarity index 100% rename from dist/images/1x/icon/dark/tree_vertical_line_2.png rename to packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_2.png diff --git a/dist/images/1x/icon/dark/tree_vertical_line_3.png b/packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_3.png similarity index 100% rename from dist/images/1x/icon/dark/tree_vertical_line_3.png rename to packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_3.png diff --git a/dist/images/1x/icon/dark/tree_vertical_line_4.png b/packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_4.png similarity index 100% rename from dist/images/1x/icon/dark/tree_vertical_line_4.png rename to packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_4.png diff --git a/dist/images/1x/icon/dark/tree_vertical_line_5.png b/packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_5.png similarity index 100% rename from dist/images/1x/icon/dark/tree_vertical_line_5.png rename to packages/fineui/dist/images/1x/icon/dark/tree_vertical_line_5.png diff --git a/dist/images/1x/icon/dots.png b/packages/fineui/dist/images/1x/icon/dots.png similarity index 100% rename from dist/images/1x/icon/dots.png rename to packages/fineui/dist/images/1x/icon/dots.png diff --git a/dist/images/1x/icon/half_selected.png b/packages/fineui/dist/images/1x/icon/half_selected.png similarity index 100% rename from dist/images/1x/icon/half_selected.png rename to packages/fineui/dist/images/1x/icon/half_selected.png diff --git a/dist/images/1x/icon/half_selected_disable.png b/packages/fineui/dist/images/1x/icon/half_selected_disable.png similarity index 100% rename from dist/images/1x/icon/half_selected_disable.png rename to packages/fineui/dist/images/1x/icon/half_selected_disable.png diff --git a/dist/images/1x/icon/icon_down_arrow.png b/packages/fineui/dist/images/1x/icon/icon_down_arrow.png similarity index 100% rename from dist/images/1x/icon/icon_down_arrow.png rename to packages/fineui/dist/images/1x/icon/icon_down_arrow.png diff --git a/dist/images/1x/icon/loading.gif b/packages/fineui/dist/images/1x/icon/loading.gif similarity index 100% rename from dist/images/1x/icon/loading.gif rename to packages/fineui/dist/images/1x/icon/loading.gif diff --git a/dist/images/1x/icon/push_down.png b/packages/fineui/dist/images/1x/icon/push_down.png similarity index 100% rename from dist/images/1x/icon/push_down.png rename to packages/fineui/dist/images/1x/icon/push_down.png diff --git a/dist/images/1x/icon/push_up.png b/packages/fineui/dist/images/1x/icon/push_up.png similarity index 100% rename from dist/images/1x/icon/push_up.png rename to packages/fineui/dist/images/1x/icon/push_up.png diff --git a/dist/images/1x/icon/radio_active.png b/packages/fineui/dist/images/1x/icon/radio_active.png similarity index 100% rename from dist/images/1x/icon/radio_active.png rename to packages/fineui/dist/images/1x/icon/radio_active.png diff --git a/dist/images/1x/icon/radio_disable.png b/packages/fineui/dist/images/1x/icon/radio_disable.png similarity index 100% rename from dist/images/1x/icon/radio_disable.png rename to packages/fineui/dist/images/1x/icon/radio_disable.png diff --git a/dist/images/1x/icon/radio_disable2.png b/packages/fineui/dist/images/1x/icon/radio_disable2.png similarity index 100% rename from dist/images/1x/icon/radio_disable2.png rename to packages/fineui/dist/images/1x/icon/radio_disable2.png diff --git a/dist/images/1x/icon/radio_hover.png b/packages/fineui/dist/images/1x/icon/radio_hover.png similarity index 100% rename from dist/images/1x/icon/radio_hover.png rename to packages/fineui/dist/images/1x/icon/radio_hover.png diff --git a/dist/images/1x/icon/radio_normal.png b/packages/fineui/dist/images/1x/icon/radio_normal.png similarity index 100% rename from dist/images/1x/icon/radio_normal.png rename to packages/fineui/dist/images/1x/icon/radio_normal.png diff --git a/dist/images/1x/icon/slider_active.png b/packages/fineui/dist/images/1x/icon/slider_active.png similarity index 100% rename from dist/images/1x/icon/slider_active.png rename to packages/fineui/dist/images/1x/icon/slider_active.png diff --git a/dist/images/1x/icon/slider_active_small.png b/packages/fineui/dist/images/1x/icon/slider_active_small.png similarity index 100% rename from dist/images/1x/icon/slider_active_small.png rename to packages/fineui/dist/images/1x/icon/slider_active_small.png diff --git a/dist/images/1x/icon/slider_normal.png b/packages/fineui/dist/images/1x/icon/slider_normal.png similarity index 100% rename from dist/images/1x/icon/slider_normal.png rename to packages/fineui/dist/images/1x/icon/slider_normal.png diff --git a/dist/images/1x/icon/slider_normal_small.png b/packages/fineui/dist/images/1x/icon/slider_normal_small.png similarity index 100% rename from dist/images/1x/icon/slider_normal_small.png rename to packages/fineui/dist/images/1x/icon/slider_normal_small.png diff --git a/dist/images/1x/icon/trans_normal.png b/packages/fineui/dist/images/1x/icon/trans_normal.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/1x/icon/trans_normal.png rename to packages/fineui/dist/images/1x/icon/trans_normal.png diff --git a/dist/images/1x/icon/trans_select.png b/packages/fineui/dist/images/1x/icon/trans_select.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/1x/icon/trans_select.png rename to packages/fineui/dist/images/1x/icon/trans_select.png diff --git a/dist/images/1x/icon/tree_collapse_1.png b/packages/fineui/dist/images/1x/icon/tree_collapse_1.png similarity index 100% rename from dist/images/1x/icon/tree_collapse_1.png rename to packages/fineui/dist/images/1x/icon/tree_collapse_1.png diff --git a/dist/images/1x/icon/tree_collapse_2.png b/packages/fineui/dist/images/1x/icon/tree_collapse_2.png similarity index 100% rename from dist/images/1x/icon/tree_collapse_2.png rename to packages/fineui/dist/images/1x/icon/tree_collapse_2.png diff --git a/dist/images/1x/icon/tree_collapse_3.png b/packages/fineui/dist/images/1x/icon/tree_collapse_3.png similarity index 100% rename from dist/images/1x/icon/tree_collapse_3.png rename to packages/fineui/dist/images/1x/icon/tree_collapse_3.png diff --git a/dist/images/1x/icon/tree_collapse_4.png b/packages/fineui/dist/images/1x/icon/tree_collapse_4.png similarity index 100% rename from dist/images/1x/icon/tree_collapse_4.png rename to packages/fineui/dist/images/1x/icon/tree_collapse_4.png diff --git a/dist/images/1x/icon/tree_expand_1.png b/packages/fineui/dist/images/1x/icon/tree_expand_1.png similarity index 100% rename from dist/images/1x/icon/tree_expand_1.png rename to packages/fineui/dist/images/1x/icon/tree_expand_1.png diff --git a/dist/images/1x/icon/tree_expand_2.png b/packages/fineui/dist/images/1x/icon/tree_expand_2.png similarity index 100% rename from dist/images/1x/icon/tree_expand_2.png rename to packages/fineui/dist/images/1x/icon/tree_expand_2.png diff --git a/dist/images/1x/icon/tree_expand_3.png b/packages/fineui/dist/images/1x/icon/tree_expand_3.png similarity index 100% rename from dist/images/1x/icon/tree_expand_3.png rename to packages/fineui/dist/images/1x/icon/tree_expand_3.png diff --git a/dist/images/1x/icon/tree_expand_4.png b/packages/fineui/dist/images/1x/icon/tree_expand_4.png similarity index 100% rename from dist/images/1x/icon/tree_expand_4.png rename to packages/fineui/dist/images/1x/icon/tree_expand_4.png diff --git a/dist/images/1x/icon/tree_solid_collapse_1.png b/packages/fineui/dist/images/1x/icon/tree_solid_collapse_1.png similarity index 100% rename from dist/images/1x/icon/tree_solid_collapse_1.png rename to packages/fineui/dist/images/1x/icon/tree_solid_collapse_1.png diff --git a/dist/images/1x/icon/tree_solid_collapse_2.png b/packages/fineui/dist/images/1x/icon/tree_solid_collapse_2.png similarity index 100% rename from dist/images/1x/icon/tree_solid_collapse_2.png rename to packages/fineui/dist/images/1x/icon/tree_solid_collapse_2.png diff --git a/dist/images/1x/icon/tree_solid_collapse_3.png b/packages/fineui/dist/images/1x/icon/tree_solid_collapse_3.png similarity index 100% rename from dist/images/1x/icon/tree_solid_collapse_3.png rename to packages/fineui/dist/images/1x/icon/tree_solid_collapse_3.png diff --git a/dist/images/1x/icon/tree_solid_collapse_4.png b/packages/fineui/dist/images/1x/icon/tree_solid_collapse_4.png similarity index 100% rename from dist/images/1x/icon/tree_solid_collapse_4.png rename to packages/fineui/dist/images/1x/icon/tree_solid_collapse_4.png diff --git a/dist/images/1x/icon/tree_solid_collapse_5.png b/packages/fineui/dist/images/1x/icon/tree_solid_collapse_5.png similarity index 100% rename from dist/images/1x/icon/tree_solid_collapse_5.png rename to packages/fineui/dist/images/1x/icon/tree_solid_collapse_5.png diff --git a/dist/images/1x/icon/tree_solid_expand_1.png b/packages/fineui/dist/images/1x/icon/tree_solid_expand_1.png similarity index 100% rename from dist/images/1x/icon/tree_solid_expand_1.png rename to packages/fineui/dist/images/1x/icon/tree_solid_expand_1.png diff --git a/dist/images/1x/icon/tree_solid_expand_2.png b/packages/fineui/dist/images/1x/icon/tree_solid_expand_2.png similarity index 100% rename from dist/images/1x/icon/tree_solid_expand_2.png rename to packages/fineui/dist/images/1x/icon/tree_solid_expand_2.png diff --git a/dist/images/1x/icon/tree_solid_expand_3.png b/packages/fineui/dist/images/1x/icon/tree_solid_expand_3.png similarity index 100% rename from dist/images/1x/icon/tree_solid_expand_3.png rename to packages/fineui/dist/images/1x/icon/tree_solid_expand_3.png diff --git a/dist/images/1x/icon/tree_solid_expand_4.png b/packages/fineui/dist/images/1x/icon/tree_solid_expand_4.png similarity index 100% rename from dist/images/1x/icon/tree_solid_expand_4.png rename to packages/fineui/dist/images/1x/icon/tree_solid_expand_4.png diff --git a/dist/images/1x/icon/tree_solid_expand_5.png b/packages/fineui/dist/images/1x/icon/tree_solid_expand_5.png similarity index 100% rename from dist/images/1x/icon/tree_solid_expand_5.png rename to packages/fineui/dist/images/1x/icon/tree_solid_expand_5.png diff --git a/dist/images/1x/icon/tree_solid_vertical_line_1.png b/packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_1.png similarity index 100% rename from dist/images/1x/icon/tree_solid_vertical_line_1.png rename to packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_1.png diff --git a/dist/images/1x/icon/tree_solid_vertical_line_2.png b/packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_2.png similarity index 100% rename from dist/images/1x/icon/tree_solid_vertical_line_2.png rename to packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_2.png diff --git a/dist/images/1x/icon/tree_solid_vertical_line_3.png b/packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_3.png similarity index 100% rename from dist/images/1x/icon/tree_solid_vertical_line_3.png rename to packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_3.png diff --git a/dist/images/1x/icon/tree_solid_vertical_line_4.png b/packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_4.png similarity index 100% rename from dist/images/1x/icon/tree_solid_vertical_line_4.png rename to packages/fineui/dist/images/1x/icon/tree_solid_vertical_line_4.png diff --git a/dist/images/1x/icon/tree_vertical_line_1.png b/packages/fineui/dist/images/1x/icon/tree_vertical_line_1.png similarity index 100% rename from dist/images/1x/icon/tree_vertical_line_1.png rename to packages/fineui/dist/images/1x/icon/tree_vertical_line_1.png diff --git a/dist/images/1x/icon/tree_vertical_line_2.png b/packages/fineui/dist/images/1x/icon/tree_vertical_line_2.png similarity index 100% rename from dist/images/1x/icon/tree_vertical_line_2.png rename to packages/fineui/dist/images/1x/icon/tree_vertical_line_2.png diff --git a/dist/images/1x/icon/tree_vertical_line_3.png b/packages/fineui/dist/images/1x/icon/tree_vertical_line_3.png similarity index 100% rename from dist/images/1x/icon/tree_vertical_line_3.png rename to packages/fineui/dist/images/1x/icon/tree_vertical_line_3.png diff --git a/dist/images/1x/icon/tree_vertical_line_4.png b/packages/fineui/dist/images/1x/icon/tree_vertical_line_4.png similarity index 100% rename from dist/images/1x/icon/tree_vertical_line_4.png rename to packages/fineui/dist/images/1x/icon/tree_vertical_line_4.png diff --git a/dist/images/1x/icon/tree_vertical_line_5.png b/packages/fineui/dist/images/1x/icon/tree_vertical_line_5.png similarity index 100% rename from dist/images/1x/icon/tree_vertical_line_5.png rename to packages/fineui/dist/images/1x/icon/tree_vertical_line_5.png diff --git a/dist/images/1x/icon/wave_loading.gif b/packages/fineui/dist/images/1x/icon/wave_loading.gif similarity index 100% rename from dist/images/1x/icon/wave_loading.gif rename to packages/fineui/dist/images/1x/icon/wave_loading.gif diff --git a/dist/images/2x/background/auto_color_disable.png b/packages/fineui/dist/images/2x/background/auto_color_disable.png similarity index 100% rename from dist/images/2x/background/auto_color_disable.png rename to packages/fineui/dist/images/2x/background/auto_color_disable.png diff --git a/dist/images/2x/background/auto_color_normal.png b/packages/fineui/dist/images/2x/background/auto_color_normal.png similarity index 100% rename from dist/images/2x/background/auto_color_normal.png rename to packages/fineui/dist/images/2x/background/auto_color_normal.png diff --git a/dist/images/2x/background/auto_color_select.png b/packages/fineui/dist/images/2x/background/auto_color_select.png similarity index 100% rename from dist/images/2x/background/auto_color_select.png rename to packages/fineui/dist/images/2x/background/auto_color_select.png diff --git a/dist/images/2x/background/line_conn.gif b/packages/fineui/dist/images/2x/background/line_conn.gif similarity index 100% rename from dist/images/2x/background/line_conn.gif rename to packages/fineui/dist/images/2x/background/line_conn.gif diff --git a/dist/images/2x/background/trans_normal.png b/packages/fineui/dist/images/2x/background/trans_normal.png similarity index 100% rename from dist/images/2x/background/trans_normal.png rename to packages/fineui/dist/images/2x/background/trans_normal.png diff --git a/dist/images/2x/icon/auto_no_square_normal.png b/packages/fineui/dist/images/2x/icon/auto_no_square_normal.png similarity index 100% rename from dist/images/2x/icon/auto_no_square_normal.png rename to packages/fineui/dist/images/2x/icon/auto_no_square_normal.png diff --git a/dist/images/2x/icon/auto_normal.png b/packages/fineui/dist/images/2x/icon/auto_normal.png similarity index 100% rename from dist/images/2x/icon/auto_normal.png rename to packages/fineui/dist/images/2x/icon/auto_normal.png diff --git a/dist/images/2x/icon/auto_select.png b/packages/fineui/dist/images/2x/icon/auto_select.png similarity index 100% rename from dist/images/2x/icon/auto_select.png rename to packages/fineui/dist/images/2x/icon/auto_select.png diff --git a/dist/images/2x/icon/auto_square_normal.png b/packages/fineui/dist/images/2x/icon/auto_square_normal.png similarity index 100% rename from dist/images/2x/icon/auto_square_normal.png rename to packages/fineui/dist/images/2x/icon/auto_square_normal.png diff --git a/dist/images/2x/icon/check_box_active.png b/packages/fineui/dist/images/2x/icon/check_box_active.png similarity index 100% rename from dist/images/2x/icon/check_box_active.png rename to packages/fineui/dist/images/2x/icon/check_box_active.png diff --git a/dist/images/2x/icon/check_box_disable.png b/packages/fineui/dist/images/2x/icon/check_box_disable.png similarity index 100% rename from dist/images/2x/icon/check_box_disable.png rename to packages/fineui/dist/images/2x/icon/check_box_disable.png diff --git a/dist/images/2x/icon/check_box_disable2.png b/packages/fineui/dist/images/2x/icon/check_box_disable2.png similarity index 100% rename from dist/images/2x/icon/check_box_disable2.png rename to packages/fineui/dist/images/2x/icon/check_box_disable2.png diff --git a/dist/images/2x/icon/check_box_hover.png b/packages/fineui/dist/images/2x/icon/check_box_hover.png similarity index 100% rename from dist/images/2x/icon/check_box_hover.png rename to packages/fineui/dist/images/2x/icon/check_box_hover.png diff --git a/dist/images/2x/icon/check_box_normal.png b/packages/fineui/dist/images/2x/icon/check_box_normal.png similarity index 100% rename from dist/images/2x/icon/check_box_normal.png rename to packages/fineui/dist/images/2x/icon/check_box_normal.png diff --git a/dist/images/2x/icon/dark/auto_square_normal.png b/packages/fineui/dist/images/2x/icon/dark/auto_square_normal.png similarity index 100% rename from dist/images/2x/icon/dark/auto_square_normal.png rename to packages/fineui/dist/images/2x/icon/dark/auto_square_normal.png diff --git a/dist/images/2x/icon/dark/trans_normal.png b/packages/fineui/dist/images/2x/icon/dark/trans_normal.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/2x/icon/dark/trans_normal.png rename to packages/fineui/dist/images/2x/icon/dark/trans_normal.png diff --git a/dist/images/2x/icon/dark/trans_select.png b/packages/fineui/dist/images/2x/icon/dark/trans_select.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/2x/icon/dark/trans_select.png rename to packages/fineui/dist/images/2x/icon/dark/trans_select.png diff --git a/dist/images/2x/icon/dark/tree_collapse_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_collapse_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_collapse_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_collapse_1.png diff --git a/dist/images/2x/icon/dark/tree_collapse_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_collapse_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_collapse_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_collapse_2.png diff --git a/dist/images/2x/icon/dark/tree_collapse_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_collapse_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_collapse_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_collapse_3.png diff --git a/dist/images/2x/icon/dark/tree_collapse_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_collapse_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_collapse_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_collapse_4.png diff --git a/dist/images/2x/icon/dark/tree_expand_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_expand_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_expand_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_expand_1.png diff --git a/dist/images/2x/icon/dark/tree_expand_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_expand_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_expand_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_expand_2.png diff --git a/dist/images/2x/icon/dark/tree_expand_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_expand_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_expand_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_expand_3.png diff --git a/dist/images/2x/icon/dark/tree_expand_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_expand_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_expand_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_expand_4.png diff --git a/dist/images/2x/icon/dark/tree_solid_collapse_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_collapse_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_1.png diff --git a/dist/images/2x/icon/dark/tree_solid_collapse_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_collapse_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_2.png diff --git a/dist/images/2x/icon/dark/tree_solid_collapse_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_collapse_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_3.png diff --git a/dist/images/2x/icon/dark/tree_solid_collapse_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_collapse_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_4.png diff --git a/dist/images/2x/icon/dark/tree_solid_collapse_5.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_5.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_collapse_5.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_collapse_5.png diff --git a/dist/images/2x/icon/dark/tree_solid_expand_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_expand_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_1.png diff --git a/dist/images/2x/icon/dark/tree_solid_expand_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_expand_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_2.png diff --git a/dist/images/2x/icon/dark/tree_solid_expand_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_expand_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_3.png diff --git a/dist/images/2x/icon/dark/tree_solid_expand_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_expand_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_4.png diff --git a/dist/images/2x/icon/dark/tree_solid_expand_5.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_5.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_expand_5.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_expand_5.png diff --git a/dist/images/2x/icon/dark/tree_solid_vertical_line_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_vertical_line_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_1.png diff --git a/dist/images/2x/icon/dark/tree_solid_vertical_line_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_vertical_line_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_2.png diff --git a/dist/images/2x/icon/dark/tree_solid_vertical_line_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_vertical_line_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_3.png diff --git a/dist/images/2x/icon/dark/tree_solid_vertical_line_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_solid_vertical_line_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_solid_vertical_line_4.png diff --git a/dist/images/2x/icon/dark/tree_vertical_line_1.png b/packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_1.png similarity index 100% rename from dist/images/2x/icon/dark/tree_vertical_line_1.png rename to packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_1.png diff --git a/dist/images/2x/icon/dark/tree_vertical_line_2.png b/packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_2.png similarity index 100% rename from dist/images/2x/icon/dark/tree_vertical_line_2.png rename to packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_2.png diff --git a/dist/images/2x/icon/dark/tree_vertical_line_3.png b/packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_3.png similarity index 100% rename from dist/images/2x/icon/dark/tree_vertical_line_3.png rename to packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_3.png diff --git a/dist/images/2x/icon/dark/tree_vertical_line_4.png b/packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_4.png similarity index 100% rename from dist/images/2x/icon/dark/tree_vertical_line_4.png rename to packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_4.png diff --git a/dist/images/2x/icon/dark/tree_vertical_line_5.png b/packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_5.png similarity index 100% rename from dist/images/2x/icon/dark/tree_vertical_line_5.png rename to packages/fineui/dist/images/2x/icon/dark/tree_vertical_line_5.png diff --git a/dist/images/2x/icon/dots.png b/packages/fineui/dist/images/2x/icon/dots.png similarity index 100% rename from dist/images/2x/icon/dots.png rename to packages/fineui/dist/images/2x/icon/dots.png diff --git a/dist/images/2x/icon/half_selected.png b/packages/fineui/dist/images/2x/icon/half_selected.png similarity index 100% rename from dist/images/2x/icon/half_selected.png rename to packages/fineui/dist/images/2x/icon/half_selected.png diff --git a/dist/images/2x/icon/half_selected_disable.png b/packages/fineui/dist/images/2x/icon/half_selected_disable.png similarity index 100% rename from dist/images/2x/icon/half_selected_disable.png rename to packages/fineui/dist/images/2x/icon/half_selected_disable.png diff --git a/dist/images/2x/icon/icon_down_arrow.png b/packages/fineui/dist/images/2x/icon/icon_down_arrow.png similarity index 100% rename from dist/images/2x/icon/icon_down_arrow.png rename to packages/fineui/dist/images/2x/icon/icon_down_arrow.png diff --git a/dist/images/2x/icon/loading.gif b/packages/fineui/dist/images/2x/icon/loading.gif similarity index 100% rename from dist/images/2x/icon/loading.gif rename to packages/fineui/dist/images/2x/icon/loading.gif diff --git a/dist/images/2x/icon/push_down.png b/packages/fineui/dist/images/2x/icon/push_down.png similarity index 100% rename from dist/images/2x/icon/push_down.png rename to packages/fineui/dist/images/2x/icon/push_down.png diff --git a/dist/images/2x/icon/push_up.png b/packages/fineui/dist/images/2x/icon/push_up.png similarity index 100% rename from dist/images/2x/icon/push_up.png rename to packages/fineui/dist/images/2x/icon/push_up.png diff --git a/dist/images/2x/icon/radio_active.png b/packages/fineui/dist/images/2x/icon/radio_active.png similarity index 100% rename from dist/images/2x/icon/radio_active.png rename to packages/fineui/dist/images/2x/icon/radio_active.png diff --git a/dist/images/2x/icon/radio_disable.png b/packages/fineui/dist/images/2x/icon/radio_disable.png similarity index 100% rename from dist/images/2x/icon/radio_disable.png rename to packages/fineui/dist/images/2x/icon/radio_disable.png diff --git a/dist/images/2x/icon/radio_disable2.png b/packages/fineui/dist/images/2x/icon/radio_disable2.png similarity index 100% rename from dist/images/2x/icon/radio_disable2.png rename to packages/fineui/dist/images/2x/icon/radio_disable2.png diff --git a/dist/images/2x/icon/radio_hover.png b/packages/fineui/dist/images/2x/icon/radio_hover.png similarity index 100% rename from dist/images/2x/icon/radio_hover.png rename to packages/fineui/dist/images/2x/icon/radio_hover.png diff --git a/dist/images/2x/icon/radio_normal.png b/packages/fineui/dist/images/2x/icon/radio_normal.png similarity index 100% rename from dist/images/2x/icon/radio_normal.png rename to packages/fineui/dist/images/2x/icon/radio_normal.png diff --git a/dist/images/2x/icon/slider_active.png b/packages/fineui/dist/images/2x/icon/slider_active.png similarity index 100% rename from dist/images/2x/icon/slider_active.png rename to packages/fineui/dist/images/2x/icon/slider_active.png diff --git a/dist/images/2x/icon/slider_active_small.png b/packages/fineui/dist/images/2x/icon/slider_active_small.png similarity index 100% rename from dist/images/2x/icon/slider_active_small.png rename to packages/fineui/dist/images/2x/icon/slider_active_small.png diff --git a/dist/images/2x/icon/slider_normal.png b/packages/fineui/dist/images/2x/icon/slider_normal.png similarity index 100% rename from dist/images/2x/icon/slider_normal.png rename to packages/fineui/dist/images/2x/icon/slider_normal.png diff --git a/dist/images/2x/icon/slider_normal_small.png b/packages/fineui/dist/images/2x/icon/slider_normal_small.png similarity index 100% rename from dist/images/2x/icon/slider_normal_small.png rename to packages/fineui/dist/images/2x/icon/slider_normal_small.png diff --git a/dist/images/2x/icon/trans_normal.png b/packages/fineui/dist/images/2x/icon/trans_normal.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/2x/icon/trans_normal.png rename to packages/fineui/dist/images/2x/icon/trans_normal.png diff --git a/dist/images/2x/icon/trans_select.png b/packages/fineui/dist/images/2x/icon/trans_select.png old mode 100755 new mode 100644 similarity index 100% rename from dist/images/2x/icon/trans_select.png rename to packages/fineui/dist/images/2x/icon/trans_select.png diff --git a/dist/images/2x/icon/tree_collapse_1.png b/packages/fineui/dist/images/2x/icon/tree_collapse_1.png similarity index 100% rename from dist/images/2x/icon/tree_collapse_1.png rename to packages/fineui/dist/images/2x/icon/tree_collapse_1.png diff --git a/dist/images/2x/icon/tree_collapse_2.png b/packages/fineui/dist/images/2x/icon/tree_collapse_2.png similarity index 100% rename from dist/images/2x/icon/tree_collapse_2.png rename to packages/fineui/dist/images/2x/icon/tree_collapse_2.png diff --git a/dist/images/2x/icon/tree_collapse_3.png b/packages/fineui/dist/images/2x/icon/tree_collapse_3.png similarity index 100% rename from dist/images/2x/icon/tree_collapse_3.png rename to packages/fineui/dist/images/2x/icon/tree_collapse_3.png diff --git a/dist/images/2x/icon/tree_collapse_4.png b/packages/fineui/dist/images/2x/icon/tree_collapse_4.png similarity index 100% rename from dist/images/2x/icon/tree_collapse_4.png rename to packages/fineui/dist/images/2x/icon/tree_collapse_4.png diff --git a/dist/images/2x/icon/tree_expand_1.png b/packages/fineui/dist/images/2x/icon/tree_expand_1.png similarity index 100% rename from dist/images/2x/icon/tree_expand_1.png rename to packages/fineui/dist/images/2x/icon/tree_expand_1.png diff --git a/dist/images/2x/icon/tree_expand_2.png b/packages/fineui/dist/images/2x/icon/tree_expand_2.png similarity index 100% rename from dist/images/2x/icon/tree_expand_2.png rename to packages/fineui/dist/images/2x/icon/tree_expand_2.png diff --git a/dist/images/2x/icon/tree_expand_3.png b/packages/fineui/dist/images/2x/icon/tree_expand_3.png similarity index 100% rename from dist/images/2x/icon/tree_expand_3.png rename to packages/fineui/dist/images/2x/icon/tree_expand_3.png diff --git a/dist/images/2x/icon/tree_expand_4.png b/packages/fineui/dist/images/2x/icon/tree_expand_4.png similarity index 100% rename from dist/images/2x/icon/tree_expand_4.png rename to packages/fineui/dist/images/2x/icon/tree_expand_4.png diff --git a/dist/images/2x/icon/tree_solid_collapse_1.png b/packages/fineui/dist/images/2x/icon/tree_solid_collapse_1.png similarity index 100% rename from dist/images/2x/icon/tree_solid_collapse_1.png rename to packages/fineui/dist/images/2x/icon/tree_solid_collapse_1.png diff --git a/dist/images/2x/icon/tree_solid_collapse_2.png b/packages/fineui/dist/images/2x/icon/tree_solid_collapse_2.png similarity index 100% rename from dist/images/2x/icon/tree_solid_collapse_2.png rename to packages/fineui/dist/images/2x/icon/tree_solid_collapse_2.png diff --git a/dist/images/2x/icon/tree_solid_collapse_3.png b/packages/fineui/dist/images/2x/icon/tree_solid_collapse_3.png similarity index 100% rename from dist/images/2x/icon/tree_solid_collapse_3.png rename to packages/fineui/dist/images/2x/icon/tree_solid_collapse_3.png diff --git a/dist/images/2x/icon/tree_solid_collapse_4.png b/packages/fineui/dist/images/2x/icon/tree_solid_collapse_4.png similarity index 100% rename from dist/images/2x/icon/tree_solid_collapse_4.png rename to packages/fineui/dist/images/2x/icon/tree_solid_collapse_4.png diff --git a/dist/images/2x/icon/tree_solid_collapse_5.png b/packages/fineui/dist/images/2x/icon/tree_solid_collapse_5.png similarity index 100% rename from dist/images/2x/icon/tree_solid_collapse_5.png rename to packages/fineui/dist/images/2x/icon/tree_solid_collapse_5.png diff --git a/dist/images/2x/icon/tree_solid_expand_1.png b/packages/fineui/dist/images/2x/icon/tree_solid_expand_1.png similarity index 100% rename from dist/images/2x/icon/tree_solid_expand_1.png rename to packages/fineui/dist/images/2x/icon/tree_solid_expand_1.png diff --git a/dist/images/2x/icon/tree_solid_expand_2.png b/packages/fineui/dist/images/2x/icon/tree_solid_expand_2.png similarity index 100% rename from dist/images/2x/icon/tree_solid_expand_2.png rename to packages/fineui/dist/images/2x/icon/tree_solid_expand_2.png diff --git a/dist/images/2x/icon/tree_solid_expand_3.png b/packages/fineui/dist/images/2x/icon/tree_solid_expand_3.png similarity index 100% rename from dist/images/2x/icon/tree_solid_expand_3.png rename to packages/fineui/dist/images/2x/icon/tree_solid_expand_3.png diff --git a/dist/images/2x/icon/tree_solid_expand_4.png b/packages/fineui/dist/images/2x/icon/tree_solid_expand_4.png similarity index 100% rename from dist/images/2x/icon/tree_solid_expand_4.png rename to packages/fineui/dist/images/2x/icon/tree_solid_expand_4.png diff --git a/dist/images/2x/icon/tree_solid_expand_5.png b/packages/fineui/dist/images/2x/icon/tree_solid_expand_5.png similarity index 100% rename from dist/images/2x/icon/tree_solid_expand_5.png rename to packages/fineui/dist/images/2x/icon/tree_solid_expand_5.png diff --git a/dist/images/2x/icon/tree_solid_vertical_line_1.png b/packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_1.png similarity index 100% rename from dist/images/2x/icon/tree_solid_vertical_line_1.png rename to packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_1.png diff --git a/dist/images/2x/icon/tree_solid_vertical_line_2.png b/packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_2.png similarity index 100% rename from dist/images/2x/icon/tree_solid_vertical_line_2.png rename to packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_2.png diff --git a/dist/images/2x/icon/tree_solid_vertical_line_3.png b/packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_3.png similarity index 100% rename from dist/images/2x/icon/tree_solid_vertical_line_3.png rename to packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_3.png diff --git a/dist/images/2x/icon/tree_solid_vertical_line_4.png b/packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_4.png similarity index 100% rename from dist/images/2x/icon/tree_solid_vertical_line_4.png rename to packages/fineui/dist/images/2x/icon/tree_solid_vertical_line_4.png diff --git a/dist/images/2x/icon/tree_vertical_line_1.png b/packages/fineui/dist/images/2x/icon/tree_vertical_line_1.png similarity index 100% rename from dist/images/2x/icon/tree_vertical_line_1.png rename to packages/fineui/dist/images/2x/icon/tree_vertical_line_1.png diff --git a/dist/images/2x/icon/tree_vertical_line_2.png b/packages/fineui/dist/images/2x/icon/tree_vertical_line_2.png similarity index 100% rename from dist/images/2x/icon/tree_vertical_line_2.png rename to packages/fineui/dist/images/2x/icon/tree_vertical_line_2.png diff --git a/dist/images/2x/icon/tree_vertical_line_3.png b/packages/fineui/dist/images/2x/icon/tree_vertical_line_3.png similarity index 100% rename from dist/images/2x/icon/tree_vertical_line_3.png rename to packages/fineui/dist/images/2x/icon/tree_vertical_line_3.png diff --git a/dist/images/2x/icon/tree_vertical_line_4.png b/packages/fineui/dist/images/2x/icon/tree_vertical_line_4.png similarity index 100% rename from dist/images/2x/icon/tree_vertical_line_4.png rename to packages/fineui/dist/images/2x/icon/tree_vertical_line_4.png diff --git a/dist/images/2x/icon/tree_vertical_line_5.png b/packages/fineui/dist/images/2x/icon/tree_vertical_line_5.png similarity index 100% rename from dist/images/2x/icon/tree_vertical_line_5.png rename to packages/fineui/dist/images/2x/icon/tree_vertical_line_5.png diff --git a/dist/images/2x/icon/wave_loading.gif b/packages/fineui/dist/images/2x/icon/wave_loading.gif similarity index 100% rename from dist/images/2x/icon/wave_loading.gif rename to packages/fineui/dist/images/2x/icon/wave_loading.gif diff --git a/packages/fineui/esm.babel.js b/packages/fineui/esm.babel.js new file mode 100644 index 000000000..c73949ee2 --- /dev/null +++ b/packages/fineui/esm.babel.js @@ -0,0 +1,37 @@ +const { resolve } = require("path"); +const modules = ["./core/platform/web/config"]; + +module.exports = { + plugins: [ + function(babel) { + const { types: t } = babel; + return { + visitor: { + Program(path) { + if (path.hub.file.opts.filename === resolve(__dirname, "src/index.js")) { + for (let i = 0; i < modules.length; i++) { + const importStatement = t.importDeclaration([], t.stringLiteral(modules[i])); + path.pushContainer("body", importStatement); + } + } + }, + }, + }; + }, + [ + "@babel/plugin-proposal-decorators", + { + legacy: true + } + ], + [ + "module-resolver", + { + root: ["./src"], + alias: { + "@": "./src" + } + } + ] + ] +}; diff --git a/bi.lessconfig.json b/packages/fineui/lessconfig/bi.lessconfig.json similarity index 100% rename from bi.lessconfig.json rename to packages/fineui/lessconfig/bi.lessconfig.json diff --git a/jsy.lessconfig.json b/packages/fineui/lessconfig/jsy.lessconfig.json similarity index 100% rename from jsy.lessconfig.json rename to packages/fineui/lessconfig/jsy.lessconfig.json diff --git a/packages/fineui/lib/prepublish.js b/packages/fineui/lib/prepublish.js new file mode 100644 index 000000000..d88a1958e --- /dev/null +++ b/packages/fineui/lib/prepublish.js @@ -0,0 +1,23 @@ +const { resolve } = require("path"); +const { writeFileSync } = require("fs"); + +function pad2(n) { + // always returns a string + return (n < 10 ? "0" : "") + n; +} +const d = new Date(); +const version = + d.getFullYear() + + pad2(d.getMonth() + 1) + + pad2(d.getDate()) + + pad2(d.getHours()) + + pad2(d.getMinutes()) + + pad2(d.getSeconds()); + +const packageJSON = require("../package.json"); +const versionChars = packageJSON.version.split("."); +versionChars[versionChars.length - 1] = version; +packageJSON.version = versionChars.join("."); +packageJSON.publishConfig.registry = "https://npm.fineres.com/"; +packageJSON.name = "@fui/core"; +writeFileSync(resolve(__dirname, "../package.json"), JSON.stringify(packageJSON, null, 2)); diff --git a/lodash.md b/packages/fineui/lodash.md similarity index 100% rename from lodash.md rename to packages/fineui/lodash.md diff --git a/packages/fineui/package.json b/packages/fineui/package.json new file mode 100644 index 000000000..d593e91b1 --- /dev/null +++ b/packages/fineui/package.json @@ -0,0 +1,61 @@ +{ + "name": "@fui/core", + "version": "3.0.20230707165537", + "description": "fineui", + "main": "dist/fineui.min.js", + "module": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "sideEffects": [ + "**/*.less", + "src/**/*.js", + "dist/lib/index.js", + "dist/lib/core/element/index.js", + "dist/lib/core/system.js", + "dist/lib/core/platform/web/config.js", + "dist/lib/core/platform/web/jquery/*.js", + "dist/lib/polyfill/**/*.js", + "dist/lib/case/ztree/jquery.ztree.core-3.5.js", + "dist/lib/case/ztree/jquery.ztree.excheck-3.5.js" + ], + "scripts": { + "dev": "tsc && run-p dev:*", + "dev:es": "babel src -d dist/lib --config-file ./esm.babel.js -w --source-maps", + "dev:fineui": "webpack-dev-server --progress --config=webpack/webpack.dev.js", + "build": "tsc && run-p build:*", + "build:es": "babel src -d dist/lib --config-file ./esm.babel.js", + "webpack:css": "webpack --progress --config=webpack/webpack.css.js --mode production", + "build:fineui": "webpack --progress --config=webpack/webpack.prod.js", + "prepublishToPrivate": "npm run build && node ./lib/prepublish.js", + "publishToPrivate": "npm publish", + "tsc": "tsc", + "link": "pnpm link --global" + }, + "files": [ + "dist", + "src/less" + ], + "repository": { + "type": "git", + "url": "https://git.coding.net/fanruan/fineui.git" + }, + "keywords": [ + "ui", + "fineui", + "finebi" + ], + "publishConfig": { + "registry": "https://npm.fineres.com/", + "access": "public" + }, + "author": "fanruan", + "license": "MIT", + "dependencies": { + "@juggle/resize-observer": "^3.4.0", + "@popperjs/core": "2.11.6", + "jquery": "3.6.3" + }, + "devDependencies": { + "core-js": "^3.30.2", + "cross-env": "^7.0.3" + } +} diff --git a/packages/fineui/src/base/0.base.js b/packages/fineui/src/base/0.base.js new file mode 100644 index 000000000..db4ad057c --- /dev/null +++ b/packages/fineui/src/base/0.base.js @@ -0,0 +1,23 @@ +import { + BroadcastController, + BubblesController, + DrawerController, + LayerController, + MaskersController, + PopoverController, + ResizeController, + TooltipsController, +} from '../core/controller'; +import { StyleLoaderManager } from '../core/loader/loader.style'; + +const Resizers = new ResizeController(); +const Layers = new LayerController(Resizers); +const Maskers = new MaskersController(Resizers); +const Bubbles = new BubblesController(); +const Tooltips = new TooltipsController(); +const Popovers = new PopoverController(); +const Drawers = new DrawerController(); +const Broadcasts = new BroadcastController(); +const StyleLoaders = new StyleLoaderManager(); + +export { Resizers, Layers, Maskers, Bubbles, Tooltips, Popovers, Drawers, Broadcasts, StyleLoaders }; diff --git a/packages/fineui/src/base/1.pane.js b/packages/fineui/src/base/1.pane.js new file mode 100644 index 000000000..e36f2bd81 --- /dev/null +++ b/packages/fineui/src/base/1.pane.js @@ -0,0 +1,161 @@ +import { + AbsoluteCenterLayout, + CenterAdaptLayout, + HorizontalAdaptLayout, + VerticalLayout, + Widget, + shortcut, + isNotEmptyString, + extend, + isNull, + isEmpty, + createWidget, + Providers, + i18nText, + emptyFn, + SystemProvider +} from "@/core"; +import { Label, Text } from "./single"; +import { Layers } from "@/base/0.base"; + +/** + * 当没有元素时有提示信息的view + * + * Created by GUY on 2015/9/8. + * @class Pane + * @extends Widget + * @abstract + */ + +@shortcut() +export class Pane extends Widget { + static xtype = "bi.pane"; + static EVENT_LOADED = "EVENT_LOADED"; + static EVENT_LOADING = "EVENT_LOADING"; + + _defaultConfig() { + return extend(super._defaultConfig(), { + _baseCls: "bi-pane", + tipText: i18nText("BI-No_Selected_Item"), + loadingText: "", + loadingSize: "small", + overlap: true, + onLoaded: emptyFn, + }); + } + + _assertTip() { + if (!this._tipText) { + createWidget({ + type: AbsoluteCenterLayout.xtype, + element: this, + items: [ + { + type: Label.xtype, + ref: _ref => { + this._tipText = _ref; + }, + cls: "bi-tips", + text: this.options.tipText, + height: 25, + } + ], + }); + } + } + + loading() { + const o = this.options; + const loadingAnimation = createWidget( + Providers.getProvider(SystemProvider.xtype).getLoading({ + loadingSize: o.loadingSize, + context: this, + }) + ); + // pane在同步方式下由items决定tipText的显示与否 + // loading的异步情况下由loaded后对面板的populate的时机决定 + this.setTipVisible(false); + if (o.overlap === true) { + if (!Layers.has(`${this.getName()}-loading`)) { + createWidget({ + type: CenterAdaptLayout.xtype, + cls: "loading-container", + items: this._getLoadingTipItems(loadingAnimation), + element: Layers.make(`${this.getName()}-loading`, this), + }); + } + Layers.show(`${this.getName()}-loading`); + } else if (isNull(this._loading)) { + loadingAnimation.element.css("zIndex", 1); + createWidget({ + type: CenterAdaptLayout.xtype, + element: this, + cls: "loading-container", + items: this._getLoadingTipItems(loadingAnimation), + }); + } + this.fireEvent(Pane.EVENT_LOADING); + this.element.addClass("loading-status"); + } + + _getSize(v) { + return Math.ceil(v / (this.options.loadingSize === "small" ? 2 : 1)); + } + + _getLoadingTipItems(loadingTip) { + const o = this.options; + const loadingTipItems = [ + { + type: HorizontalAdaptLayout.xtype, + items: [loadingTip], + } + ]; + isNotEmptyString(o.loadingText) && + loadingTipItems.push({ + type: Text.xtype, + text: o.loadingText, + tgap: this._getSize(10), + }); + + return [ + { + type: VerticalLayout.xtype, + ref: _ref => { + this._loading = _ref; + }, + items: loadingTipItems, + } + ]; + } + + loaded() { + Layers.remove(`${this.getName()}-loading`); + this._loading && this._loading.destroy(); + this.options.onLoaded(); + this.fireEvent(Pane.EVENT_LOADED); + this.element.removeClass("loading-status"); + } + + check() { + this.setTipVisible(isEmpty(this.options.items)); + } + + setTipVisible(b) { + if (b === true) { + this._assertTip(); + this._tipText && this._tipText.setVisible(true); + } else { + this._tipText && this._tipText.setVisible(false); + } + } + + setTipText(text) { + this._assertTip(); + this._tipText.setText(text); + } + + populate(items) { + this.options.items = items || []; + this.check(); + } +} diff --git a/packages/fineui/src/base/behavior/0.behavior.js b/packages/fineui/src/base/behavior/0.behavior.js new file mode 100644 index 000000000..99ef2f633 --- /dev/null +++ b/packages/fineui/src/base/behavior/0.behavior.js @@ -0,0 +1,17 @@ +/** + * guy + * 行为控件 + */ +import { OB, extend } from "@/core"; + +export class Behavior extends OB { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + rule: () => true, + }); + } + + doBehavior() { + + } +} diff --git a/packages/fineui/src/base/behavior/behavior.highlight.js b/packages/fineui/src/base/behavior/behavior.highlight.js new file mode 100644 index 000000000..bd60ac46e --- /dev/null +++ b/packages/fineui/src/base/behavior/behavior.highlight.js @@ -0,0 +1,34 @@ +/** + * guy + */ +import { isFunction, each } from "@/core"; +import { Single } from "../single/0.single"; +import { Behavior } from "./0.behavior"; + +export class HighlightBehavior extends Behavior { + doBehavior(items) { + const args = Array.prototype.slice.call(arguments, 1), + { rule } = this.options; + each(items, (i, item) => { + if (item instanceof Single) { + const rules = rule(item.getValue(), item); + + function doBe(run) { + if (run === true) { + item.doHighLight && item.doHighLight(...args); + } else { + item.unHighLight && item.unHighLight(...args); + } + } + + if (isFunction(rules)) { + rules(doBe); + } else { + doBe(rules); + } + } else { + item.doBehavior && item.doBehavior(...args); + } + }); + } +} diff --git a/packages/fineui/src/base/behavior/behavior.redmark.js b/packages/fineui/src/base/behavior/behavior.redmark.js new file mode 100644 index 000000000..9e770195a --- /dev/null +++ b/packages/fineui/src/base/behavior/behavior.redmark.js @@ -0,0 +1,25 @@ +/** + * guy + * 标红行为 + */ +import { Behavior } from "./0.behavior"; +import { each } from "@/core"; +import { Single } from "../single/0.single"; + +export class RedMarkBehavior extends Behavior { + doBehavior(items) { + const args = Array.prototype.slice.call(arguments, 1), + { rule } = this.options; + each(items, (i, item) => { + if (item instanceof Single) { + if (rule(item.getValue(), item)) { + item.doRedMark && item.doRedMark(...args); + } else { + item.doRedMark && item.unRedMark(...args); + } + } else { + item.doBehavior && item.doBehavior(...args); + } + }); + } +} diff --git a/packages/fineui/src/base/behavior/index.js b/packages/fineui/src/base/behavior/index.js new file mode 100644 index 000000000..52d5f6499 --- /dev/null +++ b/packages/fineui/src/base/behavior/index.js @@ -0,0 +1,26 @@ + +import { HighlightBehavior } from "./behavior.highlight"; +import { RedMarkBehavior } from "./behavior.redmark"; + +export const BehaviorFactory = { + createBehavior (key, options) { + let Behavior; + switch (key) { + case "highlight": + Behavior = HighlightBehavior; + break; + case "redmark": + Behavior = RedMarkBehavior; + break; + default: + } + + return new Behavior(options); + }, +}; + +export { Behavior } from "./0.behavior"; +export { + HighlightBehavior, + RedMarkBehavior +}; diff --git a/src/base/collection/__test__/collection.test.js b/packages/fineui/src/base/collection/__test__/collection.test.js similarity index 100% rename from src/base/collection/__test__/collection.test.js rename to packages/fineui/src/base/collection/__test__/collection.test.js diff --git a/packages/fineui/src/base/collection/collection.js b/packages/fineui/src/base/collection/collection.js new file mode 100644 index 000000000..2019bfa7a --- /dev/null +++ b/packages/fineui/src/base/collection/collection.js @@ -0,0 +1,487 @@ +import { + VerticalLayout, + AbsoluteLayout, + Widget, + shortcut, + extend, + emptyFn, + debounce, + _lazyCreateWidget, + isFunction, + SectionManager, + isNull, + each, + clamp, + toArray, + invert, + min, + max, + nextTick, + DOM +} from "@/core"; +import { Label } from "../single"; + +/** + * CollectionView + * + * Created by GUY on 2016/1/15. + * @class CollectionView + * @extends Widget + */ + +@shortcut() +export class CollectionView extends Widget { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-collection", + // width: 400, //必设 + // height: 300, //必设 + scrollable: true, + scrollx: false, + scrolly: false, + overflowX: true, + overflowY: true, + el: { + type: VerticalLayout.xtype, + }, + cellSizeAndPositionGetter: emptyFn, + horizontalOverscanSize: 0, + verticalOverscanSize: 0, + scrollLeft: 0, + scrollTop: 0, + items: [], + itemFormatter: (item, index) => item, + }); + } + + static EVENT_SCROLL = "EVENT_SCROLL"; + static xtype = "bi.collection_view"; + + render() { + const o = this.options; + const { overflowX, overflowY, el } = this.options; + this.renderedCells = []; + this.renderedKeys = []; + this.renderRange = {}; + this._scrollLock = false; + this._debounceRelease = debounce(() => { + this._scrollLock = false; + }, 1000 / 60); + this.container = _lazyCreateWidget({ + type: AbsoluteLayout.xtype, + }); + this.element.scroll(() => { + if (this._scrollLock === true) { + return; + } + o.scrollLeft = this.element.scrollLeft(); + o.scrollTop = this.element.scrollTop(); + this._calculateChildrenToRender(); + this.fireEvent(CollectionView.EVENT_SCROLL, { + scrollLeft: o.scrollLeft, + scrollTop: o.scrollTop, + }); + }); + // 兼容一下 + let scrollable = o.scrollable; + const scrollx = o.scrollx, + scrolly = o.scrolly; + if (overflowX === false) { + if (overflowY === false) { + scrollable = false; + } else { + scrollable = "y"; + } + } else { + if (overflowY === false) { + scrollable = "x"; + } + } + _lazyCreateWidget(el, { + type: VerticalLayout.xtype, + element: this, + scrollable, + scrolly, + scrollx, + items: [this.container], + }); + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + if (o.items.length > 0) { + this._calculateSizeAndPositionData(); + this._populate(); + } + } + + // mounted之后绑定事件 + mounted() { + const { scrollLeft, scrollTop } = this.options; + if (scrollLeft !== 0 || scrollTop !== 0) { + this.element.scrollTop(scrollTop); + this.element.scrollLeft(scrollLeft); + } + } + + _calculateSizeAndPositionData() { + const { items, cellSizeAndPositionGetter } = this.options; + const cellMetadata = []; + const sectionManager = new SectionManager(); + let height = 0; + let width = 0; + + for (let index = 0, len = items.length; index < len; index++) { + const cellMetadatum = cellSizeAndPositionGetter(index); + + if ( + isNull(cellMetadatum.height) || + isNaN(cellMetadatum.height) || + isNull(cellMetadatum.width) || + isNaN(cellMetadatum.width) || + isNull(cellMetadatum.x) || + isNaN(cellMetadatum.x) || + isNull(cellMetadatum.y) || + isNaN(cellMetadatum.y) + ) { + throw Error(); + } + + height = Math.max(height, cellMetadatum.y + cellMetadatum.height); + width = Math.max(width, cellMetadatum.x + cellMetadatum.width); + + cellMetadatum.index = index; + cellMetadata[index] = cellMetadatum; + sectionManager.registerCell(cellMetadatum, index); + } + + this._cellMetadata = cellMetadata; + this._sectionManager = sectionManager; + this._height = height; + this._width = width; + } + + _cellRenderers(height, width, x, y) { + this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y); + + return this._cellGroupRenderer(); + } + + _cellGroupRenderer() { + const rendered = []; + each(this._lastRenderedCellIndices, (i, index) => { + const cellMetadata = this._sectionManager.getCellMetadata(index); + rendered.push(cellMetadata); + }); + + return rendered; + } + + _calculateChildrenToRender() { + const o = this.options; + const { horizontalOverscanSize, verticalOverscanSize, width, height, itemFormatter, items } = this.options; + const scrollLeft = clamp(o.scrollLeft, 0, this._getMaxScrollLeft()); + const scrollTop = clamp(o.scrollTop, 0, this._getMaxScrollTop()); + const left = Math.max(0, scrollLeft - horizontalOverscanSize); + const top = Math.max(0, scrollTop - verticalOverscanSize); + const right = Math.min(this._width, scrollLeft + width + horizontalOverscanSize); + const bottom = Math.min(this._height, scrollTop + height + verticalOverscanSize); + if (right > 0 && bottom > 0) { + // 如果滚动的区间并没有超出渲染的范围 + if ( + top >= this.renderRange.minY && + bottom <= this.renderRange.maxY && + left >= this.renderRange.minX && + right <= this.renderRange.maxX + ) { + return; + } + const childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); + const renderedCells = [], + renderedKeys = {}, + renderedWidgets = {}; + // 存储所有的left和top + let lefts = {}, + tops = {}; + for (let i = 0, len = childrenToDisplay.length; i < len; i++) { + const datum = childrenToDisplay[i]; + lefts[datum.x] = datum.x; + lefts[datum.x + datum.width] = datum.x + datum.width; + tops[datum.y] = datum.y; + tops[datum.y + datum.height] = datum.y + datum.height; + } + lefts = toArray(lefts); + tops = toArray(tops); + const leftMap = invert(lefts); + const topMap = invert(tops); + // 存储上下左右四个边界 + const leftBorder = {}, + rightBorder = {}, + topBorder = {}, + bottomBorder = {}; + function assertMinBorder(border, offset) { + if (isNull(border[offset])) { + border[offset] = Number.MAX_VALUE; + } + } + function assertMaxBorder(border, offset) { + if (isNull(border[offset])) { + border[offset] = 0; + } + } + for (let i = 0, len = childrenToDisplay.length; i < len; i++) { + const datum = childrenToDisplay[i]; + const index = this.renderedKeys[datum.index] && this.renderedKeys[datum.index][1]; + let child; + if (index >= 0) { + this.renderedCells[index].el.setWidth(datum.width); + this.renderedCells[index].el.setHeight(datum.height); + // 这里只使用px + this.renderedCells[index].el.element.css("left", `${datum.x}px`); + this.renderedCells[index].el.element.css("top", `${datum.y}px`); + renderedCells.push((child = this.renderedCells[index])); + } else { + const item = itemFormatter(items[datum.index], datum.index); + child = _lazyCreateWidget( + extend( + { + type: Label.xtype, + width: datum.width, + height: datum.height, + }, + item, + { + cls: `${item.cls || ""} collection-cell${datum.y === 0 ? " first-row" : ""}${ + datum.x === 0 ? " first-col" : "" + }`, + _left: datum.x, + _top: datum.y, + } + ) + ); + renderedCells.push({ + el: child, + left: `${datum.x}px`, + top: `${datum.y}px`, + _left: datum.x, + _top: datum.y, + // _width: datum.width, + // _height: datum.height + }); + } + const startTopIndex = topMap[datum.y] | 0; + const endTopIndex = topMap[datum.y + datum.height] | 0; + for (let k = startTopIndex; k <= endTopIndex; k++) { + const t = tops[k]; + assertMinBorder(leftBorder, t); + assertMaxBorder(rightBorder, t); + leftBorder[t] = Math.min(leftBorder[t], datum.x); + rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width); + } + const startLeftIndex = leftMap[datum.x] | 0; + const endLeftIndex = leftMap[datum.x + datum.width] | 0; + for (let k = startLeftIndex; k <= endLeftIndex; k++) { + const l = lefts[k]; + assertMinBorder(topBorder, l); + assertMaxBorder(bottomBorder, l); + topBorder[l] = Math.min(topBorder[l], datum.y); + bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height); + } + + renderedKeys[datum.index] = [datum.index, i]; + renderedWidgets[i] = child; + } + // 已存在的, 需要添加的和需要删除的 + const existSet = {}, + addSet = {}, + deleteArray = []; + each(renderedKeys, (i, key) => { + if (this.renderedKeys[i]) { + existSet[i] = key; + } else { + addSet[i] = key; + } + }); + each(this.renderedKeys, (i, key) => { + if (existSet[i]) { + return; + } + if (addSet[i]) { + return; + } + deleteArray.push(key[1]); + }); + each(deleteArray, (i, index) => { + // 性能优化,不调用destroy方法防止触发destroy事件 + this.renderedCells[index].el._destroy(); + }); + const addedItems = []; + each(addSet, (index, key) => { + addedItems.push(renderedCells[key[1]]); + }); + this.container.addItems(addedItems); + // 拦截父子级关系 + this.container._children = renderedWidgets; + this.container.attr("items", renderedCells); + this.renderedCells = renderedCells; + this.renderedKeys = renderedKeys; + + // Todo 左右比较特殊 + const minX = min(leftBorder); + const maxX = max(rightBorder); + + const minY = max(topBorder); + const maxY = min(bottomBorder); + + this.renderRange = { minX, minY, maxX, maxY }; + } + } + + _isOverflowX() { + const o = this.options; + const { overflowX } = this.options; + // 兼容一下 + const scrollable = o.scrollable, + scrollx = o.scrollx; + if (overflowX === false) { + return false; + } + if (scrollx) { + return true; + } + if (scrollable === true || scrollable === "xy" || scrollable === "x") { + return true; + } + + return false; + } + + _isOverflowY() { + const o = this.options; + const { overflowY, scrollable, scrolly } = o; + // 兼容一下 + if (overflowY === false) { + return false; + } + if (scrolly) { + return true; + } + if (scrollable === true || scrollable === "xy" || scrollable === "y") { + return true; + } + + return false; + } + + _getMaxScrollLeft() { + return Math.max(0, this._width - this.options.width + (this._isOverflowX() ? DOM.getScrollWidth() : 0)); + } + + _getMaxScrollTop() { + return Math.max(0, this._height - this.options.height + (this._isOverflowY() ? DOM.getScrollWidth() : 0)); + } + + _populate(items) { + const { scrollTop, scrollLeft } = this.options; + this._reRange(); + if (items && items !== this.options.items) { + this.options.items = items; + this._calculateSizeAndPositionData(); + } + this.container.setWidth(this._width); + this.container.setHeight(this._height); + + this._debounceRelease(); + // 元素未挂载时不能设置scrollTop + try { + this.element.scrollTop(scrollTop); + this.element.scrollLeft(scrollLeft); + } catch (e) {} + this._calculateChildrenToRender(); + } + + setScrollLeft(scrollLeft) { + if (this.options.scrollLeft === scrollLeft) { + return; + } + this._scrollLock = true; + this.options.scrollLeft = clamp(scrollLeft || 0, 0, this._getMaxScrollLeft() || scrollLeft); + this._debounceRelease(); + this.element.scrollLeft(this.options.scrollLeft); + this._calculateChildrenToRender(); + } + + setScrollTop(scrollTop) { + if (this.options.scrollTop === scrollTop) { + return; + } + this._scrollLock = true; + this.options.scrollTop = clamp(scrollTop || 0, 0, this._getMaxScrollTop() || scrollTop); + this._debounceRelease(); + this.element.scrollTop(this.options.scrollTop); + this._calculateChildrenToRender(); + } + + setOverflowX(b) { + if (this.options.overflowX !== !!b) { + this.options.overflowX = !!b; + nextTick(() => { + this.element.css({ overflowX: b ? "auto" : "hidden" }); + }); + } + } + + setOverflowY(b) { + if (this.options.overflowY !== !!b) { + this.options.overflowY = !!b; + nextTick(() => { + this.element.css({ overflowY: b ? "auto" : "hidden" }); + }); + } + } + + getScrollLeft() { + return this.options.scrollLeft; + } + + getScrollTop() { + return this.options.scrollTop; + } + + getMaxScrollLeft() { + return this._getMaxScrollLeft(); + } + + getMaxScrollTop() { + return this._getMaxScrollTop(); + } + + // 重新计算children + _reRange() { + this.renderRange = {}; + } + + _clearChildren() { + this.container._children = {}; + this.container.attr("items", []); + } + + restore() { + each(this.renderedCells, (i, cell) => { + cell.el._destroy(); + }); + this._clearChildren(); + this.renderedCells = []; + this.renderedKeys = []; + this.renderRange = {}; + this._scrollLock = false; + } + + populate(items) { + if (items && items !== this.options.items) { + this.restore(); + } + this._populate(items); + } +} diff --git a/packages/fineui/src/base/combination/bubble.js b/packages/fineui/src/base/combination/bubble.js new file mode 100644 index 000000000..c78fcf111 --- /dev/null +++ b/packages/fineui/src/base/combination/bubble.js @@ -0,0 +1,575 @@ +import { BubblePopupView } from "@/case/combo/bubblecombo/popup.bubble"; +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + nextTick, + createWidget, + each, + defer, + debounce, + delay, + isNull, + isFunction, + contains, + bind, + Events, + emptyFn, + LogicFactory, + EVENT_RESPONSE_TIME, + EVENT_BLUR, +} from "@/core"; +import { createPopper } from "@popperjs/core"; + +@shortcut() +export class Bubble extends Widget { + static xtype = "bi.bubble"; + + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_EXPAND = "EVENT_EXPAND"; + static EVENT_COLLAPSE = "EVENT_COLLAPSE"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-popper`, + attributes: { + tabIndex: -1, + }, + trigger: "click", // click || hover || click-hover || "hover-click" || "" + toggle: true, + direction: "", + placement: "bottom-start", // top-start/top/top-end/bottom-start/bottom/bottom-end/left-start/left/left-end/right-start/right/right-end + logic: { + dynamic: true, + }, + container: null, // popupview放置的容器,默认为this.element + isDefaultInit: false, + destroyWhenHide: false, + hideWhenClickOutside: true, + showArrow: true, + hideWhenBlur: false, + isNeedAdjustHeight: true, // 是否需要高度调整 + isNeedAdjustWidth: true, + stopEvent: false, + stopPropagation: false, + adjustLength: 0, // 调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + hideChecker: emptyFn, + offsetStyle: "left", // left,right,center + el: {}, + popup: {}, + comboClass: "bi-combo-popup", + hoverClass: "bi-combo-hover", + }); + } + + render() { + const { hoverClass, logic, isDefaultInit } = this.options; + this._initCombo(); + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + nextTick(() => { + !this.isDestroyed() && this._initPullDownAction(); + }); + this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (this.isEnabled() && this.isValid()) { + if (type === Events.EXPAND) { + this._popupView(); + } + if (type === Events.COLLAPSE) { + this._hideView(); + } + if (type === Events.EXPAND) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.fireEvent(Bubble.EVENT_EXPAND); + } + if (type === Events.COLLAPSE) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.isViewVisible() && this.fireEvent(Bubble.EVENT_COLLAPSE); + } + if (type === Events.CLICK) { + this.fireEvent(Bubble.EVENT_TRIGGER_CHANGE, obj); + } + } + }); + + this.element.on(`mouseenter.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this.element.addClass(hoverClass); + } + }); + this.element.on(`mouseleave.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this.element.removeClass(hoverClass); + } + }); + + createWidget( + extend( + { + element: this, + scrolly: false, + }, + LogicFactory.createLogic( + "vertical", + extend(logic, { + items: [{ el: this.combo }], + }) + ) + ) + ); + isDefaultInit && this._assertPopupView(); + } + + _toggle(e) { + this._assertPopupViewRender(); + if (this.popupView.isVisible()) { + this._hideView(e); + } else { + if (this.isEnabled()) { + this._popupView(e); + } + } + } + + _initPullDownAction() { + const { stopEvent, stopPropagation, toggle } = this.options; + const evs = (this.options.trigger || "").split(","); + + const st = e => { + if (stopEvent) { + e.stopEvent(); + } + if (stopPropagation) { + e.stopPropagation(); + } + }; + + let enterPopup = false; + + const hide = e => { + if ( + this.isEnabled() && + this.isValid() && + this.combo.isEnabled() && + this.combo.isValid() && + toggle === true + ) { + this._hideView(e); + this.fireEvent(Controller.EVENT_CHANGE, Events.COLLAPSE, "", this.combo); + this.fireEvent(Bubble.EVENT_COLLAPSE); + } + this.popupView && + this.popupView.element.off(`mouseenter.${this.getName()}`).off(`mouseleave.${this.getName()}`); + enterPopup = false; + }; + + each(evs, (i, ev) => { + let debounced; + switch (ev) { + case "hover": + this.element.on(`mouseenter.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this._popupView(e); + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.combo); + this.fireEvent(Bubble.EVENT_EXPAND); + } + }); + this.element.on(`mouseleave.${this.getName()}`, e => { + if (this.popupView) { + this.popupView.element.on(`mouseenter.${this.getName()}`, e => { + enterPopup = true; + this.popupView.element.on(`mouseleave.${this.getName()}`, e => { + hide(e); + }); + this.popupView.element.off(`mouseenter.${this.getName()}`); + }); + defer(() => { + if (!enterPopup) { + hide(e); + } + }, 50); + } + }); + break; + case "click": + debounced = debounce( + e => { + if (this.combo.element.__isMouseInBounds__(e)) { + if ( + this.isEnabled() && + this.isValid() && + this.combo.isEnabled() && + this.combo.isValid() + ) { + // if (!o.toggle && this.isViewVisible()) { + // return; + // } + toggle ? this._toggle(e) : this._popupView(e); + if (this.isViewVisible()) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.combo); + this.fireEvent(Bubble.EVENT_EXPAND); + } else { + this.fireEvent(Controller.EVENT_CHANGE, Events.COLLAPSE, "", this.combo); + this.fireEvent(Bubble.EVENT_COLLAPSE); + } + } + } + }, + EVENT_RESPONSE_TIME, + { + leading: true, + trailing: false, + } + ); + this.element.off(`${ev}.${this.getName()}`).on(`${ev}.${this.getName()}`, e => { + debounced(e); + st(e); + }); + break; + case "click-hover": + debounced = debounce( + e => { + if (this.combo.element.__isMouseInBounds__(e)) { + if ( + this.isEnabled() && + this.isValid() && + this.combo.isEnabled() && + this.combo.isValid() + ) { + // if (this.isViewVisible()) { + // return; + // } + this._popupView(e); + if (this.isViewVisible()) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.combo); + this.fireEvent(Bubble.EVENT_EXPAND); + } + } + } + }, + EVENT_RESPONSE_TIME, + { + leading: true, + trailing: false, + } + ); + this.element.off(`click.${this.getName()}`).on(`click.${this.getName()}`, e => { + debounced(e); + st(e); + }); + this.element.on(`mouseleave.${this.getName()}`, e => { + if (this.popupView) { + this.popupView.element.on(`mouseenter.${this.getName()}`, e => { + enterPopup = true; + this.popupView.element.on(`mouseleave.${this.getName()}`, e => { + hide(e); + }); + this.popupView.element.off(`mouseenter.${this.getName()}`); + }); + delay(() => { + if (!enterPopup) { + hide(e); + } + }, 50); + } + }); + break; + case "hover-click": + this.element.on(`mouseenter.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this._popupView(e); + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.combo); + this.fireEvent(Bubble.EVENT_EXPAND); + } + }); + break; + default: + break; + } + }); + } + + _initCombo() { + this.combo = createWidget(this.options.el, { + value: this.options.value, + }); + } + + _assertPopupView() { + const { showArrow, value } = this.options; + if (isNull(this.popupView)) { + this.popupView = createWidget( + isFunction(this.options.popup) ? this.options.popup() : this.options.popup, + { + type: BubblePopupView.xtype, + showArrow, + value, + }, + this + ); + this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (type === Events.CLICK) { + this.combo.setValue(this.getValue()); + this.fireEvent(Bubble.EVENT_CHANGE, value, obj); + } + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + }); + this.popupView.setVisible(false); + nextTick(() => { + this.fireEvent(Bubble.EVENT_AFTER_INIT); + }); + } + } + + _assertPopupViewRender() { + this._assertPopupView(); + if (!this._rendered) { + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: isFunction(this.options.container) ? this.options.container() : this.options.container || this, + items: [{ el: this.popupView }], + }); + this._rendered = true; + } + } + + _hideIf(e, skipTriggerChecker) { + // if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { + // return; + // } + // BI-10290 公式combo双击公式内容会收起 + if ( + e && + ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) || + (this.popupView && this.popupView.element.find(e.target).length > 0) || + e.target.className === "CodeMirror-cursor" || + Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0) + ) { + // BI-9887 CodeMirror的公式弹框需要特殊处理下 + const directions = this.options.direction.split(","); + if (contains(directions, "innerLeft") || contains(directions, "innerRight")) { + // popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置 + this.adjustWidth(); + this.adjustHeight(); + } + + return; + } + const isHide = this.options.hideChecker.apply(this, [e]); + if (isHide === false) { + return; + } + this._hideView(e); + + return true; + } + + _hideView(e) { + const { hideWhenBlur } = this.options; + this.fireEvent(Bubble.EVENT_BEFORE_HIDEVIEW); + if (this.options.destroyWhenHide === true) { + this.popupView && this.popupView.destroy(); + this.popupView = null; + this._rendered = false; + } else { + this.popupView && this.popupView.invisible(); + } + + if (!e || !this.combo.element.__isMouseInBounds__(e)) { + this.element.removeClass(this.options.hoverClass); + // 应对bi-focus-shadow在收起时不失焦 + this.element.blur(); + } + + if (this.popper) { + this.popper.destroy(); + this.popper = null; + } + + this.element.removeClass(this.options.comboClass); + + Widget._renderEngine + .createElement(document) + .unbind(`mousedown.${this.getName()}`) + .unbind(`mousewheel.${this.getName()}`); + EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + this.fireEvent(Bubble.EVENT_AFTER_HIDEVIEW); + } + + _popupView(e) { + const { adjustXOffset, showArrow, adjustYOffset, adjustLength, placement, hideWhenClickOutside, hideWhenBlur } = + this.options; + this._assertPopupViewRender(); + this.fireEvent(Bubble.EVENT_BEFORE_POPUPVIEW); + // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 + // this.popupView.css({left: -999999999, top: -99999999}); + this.popupView.visible(); + this.adjustWidth(e); + + if (this.popper) { + this.popper.destroy(); + } + const modifiers = [ + { + name: "offset", + options: { + offset: () => [adjustXOffset, (showArrow ? 12 : 0) + (adjustYOffset + adjustLength)], + }, + }, + ]; + if (this.options.showArrow) { + modifiers.push({ + name: "arrow", + options: { + padding: 4, + element: this.popupView.arrow.element[0], + }, + }); + } + this.popper = createPopper(this.combo.element[0], this.popupView.element[0], { + placement, + strategy: "fixed", + modifiers, + }); + + // this.adjustHeight(e); + + this.element.addClass(this.options.comboClass); + hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`); + EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + + hideWhenClickOutside && + Widget._renderEngine.createElement(document).bind(`mousedown.${this.getName()}`, bind(this._hideIf, this)); + EVENT_BLUR && + hideWhenBlur && + Widget._renderEngine.createElement(window).bind(`blur.${this.getName()}`, bind(this._hideIf, this)); + this.fireEvent(Bubble.EVENT_AFTER_POPUPVIEW); + } + + adjustWidth(e) { + const { isNeedAdjustWidth } = this.options; + if (!this.popupView) { + return; + } + if (isNeedAdjustWidth === true) { + this.resetListWidth(""); + const width = this.popupView.element.outerWidth(); + let maxW = this.element.outerWidth() || this.options.width; + // BI-93885 最大列宽算法调整 + if (maxW < 500) { + if (width >= 500) { + maxW = 500; + } else if (width > maxW) { + // 防止小数导致差那么一点 + maxW = width + 1; + } + } + + // if (width > maxW + 80) { + // maxW = maxW + 80; + // } else if (width > maxW) { + // maxW = width; + // } + this.resetListWidth(maxW < 100 ? 100 : maxW); + } + } + + adjustHeight() {} + + resetListHeight(h) { + this._assertPopupView(); + this.popupView.resetHeight && this.popupView.resetHeight(h); + } + + resetListWidth(w) { + this._assertPopupView(); + this.popupView.resetWidth && this.popupView.resetWidth(w); + } + + populate(items) { + this._assertPopupView(); + this.popupView.populate(...arguments); + this.combo.populate && this.combo.populate(...arguments); + } + + _setEnable(arg) { + super._setEnable(...arguments); + if (arg === true) { + this.element.removeClass("base-disabled disabled"); + } else if (arg === false) { + this.element.addClass("base-disabled disabled"); + } + !arg && this.element.removeClass(this.options.hoverClass); + !arg && this.isViewVisible() && this._hideView(); + } + + setValue(v) { + this.combo.setValue(v); + if (isNull(this.popupView)) { + this.options.popup.value = v; + } else { + this.popupView.setValue(v); + } + } + + getValue() { + if (isNull(this.popupView)) { + return this.options.popup.value; + } else { + return this.popupView.getValue(); + } + } + + isViewVisible() { + return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); + } + + showView(e) { + // 减少popup 调整宽高的次数 + if (this.isEnabled() && this.combo.isEnabled() && !this.isViewVisible()) { + this._popupView(e); + } + } + + hideView(e) { + this._hideView(e); + } + + getView() { + return this.popupView; + } + + getPopupPosition() { + return this.position; + } + + toggle() { + this._toggle(); + } + + destroyed() { + Widget._renderEngine + .createElement(document) + .unbind(`click.${this.getName()}`) + .unbind(`mousedown.${this.getName()}`) + .unbind(`mouseenter.${this.getName()}`) + .unbind(`mouseleave.${this.getName()}`); + Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + this.popper && this.popper.destroy(); + this.popper = null; + this.popupView && this.popupView._destroy(); + } +} diff --git a/packages/fineui/src/base/combination/combo.js b/packages/fineui/src/base/combination/combo.js new file mode 100644 index 000000000..e3c5f5db8 --- /dev/null +++ b/packages/fineui/src/base/combination/combo.js @@ -0,0 +1,564 @@ +import { PopupView } from "../layer"; +import { Bubble } from "./bubble"; +import { + shortcut, + Widget, + Controller, + extend, + createWidget, + nextTick, + bind, + isNotNull, + isNull, + isFunction, + each, + Events, + EVENT_BLUR, + DOM, + emptyFn, + isIE, + LogicFactory +} from "@/core"; +import { Resizers } from "@/base/0.base"; + +let needHideWhenAnotherComboOpen = {}; +let currentOpenedCombos = {}; + +@shortcut() +export class Combo extends Bubble { + static xtype = "bi.combo"; + + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_EXPAND = "EVENT_EXPAND"; + static EVENT_COLLAPSE = "EVENT_COLLAPSE"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-combo${isIE() ? " hack" : ""}`, + attributes: { + tabIndex: -1, + }, + trigger: "click", // click || hover || click-hover || "" + toggle: true, + direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right||right,innerRight||right,innerLeft||innerRight||innerLeft + logic: { + dynamic: true, + }, + container: null, // popupview放置的容器,默认为this.element + isDefaultInit: false, + destroyWhenHide: false, + hideWhenBlur: true, + hideWhenAnotherComboOpen: false, + hideWhenClickOutside: true, + showArrow: false, + isNeedAdjustHeight: true, // 是否需要高度调整 + isNeedAdjustWidth: true, + stopEvent: false, + stopPropagation: false, + adjustLength: 0, // 调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + supportCSSTransform: true, + hideChecker: emptyFn, + offsetStyle: "", // "",center,middle + el: {}, + popup: {}, + comboClass: "bi-combo-popup", + hoverClass: "bi-combo-hover", + belowMouse: false, + }); + } + + render() { + const { hoverClass, logic, isDefaultInit } = this.options; + this._initCombo(); + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + nextTick(() => { + !this.isDestroyed() && this._initPullDownAction(); + }); + this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (this.isEnabled() && this.isValid()) { + if (type === Events.TOGGLE) { + this._toggle(); + } + if (type === Events.EXPAND) { + this._popupView(); + } + if (type === Events.COLLAPSE) { + this._hideView(); + } + if (type === Events.EXPAND) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.fireEvent(Combo.EVENT_EXPAND); + } + if (type === Events.COLLAPSE) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.isViewVisible() && this.fireEvent(Combo.EVENT_COLLAPSE); + } + if (type === Events.CLICK) { + this.fireEvent(Combo.EVENT_TRIGGER_CHANGE, obj); + } + } + }); + + this.element.on(`mouseenter.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this.element.addClass(hoverClass); + } + }); + this.element.on(`mouseleave.${this.getName()}`, e => { + if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { + this.element.removeClass(hoverClass); + } + }); + + createWidget( + extend( + { + element: this, + scrolly: false, + }, + LogicFactory.createLogic( + "vertical", + extend(logic, { + items: [{ el: this.combo }], + }) + ) + ) + ); + isDefaultInit && this._assertPopupView(); + Resizers.add( + this.getName(), + bind(e => { + // 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理 + if (this.isViewVisible()) { + isNotNull(e) ? this._hideIf(e) : this._hideView(); + } + }, this) + ); + } + + _assertPopupView() { + const { showArrow, value } = this.options; + if (isNull(this.popupView)) { + this.popupView = createWidget( + isFunction(this.options.popup) ? this.options.popup() : this.options.popup, + { + type: PopupView.xtype, + showArrow, + value, + }, + this + ); + this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (type === Events.CLICK) { + this.combo.setValue(this.getValue()); + this.fireEvent(Bubble.EVENT_CHANGE, value, obj); + } + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + }); + this.popupView.setVisible(false); + nextTick(() => { + this.fireEvent(Bubble.EVENT_AFTER_INIT); + }); + } + } + + _hideView(e) { + const { hideWhenClickOutside, hideWhenBlur } = this.options; + this.fireEvent(Combo.EVENT_BEFORE_HIDEVIEW); + if (this.options.destroyWhenHide === true) { + this.popupView && this.popupView.destroy(); + this.popupView = null; + this._rendered = false; + } else { + this.popupView && this.popupView.invisible(); + } + + if (!e || !this.combo.element.__isMouseInBounds__(e)) { + this.element.removeClass(this.options.hoverClass); + // 应对bi-focus-shadow在收起时不失焦 + this.element.blur(); + } + + this.element.removeClass(this.options.comboClass); + delete needHideWhenAnotherComboOpen[this.getName()]; + delete currentOpenedCombos[this.getName()]; + + hideWhenClickOutside && + Widget._renderEngine + .createElement(document) + .unbind(`mousedown.${this.getName()}`) + .unbind(`mousewheel.${this.getName()}`); + EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + this.fireEvent(Combo.EVENT_AFTER_HIDEVIEW, e); + } + + _popupView(e) { + const { hideWhenClickOutside, hideWhenBlur } = this.options; + this._assertPopupViewRender(); + this.fireEvent(Combo.EVENT_BEFORE_POPUPVIEW); + // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 + this.popupView.css({ left: -99999, top: -99999 }); + this.popupView.visible(); + each(needHideWhenAnotherComboOpen, (i, combo) => { + if (i !== this.getName()) { + if (combo && combo._hideIf(e, true) === true) { + delete needHideWhenAnotherComboOpen[i]; + } + } + }); + currentOpenedCombos[this.getName()] = this; + this.options.hideWhenAnotherComboOpen && (needHideWhenAnotherComboOpen[this.getName()] = this); + this.adjustWidth(e); + this.adjustHeight(e); + + this.element.addClass(this.options.comboClass); + hideWhenClickOutside && + Widget._renderEngine + .createElement(document) + .unbind(`mousedown.${this.getName()}`) + .unbind(`mousewheel.${this.getName()}`); + hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind(`mousewheel.${this.getName()}`); + EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + + hideWhenClickOutside && + Widget._renderEngine.createElement(document).bind(`mousewheel.${this.getName()}`, bind(this._hideIf, this)); + hideWhenClickOutside && + Widget._renderEngine + .createElement(document) + .bind(`mousedown.${this.getName()}`, bind(this._hideIf, this)) + .bind(`mousewheel.${this.getName()}`, bind(this._hideIf, this)); + EVENT_BLUR && + hideWhenBlur && + Widget._renderEngine.createElement(window).bind(`blur.${this.getName()}`, bind(this._hideIf, this)); + this.fireEvent(Combo.EVENT_AFTER_POPUPVIEW); + } + + adjustHeight(e) { + const { + belowMouse, + supportCSSTransform, + container, + direction, + adjustXOffset, + adjustYOffset, + adjustLength, + showArrow, + isNeedAdjustHeight, + offsetStyle, + } = this.options; + let p = {}; + if (!this.popupView) { + return; + } + const isVisible = this.popupView.isVisible(); + this.popupView.visible(); + const combo = + belowMouse && isNotNull(e) + ? { + element: { + 0: extend({}, e.target, { + getBoundingClientRect: function () { + return { + left: e.pageX, + top: e.pageY, + width: 0, + height: 0, + }; + } + }), + offset: function () { + return { + left: e.pageX, + top: e.pageY, + }; + }, + }, + } + : this.combo; + + const positionRelativeElement = DOM.getPositionRelativeContainingBlock( + isNull(container) + ? this.element[0] + : BI.isWidget(container) + ? container.element[0] + : BI.Widget._renderEngine.createElement(isFunction(container) ? container() : container)[0] + ); + + const TRIANGLE_LENGTH = 12; + switch (direction) { + case "bottom": + case "bottom,right": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight, + ["bottom", "top", "right", "left"], + offsetStyle, + positionRelativeElement + ); + break; + case "top": + case "top,right": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight, + ["top", "bottom", "right", "left"], + offsetStyle, + positionRelativeElement + ); + break; + case "left": + case "left,bottom": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["left", "right", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "right": + case "right,bottom": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["right", "left", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "top,left": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight, + ["top", "bottom", "left", "right"], + offsetStyle, + positionRelativeElement + ); + break; + case "bottom,left": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight, + ["bottom", "top", "left", "right"], + offsetStyle, + positionRelativeElement + ); + break; + case "left,top": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["left", "right", "top", "bottom"], + offsetStyle, + positionRelativeElement + ); + break; + case "right,top": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["right", "left", "top", "bottom"], + offsetStyle, + positionRelativeElement + ); + break; + case "right,innerRight": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["right", "left", "innerRight", "innerLeft", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "right,innerLeft": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["right", "left", "innerLeft", "innerRight", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "innerRight": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["innerRight", "innerLeft", "right", "left", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "innerLeft": + p = DOM.getComboPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + adjustYOffset, + isNeedAdjustHeight, + ["innerLeft", "innerRight", "left", "right", "bottom", "top"], + offsetStyle, + positionRelativeElement + ); + break; + case "top,custom": + case "custom,top": + p = DOM.getTopAdaptPosition( + combo, + this.popupView, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight + ); + p.dir = "top"; + break; + case "custom,bottom": + case "bottom,custom": + p = DOM.getBottomAdaptPosition( + combo, + this.popupView, + adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0), + isNeedAdjustHeight + ); + p.dir = "bottom"; + break; + case "left,custom": + case "custom,left": + p = DOM.getLeftAdaptPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0) + ); + delete p.top; + delete p.adaptHeight; + p.dir = "left"; + break; + case "custom,right": + case "right,custom": + p = DOM.getRightAdaptPosition( + combo, + this.popupView, + adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0) + ); + delete p.top; + delete p.adaptHeight; + p.dir = "right"; + break; + default: + break; + } + + if ("adaptHeight" in p) { + this.resetListHeight(p.adaptHeight); + } + + const width = this.combo.element.outerWidth(); + const height = this.combo.element.outerHeight(); + this.popupView.setDirection && + this.popupView.setDirection(p.dir, { + width, + height, + offsetStyle, + adjustXOffset, + adjustYOffset, + offset: this.combo.element.offset(), + }); + + if (supportCSSTransform) { + const positonedRect = positionRelativeElement.getBoundingClientRect(); + + const scaleX = positonedRect.width / positionRelativeElement.offsetWidth; + const scaleY = positonedRect.height / positionRelativeElement.offsetHeight; + + p.top && (p.top = Math.round(p.top / scaleY + positionRelativeElement.scrollTop)); + p.left && (p.left = Math.round(p.left / scaleX + positionRelativeElement.scrollLeft)); + + p.adaptHeight && (p.adaptHeight = Math.round(p.adaptHeight / scaleY)); + } + + if ("adaptHeight" in p) { + this.resetListHeight(p.adaptHeight); + } + + if ("left" in p) { + this.popupView.element.css({ + left: p.left, + }); + } + if ("top" in p) { + this.popupView.element.css({ + top: p.top, + }); + } + this.position = p; + this.popupView.setVisible(isVisible); + } + + destroyed() { + Widget._renderEngine + .createElement(document) + .unbind(`click.${this.getName()}`) + .unbind(`mousedown.${this.getName()}`) + .unbind(`mousewheel.${this.getName()}`) + .unbind(`mouseenter.${this.getName()}`) + .unbind(`mouseleave.${this.getName()}`); + Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`); + Resizers.remove(this.getName()); + this.popupView && this.popupView._destroy(); + delete needHideWhenAnotherComboOpen[this.getName()]; + delete currentOpenedCombos[this.getName()]; + } +} + +Combo.closeAll = () => { + each(currentOpenedCombos, (i, combo) => { + if (combo) { + combo.hideView(); + } + }); + currentOpenedCombos = {}; + needHideWhenAnotherComboOpen = {}; +}; diff --git a/packages/fineui/src/base/combination/expander.js b/packages/fineui/src/base/combination/expander.js new file mode 100644 index 000000000..ad418a0f9 --- /dev/null +++ b/packages/fineui/src/base/combination/expander.js @@ -0,0 +1,346 @@ +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + nextTick, + each, + debounce, + isNull, + createWidget, + Events, + EVENT_RESPONSE_TIME +} from "@/core"; +import { ButtonGroup } from "./group.button"; + +/** + * + * 某个可以展开的节点 + * + * Created by GUY on 2015/9/10. + * @class Expander + * @extends Widget + */ +@shortcut() +export class Expander extends Widget { + static xtype = "bi.expander"; + + static EVENT_EXPAND = "EVENT_EXPAND"; + static EVENT_COLLAPSE = "EVENT_COLLAPSE"; + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-expander", + trigger: "click", + toggle: true, + // direction: "bottom", //top,bottom四个方向 + isDefaultInit: false, // 是否默认初始化子节点 + el: {}, + popup: {}, + expanderClass: "bi-expander-popup", + hoverClass: "bi-expander-hover", + }); + } + + render() { + const { el, hoverClass, isDefaultInit } = this.options; + this._expanded = !!el.open; + this._initExpander(); + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + nextTick(() => { + !this.isDestroyed() && this._initPullDownAction(); + }); + this.expander.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (this.isEnabled() && this.isValid()) { + if (type === Events.EXPAND) { + this._popupView(); + } + if (type === Events.COLLAPSE) { + this._hideView(); + } + if (type === Events.EXPAND) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.fireEvent(Expander.EVENT_EXPAND); + } + if (type === Events.COLLAPSE) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.isViewVisible() && this.fireEvent(Expander.EVENT_COLLAPSE); + } + if (type === Events.CLICK) { + this.fireEvent(Expander.EVENT_TRIGGER_CHANGE, value, obj); + } + } + }); + + this.element.hover( + () => { + if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { + this.element.addClass(hoverClass); + } + }, + () => { + if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { + this.element.removeClass(hoverClass); + } + } + ); + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [{ el: this.expander }], + }); + isDefaultInit && this._assertPopupView(); + if (this.expander.isOpened() === true) { + this._popupView(); + } + } + + _toggle() { + this._assertPopupViewRender(); + if (this.popupView.isVisible()) { + this._hideView(); + } else { + if (this.isEnabled()) { + this._popupView(); + } + } + } + + _initPullDownAction() { + const { toggle } = this.options; + const evs = this.options.trigger.split(","); + each(evs, (i, e) => { + switch (e) { + case "hover": + this.element[e]( + e => { + if ( + this.isEnabled() && + this.isValid() && + this.expander.isEnabled() && + this.expander.isValid() + ) { + this._popupView(); + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.expander); + this.fireEvent(Expander.EVENT_EXPAND); + } + }, + () => { + if ( + this.isEnabled() && + this.isValid() && + this.expander.isEnabled() && + this.expander.isValid() && + toggle + ) { + this._hideView(); + this.fireEvent(Controller.EVENT_CHANGE, Events.COLLAPSE, "", this.expander); + this.fireEvent(Expander.EVENT_COLLAPSE); + } + } + ); + break; + case "click": + if (e) { + this.element.off(`${e}.${this.getName()}`).on( + `${e}.${this.getName()}`, + debounce( + e => { + if (this.expander.element.__isMouseInBounds__(e)) { + if ( + this.isEnabled() && + this.isValid() && + this.expander.isEnabled() && + this.expander.isValid() + ) { + toggle ? this._toggle() : this._popupView(); + if (this.isExpanded()) { + this.fireEvent( + Controller.EVENT_CHANGE, + Events.EXPAND, + "", + this.expander + ); + this.fireEvent(Expander.EVENT_EXPAND); + } else { + this.fireEvent( + Controller.EVENT_CHANGE, + Events.COLLAPSE, + "", + this.expander + ); + this.fireEvent(Expander.EVENT_COLLAPSE); + } + } + } + }, + EVENT_RESPONSE_TIME, + { + leading: true, + trailing: false, + } + ) + ); + } + break; + default: + break; + } + }); + } + + _initExpander() { + this.expander = createWidget(this.options.el); + } + + _assertPopupView() { + const { value } = this.options; + if (isNull(this.popupView)) { + this.popupView = createWidget( + this.options.popup, + { + type: ButtonGroup.xtype, + cls: "expander-popup", + layouts: [ + { + type: VerticalLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + value, + }, + this + ); + this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + // self.setValue(self.getValue()); + this.fireEvent(Expander.EVENT_CHANGE, value, obj); + } + }); + this.popupView.setVisible(this.isExpanded()); + nextTick(() => { + this.fireEvent(Expander.EVENT_AFTER_INIT); + }); + } + } + + _assertPopupViewRender() { + this._assertPopupView(); + if (!this._rendered) { + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [{ el: this.popupView }], + }); + this._rendered = true; + } + } + + _hideView() { + this.fireEvent(Expander.EVENT_BEFORE_HIDEVIEW); + this._expanded = false; + this.expander.setOpened(false); + this.popupView && this.popupView.invisible(); + this.element.removeClass(this.options.expanderClass); + + this.fireEvent(Expander.EVENT_AFTER_HIDEVIEW); + } + + _popupView() { + this._assertPopupViewRender(); + this.fireEvent(Expander.EVENT_BEFORE_POPUPVIEW); + this._expanded = true; + this.expander.setOpened(true); + this.popupView.visible(); + this.element.addClass(this.options.expanderClass); + this.fireEvent(Expander.EVENT_AFTER_POPUPVIEW); + } + + populate(items) { + // this._assertPopupView(); + this.popupView && this.popupView.populate(...arguments); + this.expander.populate && this.expander.populate(...arguments); + } + + _setEnable(arg) { + super._setEnable(...arguments); + !arg && this.element.removeClass(this.options.hoverClass); + !arg && this.isViewVisible() && this._hideView(); + } + + setValue(v) { + this.expander.setValue(v); + if (isNull(this.popupView)) { + this.options.popup.value = v; + } else { + this.popupView.setValue(v); + } + } + + getValue() { + if (isNull(this.popupView)) { + return this.options.popup.value; + } else { + return this.popupView.getValue(); + } + } + + isViewVisible() { + return this.isEnabled() && this.expander.isEnabled() && !!this.popupView && this.popupView.isVisible(); + } + + isExpanded() { + return this._expanded; + } + + showView() { + if (this.isEnabled() && this.expander.isEnabled()) { + this._popupView(); + } + } + + hideView() { + this._hideView(); + } + + getView() { + return this.popupView; + } + + getAllLeaves() { + return this.popupView && this.popupView.getAllLeaves(); + } + + getNodeById(id) { + if (this.expander.options.id === id) { + return this.expander; + } + + return this.popupView && this.popupView.getNodeById(id); + } + + getNodeByValue(value) { + if (this.expander.getValue() === value) { + return this.expander; + } + + return this.popupView && this.popupView.getNodeByValue(value); + } + + destroy() { + super.destroy(...arguments); + } +} diff --git a/packages/fineui/src/base/combination/group.button.js b/packages/fineui/src/base/combination/group.button.js new file mode 100644 index 000000000..1b228d4e6 --- /dev/null +++ b/packages/fineui/src/base/combination/group.button.js @@ -0,0 +1,429 @@ +import { + Selection, + CenterLayout, + shortcut, + Widget, + Controller, + extend, + createWidget, + createWidgets, + each, + isFunction, + isKey, + isNotEmptyArray, + createItems, + isArray, + remove, + map, + stripEL, + makeArrayByArray, + clone, + deepClone, + formatEL, + isEmpty, + concat, + removeAt, + deepContains, + has, + any, + Events +} from "@/core"; +import { TextButton } from "../single"; +import { BehaviorFactory } from "../behavior"; + +/** + * Created by GUY on 2015/6/26. + * @class ButtonGroup + * @extends Widget + */ + +@shortcut() +export class ButtonGroup extends Widget { + static xtype = "bi.button_group"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + static CHOOSE_TYPE_SINGLE = Selection.Single; + static CHOOSE_TYPE_MULTI = Selection.Multi; + static CHOOSE_TYPE_ALL = Selection.All; + static CHOOSE_TYPE_NONE = Selection.None; + static CHOOSE_TYPE_DEFAULT = Selection.Default; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-button-group", + behaviors: {}, + items: [], + value: "", + chooseType: Selection.Single, + layouts: [ + { + type: CenterLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + }); + } + + render() { + const { behaviors: optionsBehaviors, items: optionsItems, value } = this.options; + const behaviors = {}; + each(optionsBehaviors, (key, rule) => { + behaviors[key] = BehaviorFactory.createBehavior(key, { + rule, + }); + }); + this.behaviors = behaviors; + const items = isFunction(optionsItems) + ? this.__watch(optionsItems, (context, newValue) => { + this.populate(newValue); + }) + : optionsItems; + this.populate(items); + this.options.value = isFunction(value) + ? this.__watch(value, (context, newValue) => { + this.setValue(newValue); + }) + : value; + if (isKey(this.options.value) || isNotEmptyArray(this.options.value)) { + this.setValue(this.options.value); + } + } + + _createBtns(items) { + let btns; + Widget.execWithContext(this, () => { + btns = createWidgets( + createItems(items, { + type: TextButton.xtype, + }) + ); + }); + + return btns; + } + + _btnsCreator(items) { + const args = Array.prototype.slice.call(arguments); + const { chooseType } = this.options; + const buttons = this._createBtns(items); + args[0] = buttons; + + each(this.behaviors, (i, behavior) => { + behavior.doBehavior(...args); + }); + each(buttons, (i, btn) => { + btn.on(Controller.EVENT_CHANGE, (...arg) => { + const [type, value, obj] = arg; + if (type === Events.CLICK) { + switch (chooseType) { + case ButtonGroup.CHOOSE_TYPE_SINGLE: + this.setValue(btn.getValue()); + break; + case ButtonGroup.CHOOSE_TYPE_NONE: + this.setValue([]); + break; + default: + break; + } + this.fireEvent(Controller.EVENT_CHANGE, ...arg); + this.fireEvent(ButtonGroup.EVENT_CHANGE, value, obj); + } else { + this.fireEvent(Controller.EVENT_CHANGE, ...arg); + } + }); + btn.on(Events.DESTROY, () => { + remove(this.buttons, btn); + }); + }); + + return buttons; + } + + _packageBtns(btns) { + const { layouts: optionsLayouts } = this.options; + const layouts = isArray(optionsLayouts) ? optionsLayouts : [optionsLayouts]; + for (let i = layouts.length - 1; i > 0; i--) { + btns = map(btns, (k, it) => + extend({}, layouts[i], { + items: [ + extend({}, layouts[i].el, { + el: it, + }) + ], + }) + ); + } + + return btns; + } + + _packageSimpleItems(btns) { + const { items } = this.options; + + return map(items, (i, item) => { + if (stripEL(item) === item) { + return btns[i]; + } + + return extend({}, item, { + el: btns[i], + }); + }); + } + + _packageItems(items, packBtns) { + return createItems(makeArrayByArray(items, {}), clone(packBtns)); + } + + _packageLayout(items) { + const { layouts } = this.options; + const layout = deepClone(isArray(layouts) ? layouts[0] : layouts); + + let lay = formatEL(layout).el; + while (lay && lay.items && !isEmpty(lay.items)) { + lay = formatEL(lay.items[0]).el; + } + lay.items = items; + + return layout; + } + + // 如果是一个简单的layout + _isSimpleLayout() { + const { layouts, items } = this.options; + + return isArray(layouts) ? layouts.length === 1 && !isArray(items[0]) : true; + } + + doBehavior() { + const args = Array.prototype.slice.call(arguments); + args.unshift(this.buttons); + each(this.behaviors, (i, behavior) => { + behavior.doBehavior(...args); + }); + } + + prependItems(items) { + const btns = this._btnsCreator(...arguments); + this.buttons = concat(btns, this.buttons); + + if (this._isSimpleLayout() && this.layouts && this.layouts.prependItems) { + this.layouts.prependItems(btns); + + return; + } + + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.prependItems(this._packageLayout(items).items); + } + + addItems(items) { + const btns = this._btnsCreator(...arguments); + this.buttons = concat(this.buttons, btns); + + // 如果是一个简单的layout + if (this._isSimpleLayout() && this.layouts && this.layouts.addItems) { + this.layouts.addItems(btns); + + return; + } + + items = this._packageItems(items, this._packageBtns(btns)); + this.layouts.addItems(this._packageLayout(items).items); + } + + removeItemAt(indexes) { + removeAt(this.buttons, indexes); + this.layouts.removeItemAt(indexes); + } + + removeItems(values) { + values = isArray(values) ? values : [values]; + const deleted = []; + each(this.buttons, (i, button) => { + if (deepContains(values, button.getValue())) { + deleted.push(i); + } + }); + removeAt(this.buttons, deleted); + this.layouts.removeItemAt(deleted); + } + + populate(items) { + items = items || []; + this.empty(); + this.options.items = items; + + this.buttons = this._btnsCreator(...arguments); + if (this._isSimpleLayout()) { + items = this._packageSimpleItems(this.buttons); + } else { + items = this._packageItems(items, this._packageBtns(this.buttons)); + } + + this.layouts = createWidget(extend({ element: this }, this._packageLayout(items))); + } + + setNotSelectedValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (deepContains(v, item.getValue())) { + item.setSelected && item.setSelected(false); + } else { + item.setSelected && item.setSelected(true); + } + }); + } + + setEnabledValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (deepContains(v, item.getValue())) { + item.setEnable(true); + } else { + item.setEnable(false); + } + }); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (deepContains(v, item.getValue())) { + item.setSelected && item.setSelected(true); + } else { + item.setSelected && item.setSelected(false); + } + }); + } + + setValueMap(map) { + map = map || {}; + each(this.buttons, (i, item) => { + if (has(map, item.getValue())) { + item.setSelected && item.setSelected(true); + } else { + item.setSelected && item.setSelected(false); + } + }); + } + + setAllSelected(v) { + each(this.getAllButtons(), (i, btn) => { + (btn.setSelected || btn.setAllSelected).apply(btn, [v]); + }); + } + + getNotSelectedValue() { + const v = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !(item.isSelected && item.isSelected())) { + v.push(item.getValue()); + } + }); + + return v; + } + + getValue() { + const v = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && item.isSelected && item.isSelected()) { + v.push(item.getValue()); + } + }); + + return v; + } + + getAllButtons() { + return this.buttons; + } + + getAllLeaves() { + return this.buttons; + } + + getSelectedButtons() { + const btns = []; + each(this.buttons, (i, item) => { + if (item.isSelected && item.isSelected()) { + btns.push(item); + } + }); + + return btns; + } + + getNotSelectedButtons() { + const btns = []; + each(this.buttons, (i, item) => { + if (item.isSelected && !item.isSelected()) { + btns.push(item); + } + }); + + return btns; + } + + getIndexByValue(value) { + let index = -1; + any(this.buttons, (i, item) => { + if (item.isEnabled() && item.getValue() === value) { + index = i; + + return true; + } + }); + + return index; + } + + getNodeById(id) { + let node; + any(this.buttons, (i, item) => { + if (item.isEnabled() && item.options.id === id) { + node = item; + + return true; + } + }); + + return node; + } + + getNodeByValue(value) { + let node; + any(this.buttons, (i, item) => { + if (item.isEnabled() && item.getValue() === value) { + node = item; + + return true; + } + }); + + return node; + } + + /** + * 滚动到指定的节点 + */ + scrollToValue(value, scrollIntoViewOptions) { + const node = this.getNodeByValue(value); + if (node) { + node.element[0].scrollIntoView(scrollIntoViewOptions); + } + } + + empty() { + super.empty(...arguments); + this.options.items = []; + } + + destroy() { + super.destroy(...arguments); + this.options.items = []; + } +} diff --git a/packages/fineui/src/base/combination/group.combo.js b/packages/fineui/src/base/combination/group.combo.js new file mode 100644 index 000000000..252828ef8 --- /dev/null +++ b/packages/fineui/src/base/combination/group.combo.js @@ -0,0 +1,132 @@ +import { TextButton } from "../single"; +import { ButtonTree } from "./tree.button"; +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + isEmpty, + each, + formatEL, + clone, + createWidget, + Events +} from "@/core"; +import { Combo } from "./combo"; + +/** + * Created by GUY on 2015/8/10. + */ + +@shortcut() +export class ComboGroup extends Widget { + static xtype = "bi.combo_group"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-combo-group bi-list-item", + + // 以下这些属性对每一个combo都是公用的 + trigger: "click,hover", + direction: "right", + adjustLength: 0, + isDefaultInit: false, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + + el: { type: TextButton.xtype, text: "", value: "" }, + items: [], + + popup: { + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + }); + } + + render() { + this._populate(this.options.el); + } + + _populate(item) { + const { + items, + action, + height, + direction, + isDefaultInit, + isNeedAdjustHeight, + isNeedAdjustWidth, + adjustLength, + popup, + container, + trigger, + } = this.options; + const children = items; + if (isEmpty(children)) { + throw new Error("ComboGroup create items error"); + } + each(children, (i, ch) => { + const son = formatEL(ch).el.children; + ch = formatEL(ch).el; + if (!isEmpty(son)) { + ch.el = clone(ch); + ch.items = son; + ch.type = "bi.combo_group"; + ch.action = action; + ch.height = height; + ch.direction = direction; + ch.isDefaultInit = isDefaultInit; + ch.isNeedAdjustHeight = isNeedAdjustHeight; + ch.isNeedAdjustWidth = isNeedAdjustWidth; + ch.adjustLength = adjustLength; + ch.popup = popup; + } + }); + this.combo = createWidget({ + type: Combo.xtype, + element: this, + container, + height, + trigger, + direction, + isDefaultInit, + isNeedAdjustWidth, + isNeedAdjustHeight, + adjustLength, + el: item, + popup: extend({}, popup, { + el: extend( + { + items: children, + }, + popup.el + ), + }), + }); + this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + this.fireEvent(ComboGroup.EVENT_CHANGE, obj); + } + }); + } + + getValue() { + return this.combo.getValue(); + } + + setValue(v) { + this.combo.setValue(v); + } +} diff --git a/packages/fineui/src/base/combination/group.virtual.js b/packages/fineui/src/base/combination/group.virtual.js new file mode 100644 index 000000000..5b7cd7e32 --- /dev/null +++ b/packages/fineui/src/base/combination/group.virtual.js @@ -0,0 +1,174 @@ +import { + CenterLayout, + shortcut, + Widget, + Controller, + extend, + isFunction, + isKey, + isArray, + map, + stripEL, + deepClone, + formatEL, + isEmpty, + each, + createWidget +} from "@/core"; + +@shortcut() +export class VirtualGroup extends Widget { + static xtype = "bi.virtual_group"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-virtual-group", + items: [], + layouts: [ + { + type: CenterLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + }); + } + + render() { + const { items: optionsItems, value } = this.options; + const items = isFunction(optionsItems) + ? this.__watch(optionsItems, (context, newValue) => { + this.populate(newValue); + }) + : optionsItems; + this.populate(items); + this.options.value = isFunction(value) + ? this.__watch(value, (context, newValue) => { + this.setValue(newValue); + }) + : value; + if (isKey(value)) { + this.setValue(value); + } + } + + _packageBtns(items) { + const o = this.options; + const map = (this.buttonMap = {}); + const layouts = isArray(o.layouts) ? o.layouts : [o.layouts]; + for (let i = layouts.length - 1; i > 0; i--) { + items = map(items, (k, it) => { + const el = stripEL(it); + + return extend({}, layouts[i], { + items: [ + extend({}, layouts[i].el, { + el: extend( + { + ref: _ref => { + if (isKey(map[el.value])) { + map[el.value] = _ref; + } + }, + }, + el + ), + }) + ], + }); + }); + } + + return items; + } + + _packageLayout(items) { + const o = this.options; + const layouts = isArray(o.layouts) ? o.layouts : [o.layouts]; + const layout = deepClone(layouts[0]); + + let lay = formatEL(layout).el; + while (lay && lay.items && !isEmpty(lay.items)) { + lay = formatEL(lay.items[0]).el; + } + lay.items = items; + + return layout; + } + + addItems(items) { + this.layouts.addItems(items, this); + } + + prependItems(items) { + this.layouts.prependItems(items, this); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttonMap, (key, item) => { + if (item) { + if (v.deepContains(key)) { + item.setSelected && item.setSelected(true); + } else { + item.setSelected && item.setSelected(false); + } + } + }); + } + + getNotSelectedValue() { + const v = []; + each(this.buttonMap, (i, item) => { + if (item) { + if (item.isEnabled() && !(item.isSelected && item.isSelected())) { + v.push(item.getValue()); + } + } + }); + + return v; + } + + getNodeByValue(value) { + return this.buttonMap[value]; + } + + /** + * 滚动到指定的节点 + */ + scrollToValue(value, scrollIntoViewOptions) { + const node = this.getNodeByValue(value); + if (node) { + node.element[0].scrollIntoView(scrollIntoViewOptions); + } + } + + getValue() { + const v = []; + each(this.buttonMap, (i, item) => { + if (item) { + if (item.isEnabled() && item.isSelected && item.isSelected()) { + v.push(item.getValue()); + } + } + }); + + return v; + } + + populate(items) { + items = items || []; + this.options.items = items; + items = this._packageBtns(items); + if (!this.layouts) { + this.layouts = createWidget(extend({ element: this }, this._packageLayout(items))); + } else { + this.layouts.populate(items, { + context: this, + }); + } + } +} diff --git a/packages/fineui/src/base/combination/index.js b/packages/fineui/src/base/combination/index.js new file mode 100644 index 000000000..d2a5bee80 --- /dev/null +++ b/packages/fineui/src/base/combination/index.js @@ -0,0 +1,12 @@ +export { Bubble } from "./bubble"; +export { Combo } from "./combo"; +export { Expander } from "./expander"; +export { ButtonGroup } from "./group.button"; +export { ComboGroup } from "./group.combo"; +export { VirtualGroup } from "./group.virtual"; +export { Loader } from "./loader"; +export { Navigation } from "./navigation"; +export { Searcher } from "./searcher"; +export { Switcher } from "./switcher"; +export { Tab } from "./tab"; +export { ButtonTree } from "./tree.button"; diff --git a/packages/fineui/src/base/combination/loader.js b/packages/fineui/src/base/combination/loader.js new file mode 100644 index 000000000..4706d4c2a --- /dev/null +++ b/packages/fineui/src/base/combination/loader.js @@ -0,0 +1,347 @@ +import { ButtonGroup } from "./group.button"; +import { LoadingBar } from "../single"; +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + createWidget, + isEmpty, + nextTick, + bind, + isFunction, + isNotEmptyArray, + isNumber, + isObject, + each, + emptyFn, + Events, + LogicFactory +} from "@/core"; + +/** + * 加载控件 + * + * Created by GUY on 2015/8/31. + * @class Loader + * @extends Widget + */ + +@shortcut() +export class Loader extends Widget { + static xtype = "bi.loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-loader", + + direction: "top", + isDefaultInit: true, // 是否默认初始化数据 + logic: { + dynamic: true, + scrolly: true, + }, + + // 下面是button_group的属性 + el: { + type: ButtonGroup.xtype, + }, + + items: [], + itemsCreator: emptyFn, + onLoaded: emptyFn, + + // 下面是分页信息 + count: false, + prev: false, + next: {}, + hasPrev: emptyFn, + hasNext: emptyFn, + }); + } + + _prevLoad() { + const o = this.options; + this.prev.setLoading(); + o.itemsCreator.apply(this, [ + { times: --this.times }, + (...args) => { + this.prev.setLoaded(); + this.prependItems(...args); + } + ]); + } + + _nextLoad() { + const o = this.options; + this.next.setLoading(); + o.itemsCreator.apply(this, [ + { times: ++this.times }, + (...args) => { + this.next.setLoaded(); + this.addItems(...args); + } + ]); + } + + render() { + const { + itemsCreator, + el, + items: optionsItems, + value, + direction, + logic, + isDefaultInit, + } = this.options; + if (itemsCreator === false) { + this.options.prev = false; + this.options.next = false; + } + if (this.options.prev !== false) { + this.prev = createWidget( + extend( + { + type: LoadingBar.xtype, + }, + this.options.prev + ) + ); + this.prev.on(Controller.EVENT_CHANGE, type => { + if (type === Events.CLICK) { + this._prevLoad(); + } + }); + } + + this.button_group = createWidget(el, { + type: ButtonGroup.xtype, + chooseType: 0, + items: optionsItems, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value, + }); + this.button_group.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + this.fireEvent(Loader.EVENT_CHANGE, obj); + } + }); + + if (this.options.next !== false) { + this.next = createWidget( + extend( + { + type: LoadingBar.xtype, + }, + this.options.next + ) + ); + this.next.on(Controller.EVENT_CHANGE, type => { + if (type === Events.CLICK) { + this._nextLoad(); + } + }); + } + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(direction), + extend( + { + scrolly: true, + }, + logic, + { + items: LogicFactory.createLogicItemsByDirection( + direction, + this.prev, + this.button_group, + this.next + ), + } + ) + ) + ) + ); + + isDefaultInit && + isEmpty(optionsItems) && + nextTick( + bind(() => { + isDefaultInit && isEmpty(this.options.items) && this._populate(); + }, this) + ); + const items = isFunction(optionsItems) + ? this.__watch(optionsItems, (context, newValue) => { + this.populate(newValue); + }) + : optionsItems; + if (isNotEmptyArray(items)) { + this._populate(items); + } + } + + hasPrev() { + const { count, hasPrev } = this.options; + if (isNumber(count)) { + return this.count < count; + } + + return !!hasPrev.apply(this, [ + { + times: this.times, + count: this.count, + } + ]); + } + + hasNext() { + const { count, hasNext } = this.options; + if (isNumber(count)) { + return this.count < count; + } + + return !!hasNext.apply(this, [ + { + times: this.times, + count: this.count, + } + ]); + } + + prependItems(items) { + this.count += items.length; + if (this.next !== false) { + if (this.hasPrev()) { + this.options.items = this.options.items.concat(items); + this.prev.setLoaded(); + } else { + this.prev.setEnd(); + } + } + this.button_group.prependItems(...arguments); + } + + addItems(items) { + this.count += items.length; + if (isObject(this.next)) { + if (this.hasNext()) { + this.options.items = this.options.items.concat(items); + this.next.setLoaded(); + } else { + this.next.setEnd(); + } + } + this.button_group.addItems(...arguments); + } + + _populate(items) { + const o = this.options; + if (arguments.length === 0 && isFunction(o.itemsCreator)) { + o.itemsCreator.apply(this, [ + { times: 1 }, + (...args) => { + if (args.length === 0) { + throw new Error("Parameter cannot be empty"); + } + this.populate(...args); + o.onLoaded(); + } + ]); + + return false; + } + this.options.items = items; + this.times = 1; + this.count = 0; + this.count += items.length; + if (isObject(this.next)) { + if (this.hasNext()) { + this.next.setLoaded(); + } else { + this.next.invisible(); + } + } + if (isObject(this.prev)) { + if (this.hasPrev()) { + this.prev.setLoaded(); + } else { + this.prev.invisible(); + } + } + + return true; + } + + populate() { + this._populate(...arguments) && this.button_group.populate(...arguments); + } + + setNotSelectedValue() { + this.button_group.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.button_group.getNotSelectedValue(); + } + + setValue() { + this.button_group.setValue(...arguments); + } + + getValue() { + return this.button_group.getValue(...arguments); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + getAllLeaves() { + return this.button_group.getAllLeaves(); + } + + getSelectedButtons() { + return this.button_group.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.button_group.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.button_group.getIndexByValue(value); + } + + getNodeById(id) { + return this.button_group.getNodeById(id); + } + + getNodeByValue(value) { + return this.button_group.getNodeByValue(value); + } + + empty() { + this.button_group.empty(); + each([this.prev, this.next], (i, ob) => { + ob && ob.setVisible(false); + }); + } + + destroy() { + super.destroy(...arguments); + } +} diff --git a/packages/fineui/src/base/combination/navigation.js b/packages/fineui/src/base/combination/navigation.js new file mode 100644 index 000000000..f79df33a2 --- /dev/null +++ b/packages/fineui/src/base/combination/navigation.js @@ -0,0 +1,196 @@ +import { ButtonGroup } from "./group.button"; +import { + CardLayout, + shortcut, + Widget, + Controller, + extend, + createWidget, + bind, + ShowListener, + isFunction, + each, + nextTick, + isKey, + values, + emptyFn, + LogicFactory, + Events +} from "@/core"; + +/** + * Created by GUY on 2015/6/26. + */ + +@shortcut() +export class Navigation extends Widget { + static xtype = "bi.navigation"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + direction: "bottom", // top, bottom, left, right, custom + logic: { + dynamic: false, + }, + single: false, + showIndex: false, + tab: false, + cardCreator: v => createWidget(), + + afterCardCreated: emptyFn, + afterCardShow: emptyFn, + }); + } + + render() { + const { direction, logic, cardCreator, showIndex } = this.options; + this.tab = createWidget(this.options.tab, { type: ButtonGroup.xtype }); + this.cardMap = {}; + this.showIndex = 0; + this.layout = createWidget({ + type: CardLayout.xtype, + }); + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(direction), + extend({}, logic, { + items: LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout), + }) + ) + ) + ); + + new ShowListener({ + eventObj: this.tab, + cardLayout: this.layout, + cardNameCreator: v => this.showIndex + v, + cardCreator: v => { + Widget.execWithContext(this, () => { + this.cardMap[v] = cardCreator(v); + }); + + return this.cardMap[v]; + }, + afterCardCreated: bind(this.afterCardCreated, this), + afterCardShow: bind(this.afterCardShow, this), + }); + + if (isFunction(showIndex)) { + this.__watch(showIndex, (context, newValue) => { + this.setSelect(newValue); + }); + } + } + + created() { + const { showIndex } = this.options; + if (showIndex !== false) { + this.setSelect(showIndex); + } + } + + _deleteOtherCards(currCardName) { + const { single } = this.options; + if (single === true) { + each(this.cardMap, (name, card) => { + if (name !== `${currCardName}`) { + this.layout.deleteCardByName(name); + delete this.cardMap[name]; + } + }); + } + } + + afterCardCreated(v) { + this.cardMap[v].on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + this.fireEvent(Navigation.EVENT_CHANGE, obj); + } + }); + this.options.afterCardCreated.apply(this, arguments); + } + + afterCardShow(v) { + this.showIndex = v; + this._deleteOtherCards(v); + this.options.afterCardShow.apply(this, arguments); + } + + populate() { + const card = this.layout.getShowingCard(); + if (card) { + return card.populate(...arguments); + } + } + + _assertCard(v) { + const { cardCreator } = this.options; + if (!this.layout.isCardExisted(v)) { + Widget.execWithContext(this, () => { + this.cardMap[v] = cardCreator(v); + }); + this.layout.addCardByName(v, this.cardMap[v]); + this.afterCardCreated(v); + } + } + + setSelect(v) { + this._assertCard(v); + this.layout.showCardByName(v); + this._deleteOtherCards(v); + if (this.showIndex !== v) { + this.showIndex = v; + nextTick(bind(this.afterCardShow, this, v)); + } + } + + getSelect() { + return this.showIndex; + } + + getSelectedCard() { + if (isKey(this.showIndex)) { + return this.cardMap[this.showIndex]; + } + } + + getAllCard() { + return values(this.cardMap); + } + + /** + * @override + */ + setValue(v) { + const card = this.layout.getShowingCard(); + if (card) { + card.setValue(v); + } + } + + /** + * @override + */ + getValue() { + const card = this.layout.getShowingCard(); + if (card) { + return card.getValue(); + } + } + + empty() { + this.layout.deleteAllCard(); + this.cardMap = {}; + } + + destroy() { + super.destroy(...arguments); + } +} diff --git a/packages/fineui/src/base/combination/searcher.js b/packages/fineui/src/base/combination/searcher.js new file mode 100644 index 000000000..bd161c7ef --- /dev/null +++ b/packages/fineui/src/base/combination/searcher.js @@ -0,0 +1,385 @@ +import { SearchEditor } from "@/widget/editor/editor.search.js"; +import { SearcherView } from "../layer"; +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + createWidget, + debounce, + bind, + endWith, + deepWithout, + nextTick, + isEmptyString, + isNull, + BlankSplitChar, + Events, + EVENT_RESPONSE_TIME, + Func, + isFunction, +} from "@/core"; +import { ButtonGroup } from "./group.button"; +import { Maskers } from "@/base/0.base"; + +/** + * 搜索逻辑控件 + * + * Created by GUY on 2015/9/28. + * @class Searcher + * @extends Widget + */ + +@shortcut() +export class Searcher extends Widget { + static xtype = "bi.searcher"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-searcher", + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + hgap: 0, + + isDefaultInit: false, + isAutoSearch: true, // 是否自动搜索 + isAutoSync: true, // 是否自动同步数据, 即是否保持搜索面板和adapter面板状态值的统一 + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + + // isAutoSearch为false时启用 + onSearch: (op, callback) => { + callback([]); + }, + + el: { + type: SearchEditor.xtype, + }, + + popup: { + type: SearcherView.xtype, + }, + + adapter: null, + masker: { + // masker层 + offset: {}, + }, + + simple: false, + }); + } + + render() { + const { el, lgap, rgap, tgap, bgap, vgap, hgap, isDefaultInit, simple } = this.options; + + this.editor = createWidget(el, { + type: SearchEditor.xtype, + simple, + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + lgap, + rgap, + tgap, + bgap, + vgap, + hgap, + items: [this.editor], + }); + isDefaultInit && this._assertPopupView(); + + const search = debounce(bind(this._search, this), EVENT_RESPONSE_TIME, { + leading: true, + trailing: false, + }); + this.editor.on(Controller.EVENT_CHANGE, type => { + switch (type) { + case Events.STARTEDIT: + this._startSearch(); + break; + case Events.EMPTY: + this._stopSearch(); + break; + case Events.CHANGE: + search(); + break; + case Events.PAUSE: + if (endWith(this.editor.getValue(), BlankSplitChar)) { + this._pauseSearch(); + } + break; + default: + break; + } + }); + } + + _assertPopupView() { + const { masker, popup, chooseType, isAutoSync } = this.options; + const adapter = isFunction(this.options.adapter) ? this.options.adapter() : this.options.adapter; + if ((masker && !Maskers.has(this.getName())) || (masker === false && !this.popupView)) { + this.popupView = createWidget(popup, { + type: SearcherView.xtype, + chooseType, + }); + this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + if (isAutoSync) { + const values = adapter && adapter.getValue(); + switch (chooseType) { + case ButtonGroup.CHOOSE_TYPE_SINGLE: + adapter && adapter.setValue([obj.getValue()]); + break; + case ButtonGroup.CHOOSE_TYPE_MULTI: + if (!obj.isSelected()) { + adapter && adapter.setValue(deepWithout(values, obj.getValue())); + } + values.push(obj.getValue()); + adapter && adapter.setValue(values); + break; + default: + break; + } + } + this.fireEvent(Searcher.EVENT_CHANGE, value, obj); + } + }); + nextTick(() => { + this.fireEvent(Searcher.EVENT_AFTER_INIT); + }); + } + if (masker && !Maskers.has(this.getName())) { + Maskers.create( + this.getName(), + adapter, + extend( + { + container: this, + render: this.popupView, + }, + masker + ), + this + ); + } + } + + _startSearch() { + this._assertPopupView(); + this._stop = false; + this._isSearching = true; + this.fireEvent(Searcher.EVENT_START); + this.popupView.startSearch && this.popupView.startSearch(); + // 搜索前先清空dom + // Maskers.get(this.getName()).empty(); + nextTick(name => { + Maskers.show(name); + }, this.getName()); + } + + _pauseSearch() { + this._stop = true; + nextTick(name => { + Maskers.hide(name); + }, this.getName()); + if (this._isSearching === true) { + this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); + this.fireEvent(Searcher.EVENT_PAUSE); + } + this._isSearching = false; + } + + _stopSearch() { + const name = this.getName(); + this._stop = true; + Maskers.hide(name); + if (this._isSearching === true) { + this.popupView && this.popupView.stopSearch && this.popupView.stopSearch(); + this.fireEvent(Searcher.EVENT_STOP); + } + this._isSearching = false; + } + + _search() { + const { isAutoSearch, isAutoSync, onSearch } = this.options; + const adapter = isFunction(this.options.adapter) ? this.options.adapter() : this.options.adapter; + const keyword = this.editor.getValue(); + if (keyword === "" || this._stop) { + return; + } + if (isAutoSearch) { + const items = (adapter && ((adapter.getItems && adapter.getItems()) || adapter.attr("items"))) || []; + const finding = Func.getSearchResult(items, keyword); + const match = finding.match, + find = finding.find; + this.popupView.populate(find, match, keyword); + isAutoSync && adapter && adapter.getValue && this.popupView.setValue(adapter.getValue()); + this.fireEvent(Searcher.EVENT_SEARCHING); + + return; + } + this.popupView.loading && this.popupView.loading(); + onSearch( + { + times: 1, + keyword, + selectedValues: adapter && adapter.getValue(), + }, + (...args) => { + if (!this._stop && keyword === this.editor.getValue()) { + const _args = args; + if (_args.length > 0) { + _args.push(keyword); + } + Maskers.show(this.getName()); + this.popupView.populate(..._args); + isAutoSync && adapter && adapter.getValue && this.popupView.setValue(adapter.getValue()); + this.popupView.loaded && this.popupView.loaded(); + this.fireEvent(Searcher.EVENT_SEARCHING); + } + } + ); + } + + _getLastSearchKeyword() { + if (this.isValid()) { + let res = this.editor.getValue().split(/\u200b\s\u200b/); + if (isEmptyString(res[res.length - 1])) { + res = res.slice(0, res.length - 1); + } + + return isNull(res) ? "" : res[res.length - 1]; + } + } + + setAdapter(adapter) { + this.options.adapter = adapter; + Maskers.remove(this.getName()); + } + + doSearch() { + if (this.isSearching()) { + this._search(); + } + } + + stopSearch() { + this._stopSearch(); // 先停止搜索,然后再去设置editor为空 + // important:停止搜索必须退出编辑状态,这里必须加上try(input框不显示时blur会抛异常) + try { + this.editor.blur(); + } catch (e) { + if (!this.editor.blur) { + throw new Error("The editor does not implement the blur method"); + } + } finally { + this.editor.setValue(""); + } + } + + isSearching() { + return this._isSearching; + } + + isViewVisible() { + return this.editor.isEnabled() && Maskers.isVisible(this.getName()); + } + + getView() { + return this.popupView; + } + + hasMatched() { + this._assertPopupView(); + + return this.popupView.hasMatched(); + } + + adjustHeight() { + if (Maskers.has(this.getName()) && Maskers.get(this.getName()).isVisible()) { + Maskers.show(this.getName()); + } + } + + adjustView() { + this.isViewVisible() && Maskers.show(this.getName()); + } + + setValue(v) { + if (isNull(this.popupView)) { + this.options.popup.value = v; + } else { + this.popupView.setValue(v); + } + } + + getKeyword() { + return this._getLastSearchKeyword(); + } + + getKeywords() { + return this.editor.getKeywords(); + } + + getValue() { + const { isAutoSync, popup } = this.options; + const adapter = isFunction(this.options.adapter) ? this.options.adapter() : this.options.adapter; + if (isAutoSync && adapter && adapter.getValue) { + return adapter.getValue(); + } + if (this.isSearching()) { + return this.popupView.getValue(); + } else if (adapter && adapter.getValue) { + return adapter.getValue(); + } + if (isNull(this.popupView)) { + return popup.value; + } + + return this.popupView.getValue(); + } + + populate(result, searchResult, keyword) { + const { isAutoSync } = this.options; + const adapter = isFunction(this.options.adapter) ? this.options.adapter() : this.options.adapter; + this._assertPopupView(); + this.popupView.populate(...arguments); + if (isAutoSync && adapter && adapter.getValue) { + this.popupView.setValue(adapter.getValue()); + } + } + + empty() { + this.popupView && this.popupView.empty(); + } + + destroyed() { + Maskers.remove(this.getName()); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/base/combination/switcher.js b/packages/fineui/src/base/combination/switcher.js new file mode 100644 index 000000000..dfb0c1da9 --- /dev/null +++ b/packages/fineui/src/base/combination/switcher.js @@ -0,0 +1,345 @@ +import { + VerticalLayout, + shortcut, + Widget, + Controller, + extend, + nextTick, + createWidget, + each, + debounce, + isNull, + Events, + Direction, + EVENT_RESPONSE_TIME, isFunction +} from "@/core"; +import { ButtonGroup } from "./group.button"; +import { Maskers } from "@/base/0.base"; + +/** + * + * 切换显示或隐藏面板 + * + * Created by GUY on 2015/11/2. + * @class Switcher + * @extends Widget + */ + +@shortcut() +export class Switcher extends Widget { + static xtype = "bi.switcher"; + + static EVENT_EXPAND = "EVENT_EXPAND"; + static EVENT_COLLAPSE = "EVENT_COLLAPSE"; + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-switcher", + direction: Direction.Top, + trigger: "click", + toggle: true, + el: {}, + popup: {}, + adapter: null, + masker: {}, + switcherClass: "bi-switcher-popup", + hoverClass: "bi-switcher-hover", + }); + } + + render() { + const { hoverClass, isDefaultInit } = this.options; + this._initSwitcher(); + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + nextTick(() => { + !this.isDestroyed() && this._initPullDownAction(); + }); + this.switcher.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (this.isEnabled() && this.isValid()) { + if (type === Events.EXPAND) { + this._popupView(); + } + if (type === Events.COLLAPSE) { + this._hideView(); + } + if (type === Events.EXPAND) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.fireEvent(Switcher.EVENT_EXPAND); + } + if (type === Events.COLLAPSE) { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + this.isViewVisible() && this.fireEvent(Switcher.EVENT_COLLAPSE); + } + if (type === Events.CLICK) { + this.fireEvent(Switcher.EVENT_TRIGGER_CHANGE, value, obj); + } + } + }); + + this.element.hover( + () => { + if (this.isEnabled() && this.switcher.isEnabled()) { + this.element.addClass(hoverClass); + } + }, + () => { + if (this.isEnabled() && this.switcher.isEnabled()) { + this.element.removeClass(hoverClass); + } + } + ); + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [{ el: this.switcher }], + }); + isDefaultInit && this._assertPopupView(); + } + + _toggle() { + this._assertPopupView(); + if (this.isExpanded()) { + this._hideView(); + } else { + if (this.isEnabled()) { + this._popupView(); + } + } + } + + _initPullDownAction() { + const { toggle } = this.options; + const evs = this.options.trigger.split(","); + each(evs, (i, e) => { + switch (e) { + case "hover": + this.element[e]( + e => { + if (this.isEnabled() && this.switcher.isEnabled()) { + this._popupView(); + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, "", this.switcher); + this.fireEvent(Switcher.EVENT_EXPAND); + } + }, + () => { + if (this.isEnabled() && this.switcher.isEnabled() && toggle) { + this._hideView(); + this.fireEvent(Controller.EVENT_CHANGE, Events.COLLAPSE, "", this.switcher); + this.fireEvent(Switcher.EVENT_COLLAPSE); + } + } + ); + break; + default: + if (e) { + this.element.off(`${e}.${this.getName()}`).on( + `${e}.${this.getName()}`, + debounce( + e => { + if (this.switcher.element.__isMouseInBounds__(e)) { + if (this.isEnabled() && this.switcher.isEnabled()) { + toggle ? this._toggle() : this._popupView(); + if (this.isExpanded()) { + this.fireEvent( + Controller.EVENT_CHANGE, + Events.EXPAND, + "", + this.switcher + ); + this.fireEvent(Switcher.EVENT_EXPAND); + } else { + this.fireEvent( + Controller.EVENT_CHANGE, + Events.COLLAPSE, + "", + this.switcher + ); + this.fireEvent(Switcher.EVENT_COLLAPSE); + } + } + } + }, + EVENT_RESPONSE_TIME, + { + leading: true, + trailing: false, + } + ) + ); + } + break; + } + }); + } + + _initSwitcher() { + this.switcher = createWidget(this.options.el, { + value: this.options.value, + }); + } + + _assertPopupView() { + const { popup, masker, value, direction } = this.options; + const adapter = isFunction(this.options.adapter) ? this.options.adapter() : this.options.adapter; + if (!this._created) { + this.popupView = createWidget( + popup, + { + type: ButtonGroup.xtype, + element: adapter && Maskers.create(this.getName(), adapter, extend({ container: this }, masker)), + cls: "switcher-popup", + layouts: [ + { + type: VerticalLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + value, + }, + this + ); + this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + if (type === Events.CLICK) { + this.fireEvent(Switcher.EVENT_CHANGE, value, obj); + } + }); + if (direction !== Direction.Custom && !adapter) { + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [{ el: this.popupView }], + }); + } + this._created = true; + nextTick(() => { + this.fireEvent(Switcher.EVENT_AFTER_INIT); + }); + } + } + + _hideView() { + this.fireEvent(Switcher.EVENT_BEFORE_HIDEVIEW); + const { adapter, switcherClass } = this.options; + adapter ? Maskers.hide(this.getName()) : this.popupView && this.popupView.setVisible(false); + nextTick(() => { + adapter ? Maskers.hide(this.getName()) : this.popupView && this.popupView.setVisible(false); + this.element.removeClass(switcherClass); + this.fireEvent(Switcher.EVENT_AFTER_HIDEVIEW); + }); + } + + _popupView() { + const { adapter, switcherClass } = this.options; + this._assertPopupView(); + this.fireEvent(Switcher.EVENT_BEFORE_POPUPVIEW); + adapter ? Maskers.show(this.getName()) : this.popupView.setVisible(true); + nextTick(name => { + adapter ? Maskers.show(name) : this.popupView.setVisible(true); + this.element.addClass(switcherClass); + this.fireEvent(Switcher.EVENT_AFTER_POPUPVIEW); + }, this.getName()); + } + + _populate() { + this._assertPopupView(); + this.popupView.populate(...arguments); + } + + populate(items) { + this._populate(...arguments); + this.switcher.populate && this.switcher.populate(...arguments); + } + + _setEnable(arg) { + super._setEnable(...arguments); + !arg && this.isViewVisible() && this._hideView(); + } + + setValue(v) { + this.switcher.setValue(v); + if (isNull(this.popupView)) { + this.options.popup.value = v; + } else { + this.popupView.setValue(v); + } + } + + getValue() { + if (isNull(this.popupView)) { + return this.options.popup.value; + } else { + return this.popupView.getValue(); + } + } + + setAdapter(adapter) { + this.options.adapter = adapter; + Maskers.remove(this.getName()); + } + + isViewVisible() { + return ( + this.isEnabled() && + this.switcher.isEnabled() && + (this.options.adapter ? Maskers.isVisible(this.getName()) : this.popupView && this.popupView.isVisible()) + ); + } + + isExpanded() { + return this.isViewVisible(); + } + + showView() { + if (this.isEnabled() && this.switcher.isEnabled()) { + this._popupView(); + } + } + + hideView() { + this._hideView(); + } + + getView() { + return this.popupView; + } + + adjustView() { + this.isViewVisible() && Maskers.show(this.getName()); + } + + getAllLeaves() { + return this.popupView && this.popupView.getAllLeaves(); + } + + getNodeById(id) { + if (this.switcher.attr("id") === id) { + return this.switcher; + } + + return this.popupView && this.popupView.getNodeById(id); + } + + getNodeByValue(value) { + if (this.switcher.getValue() === value) { + return this.switcher; + } + + return this.popupView && this.popupView.getNodeByValue(value); + } + + empty() { + this.popupView && this.popupView.empty(); + } +} diff --git a/packages/fineui/src/base/combination/tab.js b/packages/fineui/src/base/combination/tab.js new file mode 100644 index 000000000..6f025baf4 --- /dev/null +++ b/packages/fineui/src/base/combination/tab.js @@ -0,0 +1,205 @@ +import { ButtonGroup } from "./group.button"; +import { + CardLayout, + shortcut, + Widget, + Controller, + ShowListener, + extend, + createWidget, + isObject, + each, + isFunction, + contains, + any, + isEqual, + LogicFactory +} from "@/core"; + +/** + * Created by GUY on 2015/6/26. + */ + +@shortcut() +export class Tab extends Widget { + static xtype = "bi.tab"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-tab", + direction: "top", // top, bottom, left, right, custom + single: false, // 是不是单页面 + logic: { + dynamic: false, + }, + showIndex: false, + tab: false, + cardCreator: v => createWidget(), + keepAlives: [], + }); + } + + render() { + const { tab, direction, logic, cardCreator } = this.options; + if (isObject(tab)) { + this.tab = createWidget(this.options.tab, { type: ButtonGroup.xtype }); + this.tab.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + }); + } + this.cardMap = {}; + this.layout = createWidget({ + type: CardLayout.xtype, + }); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(direction), + extend({}, logic, { + items: LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout), + }) + ) + ) + ); + + const listener = new ShowListener({ + eventObj: this.tab, + cardLayout: this.layout, + cardCreator: v => { + Widget.execWithContext(this, () => { + this.cardMap[v] = cardCreator(v); + }); + + return this.cardMap[v]; + }, + afterCardShow: v => { + this._deleteOtherCards(v); + this.curr = v; + }, + }); + listener.on(ShowListener.EVENT_CHANGE, value => { + this.fireEvent(Tab.EVENT_CHANGE, value, this); + }); + } + + _deleteOtherCards(currCardName) { + const { single } = this.options; + if (single === true) { + each(this.cardMap, (name, card) => { + if (name !== `${currCardName}` && this._keepAlive(name) !== true) { + this.layout.deleteCardByName(name); + delete this.cardMap[name]; + } + }); + } + } + + _assertCard(v) { + const { cardCreator } = this.options; + if (!this.layout.isCardExisted(v)) { + Widget.execWithContext(this, () => { + this.cardMap[v] = cardCreator(v); + }); + this.layout.addCardByName(v, this.cardMap[v]); + } + } + + _keepAlive(v) { + const { keepAlives } = this.options; + + return isFunction(keepAlives) ? keepAlives(v) : contains(keepAlives, v); + } + + created() { + const o = this.options; + let showIndex; + + if (isFunction(o.showIndex)) { + showIndex = this.__watch(o.showIndex, (context, newValue) => { + this.setSelect(newValue); + }); + } else { + showIndex = o.showIndex; + } + + if (showIndex !== false) { + this.setSelect(showIndex); + } + } + + setSelect(v, action, callback) { + this.tab && this.tab.setValue(v); + this._assertCard(v); + this.layout.showCardByName(v, action, callback); + this._deleteOtherCards(v); + if (this.curr !== v) { + this.curr = v; + } + } + + removeTab(cardname) { + any(this.cardMap, (name, card) => { + if (isEqual(name, `${cardname}`)) { + this.layout.deleteCardByName(name); + delete this.cardMap[name]; + + return true; + } + }); + } + + isCardExisted(cardName) { + return this.layout.isCardExisted(cardName); + } + + getSelect() { + return this.curr; + } + + getSelectedTab() { + return this.layout.getShowingCard(); + } + + getTab(v) { + this._assertCard(v); + + return this.layout.getCardByName(v); + } + + setValue(v) { + const card = this.layout.getShowingCard(); + if (card) { + card.setValue(v); + } + } + + getValue() { + const card = this.layout.getShowingCard(); + if (card) { + return card.getValue(); + } + } + + populate() { + const card = this.layout.getShowingCard(); + if (card) { + return card.populate && card.populate(...arguments); + } + } + + empty() { + this.layout.deleteAllCard(); + this.cardMap = {}; + } + + destroy() { + this.cardMap = {}; + super.destroy(...arguments); + } +} diff --git a/packages/fineui/src/base/combination/tree.button.js b/packages/fineui/src/base/combination/tree.button.js new file mode 100644 index 000000000..48bd626b5 --- /dev/null +++ b/packages/fineui/src/base/combination/tree.button.js @@ -0,0 +1,198 @@ +import { ButtonGroup } from "./group.button"; +import { shortcut, extend, isArray, each, isFunction, deepContains, concat, any, contains } from "@/core"; + +@shortcut() +export class ButtonTree extends ButtonGroup { + static xtype = "bi.button_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-button-tree", + }); + } + + setNotSelectedValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (!isFunction(item.setSelected)) { + item.setNotSelectedValue(v); + + return; + } + if (deepContains(v, item.getValue())) { + item.setSelected(false); + } else { + item.setSelected(true); + } + }); + } + + setEnabledValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (isFunction(item.setEnabledValue)) { + item.setEnabledValue(v); + + return; + } + if (deepContains(v, item.getValue())) { + item.setEnable(true); + } else { + item.setEnable(false); + } + }); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + each(this.buttons, (i, item) => { + if (!isFunction(item.setSelected)) { + item.setValue(v); + + return; + } + if (deepContains(v, item.getValue())) { + item.setSelected(true); + } else { + item.setSelected(false); + } + }); + } + + getNotSelectedValue() { + let v = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !isFunction(item.setSelected)) { + v = concat(v, item.getNotSelectedValue()); + + return; + } + if (item.isEnabled() && item.isSelected && !item.isSelected()) { + v.push(item.getValue()); + } + }); + + return v; + } + + getValue() { + let v = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !isFunction(item.setSelected)) { + v = concat(v, item.getValue()); + + return; + } + if (item.isEnabled() && item.isSelected && item.isSelected()) { + v.push(item.getValue()); + } + }); + + return v; + } + + getSelectedButtons() { + let btns = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !isFunction(item.setSelected)) { + btns = btns.concat(item.getSelectedButtons()); + + return; + } + if (item.isSelected && item.isSelected()) { + btns.push(item); + } + }); + + return btns; + } + + getNotSelectedButtons() { + let btns = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !isFunction(item.setSelected)) { + btns = btns.concat(item.getNotSelectedButtons()); + + return; + } + if (item.isSelected && !item.isSelected()) { + btns.push(item); + } + }); + + return btns; + } + + // 获取所有的叶子节点 + getAllLeaves() { + let leaves = []; + each(this.buttons, (i, item) => { + if (item.isEnabled() && !isFunction(item.setSelected)) { + leaves = leaves.concat(item.getAllLeaves()); + + return; + } + if (item.isEnabled()) { + leaves.push(item); + } + }); + + return leaves; + } + + getIndexByValue(value) { + let index = -1; + any(this.buttons, (i, item) => { + const vs = item.getValue(); + if (item.isEnabled() && (vs === value || contains(vs, value))) { + index = i; + + return true; + } + }); + + return index; + } + + getNodeById(id) { + let node; + any(this.buttons, (i, item) => { + if (item.isEnabled()) { + if (item.attr("id") === id) { + node = item; + + return true; + } else if (isFunction(item.getNodeById)) { + node = item.getNodeById(id); + if (node) { + return true; + } + } + } + }); + + return node; + } + + getNodeByValue(value) { + let node; + any(this.buttons, (i, item) => { + if (item.isEnabled()) { + if (isFunction(item.getNodeByValue)) { + node = item.getNodeByValue(value); + if (node) { + return true; + } + } else if (item.attr("value") === value) { + node = item; + + return true; + } + } + }); + + return node; + } +} diff --git a/packages/fineui/src/base/context.js b/packages/fineui/src/base/context.js new file mode 100644 index 000000000..8f236d5d9 --- /dev/null +++ b/packages/fineui/src/base/context.js @@ -0,0 +1,40 @@ +import { shortcut, Widget, createWidget, Controller, useContext, watch } from "@/core"; + +@shortcut() +export class Context extends Widget { + static xtype = "bi.context"; + + props = { context: "", watch: {}, el: {}, items: [] }; + + render() { + const self = this, + o = this.options; + if (o.context) { + this.context = useContext(o.context); + } + this.widget = createWidget((o.items[0] || o.el)(this.context), { + element: this, + }); + this.widget.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + } + + __initWatch() { + super.__initWatch.call(this); + const o = this.options; + watch(this.context, o.context, o.watch); + } + + setValue(v) { + this.widget.setValue(v); + } + + getValue() { + return this.widget.getValue(); + } + + populate() { + this.widget.populate.apply(this, arguments); + } +} diff --git a/packages/fineui/src/base/el.js b/packages/fineui/src/base/el.js new file mode 100644 index 000000000..e258c3b0a --- /dev/null +++ b/packages/fineui/src/base/el.js @@ -0,0 +1,36 @@ +import { shortcut, Widget, extend, createWidget, Controller } from "@/core"; + +@shortcut() +export class EL extends Widget { + static xtype = "bi.el"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-el", + el: {}, + }); + } + + render() { + const self = this, + o = this.options; + this.ele = createWidget(o.el, { + element: this, + }); + this.ele.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + } + + setValue(v) { + this.ele.setValue(v); + } + + getValue() { + return this.ele.getValue(); + } + + populate() { + this.ele.populate.apply(this, arguments); + } +} diff --git a/src/base/foundation/__test__/message.test.js b/packages/fineui/src/base/foundation/__test__/message.test.js similarity index 100% rename from src/base/foundation/__test__/message.test.js rename to packages/fineui/src/base/foundation/__test__/message.test.js diff --git a/packages/fineui/src/base/foundation/message.js b/packages/fineui/src/base/foundation/message.js new file mode 100644 index 000000000..3866f2475 --- /dev/null +++ b/packages/fineui/src/base/foundation/message.js @@ -0,0 +1,274 @@ +/** + * z-index在1亿层级 + * 弹出提示消息框,用于模拟阻塞操作(通过回调函数实现) + * @class Msg + */ +import { + Widget, + isString, + isNull, + isFunction, + createWidget, + remove, + each, + emptyFn, + delay, + zIndex_tip, + i18nText, + KeyCode, + isPlainObject, + SIZE_CONSANTS +} from "../../core"; +import { Toast } from "../single"; + +export const Msg = (() => { + let $mask, $pop; + + const messageShows = []; + + const toastStack = []; + + const defaultConfig = { + buttonHeight: 24, + }; + + return { + alert(title, message, callback, config = defaultConfig) { + this._show(false, title, message, callback, config); + }, + confirm(title, message, callback, config = defaultConfig) { + this._show(true, title, message, callback, config); + }, + prompt(title, message, value, callback, min_width) { + // Msg.prompt(title, message, value, callback, min_width); + }, + toast(message, options, context) { + isString(options) && (options = { level: options }); + options = options || {}; + context = context || Widget._renderEngine.createElement("body"); + const level = options.level || "common"; + const autoClose = isNull(options.autoClose) ? true : options.autoClose; + const callback = isFunction(options.callback) ? options.callback : emptyFn; + const toast = createWidget({ + type: "bi.toast", + cls: "bi-message-animate bi-message-leave", + level, + autoClose, + closable: options.closable, + text: message, + listeners: [ + { + eventName: Toast.EVENT_DESTORY, + action() { + remove(toastStack, toast.element); + let _height = SIZE_CONSANTS.TOAST_TOP; + each(toastStack, (i, element) => { + element.css({ top: _height }); + _height += element.outerHeight() + 10; + }); + callback(); + }, + } + ], + }); + let height = SIZE_CONSANTS.TOAST_TOP; + each(toastStack, (i, element) => { + height += element.outerHeight() + 10; + }); + createWidget({ + type: "bi.absolute", + element: context, + items: [ + { + el: toast, + left: "50%", + top: height, + } + ], + }); + toastStack.push(toast.element); + toast.element.css({ "margin-left": (-1 * toast.element.outerWidth()) / 2 }); + toast.element.removeClass("bi-message-leave").addClass("bi-message-enter"); + + autoClose && + delay(() => { + toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); + toast.destroy?.(); + }, 5000); + + return function() { + toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); + toast.destroy?.(); + }; + }, + _show(hasCancel, title, message, callback, config) { + isNull($mask) && + ($mask = Widget._renderEngine + .createElement("
") + .css({ + position: "absolute", + zIndex: zIndex_tip - 2, + top: 0, + left: 0, + right: 0, + bottom: 0, + opacity: 0.5, + }) + .appendTo("body")); + $pop = Widget._renderEngine + .createElement("
") + .css({ + position: "absolute", + zIndex: zIndex_tip - 1, + top: 0, + left: 0, + right: 0, + bottom: 0, + }) + .appendTo("body"); + + function close() { + messageShows[messageShows.length - 1].destroy(); + messageShows.pop(); + if (messageShows.length === 0) { + $mask.remove(); + $mask = null; + } + } + + const controlItems = []; + if (hasCancel === true) { + controlItems.push({ + el: { + type: "bi.button", + height: config.buttonHeight, + text: i18nText("BI-Basic_Cancel"), + light: true, + handler() { + close(); + if (isFunction(callback)) { + callback.apply(null, [false]); + } + }, + }, + }); + } + controlItems.push({ + el: { + type: "bi.button", + height: config.buttonHeight, + text: i18nText("BI-Basic_OK"), + handler() { + close(); + if (isFunction(callback)) { + callback.apply(null, [true]); + } + }, + }, + }); + const conf = { + element: $pop, + type: "bi.center_adapt", + items: [ + { + type: "bi.border", + attributes: { + tabIndex: 1, + }, + mounted() { + this.element.keyup(e => { + if (e.keyCode === KeyCode.ENTER) { + close(); + if (isFunction(callback)) { + callback.apply(null, [true]); + } + } else if (e.keyCode === KeyCode.ESCAPE) { + close(); + if (hasCancel === true) { + if (isFunction(callback)) { + callback.apply(null, [false]); + } + } + } + }); + try { + this.element.focus(); + } catch (e) { + } + }, + cls: "bi-card", + items: { + north: { + el: { + type: "bi.border", + cls: "bi-message-title bi-background", + items: { + center: { + el: { + type: "bi.label", + cls: "bi-font-bold", + text: title || i18nText("BI-Basic_Prompt"), + textAlign: "left", + hgap: 20, + height: 40, + }, + }, + east: { + el: { + type: "bi.icon_button", + cls: "bi-message-close close-font", + // height: 50, + handler() { + close(); + if (isFunction(callback)) { + callback.apply(null, [false]); + } + }, + }, + width: 56, + }, + }, + }, + height: 40, + }, + center: { + el: isPlainObject(message) + ? message + : { + type: "bi.label", + vgap: 10, + hgap: 20, + whiteSpace: "normal", + text: message, + }, + }, + south: { + el: { + type: "bi.absolute", + items: [ + { + el: { + type: "bi.right_vertical_adapt", + lgap: 10, + items: controlItems, + }, + top: 0, + left: 20, + right: 20, + bottom: 0, + } + ], + }, + height: 44, + }, + }, + width: 450, + height: 200, + } + ], + }; + + messageShows[messageShows.length] = createWidget(conf); + }, + }; +})(); diff --git a/src/base/grid/__test__/grid.test.js b/packages/fineui/src/base/grid/__test__/grid.test.js similarity index 100% rename from src/base/grid/__test__/grid.test.js rename to packages/fineui/src/base/grid/__test__/grid.test.js diff --git a/packages/fineui/src/base/grid/grid.js b/packages/fineui/src/base/grid/grid.js new file mode 100644 index 000000000..1d01b80a2 --- /dev/null +++ b/packages/fineui/src/base/grid/grid.js @@ -0,0 +1,517 @@ +import { + VerticalLayout, + AbsoluteLayout, + Widget, + shortcut, + extend, + emptyFn, + debounce, + _lazyCreateWidget, + isFunction, + each, + isNumber, + ScalingCellSizeAndPositionManager, + clamp, + isEmpty, + nextTick, + DOM +} from "@/core"; +import { Label } from "../single"; + +@shortcut() +export class GridView extends Widget { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-grid-view", + // width: 400, //必设 + // height: 300, //必设 + scrollable: true, + scrollx: false, + scrolly: false, + overflowX: true, + overflowY: true, + el: { + type: VerticalLayout.xtype, + }, + overscanColumnCount: 0, + overscanRowCount: 0, + rowHeightGetter: emptyFn, // number类型或function类型 + columnWidthGetter: emptyFn, // number类型或function类型 + // estimatedColumnSize: 100, //columnWidthGetter为function时必设 + // estimatedRowSize: 30, //rowHeightGetter为function时必设 + scrollLeft: 0, + scrollTop: 0, + items: [], + itemFormatter: (item, row, col) => item, + }); + } + + static xtype = "bi.grid_view"; + static EVENT_SCROLL = "EVENT_SCROLL"; + + render() { + const o = this.options; + const { overflowX, overflowY, el } = this.options; + this.renderedCells = []; + this.renderedKeys = []; + this.renderRange = {}; + this._scrollLock = false; + this._debounceRelease = debounce(() => { + this._scrollLock = false; + }, 1000 / 60); + this.container = _lazyCreateWidget({ + type: AbsoluteLayout.xtype, + }); + this.element.scroll(() => { + if (this._scrollLock === true) { + return; + } + o.scrollLeft = this.element.scrollLeft(); + o.scrollTop = this.element.scrollTop(); + this._calculateChildrenToRender(); + this.fireEvent(GridView.EVENT_SCROLL, { + scrollLeft: o.scrollLeft, + scrollTop: o.scrollTop, + }); + }); + // 兼容一下 + let scrollable = o.scrollable; + const scrollx = o.scrollx, + scrolly = o.scrolly; + if (overflowX === false) { + if (overflowY === false) { + scrollable = false; + } else { + scrollable = "y"; + } + } else { + if (overflowY === false) { + scrollable = "x"; + } + } + _lazyCreateWidget(el, { + type: VerticalLayout.xtype, + element: this, + scrollable, + scrolly, + scrollx, + items: [this.container], + }); + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + if (o.items.length > 0) { + this._calculateSizeAndPositionData(); + this._populate(); + } + } + + // mounted之后绑定事件 + mounted() { + const { scrollLeft, scrollTop } = this.options; + if (scrollLeft !== 0 || scrollTop !== 0) { + this.element.scrollTop(scrollTop); + this.element.scrollLeft(scrollLeft); + } + } + + destroyed() { + each(this.renderedCells, (i, cell) => { + cell.el._destroy(); + }); + } + + _calculateSizeAndPositionData() { + const { + columnCount, + items, + rowCount, + columnWidthGetter, + estimatedColumnSize, + rowHeightGetter, + estimatedRowSize, + } = this.options; + this.rowCount = 0; + this.columnCount = 0; + if (isNumber(columnCount)) { + this.columnCount = columnCount; + } else if (items.length > 0) { + this.columnCount = items[0].length; + } + if (isNumber(rowCount)) { + this.rowCount = rowCount; + } else { + this.rowCount = items.length; + } + this._columnSizeAndPositionManager = new ScalingCellSizeAndPositionManager( + this.columnCount, + columnWidthGetter, + estimatedColumnSize + ); + this._rowSizeAndPositionManager = new ScalingCellSizeAndPositionManager( + this.rowCount, + rowHeightGetter, + estimatedRowSize + ); + } + + _getOverscanIndices(cellCount, overscanCellsCount, startIndex, stopIndex) { + return { + overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), + overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount), + }; + } + + _calculateChildrenToRender() { + const o = this.options; + + const { itemFormatter, items } = this.options; + + const width = o.width, + height = o.height, + scrollLeft = clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), + scrollTop = clamp(o.scrollTop, 0, this._getMaxScrollTop()), + overscanColumnCount = o.overscanColumnCount, + overscanRowCount = o.overscanRowCount; + + if (height > 0 && width > 0) { + const visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); + const visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); + + const renderedCells = [], + renderedKeys = {}, + renderedWidgets = {}; + let minX = this._getMaxScrollLeft(), + minY = this._getMaxScrollTop(), + maxX = 0, + maxY = 0; + // 没有可见的单元格就干掉所有渲染过的 + if (!isEmpty(visibleColumnIndices) && !isEmpty(visibleRowIndices)) { + const horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment( + width, + scrollLeft + ); + const verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); + + this._renderedColumnStartIndex = visibleColumnIndices.start; + this._renderedColumnStopIndex = visibleColumnIndices.stop; + this._renderedRowStartIndex = visibleRowIndices.start; + this._renderedRowStopIndex = visibleRowIndices.stop; + + const overscanColumnIndices = this._getOverscanIndices( + this.columnCount, + overscanColumnCount, + this._renderedColumnStartIndex, + this._renderedColumnStopIndex + ); + + const overscanRowIndices = this._getOverscanIndices( + this.rowCount, + overscanRowCount, + this._renderedRowStartIndex, + this._renderedRowStopIndex + ); + + const columnStartIndex = overscanColumnIndices.overscanStartIndex; + const columnStopIndex = overscanColumnIndices.overscanStopIndex; + const rowStartIndex = overscanRowIndices.overscanStartIndex; + const rowStopIndex = overscanRowIndices.overscanStopIndex; + + // 算区间size + const minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex); + const minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex); + const maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex); + const maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex); + const top = minRowDatum.offset + verticalOffsetAdjustment; + const left = minColumnDatum.offset + horizontalOffsetAdjustment; + const bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size; + const right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size; + // 如果滚动的区间并没有超出渲染的范围 + if ( + top >= this.renderRange.minY && + bottom <= this.renderRange.maxY && + left >= this.renderRange.minX && + right <= this.renderRange.maxX + ) { + return; + } + + let count = 0; + for (let rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { + const rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); + + for (let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { + const key = `${rowIndex}-${columnIndex}`; + const columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); + + const index = this.renderedKeys[key] && this.renderedKeys[key][2]; + let child; + if (index >= 0) { + this.renderedCells[index].el.setWidth(columnDatum.size); + this.renderedCells[index].el.setHeight(rowDatum.size); + // 这里只使用px + this.renderedCells[index].el.element.css( + "left", + `${columnDatum.offset + horizontalOffsetAdjustment}px` + ); + this.renderedCells[index].el.element.css( + "top", + `${rowDatum.offset + verticalOffsetAdjustment}px` + ); + child = this.renderedCells[index].el; + renderedCells.push(this.renderedCells[index]); + } else { + const item = itemFormatter(items[rowIndex][columnIndex], rowIndex, columnIndex); + child = _lazyCreateWidget( + extend( + { + type: Label.xtype, + width: columnDatum.size, + height: rowDatum.size, + }, + item, + { + cls: `${item.cls || ""} grid-cell${rowIndex === 0 ? " first-row" : ""}${ + columnIndex === 0 ? " first-col" : "" + }`, + _rowIndex: rowIndex, + _columnIndex: columnIndex, + _left: columnDatum.offset + horizontalOffsetAdjustment, + _top: rowDatum.offset + verticalOffsetAdjustment, + } + ), + this + ); + renderedCells.push({ + el: child, + left: `${columnDatum.offset + horizontalOffsetAdjustment}px`, + top: `${rowDatum.offset + verticalOffsetAdjustment}px`, + _left: columnDatum.offset + horizontalOffsetAdjustment, + _top: rowDatum.offset + verticalOffsetAdjustment, + // _width: columnDatum.size, + // _height: rowDatum.size + }); + } + minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment); + maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size); + minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment); + maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size); + renderedKeys[key] = [rowIndex, columnIndex, count]; + renderedWidgets[count] = child; + count++; + } + } + } + // 已存在的, 需要添加的和需要删除的 + const existSet = {}, + addSet = {}, + deleteArray = []; + each(renderedKeys, (i, key) => { + if (this.renderedKeys[i]) { + existSet[i] = key; + } else { + addSet[i] = key; + } + }); + each(this.renderedKeys, (i, key) => { + if (existSet[i]) { + return; + } + if (addSet[i]) { + return; + } + deleteArray.push(key[2]); + }); + each(deleteArray, (i, index) => { + // 性能优化,不调用destroy方法防止触发destroy事件 + this.renderedCells[index].el._destroy(); + }); + const addedItems = []; + each(addSet, (index, key) => { + addedItems.push(renderedCells[key[2]]); + }); + // 与listview一样, 给上下文 + this.container.addItems(addedItems, this); + // 拦截父子级关系 + this.container._children = renderedWidgets; + this.container.attr("items", renderedCells); + this.renderedCells = renderedCells; + this.renderedKeys = renderedKeys; + this.renderRange = { minX, minY, maxX, maxY }; + } + } + + _isOverflowX() { + const { scrollable, scrollx, overflowX } = this.options; + // 兼容一下 + if (overflowX === false) { + return false; + } + if (scrollx) { + return true; + } + if (scrollable === true || scrollable === "xy" || scrollable === "x") { + return true; + } + + return false; + } + + _isOverflowY() { + const { scrollable, scrolly, overflowX } = this.options; + // 兼容一下 + // var scrollable = o.scrollable, scrolly = o.scrolly; + if (overflowX === false) { + return false; + } + if (scrolly) { + return true; + } + if (scrollable === true || scrollable === "xy" || scrollable === "y") { + return true; + } + + return false; + } + + _getMaxScrollLeft() { + return Math.max( + 0, + this._getContainerWidth() - this.options.width + (this._isOverflowX() ? DOM.getScrollWidth() : 0) + ); + } + + _getMaxScrollTop() { + return Math.max( + 0, + this._getContainerHeight() - this.options.height + (this._isOverflowY() ? DOM.getScrollWidth() : 0) + ); + } + + _getContainerWidth() { + return this.columnCount * this.options.estimatedColumnSize; + } + + _getContainerHeight() { + return this.rowCount * this.options.estimatedRowSize; + } + + _populate(items) { + const { scrollTop, scrollLeft } = this.options; + this._reRange(); + if (items && items !== this.options.items) { + this.options.items = items; + this._calculateSizeAndPositionData(); + } + this.container.setWidth(this._getContainerWidth()); + this.container.setHeight(this._getContainerHeight()); + + // 元素未挂载时不能设置scrollTop + this._debounceRelease(); + try { + this.element.scrollTop(scrollTop); + this.element.scrollLeft(scrollLeft); + } catch (e) {} + this._calculateChildrenToRender(); + } + + setScrollLeft(scrollLeft) { + if (this.options.scrollLeft === scrollLeft) { + return; + } + this._scrollLock = true; + this.options.scrollLeft = clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); + this._debounceRelease(); + this.element.scrollLeft(this.options.scrollLeft); + this._calculateChildrenToRender(); + } + + setScrollTop(scrollTop) { + if (this.options.scrollTop === scrollTop) { + return; + } + this._scrollLock = true; + this.options.scrollTop = clamp(scrollTop || 0, 0, this._getMaxScrollTop()); + this._debounceRelease(); + this.element.scrollTop(this.options.scrollTop); + this._calculateChildrenToRender(); + } + + setColumnCount(columnCount) { + this.options.columnCount = columnCount; + } + + setRowCount(rowCount) { + this.options.rowCount = rowCount; + } + + setOverflowX(b) { + if (this.options.overflowX !== !!b) { + this.options.overflowX = !!b; + nextTick(() => { + this.element.css({ overflowX: b ? "auto" : "hidden" }); + }); + } + } + + setOverflowY(b) { + if (this.options.overflowY !== !!b) { + this.options.overflowY = !!b; + nextTick(() => { + this.element.css({ overflowY: b ? "auto" : "hidden" }); + }); + } + } + + getScrollLeft() { + return this.options.scrollLeft; + } + getScrollTop() { + return this.options.scrollTop; + } + + getMaxScrollLeft() { + return this._getMaxScrollLeft(); + } + + getMaxScrollTop() { + return this._getMaxScrollTop(); + } + + setEstimatedColumnSize(width) { + this.options.estimatedColumnSize = width; + } + + setEstimatedRowSize(height) { + this.options.estimatedRowSize = height; + } + // 重新计算children + _reRange() { + this.renderRange = {}; + } + + _clearChildren() { + this.container._children = {}; + this.container.attr("items", []); + } + + restore() { + each(this.renderedCells, (i, cell) => { + cell.el._destroy(); + }); + this._clearChildren(); + this.renderedCells = []; + this.renderedKeys = []; + this.renderRange = {}; + this._scrollLock = false; + } + + populate(items) { + if (items && items !== this.options.items) { + this.restore(); + } + this._populate(items); + } +} diff --git a/packages/fineui/src/base/index.js b/packages/fineui/src/base/index.js new file mode 100644 index 000000000..da9f8a0c0 --- /dev/null +++ b/packages/fineui/src/base/index.js @@ -0,0 +1,14 @@ +export { Pane } from "./1.pane"; +export { GridView } from "./grid/grid"; +export { Pager } from "./pager/pager"; +export { Msg } from "./foundation/message"; +export { CollectionView } from "./collection/collection"; +export { CustomTree } from "./tree/customtree"; + +export * from "./0.base"; +export * from "./combination"; +export * from "./layer"; +export * from "./list"; +export * from "./single"; +export * from "./el"; +export * from "./context"; \ No newline at end of file diff --git a/src/base/layer/__test__/layer.popover.test.js b/packages/fineui/src/base/layer/__test__/layer.popover.test.js similarity index 100% rename from src/base/layer/__test__/layer.popover.test.js rename to packages/fineui/src/base/layer/__test__/layer.popover.test.js diff --git a/packages/fineui/src/base/layer/index.js b/packages/fineui/src/base/layer/index.js new file mode 100644 index 000000000..3f2423948 --- /dev/null +++ b/packages/fineui/src/base/layer/index.js @@ -0,0 +1,4 @@ +export { Drawer } from "./layer.drawer"; +export { Popover, BarPopover } from "./layer.popover"; +export { PopupView } from "./layer.popup"; +export { SearcherView } from "./layer.searcher"; diff --git a/packages/fineui/src/base/layer/layer.drawer.js b/packages/fineui/src/base/layer/layer.drawer.js new file mode 100644 index 000000000..2f171a090 --- /dev/null +++ b/packages/fineui/src/base/layer/layer.drawer.js @@ -0,0 +1,263 @@ +import { + VTapeLayout, + HTapeLayout, + AbsoluteLayout, + Layout, + VerticalLayout, + Widget, + shortcut, + isPlainObject, + extend +} from "@/core"; +import { Label, IconButton } from "../single"; + +/** + * Popover弹出层, + * @class Popover + * @extends Widget + */ + +@shortcut() +export class Drawer extends Widget { + SIZE = { + SMALL: "small", + NORMAL: "normal", + BIG: "big", + }; + props = { + baseCls: "bi-drawer bi-card", + size: "normal", + placement: "right", // top/bottom/left/right + header: null, + headerHeight: 40, + body: null, + closable: true, // BI-40839 是否显示右上角的关闭按钮 + bodyHgap: 20, + bodyTgap: 10, + bodyBgap: 10, + }; + static xtype = "bi.drawer"; + static EVENT_CLOSE = "EVENT_CLOSE"; + static EVENT_OPEN = "EVENT_OPEN"; + _getSuitableSize() { + const { size, height, placement, width } = this.options; + let sizeValue = 0; + switch (size) { + case "big": + sizeValue = 736; + break; + case "small": + sizeValue = 200; + break; + case "normal": + default: + sizeValue = 378; + break; + } + if (placement === "top" || placement === "bottom") { + return { + height: height || sizeValue, + }; + } + if (placement === "left" || placement === "right") { + return { + width: width || sizeValue, + }; + } + } + render() { + const { header, headerHeight, closable, body, bodyHgap, bodyTgap, bodyBgap } = this.options; + const items = [ + { + el: { + type: HTapeLayout.xtype, + cls: "bi-message-title bi-header-background", + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: isPlainObject(header) + ? extend({}, header, { + extraCls: "bi-font-bold", + }) + : { + type: Label.xtype, + cls: "bi-font-bold", + height: headerHeight, + text: header, + title: header, + textAlign: "left", + }, + left: 20, + top: 0, + right: 0, + bottom: 0, + } + ], + }, + { + el: closable + ? { + type: IconButton.xtype, + cls: "bi-message-close close-font", + height: headerHeight, + handler: () => { + this.close(); + }, + } + : { + type: Layout.xtype, + }, + width: 56, + } + ], + height: headerHeight, + }, + height: headerHeight, + }, + { + el: { + type: VerticalLayout.xtype, + scrolly: true, + cls: "drawer-body", + ref: _ref => { + this.body = _ref; + }, + items: [ + { + el: body, + } + ], + }, + hgap: bodyHgap, + tgap: bodyTgap, + bgap: bodyBgap, + } + ]; + + return extend( + { + type: VTapeLayout.xtype, + items, + }, + this._getSuitableSize() + ); + } + mounted() { + const { placement } = this.options; + switch (placement) { + case "right": + this.element.css({ + top: 0, + left: "100%", + bottom: 0, + }); + break; + case "left": + this.element.css({ + top: 0, + right: "100%", + bottom: 0, + }); + break; + case "top": + this.element.css({ + left: 0, + right: 0, + bottom: "100%", + }); + break; + case "bottom": + this.element.css({ + left: 0, + right: 0, + top: "100%", + }); + break; + default: + break; + } + } + + show(callback) { + const { placement } = this.options; + requestAnimationFrame(() => { + const size = this._getSuitableSize(); + switch (placement) { + case "right": + this.element.css({ + left: `calc(100% - ${size.width}px)`, + }); + break; + case "left": + this.element.css({ + right: `calc(100% - ${size.width}px)`, + }); + break; + case "top": + this.element.css({ + bottom: `calc(100% - ${size.height}px)`, + }); + break; + case "bottom": + this.element.css({ + top: `calc(100% - ${size.height}px)`, + }); + break; + default: + break; + } + callback && callback(); + }); + } + + hide(callback) { + const { placement } = this.options; + requestAnimationFrame(() => { + switch (placement) { + case "right": + this.element.css({ + left: "100%", + }); + break; + case "left": + this.element.css({ + right: "100%", + }); + break; + case "top": + this.element.css({ + bottom: "100%", + }); + break; + case "bottom": + this.element.css({ + top: "100%", + }); + break; + default: + break; + } + setTimeout(callback, 300); + }); + } + + open() { + this.show(() => { + this.fireEvent(Drawer.EVENT_OPEN); + }); + } + + close() { + this.hide(() => { + this.fireEvent(Drawer.EVENT_CLOSE); + }); + } + + setZindex(zindex) { + this.element.css({ "z-index": zindex }); + } + + destroyed() {} +} diff --git a/packages/fineui/src/base/layer/layer.popover.js b/packages/fineui/src/base/layer/layer.popover.js new file mode 100644 index 000000000..37b4c3d5c --- /dev/null +++ b/packages/fineui/src/base/layer/layer.popover.js @@ -0,0 +1,343 @@ +import { + VTapeLayout, + RightVerticalAdaptLayout, + HTapeLayout, + AbsoluteLayout, + VerticalLayout, + Widget, + shortcut, + clamp, + isPlainObject, + extend, + isNotNull, + MouseMoveTracker, + i18nText, + SIZE_CONSANTS +} from "@/core"; +import { Label, IconButton, Button } from "../single"; +import { Resizers } from "../0.base"; + +/** + * Popover弹出层, + * @class Popover + * @extends Widget + */ + +@shortcut() +export class Popover extends Widget { + _constant = { + SIZE: { + SMALL: "small", + NORMAL: "normal", + BIG: "big", + }, + MAX_HEIGHT: 600, + }; + + props() { + return { + baseCls: "bi-popover bi-card bi-border-radius", + size: "normal", // small, normal, big + logic: { + dynamic: false, + }, + header: null, + headerHeight: 40, + body: null, + footer: null, + footerHeight: 44, + footerButtonHeight: 24, + closable: true, // BI-40839 是否显示右上角的关闭按钮 + bodyHgap: SIZE_CONSANTS.H_GAP_SIZE, + bodyTgap: SIZE_CONSANTS.V_GAP_SIZE, + }; + } + + static xtype = "bi.popover"; + static EVENT_CLOSE = "EVENT_CLOSE"; + static EVENT_OPEN = "EVENT_OPEN"; + static EVENT_CANCEL = "EVENT_CANCEL"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + render() { + // var self = this; + const { header, headerHeight, closable, logic, footer, footerHeight, body, bodyTgap, bodyHgap } = this.options; + const c = this._constant; + this.startX = 0; + this.startY = 0; + const size = this._calculateSize(); + this.tracker = new MouseMoveTracker( + (deltaX, deltaY) => { + const W = Widget._renderEngine.createElement("body").width(); + const H = Widget._renderEngine.createElement("body").height(); + this.startX += deltaX; + this.startY += deltaY; + this.element.css({ + left: `${clamp(this.startX, 0, W - this.element.width())}px`, + top: `${clamp(this.startY, 0, H - this.element.height())}px`, + }); + // BI-12134 没有什么特别好的方法 + Resizers._resize({ + target: this.element[0], + }); + }, + () => { + this.tracker.releaseMouseMoves(); + }, + _global + ); + const items = [ + { + el: { + type: HTapeLayout.xtype, + cls: "bi-message-title bi-header-background", + items: [ + { + el: { + type: AbsoluteLayout.xtype, + ref: _ref => { + this.dragger = _ref; + }, + items: [ + { + el: isPlainObject(header) + ? extend({}, header, { + extraCls: "bi-font-bold", + }) + : { + type: Label.xtype, + cls: "bi-font-bold", + height: headerHeight, + text: header, + title: header, + textAlign: "left", + }, + top: 0, + bottom: 0, + left: SIZE_CONSANTS.H_GAP_SIZE, + right: closable ? 0 : SIZE_CONSANTS.H_GAP_SIZE, + } + ], + }, + }, + closable + ? { + el: { + type: IconButton.xtype, + cls: "bi-message-close close-font", + height: headerHeight, + handler: () => { + this.close(); + }, + }, + width: 56, + } + : null + ], + height: headerHeight, + }, + height: headerHeight, + }, + logic.dynamic + ? { + el: { + type: VerticalLayout.xtype, + scrolly: true, + cls: "popover-body", + ref: _ref => { + this.body = _ref; + }, + css: { + "max-height": this._getSuitableBodyHeight( + c.MAX_HEIGHT - headerHeight - (footer ? footerHeight : 0) - bodyTgap + ), + "min-height": this._getSuitableBodyHeight( + size.height - headerHeight - (footer ? footerHeight : 0) - bodyTgap + ), + }, + items: [ + { + el: body, + } + ], + hgap: bodyHgap, + tgap: bodyTgap, + }, + } + : { + el: { + type: AbsoluteLayout.xtype, + items: [ + { + el: body, + left: bodyHgap, + top: bodyTgap, + right: bodyHgap, + bottom: 0, + } + ], + }, + } + ]; + if (footer) { + items.push({ + el: { + type: AbsoluteLayout.xtype, + items: [ + { + el: footer, + left: SIZE_CONSANTS.H_GAP_SIZE, + top: 0, + right: SIZE_CONSANTS.H_GAP_SIZE, + bottom: 0, + } + ], + height: footerHeight, + }, + height: footerHeight, + }); + } + + return extend( + { + items, + width: this._getSuitableWidth(size.width), + }, + logic.dynamic + ? { + type: VerticalLayout.xtype, + scrolly: false, + } + : { + type: VTapeLayout.xtype, + height: this._getSuitableHeight(size.height), + } + ); + } + + // mounted之后绑定事件 + mounted() { + this.dragger.element.mousedown(e => { + if (this.options.draggable !== false) { + this.startX = this.element[0].offsetLeft; + this.startY = this.element[0].offsetTop; + this.tracker.captureMouseMoves(e); + } + }); + } + + _getSuitableBodyHeight(height) { + const { headerHeight, footer, footerHeight, bodyTgap } = this.options; + + return clamp( + height, + 0, + Widget._renderEngine.createElement("body")[0].clientHeight - + headerHeight - + (footer ? footerHeight : 0) - + bodyTgap + ); + } + + _getSuitableHeight(height) { + return clamp(height, 0, Widget._renderEngine.createElement("body")[0].clientHeight); + } + + _getSuitableWidth(width) { + return clamp(width, 0, Widget._renderEngine.createElement("body").width()); + } + + _calculateSize() { + const { size, width, height } = this.options; + const sizeValue = {}; + if (isNotNull(size)) { + switch (size) { + case this._constant.SIZE.SMALL: + sizeValue.width = 450; + sizeValue.height = 200; + sizeValue.type = "small"; + break; + case this._constant.SIZE.BIG: + sizeValue.width = 900; + sizeValue.height = 500; + sizeValue.type = "big"; + break; + default: + sizeValue.width = 550; + sizeValue.height = 500; + sizeValue.type = "default"; + } + } + + return { + width: width || sizeValue.width, + height: height || sizeValue.height, + type: sizeValue.type || "default", + }; + } + + setDraggable(b) { + this.options.draggable = b; + } + + hide() { + } + + open() { + this.show(); + this.fireEvent(Popover.EVENT_OPEN, arguments); + } + + close() { + this.hide(); + this.fireEvent(Popover.EVENT_CLOSE, arguments); + } + + setZindex(zindex) { + this.element.css({ "z-index": zindex }); + } +} + +@shortcut() +export class BarPopover extends Popover { + static xtype = "bi.bar_popover"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + btns: [i18nText("BI-Basic_OK"), i18nText("BI-Basic_Cancel")], + }); + } + + beforeCreate() { + const { footer, warningTitle, footerButtonHeight } = this.options; + footer || + (this.options.footer = { + type: RightVerticalAdaptLayout.xtype, + lgap: 10, + items: [ + { + type: Button.xtype, + height: footerButtonHeight, + text: this.options.btns[1], + value: 1, + light: true, + handler: v => { + this.fireEvent(Popover.EVENT_CANCEL, v); + this.close(v); + }, + }, + { + type: Button.xtype, + height: footerButtonHeight, + text: this.options.btns[0], + warningTitle, + value: 0, + handler: v => { + this.fireEvent(Popover.EVENT_CONFIRM, v); + this.close(v); + }, + } + ], + }); + } +} diff --git a/packages/fineui/src/base/layer/layer.popup.js b/packages/fineui/src/base/layer/layer.popup.js new file mode 100644 index 000000000..c00b272b3 --- /dev/null +++ b/packages/fineui/src/base/layer/layer.popup.js @@ -0,0 +1,516 @@ +import { ButtonGroup } from "../combination/group.button"; +import { + VerticalLayout, + AbsoluteLayout, + Layout, + CenterLayout, + Widget, + shortcut, + extend, + Controller, + createWidget, + createItems, + clamp, + Direction, + zIndex_popup, + pixFormat, + LogicFactory, + Events +} from "@/core"; + +/** + * 下拉框弹出层, zIndex在1000w + * @class PopupView + * @extends Widget + */ + +@shortcut() +export class PopupView extends Widget { + _const = { + TRIANGLE_LENGTH: 12, + }; + + static xtype = "bi.popup_view"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(props) { + return extend(super._defaultConfig(...arguments), { + _baseCls: `bi-popup-view${props.primary ? " bi-primary" : ""}`, + // 品牌色 + primary: false, + maxWidth: "auto", + minWidth: 100, + // maxHeight: 200, + minHeight: 24, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + hgap: 0, + innerVgap: 0, + innerHgap: 0, + showArrow: false, + direction: Direction.Top, // 工具栏的方向 + stopEvent: false, // 是否停止mousedown、mouseup事件 + stopPropagation: false, // 是否停止mousedown、mouseup向上冒泡 + logic: { + dynamic: true, + }, + + tool: false, // 自定义工具栏 + tabs: [], // 导航栏 + buttons: [], // toolbar栏 + + el: { + type: ButtonGroup.xtype, + items: [], + chooseType: 0, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }); + } + render() { + const { + minWidth, + maxWidth, + stopPropagation, + stopEvent, + direction, + logic, + lgap, + rgap, + tgap, + bgap, + vgap, + hgap, + primary, + showArrow, + } = this.options; + function fn(e) { + e.stopPropagation(); + } + function stop(e) { + e.stopEvent(); + + return false; + } + this.element + .css({ + "z-index": zIndex_popup, + "min-width": pixFormat(minWidth), + "max-width": pixFormat(maxWidth), + }) + .bind({ click: fn }); + + this.element.bind("mousewheel", fn); + + stopPropagation && this.element.bind({ mousedown: fn, mouseup: fn, mouseover: fn }); + stopEvent && this.element.bind({ mousedown: stop, mouseup: stop, mouseover: stop }); + this.tool = this._createTool(); + this.tab = this._createTab(); + this.view = this._createView(); + this.toolbar = this._createToolBar(); + + this.view.on(Controller.EVENT_CHANGE, (type, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, ...args); + if (type === Events.CLICK) { + this.fireEvent(PopupView.EVENT_CHANGE); + } + }); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(direction), + extend({}, logic, { + scrolly: false, + lgap, + rgap, + tgap, + bgap, + vgap, + hgap, + items: LogicFactory.createLogicItemsByDirection( + direction, + extend( + { + cls: `list-view-outer bi-card list-view-shadow${primary ? " bi-primary" : ""}`, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(direction), + extend({}, logic, { + items: LogicFactory.createLogicItemsByDirection( + direction, + this.tool, + this.tab, + this.view, + this.toolbar + ), + }) + ) + ) + ), + }) + ) + ) + ); + if (showArrow) { + this.arrow = createWidget({ + type: AbsoluteLayout.xtype, + cls: "bi-bubble-arrow", + items: [ + { + type: Layout.xtype, + cls: "bubble-arrow", + } + ], + }); + this.arrowWrapper = createWidget({ + type: AbsoluteLayout.xtype, + cls: "bi-bubble-arrow-wrapper", + items: [ + { + el: this.arrow, + } + ], + }); + // 因为三角符号的原因位置变大了,需要占位 + this.placeholder = createWidget({ + type: Layout.xtype, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.arrowWrapper, + left: 0, + top: 0, + }, + { + el: this.placeholder, + } + ], + }); + } + } + _createView() { + const { el, value, minHeight, innerVgap, innerHgap } = this.options; + this.button_group = createWidget(el, { type: ButtonGroup.xtype, value }); + this.button_group.element.css({ + "min-height": pixFormat(minHeight), + "padding-top": pixFormat(innerVgap), + "padding-bottom": pixFormat(innerVgap), + "padding-left": pixFormat(innerHgap), + "padding-right": pixFormat(innerHgap), + }); + + return this.button_group; + } + + _createTool() { + const { tool } = this.options; + if (false === tool) { + return; + } + + return createWidget(tool); + } + + _createTab() { + const { tabs, value } = this.options; + if (tabs.length === 0) { + return; + } + + return createWidget({ + type: CenterLayout.xtype, + cls: "list-view-tab", + height: 25, + items: tabs, + value, + }); + } + + _createToolBar() { + const { buttons } = this.options; + if (buttons.length === 0) { + return; + } + + return createWidget({ + type: CenterLayout.xtype, + cls: "list-view-toolbar bi-high-light bi-split-top", + height: 24, + items: createItems(buttons, { + once: false, + shadow: true, + isShadowShowingOnSelected: true, + }), + }); + } + + setDirection(direction, position) { + const { showArrow, tgap, vgap, bgap, rgap, hgap, lgap } = this.options; + if (showArrow) { + let style = {}, + wrapperStyle = {}, + placeholderStyle = {}; + const adjustXOffset = position.adjustXOffset || 0; + const adjustYOffset = position.adjustYOffset || 0; + const bodyBounds = Widget._renderEngine.createElement("body").bounds(); + const bodyWidth = bodyBounds.width; + const bodyHeight = bodyBounds.height; + const popupWidth = this.element.outerWidth(); + const popupHeight = this.element.outerHeight(); + const offset = position.offset; + const offsetStyle = position.offsetStyle; + const middle = offsetStyle === "center" || offsetStyle === "middle"; + + const minLeft = Math.max(4, offset.left + 4 + popupWidth - bodyWidth); + const minRight = Math.max(4, popupWidth - (offset.left + 4)); + const minTop = Math.max(4, offset.top + 4 + popupHeight - bodyHeight); + const minBottom = Math.max(4, popupHeight - (offset.top + 4)); + + const maxLeft = Math.min(popupWidth - 16 - 4, offset.left + position.width - 16 - 4); + const maxRight = Math.min(popupWidth - 16 - 4, bodyWidth - (offset.left + position.width - 16 - 4)); + const maxTop = Math.min(popupHeight - 16 - 4, offset.top + position.height - 16 - 4); + const maxBottom = Math.min(popupHeight - 16 - 4, bodyHeight - (offset.top + position.height - 16 - 4)); + switch (direction) { + case "bottom": + case "bottom,right": + direction = "bottom"; + style = { + // 5表示留出一定的空间 + left: clamp(((middle ? popupWidth : position.width) - adjustXOffset) / 2 - 8, minLeft, maxLeft), + }; + wrapperStyle = { + top: tgap + vgap, + left: 0, + right: "", + bottom: "", + }; + placeholderStyle = { + left: 0, + right: 0, + height: this._const.TRIANGLE_LENGTH, + top: -this._const.TRIANGLE_LENGTH, + bottom: "", + }; + break; + case "bottom,left": + direction = "bottom"; + style = { + right: clamp( + ((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, + minRight, + maxRight + ), + }; + wrapperStyle = { + top: bgap + vgap, + left: "", + right: 0, + bottom: "", + }; + placeholderStyle = { + left: 0, + right: 0, + height: this._const.TRIANGLE_LENGTH, + top: -this._const.TRIANGLE_LENGTH, + bottom: "", + }; + break; + case "top": + case "top,right": + direction = "top"; + style = { + left: clamp(((middle ? popupWidth : position.width) - adjustXOffset) / 2 - 8, minLeft, maxLeft), + }; + wrapperStyle = { + bottom: bgap + vgap, + left: 0, + right: "", + top: "", + }; + placeholderStyle = { + left: 0, + right: 0, + height: this._const.TRIANGLE_LENGTH, + top: "", + bottom: -this._const.TRIANGLE_LENGTH, + }; + break; + case "top,left": + direction = "top"; + style = { + right: clamp( + ((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, + minRight, + maxRight + ), + }; + wrapperStyle = { + bottom: bgap + vgap, + right: 0, + left: "", + top: "", + }; + placeholderStyle = { + left: 0, + right: 0, + height: this._const.TRIANGLE_LENGTH, + top: "", + bottom: -this._const.TRIANGLE_LENGTH, + }; + break; + case "left": + case "left,bottom": + direction = "left"; + style = { + top: clamp(((middle ? popupHeight : position.height) - adjustYOffset) / 2 - 8, minTop, maxTop), + }; + wrapperStyle = { + right: rgap + hgap, + top: 0, + bottom: "", + left: "", + }; + placeholderStyle = { + top: 0, + bottom: 0, + width: this._const.TRIANGLE_LENGTH, + right: -this._const.TRIANGLE_LENGTH, + left: "", + }; + break; + case "left,top": + direction = "left"; + style = { + bottom: clamp( + ((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, + minBottom, + maxBottom + ), + }; + wrapperStyle = { + right: rgap + hgap, + bottom: 0, + top: "", + left: "", + }; + placeholderStyle = { + top: 0, + bottom: 0, + width: this._const.TRIANGLE_LENGTH, + right: -this._const.TRIANGLE_LENGTH, + left: "", + }; + break; + case "right": + case "right,bottom": + direction = "right"; + style = { + top: clamp(((middle ? popupHeight : position.height) - adjustYOffset) / 2 - 8, minTop, maxTop), + }; + wrapperStyle = { + left: lgap + hgap, + top: 0, + bottom: "", + right: "", + }; + placeholderStyle = { + top: 0, + bottom: 0, + width: this._const.TRIANGLE_LENGTH, + left: -this._const.TRIANGLE_LENGTH, + right: "", + }; + break; + case "right,top": + direction = "right"; + style = { + bottom: clamp( + ((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, + minBottom, + maxBottom + ), + }; + wrapperStyle = { + left: lgap + hgap, + bottom: 0, + top: "", + right: "", + }; + placeholderStyle = { + top: 0, + bottom: 0, + width: this._const.TRIANGLE_LENGTH, + left: -this._const.TRIANGLE_LENGTH, + right: "", + }; + break; + case "right,innerRight": + break; + case "right,innerLeft": + break; + case "innerRight": + break; + case "innerLeft": + break; + default: + break; + } + this.element + .removeClass("left") + .removeClass("right") + .removeClass("top") + .removeClass("bottom") + .addClass(direction); + this.arrow.element.css(style); + this.arrowWrapper.element.css(wrapperStyle); + this.placeholder.element.css(placeholderStyle); + } + } + + getView() { + return this.view; + } + + populate(items) { + this.view.populate(...arguments); + } + + resetWidth(w) { + this.options.width = w; + this.element.width(w); + } + + resetHeight(h) { + const tbHeight = this.toolbar ? this.toolbar.attr("height") || 24 : 0, + tabHeight = this.tab ? this.tab.attr("height") || 24 : 0, + toolHeight = ((this.tool && this.tool.attr("height")) || 24) * (this.tool && this.tool.isVisible() ? 1 : 0); + const resetHeight = h - tbHeight - tabHeight - toolHeight - 2 * this.options.innerVgap; + this.view.resetHeight + ? this.view.resetHeight(resetHeight) + : this.view.element.css({ "max-height": pixFormat(resetHeight) }); + } + + setValue(selectedValues) { + this.tab && this.tab.setValue(selectedValues); + this.view.setValue(selectedValues); + } + + getValue() { + return this.view.getValue(); + } +} diff --git a/packages/fineui/src/base/layer/layer.searcher.js b/packages/fineui/src/base/layer/layer.searcher.js new file mode 100644 index 000000000..8fc36e8d6 --- /dev/null +++ b/packages/fineui/src/base/layer/layer.searcher.js @@ -0,0 +1,144 @@ +import { ButtonGroup } from "../combination"; +import { VerticalLayout, Layout, shortcut, extend, createWidget, Controller, isNotEmptyArray, Selection, i18nText, Events } from "@/core"; +import { Pane } from "../1.pane"; + +/** + * 搜索面板 + * + * Created by GUY on 2015/9/28. + * @class SearcherView + * @extends Pane + */ + +@shortcut() +export class SearcherView extends Pane { + static xtype = "bi.searcher_view"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-searcher-view bi-card`, + tipText: i18nText("BI-No_Select"), + chooseType: Selection.Single, + + matcher: { + // 完全匹配的构造器 + type: ButtonGroup.xtype, + behaviors: { + redmark: () => true, + }, + items: [], + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + searcher: { + type: ButtonGroup.xtype, + behaviors: { + redmark: () => true, + }, + items: [], + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }); + } + render() { + const { matcher, chooseType, value, searcher } = this.options; + + this.matcher = createWidget(matcher, { + type: ButtonGroup.xtype, + chooseType, + behaviors: { + redmark: () => true, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value, + }); + this.matcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, val, ob, ...args); + if (type === Events.CLICK) { + this.fireEvent(SearcherView.EVENT_CHANGE, val, ob); + } + }); + this.spliter = createWidget({ + type: VerticalLayout.xtype, + height: 1, + hgap: 10, + items: [ + { + type: Layout.xtype, + height: 1, + cls: "searcher-view-spliter bi-background", + } + ], + }); + this.searcher = createWidget(searcher, { + type: ButtonGroup.xtype, + chooseType, + behaviors: { + redmark: () => true, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value, + }); + this.searcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, val, ob, ...args); + if (type === Events.CLICK) { + this.fireEvent(SearcherView.EVENT_CHANGE, val, ob); + } + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.matcher, this.spliter, this.searcher], + }); + } + + startSearch() {} + + stopSearch() {} + + setValue(v) { + this.matcher.setValue(v); + this.searcher.setValue(v); + } + + getValue() { + return this.matcher.getValue().concat(this.searcher.getValue()); + } + + populate(searchResult, matchResult, keyword) { + searchResult || (searchResult = []); + matchResult || (matchResult = []); + this.setTipVisible(searchResult.length + matchResult.length === 0); + this.spliter.setVisible(isNotEmptyArray(matchResult) && isNotEmptyArray(searchResult)); + this.matcher.populate(matchResult, keyword); + this.searcher.populate(searchResult, keyword); + } + + empty() { + this.searcher.empty(); + this.matcher.empty(); + } + + hasMatched() { + return this.matcher.getAllButtons().length > 0; + } +} diff --git a/src/base/list/__test__/listview.test.js b/packages/fineui/src/base/list/__test__/listview.test.js similarity index 100% rename from src/base/list/__test__/listview.test.js rename to packages/fineui/src/base/list/__test__/listview.test.js diff --git a/packages/fineui/src/base/list/index.js b/packages/fineui/src/base/list/index.js new file mode 100644 index 000000000..fac027df7 --- /dev/null +++ b/packages/fineui/src/base/list/index.js @@ -0,0 +1,3 @@ +export { ListView } from "./listview"; +export { VirtualGroupList } from "./virtualgrouplist"; +export { VirtualList } from "./virtuallist"; diff --git a/packages/fineui/src/base/list/listview.js b/packages/fineui/src/base/list/listview.js new file mode 100644 index 000000000..ae1add7fb --- /dev/null +++ b/packages/fineui/src/base/list/listview.js @@ -0,0 +1,154 @@ +import { VerticalLayout, Widget, shortcut, extend, isFunction, ResizeDetector } from "@/core"; + +/** + * 边滚动边加载的列表控件 + * + * Created by GUY on 2017/5/23. + * @class ListView + * @extends Widget + */ + +@shortcut() +export class ListView extends Widget { + props() { + return { + baseCls: "bi-list-view", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + el: {}, + items: [], + itemFormatter: (item, index) => item, + }; + } + + init() { + this.renderedIndex = -1; + this.cache = {}; + } + + static xtype = "bi.list_view"; + + render() { + const { el } = this.options; + + return { + type: VerticalLayout.xtype, + items: [ + extend( + { + type: VerticalLayout.xtype, + scrolly: false, + ref: _ref => { + this.container = _ref; + }, + }, + el + ) + ], + element: this, + }; + } + + // mounted之后绑定事件 + mounted() { + const o = this.options; + // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + this._populate(); + this.element.scroll(e => { + o.scrollTop = this.element.scrollTop(); + this._calculateBlocksToRender(); + }); + let lastWidth = this.element.width(), + lastHeight = this.element.height(); + ResizeDetector.addResizeListener(this, () => { + if (!this.element.is(":visible")) { + return; + } + const width = this.element.width(), + height = this.element.height(); + if (width !== lastWidth || height !== lastHeight) { + lastWidth = width; + lastHeight = height; + this._calculateBlocksToRender(); + } + }); + } + + _renderMoreIf() { + const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; + const height = this.element.height(); + const minContentHeight = scrollTop + height + overscanHeight; + let index = (this.cache[this.renderedIndex] && this.cache[this.renderedIndex].index + blockSize) || 0; + let cnt = this.renderedIndex + 1; + let lastHeight; + + const getElementHeight = () => this.container.element.height(); + + lastHeight = getElementHeight(); + while (lastHeight < minContentHeight && index < items.length) { + const itemsArr = items.slice(index, index + blockSize); + this.container.addItems( + // eslint-disable-next-line no-loop-func + itemsArr.map((item, i) => itemFormatter(item, index + i)), + this + ); + const addedHeight = getElementHeight() - lastHeight; + this.cache[cnt] = { + index, + scrollTop: lastHeight, + height: addedHeight, + }; + this.renderedIndex = cnt; + cnt++; + index += blockSize; + lastHeight = getElementHeight(); + } + } + _calculateBlocksToRender() { + // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 + // 这样从不可见状态变为可见状态能够重新触发线段树初始化 + if (!this.element.is(":visible")) { + return; + } + this._renderMoreIf(); + } + + _populate(items) { + const { scrollTop } = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } + this._calculateBlocksToRender(); + this.element.scrollTop(scrollTop); + } + + restore() { + this.renderedIndex = -1; + this.container.empty(); + this.cache = {}; + } + + scrollTo(scrollTop) { + this.options.scrollTop = scrollTop; + this._calculateBlocksToRender(); + this.element.scrollTop(scrollTop); + } + + populate(items) { + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(items); + } + + beforeDestroy() { + ResizeDetector.removeResizeListener(this); + this.restore(); + } +} diff --git a/packages/fineui/src/base/list/virtualgrouplist.js b/packages/fineui/src/base/list/virtualgrouplist.js new file mode 100644 index 000000000..06edd5692 --- /dev/null +++ b/packages/fineui/src/base/list/virtualgrouplist.js @@ -0,0 +1,221 @@ +import { VerticalLayout, Layout, Widget, shortcut, extend, isFunction, isNumber, PrefixIntervalTree, ResizeDetector } from "@/core"; +import { VirtualGroup } from "../combination"; + +/** + * 同时用于virtualGroup和virtualList特性的虚拟列表 + * + * Created by GUY on 2017/5/22. + * @class VirtualList + * @extends Widget + */ + +@shortcut() +export class VirtualGroupList extends Widget { + props() { + return { + baseCls: "bi-virtual-group-list", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + rowHeight: "auto", + items: [], + el: {}, + itemFormatter: (item, index) => item, + }; + } + + init() { + this.renderedIndex = -1; + } + + static xtype = "bi.virtual_group_list"; + + render() { + const { rowHeight, items, el } = this.options; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: Layout.xtype, + ref: (ref) => { + this.topBlank = ref; + }, + }, + { + type: VirtualGroup.xtype, + height: rowHeight * items.length, + ref: (ref) => { + this.container = ref; + }, + layouts: [ + extend( + { + type: VerticalLayout.xtype, + scrolly: false, + }, + el + ) + ], + }, + { + type: Layout.xtype, + ref: (ref) => { + this.bottomBlank = ref; + }, + } + ], + element: this, + }; + } + // mounted之后绑定事件 + mounted() { + // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 + const o = this.options; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + this._populate(); + this.ticking = false; + this.element.scroll(() => { + o.scrollTop = this.element.scrollTop(); + if (!this.ticking) { + requestAnimationFrame(() => { + this._calculateBlocksToRender(); + this.ticking = false; + }); + this.ticking = true; + } + }); + ResizeDetector.addResizeListener(this, () => { + if (this.element.is(":visible")) { + this._calculateBlocksToRender(); + } + }); + } + + _isAutoHeight() { + return !isNumber(this.options.rowHeight); + } + + _renderMoreIf() { + const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; + const height = this.element.height(); + const minContentHeight = scrollTop + height + overscanHeight; + let index = (this.renderedIndex + 1) * blockSize, + cnt = this.renderedIndex + 1; + let lastHeight; + const getElementHeight = () => + this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height(); + lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight(); + while (lastHeight < minContentHeight && index < items.length) { + const itemsArr = items.slice(index, index + blockSize); + this.container[this.renderedIndex === -1 ? "populate" : "addItems"]( + // eslint-disable-next-line no-loop-func + itemsArr.map((item, i) => itemFormatter(item, index + i)), + this + ); + const elementHeight = getElementHeight(); + const addedHeight = elementHeight - lastHeight; + this.tree.set(cnt, addedHeight); + this.renderedIndex = cnt; + cnt++; + index += blockSize; + lastHeight = this.renderedIndex === -1 ? 0 : elementHeight; + } + } + + _calculateBlocksToRender() { + // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 + // 这样从不可见状态变为可见状态能够重新触发线段树初始化 + if (!this.element.is(":visible")) { + return; + } + const { scrollTop, overscanHeight, blockSize, items, itemFormatter, rowHeight } = this.options; + this._isAutoHeight() && this._renderMoreIf(); + const height = this.element.height(); + const minContentHeightFrom = scrollTop - overscanHeight; + const minContentHeightTo = scrollTop + height + overscanHeight; + const start = this.tree.greatestLowerBound(minContentHeightFrom); + const end = this.tree.leastUpperBound(minContentHeightTo); + const itemsArr = []; + const topHeight = this.tree.sumTo(Math.max(-1, start - 1)); + this.topBlank.setHeight(`${topHeight}px`); + if (this._isAutoHeight()) { + for (let i = start < 0 ? 0 : start; i <= end && i <= this.renderedIndex; i++) { + const index = i * blockSize; + for (let j = index; j < index + blockSize && j < items.length; j++) { + itemsArr.push(items[j]); + } + } + this.bottomBlank.setHeight( + `${this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))}px` + ); + this.container.populate( + itemsArr.map((item, i) => itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i)) + ); + } else { + for (let i = start < 0 ? 0 : start; i <= end; i++) { + const index = i * blockSize; + for (let j = index; j < index + blockSize && j < items.length; j++) { + itemsArr.push(items[j]); + } + } + this.container.element.height(rowHeight * items.length - topHeight); + this.container.populate( + itemsArr.map((item, i) => itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i)) + ); + } + } + _populate(items) { + const { blockSize, rowHeight, scrollTop } = this.options; + if (items && this.options.items !== items) { + // 重新populate一组items,需要重新对线段树分块 + this.options.items = items; + this._restore(); + } + this.tree = PrefixIntervalTree.uniform( + Math.ceil(this.options.items.length / blockSize), + this._isAutoHeight() ? 0 : rowHeight * blockSize + ); + + this._calculateBlocksToRender(); + try { + this.element.scrollTop(scrollTop); + } catch (e) {} + } + + _restore() { + this.renderedIndex = -1; + // 依赖于cache的占位元素也要初始化 + this.topBlank.setHeight(0); + this.bottomBlank.setHeight(0); + } + + // 暂时只支持固定行高的场景 + scrollTo(scrollTop) { + this.options.scrollTop = scrollTop; + this._calculateBlocksToRender(); + this.element.scrollTop(scrollTop); + } + + restore() { + this.options.scrollTop = 0; + this._restore(); + } + + populate(items) { + this._populate(items); + } + + beforeDestroy() { + ResizeDetector.removeResizeListener(this); + this.restore(); + } + + getNodeByValue(value) { + return this.container.getNodeByValue(value); + } +} diff --git a/packages/fineui/src/base/list/virtuallist.js b/packages/fineui/src/base/list/virtuallist.js new file mode 100644 index 000000000..59cf7050d --- /dev/null +++ b/packages/fineui/src/base/list/virtuallist.js @@ -0,0 +1,226 @@ +import { VerticalLayout, Layout, Widget, shortcut, isFunction, each, PrefixIntervalTree, ResizeDetector } from "@/core"; + +/** + * 虚拟列表 + * + * Created by GUY on 2017/5/22. + * @class VirtualList + * @extends Widget + */ + +@shortcut() +export class VirtualList extends Widget { + props() { + return { + baseCls: "bi-virtual-list", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + items: [], + itemFormatter: (item, index) => item, + }; + } + + init() { + this.renderedIndex = -1; + this.cache = {}; + } + + static xtype = "bi.virtual_list"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Layout.xtype, + ref: _ref => { + this.topBlank = _ref; + }, + }, + { + type: VerticalLayout.xtype, + scrolly: false, + ref: _ref => { + this.container = _ref; + }, + }, + { + type: Layout.xtype, + ref: _ref => { + this.bottomBlank = _ref; + }, + } + ], + }; + } + // mounted之后绑定事件 + mounted() { + // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 + const o = this.options; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + this._populate(); + this.element.scroll(e => { + o.scrollTop = this.element.scrollTop(); + this._calculateBlocksToRender(); + }); + ResizeDetector.addResizeListener(this, () => { + if (this.element.is(":visible")) { + this._calculateBlocksToRender(); + } + }); + } + + _renderMoreIf() { + const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; + const height = this.element.height(); + const minContentHeight = scrollTop + height + overscanHeight; + let index = (this.renderedIndex + 1) * blockSize, + cnt = this.renderedIndex + 1; + let lastHeight; + const getElementHeight = () => + this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height(); + lastHeight = getElementHeight(); + while (lastHeight < minContentHeight && index < items.length) { + const itemsArr = items.slice(index, index + blockSize); + this.container.addItems( + // eslint-disable-next-line no-loop-func + itemsArr.map((item, i) => itemFormatter(item, index + i)), + this + ); + const addedHeight = getElementHeight() - lastHeight; + this.tree.set(cnt, addedHeight); + this.renderedIndex = cnt; + cnt++; + index += blockSize; + lastHeight = getElementHeight(); + } + } + + _calculateBlocksToRender() { + const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; + // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 + // 这样从不可见状态变为可见状态能够重新触发线段树初始化 + if (!this.element.is(":visible")) { + return; + } + this._renderMoreIf(); + const height = this.element.height(); + const minContentHeightFrom = scrollTop - overscanHeight; + const minContentHeightTo = scrollTop + height + overscanHeight; + const start = this.tree.greatestLowerBound(minContentHeightFrom); + const end = this.tree.leastUpperBound(minContentHeightTo); + const needDestroyed = [], + needMount = []; + for (let i = 0; i < start; i++) { + const index = i * blockSize; + if (!this.cache[i]) { + this.cache[i] = {}; + } + if (!this.cache[i].destroyed) { + for (let j = index; j < index + blockSize && j < items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + for (let i = end + 1; i <= this.renderedIndex; i++) { + const index = i * blockSize; + if (!this.cache[i]) { + this.cache[i] = {}; + } + if (!this.cache[i].destroyed) { + for (let j = index; j < index + blockSize && j < items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + const firstFragment = Widget._renderEngine.createFragment(), + lastFragment = Widget._renderEngine.createFragment(); + let currentFragment = firstFragment; + for (let i = start < 0 ? 0 : start; i <= end && i <= this.renderedIndex; i++) { + const index = i * blockSize; + if (!this.cache[i]) { + this.cache[i] = {}; + } + if (!this.cache[i].destroyed) { + currentFragment = lastFragment; + } + if (this.cache[i].destroyed === true) { + for (let j = index; j < index + blockSize && j < items.length; j++) { + const w = this.container._addElement(j, itemFormatter(items[j], j), this); + needMount.push(w); + currentFragment.appendChild(w.element[0]); + } + this.cache[i].destroyed = false; + } + } + this.container.element.prepend(firstFragment); + this.container.element.append(lastFragment); + this.topBlank.setHeight(`${this.tree.sumTo(Math.max(-1, start - 1))}px`); + this.bottomBlank.setHeight( + `${this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))}px` + ); + each(needMount, (i, child) => { + child && child._mount(); + }); + each(needDestroyed, (i, child) => { + child && child._destroy(); + }); + } + _populate(items) { + const { blockSize, scrollTop } = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } + this.tree = PrefixIntervalTree.empty(Math.ceil(this.options.items.length / blockSize)); + + this._calculateBlocksToRender(); + try { + this.element.scrollTop(scrollTop); + } catch (e) {} + } + + _clearChildren() { + each(this.container._children, (i, cell) => { + cell && cell._destroy(); + }); + this.container._children = {}; + this.container.attr("items", []); + } + + scrollTo(scrollTop) { + this.options.scrollTop = scrollTop; + this._calculateBlocksToRender(); + this.element.scrollTop(scrollTop); + } + + restore() { + this.renderedIndex = -1; + this._clearChildren(); + this.cache = {}; + this.options.scrollTop = 0; + // 依赖于cache的占位元素也要初始化 + this.topBlank.setHeight(0); + this.bottomBlank.setHeight(0); + } + + populate(items) { + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(items); + } + + beforeDestroy() { + ResizeDetector.removeResizeListener(this); + this.restore(); + } +} diff --git a/packages/fineui/src/base/pager/pager.js b/packages/fineui/src/base/pager/pager.js new file mode 100644 index 000000000..7858ac323 --- /dev/null +++ b/packages/fineui/src/base/pager/pager.js @@ -0,0 +1,419 @@ +import { + HorizontalLayout, + Widget, + shortcut, + extend, + emptyFn, + result, + isKey, + createWidget, + map, + stripEL, + formatEL, + Controller, + Events, + MIN, + MAX, + i18nText +} from "@/core"; +import { Label } from "../single"; +import { ButtonGroup } from "../combination"; + +/** + * 分页控件 + * + * Created by GUY on 2015/8/31. + * @class Pager + * @extends Widget + */ + +@shortcut() +export class Pager extends Widget { + static xtype = "bi.pager"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-pager", + behaviors: {}, + layouts: [ + { + type: HorizontalLayout.xtype, + hgap: 10, + vgap: 0 + } + ], + + dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 + // dynamicShow为false时以下两个有用 + dynamicShowFirstLast: false, // 是否动态显示首页、尾页 + dynamicShowPrevNext: false, // 是否动态显示上一页、下一页 + pages: false, // 总页数 + curr: () => 1, // 初始化当前页 + groups: 0, // 连续显示分页数 + jump: emptyFn, // 分页的回调函数 + first: false, // 是否显示首页 + last: false, // 是否显示尾页 + prev: i18nText("BI-Previous_Page"), + next: i18nText("BI-Next_Page"), + + firstPage: 1, + lastPage: () => + // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 + 1, + hasPrev: emptyFn, // pages不可用时有效 + hasNext: emptyFn // pages不可用时有效 + }); + } + + render() { + this.currPage = result(this.options, "curr"); + // 翻页太灵敏 + // this._lock = false; + // this._debouce = debounce(function () { + // self._lock = false; + // }, 300); + this._populate(); + } + + _populate() { + const o = this.options, + view = [], + dict = {}; + const { + dynamicShow, + dynamicShowPrevNext, + hasPrev, + dynamicShowFirstLast, + hasNext, + behaviors, + layouts, + jump + } = this.options; + this.empty(); + const pages = result(o, "pages"); + const curr = result(this, "currPage"); + let groups = result(o, "groups"); + let first = result(o, "first"); + let last = result(o, "last"); + const prev = result(o, "prev"); + const next = result(o, "next"); + + if (pages === false) { + groups = 0; + first = false; + last = false; + } else { + groups > pages && (groups = pages); + } + + // 计算当前组 + dict.index = Math.ceil( + (curr + (groups > 1 && groups !== pages ? 1 : 0)) / + (groups === 0 ? 1 : groups) + ); + + // 当前页非首页,则输出上一页 + if ( + ((!dynamicShow && !dynamicShowPrevNext) || curr > 1) && + prev !== false + ) { + if (isKey(prev)) { + view.push({ + text: prev, + value: "prev", + disabled: + pages === false + ? hasPrev(curr) === false + : !(curr > 1 && prev !== false) + }); + } else { + view.push({ + el: extend( + { + disabled: + pages === false + ? hasPrev(curr) === false + : !(curr > 1 && prev !== false) + }, + prev + ) + }); + } + } + + // 当前组非首组,则输出首页 + if ( + ((!dynamicShow && !dynamicShowFirstLast) || + (dict.index > 1 && groups !== 0)) && + first + ) { + view.push({ + text: first, + value: "first", + disabled: !(dict.index > 1 && groups !== 0) + }); + if (dict.index > 1 && groups !== 0 && groups !== pages - 1) { + view.push({ + type: Label.xtype, + cls: "page-ellipsis", + text: "\u2026" + }); + } + } + + // 输出当前页组 + dict.poor = Math.floor((groups - 1) / 2); + dict.start = dict.index > 1 ? curr - dict.poor : 1; + dict.end = + dict.index > 1 + ? (function () { + const max = curr + (groups - dict.poor - 1); + + return max > pages ? pages : max; + })() + : groups; + if (dict.end - dict.start < groups - 1) { + // 最后一组状态 + dict.start = dict.end - groups + 1; + } + let s = dict.start, + e = dict.end; + if ( + first && + last && + dict.index > 1 && + groups !== 0 && + pages > groups && + dict.end < pages && + groups !== 0 + ) { + s++; + e--; + } + for (; s <= e; s++) { + if (s === curr) { + view.push({ + text: s, + value: s, + selected: true + }); + } else { + view.push({ + text: s, + value: s + }); + } + } + + // 总页数大于连续分页数,且当前组最大页小于总页,输出尾页 + if ( + ((!dynamicShow && !dynamicShowFirstLast) || + (pages > groups && dict.end < pages && groups !== 0)) && + last + ) { + if ( + pages > groups && + dict.end < pages && + groups !== 0 && + groups !== pages - 1 + ) { + view.push({ + type: Label.xtype, + cls: "page-ellipsis", + text: "\u2026" + }); + } + view.push({ + text: last, + value: "last", + disabled: !(pages > groups && dict.end < pages && groups !== 0) + }); + } + + // 当前页不为尾页时,输出下一页 + dict.flow = !prev && groups === 0; + if ( + (!dynamicShow && !dynamicShowPrevNext && next) || + (curr !== pages && next) || + dict.flow + ) { + view.push( + (function () { + if (isKey(next)) { + if (pages === false) { + return { + text: next, + value: "next", + disabled: hasNext(curr) === false + }; + } + + return dict.flow && curr === pages + ? { text: next, value: "next", disabled: true } + : { + text: next, + value: "next", + disabled: !( + (curr !== pages && next) || + dict.flow + ) + }; + } + + return { + el: extend( + { + disabled: + pages === false + ? hasNext(curr) === false + : !( + (curr !== pages && next) || + dict.flow + ) + }, + next + ) + }; + })() + ); + } + + this.button_group = createWidget({ + type: ButtonGroup.xtype, + element: this, + items: map(view, (idx, v) => { + v = extend( + { + cls: "bi-list-item-select bi-border-radius", + height: 23, + hgap: v.el ? 0 : 10, + stopPropagation: true + }, + stripEL(v) + ); + + return formatEL(v); + }), + behaviors, + layouts + }); + this.button_group.on( + Controller.EVENT_CHANGE, + (type, value, obj, ...args) => { + // if (self._lock === true) { + // return; + // } + // self._lock = true; + // self._debouce(); + if (type === Events.CLICK) { + const v = this.button_group.getValue()[0]; + switch (v) { + case "first": + this.currPage = 1; + break; + case "last": + this.currPage = pages; + break; + case "prev": + this.currPage--; + break; + case "next": + this.currPage++; + break; + default: + this.currPage = v; + break; + } + jump.apply(this, [ + { + pages, + curr: this.currPage + } + ]); + this._populate(); + this.fireEvent(Pager.EVENT_CHANGE, obj); + } + this.fireEvent( + Controller.EVENT_CHANGE, + type, + value, + obj, + ...args + ); + } + ); + this.fireEvent(Pager.EVENT_AFTER_POPULATE); + } + + getCurrentPage() { + return this.currPage; + } + + setAllPages(pages) { + this.options.pages = pages; + this._populate(); + } + + hasPrev(v) { + v || (v = 1); + const { pages, hasPrev } = this.options; + + return pages === false ? hasPrev(v) : v > 1; + } + + hasNext(v) { + v || (v = 1); + const { pages, hasNext } = this.options; + + return pages === false ? hasNext(v) : v < pages; + } + + setValue(v) { + const o = this.options; + const { pages } = this.options; + v = v || 0; + v = v < 1 ? 1 : v; + if (pages === false) { + const lastPage = result(o, "lastPage"); + let firstPage = 1; + this.currPage = + v > lastPage + ? lastPage + : ((firstPage = result(o, "firstPage")), + v < firstPage ? firstPage : v); + } else { + v = v > pages ? pages : v; + this.currPage = v; + } + this._populate(); + } + + getValue() { + const val = this.button_group.getValue()[0]; + switch (val) { + case "prev": + return -1; + case "next": + return 1; + case "first": + return MIN; + case "last": + return MAX; + default: + return val; + } + } + + attr(key, value) { + super.attr(...arguments); + if (key === "curr") { + this.currPage = result(this.options, "curr"); + } + } + + populate() { + this._populate(); + } +} diff --git a/packages/fineui/src/base/single/0.single.js b/packages/fineui/src/base/single/0.single.js new file mode 100644 index 000000000..d113ef908 --- /dev/null +++ b/packages/fineui/src/base/single/0.single.js @@ -0,0 +1,254 @@ +import { Widget, shortcut, Actions, extend, isKey, isNotNull, isFunction, isPlainObject, isNull, delay } from "@/core"; +import { Tooltips } from "@/base/0.base"; + +/** + * guy + * 这仅仅只是一个超类, 所有简单控件的基类 + * 1、类的控制, + * 2、title的控制 + * 3、文字超过边界显示3个点 + * 4、cursor默认pointor + * @class Single + * @extends Widget + * @abstract + */ + +@shortcut() +export class Single extends Widget { + static xtype = "bi.single"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + readonly: false, + title: null, + warningTitle: null, // deprecated + tipType: null, // deprecated success或warning + belowMouse: false, // title是否跟随鼠标 + enableHover: false, + }); + } + + _showToolTip(e, opt) { + opt || (opt = {}); + const { action } = this.options; + const title = this.getTitle(); + + const showToolTip = tooltipOpt => { + if (isKey(tooltipOpt.text) && !Tooltips.has(this.getName())) { + Tooltips.show(e, this.getName(), tooltipOpt, this, opt); + if (action) { + Actions.runAction(action, "hover", this.options, this); + } + Actions.runGlobalAction("hover", this.options, this); + } + }; + + if (title instanceof Promise) { + this.requestingTitle = title; + title.then(resolvedTitle => { + // 由于是异步的,所以无法避免Promise resolve时机问题,所以设计为:鼠标移出了则不显示,并且只显示最后一次发起的查询结果 + this.mouseOver && this.requestingTitle === title && showToolTip(this._getTooltipOptions(resolvedTitle)); + }); + } else { + showToolTip(this._getTooltipOptions(title)); + } + } + + _hideTooltip() { + const tooltip = Tooltips.get(this.getName()); + if (isNotNull(tooltip)) { + tooltip.element.fadeOut(200, () => { + Tooltips.remove(this.getName()); + }); + } + } + + _init() { + const { value } = this.options; + this.options.value = isFunction(value) + ? this.__watch(value, (context, newValue) => { + this.setValue(newValue); + }) + : value; + super._init(...arguments); + } + + _mounted() { + const { enableHover, title, warningTitle, belowMouse, container } = this.options; + if (enableHover || isKey(title) || isKey(warningTitle) || isFunction(title) || isFunction(warningTitle)) { + this.enableHover({ + belowMouse, + container, + }); + } + } + + _clearTimeOut() { + if (isNotNull(this.showTimeout)) { + clearTimeout(this.showTimeout); + this.showTimeout = null; + } + if (isNotNull(this.hideTimeout)) { + clearTimeout(this.hideTimeout); + this.hideTimeout = null; + } + } + + _getTooltipOptions(title) { + const { tipType } = this.options; + let tooltipOpt = {}; + if (isPlainObject(title)) { + tooltipOpt = title; + } else { + tooltipOpt.level = this.getTipType() || "success"; + // 由于以前的用法,存在大量disabled:true搭配warningTitle的情况,所以这里做一个兼容,disabled:true的情况下,依然优先显示warningTitle,避免只设置了warningTitle而没有设置title的情况 + if (isNull(tipType) && !this.isEnabled()) { + tooltipOpt.text = this.getWarningTitle() || title; + } else { + tooltipOpt.text = tooltipOpt.level === "success" ? title : this.getWarningTitle() || title; + } + } + + return tooltipOpt; + } + + enableHover(opt) { + opt || (opt = {}); + let delayingTooltips; + if (!this._hoverBinded) { + this.element.unbind("mouseenter.title").on("mouseenter.title", e => { + this._e = e; + this.mouseOver = true; + if (this.getTipType() === "warning" || (isKey(this.getWarningTitle()) && !this.isEnabled())) { + delayingTooltips = this.getName(); + this.showTimeout = delay(() => { + if (isNotNull(this.showTimeout) && delayingTooltips === this.getName()) { + this._showToolTip(this._e || e, opt); + } + }, 200); + } else if (this.getTipType() === "success" || this.isEnabled()) { + delayingTooltips = this.getName(); + this.showTimeout = delay(() => { + if (isNotNull(this.showTimeout) && delayingTooltips === this.getName()) { + this._showToolTip(this._e || e, opt); + } + }, 500); + } + }); + this.element.unbind("mousemove.title").on("mousemove.title", e => { + this._e = e; + if (isNotNull(this.showTimeout)) { + clearTimeout(this.showTimeout); + this.showTimeout = null; + } + if (isNull(this.hideTimeout)) { + this.hideTimeout = delay(() => { + if (isNotNull(this.hideTimeout)) { + this._hideTooltip(); + } + }, 500); + } + + this.showTimeout = delay(() => { + // DEC-5321 IE下如果回调已经进入事件队列,clearTimeout将不会起作用 + if (isNotNull(this.showTimeout)) { + if (isNotNull(this.hideTimeout)) { + clearTimeout(this.hideTimeout); + this.hideTimeout = null; + } + // CHART-10611 在拖拽的情况下, 鼠标拖拽着元素离开了拖拽元素的容器,但是子元素在dom结构上仍然属于容器 + // 这样会认为鼠标仍然在容器中, 500ms内放开的话,会在容器之外显示鼠标停留处显示容器的title + if (this.element.__isMouseInBounds__(this._e || e)) { + this._showToolTip(this._e || e, opt); + } + } + }, 500); + }); + this.element.unbind("mouseleave.title").on("mouseleave.title", e => { + this._e = null; + this.mouseOver = false; + this._clearTimeOut(); + this._hideTooltip(); + }); + this._hoverBinded = true; + } + } + + disabledHover() { + // 取消hover事件 + this._clearTimeOut(); + this._hideTooltip(); + this.element.unbind("mouseenter.title").unbind("mousemove.title").unbind("mouseleave.title"); + this._hoverBinded = false; + } + + // opt: {container: '', belowMouse: false} + setTitle(title, opt) { + this.options.title = title; + if (isKey(title) || isFunction(title)) { + this.enableHover(opt); + } else { + this.disabledHover(); + } + } + + setWarningTitle(title, opt) { + this.options.warningTitle = title; + if (isKey(title) || isFunction(title)) { + this.enableHover(opt); + } else { + this.disabledHover(); + } + } + + setTipType(type) { + this.options.tipType = type; + } + + getTipType() { + return this.options.tipType; + } + + isReadOnly() { + return !!this.options.readonly; + } + + getTitle() { + const title = this.options.title; + if (isFunction(title)) { + return title(); + } + + return title; + } + + getWarningTitle() { + const title = this.options.warningTitle; + if (isFunction(title)) { + return title(); + } + + return title; + } + + setValue(val) { + if (!this.options.readonly) { + this.options.value = val; + this.options.setValue && this.options.setValue(val); + } + } + + getValue() { + return this.options.value; + } + + _destroyed() { + if (isNotNull(this.showTimeout)) { + clearTimeout(this.showTimeout); + this.showTimeout = null; + } + Tooltips.remove(this.getName()); + } +} diff --git a/packages/fineui/src/base/single/1.text.js b/packages/fineui/src/base/single/1.text.js new file mode 100644 index 000000000..9b6d596cd --- /dev/null +++ b/packages/fineui/src/base/single/1.text.js @@ -0,0 +1,198 @@ +import { Layout, DefaultLayout, shortcut, pixFormat, isWidthOrHeight, emptyFn, createWidget, isKey, isFunction, isUndefined } from "@/core"; +import { Single } from "./0.single"; + +/** + * guy 表示一行数据,通过position来定位位置的数据 + * @class Text + * @extends Single + */ + +@shortcut() +export class Text extends Single { + static xtype = "bi.text"; + + props = { + baseCls: "bi-text", + textAlign: "left", + whiteSpace: "normal", + lineHeight: null, + handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的 + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + py: "", + highLight: false, + }; + + render() { + const { + vgap, + hgap, + lgap, + rgap, + tgap, + bgap, + height, + lineHeight, + maxWidth, + textAlign, + whiteSpace, + handler, + disabled, + invalid, + text: optionsText, + value, + keyword, + highLight, + } = this.options; + if (hgap + lgap > 0) { + this.element.css({ + "padding-left": pixFormat(hgap + lgap), + }); + } + if (hgap + rgap > 0) { + this.element.css({ + "padding-right": pixFormat(hgap + rgap), + }); + } + if (vgap + tgap > 0) { + this.element.css({ + "padding-top": pixFormat(vgap + tgap), + }); + } + if (vgap + bgap > 0) { + this.element.css({ + "padding-bottom": pixFormat(vgap + bgap), + }); + } + if (isWidthOrHeight(height)) { + this.element.css({ lineHeight: pixFormat(height) }); + } + if (isWidthOrHeight(lineHeight)) { + this.element.css({ lineHeight: pixFormat(lineHeight) }); + } + if (isWidthOrHeight(maxWidth)) { + this.element.css({ maxWidth: pixFormat(maxWidth) }); + } + this.element.css({ + textAlign, + whiteSpace: this._getTextWrap(), + textOverflow: whiteSpace === "nowrap" ? "ellipsis" : "", + overflow: whiteSpace === "nowrap" ? "" : isWidthOrHeight(height) ? "auto" : "", + }); + if (handler && handler !== emptyFn) { + this.text = createWidget({ + type: Layout.xtype, + tagName: "span", + }); + this.text.element.click(e => { + !disabled && !invalid && handler.call(this, this.getValue(), this, e); + }); + createWidget({ + type: DefaultLayout.xtype, + element: this, + items: [this.text], + }); + } else { + this.text = this; + } + + const text = isFunction(optionsText) + ? this.__watch(optionsText, (context, newValue) => { + this.setText(newValue); + }) + : optionsText; + // 只要不是undefined就可以显示text值,否则显示value + if (!isUndefined(text)) { + this.setText(text); + } else if (isKey(value)) { + this.setText(value); + } + if (isKey(keyword)) { + this.doRedMark(keyword); + } + if (highLight) { + this.doHighLight(); + } + } + + _getTextWrap() { + const { whiteSpace } = this.options; + switch (whiteSpace) { + case "nowrap": + return "pre"; + case "normal": + return "pre-wrap"; + default: + return whiteSpace; + } + } + + _getShowText() { + const { text: optionsText } = this.options; + const text = isFunction(optionsText) ? optionsText() : optionsText; + + return isKey(text) ? Text.formatText(`${text}`) : text; + } + + _doRedMark(keyword) { + const { py } = this.options; + // render之后做的doRedMark,这个时候虽然标红了,但是之后text mounted执行的时候并没有keyword + this.options.keyword = keyword; + this.text.element.__textKeywordMarked__(this._getShowText(), keyword, py); + } + + doRedMark(keyword) { + if (isKey(keyword)) { + this._doRedMark(keyword); + } + } + + unRedMark() { + const { py } = this.options; + this.options.keyword = ""; + this.text.element.__textKeywordMarked__(this._getShowText(), "", py); + } + + doHighLight() { + this.text.element.addClass("bi-high-light"); + } + + unHighLight() { + this.text.element.removeClass("bi-high-light"); + } + + setValue(text) { + super.setValue(text); + if (!this.isReadOnly()) { + this.setText(text); + } + } + + setStyle(css) { + this.text.element.css(css); + } + + setText(text) { + super.setText(text); + this.options.text = text; + this._doRedMark(this.options.keyword); + } +} + +const formatters = []; +Text.addTextFormatter = formatter => { + formatters.push(formatter); +}; +Text.formatText = text => { + if (formatters.length > 0) { + for (let i = 0; i < formatters.length; i++) { + text = formatters[i](text); + } + } + + return text; +}; diff --git a/src/base/single/__test__/text.test.js b/packages/fineui/src/base/single/__test__/text.test.js similarity index 100% rename from src/base/single/__test__/text.test.js rename to packages/fineui/src/base/single/__test__/text.test.js diff --git a/src/base/single/a/__test__/a.test.js b/packages/fineui/src/base/single/a/__test__/a.test.js similarity index 100% rename from src/base/single/a/__test__/a.test.js rename to packages/fineui/src/base/single/a/__test__/a.test.js diff --git a/packages/fineui/src/base/single/a/a.js b/packages/fineui/src/base/single/a/a.js new file mode 100644 index 000000000..4f331acd7 --- /dev/null +++ b/packages/fineui/src/base/single/a/a.js @@ -0,0 +1,39 @@ +import { Text } from "../1.text"; +import { shortcut, extend, createWidget } from "@/core"; + +/** + * 超链接 + * + * Created by GUY on 2015/9/9. + * @class A + * @extends Text + * @abstract + */ + +@shortcut() +export class A extends Text { + static xtype = "bi.a"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-a display-block`, + href: "", + target: "_blank", + el: null, + tagName: "a", + }); + } + + render() { + const { href, target, el } = this.options; + super.render(); + this.element.attr({ href, target }); + if (el) { + createWidget(el, { + element: this, + }); + } + } +} diff --git a/packages/fineui/src/base/single/bar/bar.loading.js b/packages/fineui/src/base/single/bar/bar.loading.js new file mode 100644 index 000000000..d51f9c6a1 --- /dev/null +++ b/packages/fineui/src/base/single/bar/bar.loading.js @@ -0,0 +1,84 @@ +import { TextButton } from "../button"; +import { Layout, CenterAdaptLayout, CardLayout, shortcut, emptyFn, createWidget, i18nText, Controller } from "@/core"; +import { Single } from "../0.single"; + +@shortcut() +export class LoadingBar extends Single { + static xtype = "bi.loading_bar"; + + _defaultConfig() { + const conf = super._defaultConfig.apply(this, arguments); + + return { + ...conf, + baseCls: `${conf.baseCls || ""} bi-loading-bar bi-tips`, + height: 30, + handler: emptyFn, + }; + } + + render() { + this.loaded = createWidget({ + type: TextButton.xtype, + cls: "loading-text bi-list-item-simple", + text: i18nText("BI-Load_More"), + width: 120, + handler: this.options.handler, + }); + this.loaded.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.loading = createWidget({ + type: Layout.xtype, + width: this.options.height, + height: this.options.height, + cls: "loading-background cursor-default", + }); + const loaded = createWidget({ + type: CenterAdaptLayout.xtype, + items: [this.loaded], + }); + const loading = createWidget({ + type: CenterAdaptLayout.xtype, + items: [this.loading], + }); + this.cardLayout = createWidget({ + type: CardLayout.xtype, + element: this, + items: [ + { + el: loaded, + cardName: "loaded", + }, + { + el: loading, + cardName: "loading", + } + ], + }); + this.invisible(); + } + + _reset() { + this.visible(); + this.loaded.setText(i18nText("BI-Load_More")); + this.loaded.enable(); + } + + setLoaded() { + this._reset(); + this.cardLayout.showCardByName("loaded"); + } + + setEnd() { + this.setLoaded(); + this.loaded.setText(i18nText("BI-No_More_Data")); + this.loaded.disable(); + } + + setLoading() { + this._reset(); + this.cardLayout.showCardByName("loading"); + } +} diff --git a/packages/fineui/src/base/single/button/button.basic.js b/packages/fineui/src/base/single/button/button.basic.js new file mode 100644 index 000000000..7dc121efb --- /dev/null +++ b/packages/fineui/src/base/single/button/button.basic.js @@ -0,0 +1,502 @@ +import { + Layout, + AbsoluteLayout, + emptyFn, + shortcut, + extend, + isFunction, + createWidget, + Widget, + isObject, + Controller, + isIE, + getIEVersion, + nextTick, + isKey, + isNull, + DOM, + debounce, + KeyCode, + EVENT_RESPONSE_TIME, + Events, + Actions +} from "@/core"; +import { Single } from "../0.single"; + +/** + * guy + * @class BasicButton + * @extends Single + * + * 一般的button父级 + */ +@shortcut() +export class BasicButton extends Single { + static xtype = "bi.basic_button"; + + static EVENT_CHANGE = "BasicButton.EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-basic-button${conf.invalid ? "" : " cursor-pointer"}${ + isIE() && getIEVersion() < 10 ? " hack" : "" + }`, + // el: {} // 可以通过el来创建button元素 + value: "", + stopEvent: false, + stopPropagation: false, + selected: false, + once: false, // 点击一次选中有效,再点无效 + forceSelected: false, // 点击即选中, 选中了就不会被取消,与once的区别是forceSelected不影响事件的触发 + forceNotSelected: false, // 无论怎么点击都不会被选中 + disableSelected: false, // 使能选中 + + shadow: false, + isShadowShowingOnSelected: false, // 选中状态下是否显示阴影 + trigger: null, + handler: emptyFn, + bubble: null, + debounce: true, + }); + } + + _init() { + const opts = this.options; + opts.selected = isFunction(opts.selected) + ? this.__watch(opts.selected, (context, newValue) => { + this.setSelected(newValue); + }) + : opts.selected; + super._init(...arguments); + + if (opts.shadow) { + this._createShadow(); + } + if (opts.level) { + this.element.addClass(`button-${opts.level}`); + } + } + + _initRef() { + if (this.options.selected === true) { + this.setSelected(true); + } + // 延迟绑定事件,这样可以将自己绑定的事情优先执行 + nextTick(() => { + !this.isDestroyed() && this.bindEvent(); + }); + super._initRef.apply(this, arguments); + } + + // 默认render方法 + render() { + return this.options.el; + } + + _createShadow() { + const o = this.options; + + const assertMask = () => { + if (!this.$mask) { + this.$mask = createWidget(isObject(o.shadow) ? o.shadow : {}, { + type: Layout.xtype, + cls: "bi-button-mask", + }); + this.$mask.invisible(); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.$mask, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + } + }; + + this.element.mouseup(() => { + if (!this._hover && !o.isShadowShowingOnSelected) { + assertMask(); + this.$mask.invisible(); + } + }); + this.element.on(`mouseenter.${this.getName()}`, e => { + if (this.element.__isMouseInBounds__(e)) { + if (this.isEnabled() && !this._hover && (o.isShadowShowingOnSelected || !this.isSelected())) { + assertMask(); + this.$mask.visible(); + } + } + }); + this.element.on(`mousemove.${this.getName()}`, e => { + if (!this.element.__isMouseInBounds__(e)) { + if (this.isEnabled() && !this._hover) { + assertMask(); + this.$mask.invisible(); + } + } + }); + this.element.on(`mouseleave.${this.getName()}`, () => { + if (this.isEnabled() && !this._hover) { + assertMask(); + this.$mask.invisible(); + } + }); + } + + bindEvent() { + const o = this.options; + let hand = this.handle(); + if (!hand) { + return; + } + hand = hand.element; + + const getBubble = () => { + const bubble = o.bubble; + if (isFunction(bubble)) { + return bubble(); + } + + return bubble; + }; + + const clk = async (...args) => { + const [e] = args; + ev(e); + if (!this.isEnabled() || !this.isValid()) { + return; + } + if (this.isOnce() && this.isSelected()) { + return; + } + if (isKey(o.bubble) || isFunction(o.bubble)) { + if (isNull(this.combo)) { + const { BubbleCombo } = await import("@/case/combo/bubblecombo/combo.bubble"); + const { BubblePopupBarView, TextBubblePopupBarView } = await import("@/case/combo/bubblecombo/popup.bubble"); + + let popup; + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: BubbleCombo.xtype, + trigger: "", + // bubble的提示不需要一直存在在界面上 + destroyWhenHide: true, + ref: _ref => { + this.combo = _ref; + }, + el: { + type: Layout.xtype, + height: "100%", + }, + popup: { + type: TextBubblePopupBarView.xtype, + text: getBubble(), + ref: _ref => { + popup = _ref; + }, + listeners: [ + { + eventName: BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, + action: (...args) => { + const [v] = args; + this.combo.hideView(); + if (v) { + onClick.apply(this, args); + } + }, + } + ], + }, + listeners: [ + { + eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW, + action() { + popup.populate(getBubble()); + }, + } + ], + }, + left: 0, + right: 0, + bottom: 0, + top: 0, + } + ], + }); + } + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } else { + this.combo.showView(); + } + + return; + } + onClick.apply(this, args); + }; + + const triggerArr = (o.trigger || "").split(","); + triggerArr.forEach(trigger => { + let mouseDown = false; + let selected = false; + let interval; + switch (trigger) { + case "mouseup": + hand.mousedown(() => { + mouseDown = true; + }); + hand.mouseup(e => { + if (mouseDown === true) { + clk(e); + } + mouseDown = false; + ev(e); + }); + break; + case "mousedown": + // let mouseDown = false; + hand.mousedown(e => { + // if (e.button === 0) { + Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, e => { + // if (e.button === 0) { + if ( + DOM.isExist(this) && + !hand.__isMouseInBounds__(e) && + mouseDown === true && + !selected + ) { + // self.setSelected(!self.isSelected()); + this._trigger(); + } + mouseDown = false; + Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`); + // } + }); + if (mouseDown === true) { + return; + } + if (this.isSelected()) { + selected = true; + } else { + clk(e); + } + mouseDown = true; + ev(e); + // } + }); + hand.mouseup(e => { + // if (e.button === 0) { + if (DOM.isExist(this) && mouseDown === true && selected === true) { + clk(e); + } + mouseDown = false; + selected = false; + Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`); + // } + }); + break; + case "dblclick": + hand.dblclick(clk); + break; + case "lclick": + hand.mousedown(e => { + Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, () => { + interval && clearInterval(interval); + interval = null; + mouseDown = false; + Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`); + }); + if (mouseDown === true) { + return; + } + if (!this.isEnabled() || !this.isValid()) { + return; + } + if (this.isOnce() && this.isSelected()) { + return; + } + interval = setInterval(() => { + clk(e); + }, 180); + mouseDown = true; + ev(e); + }); + break; + default: + if (o.stopEvent || o.stopPropagation) { + hand.mousedown(e => { + ev(e); + }); + } + hand.click(clk); + // enter键等同于点击 + o.attributes && + o.attributes.zIndex >= 0 && + hand.keyup(e => { + if (e.keyCode === KeyCode.ENTER) { + clk(e); + } + }); + break; + } + }); + + // 之后的300ms点击无效 + const onClick = o.debounce + ? debounce(this._doClick, EVENT_RESPONSE_TIME, { + leading: true, + trailing: false, + }) + : this._doClick; + + function ev(e) { + if (o.stopEvent) { + e.stopEvent(); + } + if (o.stopPropagation) { + e.stopPropagation(); + } + } + } + + _trigger(e) { + const o = this.options; + if (!this.isEnabled()) { + return; + } + if (!this.isDisableSelected()) { + this.isForceSelected() + ? this.setSelected(true) + : this.isForceNotSelected() + ? this.setSelected(false) + : this.setSelected(!this.isSelected()); + } + if (this.isValid()) { + const v = this.getValue(); + o.handler.call(this, v, this, e); + this.fireEvent(Controller.EVENT_CHANGE, Events.CLICK, v, this, e); + this.fireEvent(BasicButton.EVENT_CHANGE, v, this); + if (o.action) { + Actions.runAction(o.action, "click", o, this); + } + Actions.runGlobalAction("click", o, this); + } + } + + _doClick(e) { + if (!this.isEnabled() || !this.isValid()) { + return; + } + const isIntercepted = this.beforeClick(e); + // 如果事件已经被消费掉了,就不再触发点击事件 + if (isIntercepted) { + return; + } + + this._trigger(e); + if (this.isEnabled() && this.isValid()) { + this.doClick(e); + } + } + + /** + * 子类可以得写这个方法,如果返回为 true,则可以阻止 handler 的触发 + */ + beforeClick() {} + + doClick() {} + + handle() { + return this; + } + + hover() { + this._hover = true; + this.handle().element.addClass("hover"); + if (this.options.shadow) { + this.$mask && this.$mask.setVisible(true); + } + } + + dishover() { + this._hover = false; + this.handle().element.removeClass("hover"); + if (this.options.shadow) { + this.$mask && this.$mask.setVisible(false); + } + } + + setSelected(b) { + const o = this.options; + o.selected = b; + if (b) { + this.handle().element.addClass("active"); + } else { + this.handle().element.removeClass("active"); + } + if (o.shadow && !o.isShadowShowingOnSelected) { + this.$mask && this.$mask.setVisible(false); + } + this.options.setSelected && this.options.setSelected.call(this, b); + } + + isSelected() { + return this.options.selected; + } + + isOnce() { + return this.options.once; + } + + isForceSelected() { + return this.options.forceSelected; + } + + isForceNotSelected() { + return this.options.forceNotSelected; + } + + isDisableSelected() { + return this.options.disableSelected; + } + + setText(text) { + this.options.text = text; + this.options.setText && this.options.setText.call(this, text); + } + + getText() { + return this.options.text; + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.removeClass("base-disabled disabled"); + } else if (enable === false) { + this.element.addClass("base-disabled disabled"); + } + if (!enable) { + if (this.options.shadow) { + this.$mask && this.$mask.setVisible(false); + } + } + } + + empty() { + Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`); + super.empty(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/button.node.js b/packages/fineui/src/base/single/button/button.node.js new file mode 100644 index 000000000..1c58f5aaa --- /dev/null +++ b/packages/fineui/src/base/single/button/button.node.js @@ -0,0 +1,59 @@ +import { BasicButton } from "./button.basic"; +import { shortcut, extend, Controller, Events } from "@/core"; + +/** + * 表示一个可以展开的节点, 不仅有选中状态而且有展开状态 + * + * Created by GUY on 2015/9/9. + * @class NodeButton + * @extends BasicButton + * @abstract + */ +@shortcut() +export class NodeButton extends BasicButton { + static xtype = "bi.node_button"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-node`, + open: false, + once: false, + }); + } + + _initRef() { + if (this.isOpened()) { + this.setOpened(this.isOpened()); + } + super._initRef(...arguments); + } + + doClick() { + super.doClick(...arguments); + this.setOpened(!this.isOpened()); + } + + isOpened() { + return !!this.options.open; + } + + setOpened(b) { + this.options.open = !!b; + } + + triggerCollapse() { + if (this.isOpened()) { + this.setOpened(false); + this.fireEvent(Controller.EVENT_CHANGE, Events.COLLAPSE, this.getValue(), this); + } + } + + triggerExpand() { + if (!this.isOpened()) { + this.setOpened(true); + this.fireEvent(Controller.EVENT_CHANGE, Events.EXPAND, this.getValue(), this); + } + } +} diff --git a/src/base/single/button/buttons/__test__/button.test.js b/packages/fineui/src/base/single/button/buttons/__test__/button.test.js similarity index 100% rename from src/base/single/button/buttons/__test__/button.test.js rename to packages/fineui/src/base/single/button/buttons/__test__/button.test.js diff --git a/packages/fineui/src/base/single/button/buttons/button.icon.js b/packages/fineui/src/base/single/button/buttons/button.icon.js new file mode 100644 index 000000000..c0e60a0fa --- /dev/null +++ b/packages/fineui/src/base/single/button/buttons/button.icon.js @@ -0,0 +1,76 @@ +import { Icon } from "../../icon/icon"; +import { DefaultLayout, CenterAdaptLayout, shortcut, extend, isNumber, createWidget, isNull, pixFormat } from "@/core"; +import { BasicButton } from "../button.basic"; + +/** + * @class IconButton + * @extends BasicButton + * 图标的button + */ +@shortcut() +export class IconButton extends BasicButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.icon_button"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-icon-button horizon-center`, + hgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + lgap: 0, + rgap: 0, + iconWidth: null, + iconHeight: null, + }); + } + + render() { + const o = this.options; + this.element.css({ + textAlign: "center", + }); + this.icon = createWidget({ + type: Icon.xtype, + width: o.iconWidth, + height: o.iconHeight, + }); + if (isNumber(o.height) && o.height > 0 && isNull(o.iconWidth) && isNull(o.iconHeight)) { + this.element.css("lineHeight", pixFormat(o.height)); + createWidget({ + type: DefaultLayout.xtype, + element: this, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + items: [this.icon], + }); + } else { + this.element.css("lineHeight", "1"); + createWidget({ + element: this, + type: CenterAdaptLayout.xtype, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + items: [this.icon], + }); + } + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(IconButton.EVENT_CHANGE, this); + } + } +} diff --git a/packages/fineui/src/base/single/button/buttons/button.image.js b/packages/fineui/src/base/single/button/buttons/button.image.js new file mode 100644 index 000000000..f46b3f1f4 --- /dev/null +++ b/packages/fineui/src/base/single/button/buttons/button.image.js @@ -0,0 +1,93 @@ +import { Img } from "../../img/img"; +import { CenterAdaptLayout, AdaptiveLayout, shortcut, extend, isNumber, createWidget } from "@/core"; +import { BasicButton } from "../button.basic"; + +/** + * 图片的button + * + * Created by GUY on 2016/1/27. + * @class ImageButton + * @extends BasicButton + */ +@shortcut() +export class ImageButton extends BasicButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.image_button"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-image-button`, + src: "", + iconWidth: "100%", + iconHeight: "100%", + }); + } + + render() { + const o = this.options; + this.image = createWidget({ + type: Img.xtype, + width: o.iconWidth, + height: o.iconHeight, + src: o.src, + }); + if (isNumber(o.iconWidth) || isNumber(o.iconHeight)) { + createWidget({ + type: CenterAdaptLayout.xtype, + element: this, + items: [this.image], + }); + } else { + createWidget({ + type: AdaptiveLayout.xtype, + element: this, + items: [this.image], + scrollable: false, + }); + } + } + + setWidth(w) { + super.setWidth(...arguments); + this.options.width = w; + } + + setHeight(h) { + super.setHeight(...arguments); + this.options.height = h; + } + + setImageWidth(w) { + this.image.setWidth(w); + } + + setImageHeight(h) { + this.image.setHeight(h); + } + + getImageWidth() { + return this.image.element.width(); + } + + getImageHeight() { + return this.image.element.height(); + } + + setSrc(src) { + this.options.src = src; + this.image.setSrc(src); + } + + getSrc() { + return this.image.getSrc(); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(ImageButton.EVENT_CHANGE, this); + } + } +} diff --git a/packages/fineui/src/base/single/button/buttons/button.js b/packages/fineui/src/base/single/button/buttons/button.js new file mode 100644 index 000000000..b912b9e00 --- /dev/null +++ b/packages/fineui/src/base/single/button/buttons/button.js @@ -0,0 +1,278 @@ +import { CenterAdaptLayout, isNumber, shortcut, isPlainObject, createWidget, isIE, isIE9Below, pixFormat, get, isNull, toPix } from "@/core"; +import { Label, IconLabel } from "../../label"; +import { BasicButton } from "../button.basic"; + +function isVertical(position) { + return position === "top" || position === "bottom"; +} + +const loadingCls = "button-loading-font anim-rotate"; + +/** + * 文字类型的按钮 + * @class Button + * @extends BasicButton + * + * @cfg {JSON} options 配置属性 + * @cfg {'common' / 'success' / 'warning' / 'ignore'} [options.level='common'] 按钮类型,用不同颜色强调不同的场景 + */ +@shortcut() +export class Button extends BasicButton { + _const = { + iconWidth: 18, + }; + + static xtype = "bi.button"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(props) { + const conf = super._defaultConfig.apply(this, arguments); + + let adaptiveHeight = 0; + if (isVertical(props.iconPosition)) { + // 图标高度和文字高度默认相等 + adaptiveHeight += (props.textHeight || 16) * 2; + adaptiveHeight += props.iconGap || 0; + const tGap = props.tgap || props.vgap || 2; + const bGap = props.bgap || props.vgap || 2; + adaptiveHeight += tGap + bGap; + } + + const clearMinWidth = props.block === true || props.clear === true || props.plain; + + return { + ...conf, + baseCls: `${conf.baseCls || ""} bi-button${isIE() && isIE9Below() ? " hack" : ""}`, + attributes: { + tabIndex: 1, + }, + minWidth: clearMinWidth ? 0 : 80, + height: isVertical(props.iconPosition) ? adaptiveHeight : 24, + shadow: props.clear !== true, + isShadowShowingOnSelected: true, + readonly: true, + iconCls: "", + level: "common", + block: false, // 是否块状显示,即不显示边框,没有最小宽度的限制 + clear: false, // 是否去掉边框和背景 + ghost: false, // 是否幽灵显示, 即正常状态无背景 + loading: false, // 是否处于加载中 + light: false, // 是否使用浅色 + plain: false, // 是否是朴素按钮,和 clear 的区别是 plain 有悬浮效果 + textAlign: "center", + whiteSpace: "nowrap", + textWidth: null, + textHeight: null, + hgap: props.clear ? 0 : props.plain && !props.text ? 4 : 10, + vgap: 0, + tgap: 0, + bgap: 0, + lgap: 0, + rgap: 0, + icon: "", + iconGap: 0, + iconPosition: "left", + }; + } + + render() { + const o = this.options; + + // bi.center_adapt 作用:让 hgap 不影响 iconGap。 + createWidget({ + type: CenterAdaptLayout.xtype, + horizontalAlign: o.textAlign, + element: this, + ref: ref => { + this.containerRef = ref; + }, + hgap: o.hgap, + vgap: o.vgap, + items: this.generateItems(), + }); + + // 如果 options 对应的属性为 true 则给元素添加 class + const classArr = ["block", "clear", "ghost", "plain", "loading", "light"]; + classArr.forEach(clz => { + if (get(o, clz) === true) { + this.element.addClass(clz); + } + }); + + if (o.minWidth > 0) { + this.element.css({ "min-width": pixFormat(o.minWidth) }); + } + } + + generateItems(defaultRenderIcon) { + const o = this.options; + + // 由于button默认情况下有个边框,所以要主动算行高 + let lineHeight, + textHeight = o.textHeight; + let hasBorder = false; + if (isNumber(o.height)) { + if (!isVertical(o.iconPosition)) { + if (!(o.clear && o.block && o.light)) { + hasBorder = true; + } + lineHeight = o.height; + } else { + lineHeight = textHeight; + } + } + if (!textHeight) { + if (o.whiteSpace === "nowrap") { + textHeight = lineHeight; + } + } + + const iconInvisible = !(o.loading || o.iconCls || o.icon || defaultRenderIcon); + + let maxTextWidth = Math.max(o.minWidth, o.width); + maxTextWidth -= o.hgap * 2 + o.iconGap; + // 减去图标水平占位宽度 + maxTextWidth -= iconInvisible || isVertical(o.iconPosition) ? 0 : this._const.iconWidth; + const textWidth = isNull(o.textWidth) ? maxTextWidth : Math.min(o.textWidth, maxTextWidth); + + this.text = createWidget({ + type: Label.xtype, + text: o.text, + whiteSpace: o.whiteSpace, + textAlign: o.textAlign, + textWidth, + textHeight: toPix(textHeight, hasBorder ? 2 : 0), + height: toPix(lineHeight, hasBorder ? 2 : 0), + value: o.value, + title: null, + }); + + if (iconInvisible) { + return [this.text]; + } + + this._iconRendered = true; + + if (isPlainObject(o.icon) && !o.loading) { + this.icon = createWidget(o.icon); + } else { + this.icon = createWidget({ + type: IconLabel.xtype, + cls: o.loading ? loadingCls : o.iconCls || o.icon, + width: this._const.iconWidth, + height: toPix(lineHeight, hasBorder ? 2 : 0), + lineHeight: toPix(lineHeight, hasBorder ? 2 : 0), + // 不设置,自定义按钮无法居中 + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + invisible: iconInvisible, + }); + } + + const gapContainer = { + lgap: o.iconPosition === "left" && o.text ? o.iconGap : 0, + rgap: o.iconPosition === "right" ? o.iconGap : 0, + tgap: o.iconPosition === "top" ? o.iconGap : 0, + bgap: o.iconPosition === "bottom" ? o.iconGap : 0, + }; + + const items = [this.icon, { el: this.text, ...gapContainer }]; + if (o.iconPosition === "right" || o.iconPosition === "bottom") { + items.reverse(); + } + + return [ + { + type: isVertical(o.iconPosition) ? "bi.vertical" : "bi.horizontal", + horizontalAlign: "center", + verticalAlign: "middle", + items, + } + ]; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(Button.EVENT_CHANGE, this); + } + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.attr("tabIndex", 1); + } else if (enable === false) { + this.element.removeAttr("tabIndex"); + } + } + + beforeClick() { + return this.isLoading(); + } + + isLoading() { + return this._loading === undefined ? this.options.loading : this._loading; + } + + loading() { + this._loading = true; + this.element.addClass("loading"); + !this._iconRendered && this.containerRef.populate(this.generateItems(true)); + if (this.icon.loading) { + this.icon.loading(); + } else { + // loadingCls 可以覆盖 iconCls 所以不需要移除 iconCls + this.icon.element.addClass(loadingCls); + this.icon.setVisible(true); + } + } + + loaded() { + this._loading = false; + this.element.removeClass("loading"); + if (this.icon.loaded) { + this.icon.loaded(); + } else { + this.icon.element.removeClass(loadingCls); + this.icon.setVisible(!!this.options.iconCls); + } + } + + setText(text) { + super.setText(...arguments); + this.text.setText(text); + } + + setValue(text) { + super.setValue(...arguments); + if (!this.isReadOnly()) { + this.text.setValue(text); + } + } + + setIcon(cls) { + const o = this.options; + !this._iconRendered && this.containerRef.populate(this.generateItems(true)); + if (this.icon && o.iconCls !== cls) { + this.icon.element.removeClass(o.iconCls).addClass(cls); + o.iconCls = cls; + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/buttons/button.text.js b/packages/fineui/src/base/single/button/buttons/button.text.js new file mode 100644 index 000000000..3404789e1 --- /dev/null +++ b/packages/fineui/src/base/single/button/buttons/button.text.js @@ -0,0 +1,96 @@ +import { Label } from "../../label"; +import { BasicButton } from "../button.basic"; +import { shortcut, extend, createWidget, isArray } from "@/core"; + +/** + * guy + * 可以点击的一行文字 + * @class TextButton + * @extends BasicButton + * 文字button + */ +@shortcut() +export class TextButton extends BasicButton { + static xtype = "bi.text_button"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-button`, + textAlign: "center", + whiteSpace: "nowrap", + textWidth: null, + textHeight: null, + hgap: 0, + lgap: 0, + rgap: 0, + vgap: 0, + py: "", + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textWidth: o.textWidth, + textHeight: o.textHeight, + width: o.width, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + }); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(TextButton.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setText(text) { + super.setText(...arguments); + text = isArray(text) ? text.join(",") : text; + this.text.setText(text); + } + + setStyle(style) { + this.text.setStyle(style); + } + + setValue(text) { + super.setValue(...arguments); + if (!this.isReadOnly()) { + text = isArray(text) ? text.join(",") : text; + this.text.setValue(text); + } + } +} diff --git a/packages/fineui/src/base/single/button/index.js b/packages/fineui/src/base/single/button/index.js new file mode 100644 index 000000000..bf1a0f903 --- /dev/null +++ b/packages/fineui/src/base/single/button/index.js @@ -0,0 +1,17 @@ +export { BasicButton } from "./button.basic"; +export { NodeButton } from "./button.node"; +export { Button } from "./buttons/button"; +export { IconButton } from "./buttons/button.icon"; +export { ImageButton } from "./buttons/button.image"; +export { TextButton } from "./buttons/button.text"; +export { BlankIconIconTextItem } from "./listitem/blankiconicontextitem"; +export { BlankIconTextIconItem } from "./listitem/blankicontexticonitem"; +export { BlankIconTextItem } from "./listitem/blankicontextitem"; +export { IconTextIconItem } from "./listitem/icontexticonitem"; +export { IconTextItem } from "./listitem/icontextitem"; +export { TextIconItem } from "./listitem/texticonitem"; +export { TextItem } from "./listitem/textitem"; +export { IconTextIconNode } from "./node/icontexticonnode"; +export { IconTextNode } from "./node/icontextnode"; +export { TextIconNode } from "./node/texticonnode"; +export { TextNode } from "./node/textnode"; diff --git a/packages/fineui/src/base/single/button/listitem/blankiconicontextitem.js b/packages/fineui/src/base/single/button/listitem/blankiconicontextitem.js new file mode 100644 index 000000000..0dacbf150 --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/blankiconicontextitem.js @@ -0,0 +1,128 @@ +import { VerticalAdaptLayout, Layout, shortcut, extend } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * 带有一个占位 + * + * Created by GUY on 2015/9/11. + * @class BlankIconIconTextItem + * @extends BasicButton + */ +@shortcut() +export class BlankIconIconTextItem extends BasicButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.blank_icon_icon_text_item"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-blank-icon-icon-text-item`, + iconCls1: "", + iconCls2: "", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, o.rightIconWrapperWidth || o.height, "fill"], + items: [ + { + type: Layout.xtype, + width: o.blankWidth, + }, + { + type: IconLabel.xtype, + cls: o.iconCls1, + width: o.leftIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + type: IconLabel.xtype, + cls: o.iconCls2, + width: o.rightIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(BlankIconIconTextItem.EVENT_CHANGE, this.getValue(), this); + } + } + + setSelected(b) { + super.setSelected(...arguments); + this.icon1.setSelected(b); + this.icon2.setSelected(b); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/blankicontexticonitem.js b/packages/fineui/src/base/single/button/listitem/blankicontexticonitem.js new file mode 100644 index 000000000..16870a911 --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/blankicontexticonitem.js @@ -0,0 +1,123 @@ +import { VerticalAdaptLayout, Layout, shortcut, extend } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * guy + * 一个占位符和两个icon和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/15. + * @class BlankIconTextIconItem + * @extends BasicButton + */ +@shortcut() +export class BlankIconTextIconItem extends BasicButton { + static xtype = "bi.blank_icon_text_icon_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-blank-icon-text-icon-item`, + iconCls1: "", + iconCls2: "", + blankWidth: 0, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], + items: [ + { + type: Layout.xtype, + width: o.blankWidth, + }, + { + type: IconLabel.xtype, + cls: o.iconCls1, + width: o.leftIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + }, + { + type: IconLabel.xtype, + cls: o.iconCls2, + width: o.rightIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(BlankIconTextIconItem.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/blankicontextitem.js b/packages/fineui/src/base/single/button/listitem/blankicontextitem.js new file mode 100644 index 000000000..df138881e --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/blankicontextitem.js @@ -0,0 +1,114 @@ +import { VerticalAdaptLayout, Layout, extend, shortcut } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * 带有一个占位 + * + * Created by GUY on 2015/9/11. + * @class BlankIconTextItem + * @extends BasicButton + */ +@shortcut() +export class BlankIconTextItem extends BasicButton { + static xtype = "bi.blank_icon_text_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-blank-icon-text-item`, + blankWidth: 0, + iconHeight: null, + iconWidth: null, + iconCls: "", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.blankWidth, o.iconWrapperWidth || o.height, "fill"], + items: [ + { + type: Layout.xtype, + width: o.blankWidth, + }, + { + type: IconLabel.xtype, + cls: o.iconCls, + width: o.iconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(BlankIconTextItem.EVENT_CHANGE, this.getValue(), this); + } + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/icontexticonitem.js b/packages/fineui/src/base/single/button/listitem/icontexticonitem.js new file mode 100644 index 000000000..2588d60d5 --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/icontexticonitem.js @@ -0,0 +1,119 @@ +import { VerticalAdaptLayout, extend, shortcut } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * guy + * 两个icon和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/9. + * @class IconTextIconItem + * @extends BasicButton + */ + +@shortcut() +export class IconTextIconItem extends BasicButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.icon_text_icon_item"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-icon-text-icon-item`, + iconCls1: "", + iconCls2: "", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], + items: [ + { + type: IconLabel.xtype, + cls: o.iconCls1, + width: o.leftIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + }, + { + type: IconLabel.xtype, + cls: o.iconCls2, + width: o.rightIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(IconTextIconItem.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/icontextitem.js b/packages/fineui/src/base/single/button/listitem/icontextitem.js new file mode 100644 index 000000000..fb0f36b46 --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/icontextitem.js @@ -0,0 +1,111 @@ +import { VerticalAdaptLayout, extend, shortcut, Direction } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * guy + * + * Created by GUY on 2015/9/9. + * @class IconTextItem + * @extends BasicButton + */ +@shortcut() +export class IconTextItem extends BasicButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.icon_text_item"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-icon-text-item`, + direction: Direction.Left, + iconWrapperWidth: null, + iconHeight: null, + iconWidth: null, + iconCls: "", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + { + type: IconLabel.xtype, + cls: o.iconCls, + width: o.iconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(IconTextItem.EVENT_CHANGE, this.getValue(), this); + } + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/texticonitem.js b/packages/fineui/src/base/single/button/listitem/texticonitem.js new file mode 100644 index 000000000..84b7e1cfe --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/texticonitem.js @@ -0,0 +1,111 @@ +import { VerticalAdaptLayout, extend, shortcut } from "@/core"; +import { Label, IconLabel } from "../../label"; +import { BasicButton } from "../button.basic"; + +/** + * + * 图标的button + * + * Created by GUY on 2015/9/9. + * @class TextIconItem + * @extends BasicButton + */ +@shortcut() +export class TextIconItem extends BasicButton { + static xtype = "bi.text_icon_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-icon-item`, + iconWrapperWidth: null, + iconHeight: null, + iconWidth: null, + iconCls: "", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: ["fill", o.iconWrapperWidth || o.height], + items: [ + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + }, + { + type: IconLabel.xtype, + cls: o.iconCls, + width: o.iconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(TextIconItem.EVENT_CHANGE, this.getValue(), this); + } + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/listitem/textitem.js b/packages/fineui/src/base/single/button/listitem/textitem.js new file mode 100644 index 000000000..7f7ab21b5 --- /dev/null +++ b/packages/fineui/src/base/single/button/listitem/textitem.js @@ -0,0 +1,92 @@ +import { Label } from "../../label"; +import { BasicButton } from "../button.basic"; +import { extend, shortcut, createWidget } from "@/core"; + +/** + * guy + * 一个button和一行数 组成的一行listitem + * + * Created by GUY on 2015/9/9. + * @class TextItem + * @extends BasicButton + */ +@shortcut() +export class TextItem extends BasicButton { + static xtype = "bi.text_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-item`, + textAlign: "left", + whiteSpace: "nowrap", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textHeight: o.whiteSpace === "nowrap" ? o.height : o.textHeight, + height: o.height, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + py: o.py, + }); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(TextItem.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } +} diff --git a/src/base/single/button/node/__test__/icontexticonnode.test.js b/packages/fineui/src/base/single/button/node/__test__/icontexticonnode.test.js similarity index 100% rename from src/base/single/button/node/__test__/icontexticonnode.test.js rename to packages/fineui/src/base/single/button/node/__test__/icontexticonnode.test.js diff --git a/src/base/single/button/node/__test__/icontextnode.test.js b/packages/fineui/src/base/single/button/node/__test__/icontextnode.test.js similarity index 100% rename from src/base/single/button/node/__test__/icontextnode.test.js rename to packages/fineui/src/base/single/button/node/__test__/icontextnode.test.js diff --git a/src/base/single/button/node/__test__/texticonnode.test.js b/packages/fineui/src/base/single/button/node/__test__/texticonnode.test.js similarity index 100% rename from src/base/single/button/node/__test__/texticonnode.test.js rename to packages/fineui/src/base/single/button/node/__test__/texticonnode.test.js diff --git a/src/base/single/button/node/__test__/textnode.test.js b/packages/fineui/src/base/single/button/node/__test__/textnode.test.js similarity index 100% rename from src/base/single/button/node/__test__/textnode.test.js rename to packages/fineui/src/base/single/button/node/__test__/textnode.test.js diff --git a/packages/fineui/src/base/single/button/node/icontexticonnode.js b/packages/fineui/src/base/single/button/node/icontexticonnode.js new file mode 100644 index 000000000..eb3ff0213 --- /dev/null +++ b/packages/fineui/src/base/single/button/node/icontexticonnode.js @@ -0,0 +1,108 @@ +import { VerticalAdaptLayout, extend, shortcut } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { NodeButton } from "../button.node"; + +/** + * guy + * Created by GUY on 2015/9/9. + * @class IconTextIconNode + * @extends NodeButton + */ +@shortcut() +export class IconTextIconNode extends NodeButton { + static xtype = "bi.icon_text_icon_node"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-icon-text-icon-node`, + iconCls1: "close-ha-font", + iconCls2: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], + items: [ + { + type: IconLabel.xtype, + cls: o.iconCls1, + width: o.leftIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + }, + { + type: IconLabel.xtype, + cls: o.iconCls2, + width: o.rightIconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(IconTextIconNode.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/base/single/button/node/icontextnode.js b/packages/fineui/src/base/single/button/node/icontextnode.js new file mode 100644 index 000000000..130fa1570 --- /dev/null +++ b/packages/fineui/src/base/single/button/node/icontextnode.js @@ -0,0 +1,100 @@ +import { VerticalAdaptLayout, extend, shortcut } from "@/core"; +import { IconLabel, Label } from "../../label"; +import { NodeButton } from "../button.node"; + +/** + * guy + * Created by GUY on 2015/9/9. + * @class IconTextNode + * @extends NodeButton + */ +@shortcut() +export class IconTextNode extends NodeButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.icon_text_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-icon-text-node`, + cls: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + { + type: IconLabel.xtype, + cls: o.iconCls, + width: o.iconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(IconTextNode.EVENT_CHANGE, this.getValue(), this); + } + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/node/texticonnode.js b/packages/fineui/src/base/single/button/node/texticonnode.js new file mode 100644 index 000000000..3f6dc8909 --- /dev/null +++ b/packages/fineui/src/base/single/button/node/texticonnode.js @@ -0,0 +1,99 @@ +import { VerticalAdaptLayout, extend, shortcut } from "@/core"; +import { Label, IconLabel } from "../../label"; +import { NodeButton } from "../button.node"; + +/** + * Created by GUY on 2015/9/9. + * @class TextIconNode + * @extends NodeButton + */ +@shortcut() +export class TextIconNode extends NodeButton { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.text_icon_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-icon-node`, + cls: "close-ha-font", + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: ["fill", o.iconWrapperWidth || o.height], + items: [ + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }, + }, + { + type: IconLabel.xtype, + cls: o.iconCls, + width: o.iconWrapperWidth || o.height, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(TextIconNode.EVENT_CHANGE, this.getValue(), this); + } + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } +} diff --git a/packages/fineui/src/base/single/button/node/textnode.js b/packages/fineui/src/base/single/button/node/textnode.js new file mode 100644 index 000000000..5218c36ff --- /dev/null +++ b/packages/fineui/src/base/single/button/node/textnode.js @@ -0,0 +1,84 @@ +import { Label } from "../../label"; +import { NodeButton } from "../button.node"; +import { extend, shortcut, createWidget } from "@/core"; + +/** + * guy + * + * Created by GUY on 2015/9/9. + * @class TextNode + * @extends NodeButton + */ +@shortcut() +export class TextNode extends NodeButton { + static xtype = "bi.text_node"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-node`, + textAlign: "left", + whiteSpace: "nowrap", + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + element: this, + textAlign: o.textAlign, + whiteSpace: o.whiteSpace, + textHeight: o.whiteSpace === "nowrap" ? o.height : o.textHeight, + height: o.height, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + py: o.py, + }); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(TextNode.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/base/single/editor/editor.js b/packages/fineui/src/base/single/editor/editor.js new file mode 100644 index 000000000..7ad107ff6 --- /dev/null +++ b/packages/fineui/src/base/single/editor/editor.js @@ -0,0 +1,412 @@ +import { Input } from "../input"; +import { + AbsoluteLayout, + shortcut, + Controller, + extend, + createWidget, + isKey, + isEmptyString, + isFunction, + isNull, + trim, + emptyFn, + KeyCode +} from "@/core"; +import { Label } from "../label"; +import { Single } from "../0.single"; +import { Bubbles } from "@/base/0.base"; + +@shortcut() +export class Editor extends Single { + static xtype = "bi.editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_BACKSPACE = "EVENT_BACKSPACE"; + + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_REMOVE = "EVENT_REMOVE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-editor bi-focus-shadow", + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + // title,warningTitle这两个属性没用 + tipType: "warning", + inputType: "text", + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: false, + watermark: "", + errorText: "", + autoTrim: true, + }); + } + + render() { + const { + value, + watermark, + validationChecker, + quitChecker, + allowBlank, + inputType, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + } = this.options; + // 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码 + const autocomplete = this.options.autocomplete ? ` autocomplete=${this.options.autocomplete}` : ""; + this.editor = this.addWidget( + createWidget({ + type: Input.xtype, + element: ``, + root: true, + value, + watermark, + validationChecker, + quitChecker, + allowBlank, + }) + ); + this.editor.element.css({ + width: "100%", + height: "100%", + border: "none", + outline: "none", + padding: "0", + margin: "0", + }); + + const items = [ + { + el: { + type: AbsoluteLayout.xtype, + ref: _ref => { + this.contentWrapper = _ref; + }, + items: [ + { + el: this.editor, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }, + left: hgap + lgap, + right: hgap + rgap, + top: vgap + tgap, + bottom: vgap + bgap, + } + ]; + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items, + }); + + this.setWaterMark(this.options.watermark); + + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Input.EVENT_FOCUS, (...args) => { + this._checkError(); + this.element.addClass("bi-editor-focus"); + this.fireEvent(Editor.EVENT_FOCUS, ...args); + }); + this.editor.on(Input.EVENT_BLUR, (...args) => { + this._setErrorVisible(false); + this.element.removeClass("bi-editor-focus"); + this.fireEvent(Editor.EVENT_BLUR, ...args); + }); + this.editor.on(Input.EVENT_CLICK, (...args) => { + this.fireEvent(Editor.EVENT_CLICK, ...args); + }); + this.editor.on(Input.EVENT_CHANGE, (...args) => { + this.fireEvent(Editor.EVENT_CHANGE, ...args); + }); + this.editor.on(Input.EVENT_KEY_DOWN, (v, ...args) => { + this.fireEvent(Editor.EVENT_KEY_DOWN, v, ...args); + }); + this.editor.on(Input.EVENT_QUICK_DOWN, (...args) => { + const [e] = args; + // tab键就不要隐藏了 + if (e.keyCode !== KeyCode.TAB && this.watermark) { + this.watermark.invisible(); + } + this.fireEvent(Editor.EVENT_QUICK_DOWN, ...args); + }); + + this.editor.on(Input.EVENT_VALID, (...args) => { + this._checkWaterMark(); + this._setErrorVisible(false); + this.element.removeClass("error"); + this.fireEvent(Editor.EVENT_VALID, ...args); + }); + this.editor.on(Input.EVENT_ERROR, (...args) => { + this._checkWaterMark(); + this.fireEvent(Editor.EVENT_ERROR, ...args); + this._setErrorVisible(this.isEditing()); + this.element.addClass("error"); + }); + this.editor.on(Input.EVENT_RESTRICT, (...args) => { + this._checkWaterMark(); + const tip = this._setErrorVisible(true); + tip && + tip.element.fadeOut(100, () => { + tip.element.fadeIn(100); + }); + this.fireEvent(Editor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Input.EVENT_EMPTY, (...args) => { + this._checkWaterMark(); + this.fireEvent(Editor.EVENT_EMPTY, ...args); + }); + this.editor.on(Input.EVENT_ENTER, (...args) => { + this.fireEvent(Editor.EVENT_ENTER, ...args); + }); + this.editor.on(Input.EVENT_SPACE, (...args) => { + this.fireEvent(Editor.EVENT_SPACE, ...args); + }); + this.editor.on(Input.EVENT_BACKSPACE, (...args) => { + this.fireEvent(Editor.EVENT_BACKSPACE, ...args); + }); + this.editor.on(Input.EVENT_REMOVE, (...args) => { + this.fireEvent(Editor.EVENT_REMOVE, ...args); + }); + this.editor.on(Input.EVENT_START, (...args) => { + this.fireEvent(Editor.EVENT_START, ...args); + }); + this.editor.on(Input.EVENT_PAUSE, (...args) => { + this.fireEvent(Editor.EVENT_PAUSE, ...args); + }); + this.editor.on(Input.EVENT_STOP, (...args) => { + this.fireEvent(Editor.EVENT_STOP, ...args); + }); + this.editor.on(Input.EVENT_CONFIRM, (...args) => { + this.fireEvent(Editor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Input.EVENT_CHANGE_CONFIRM, (...args) => { + this.fireEvent(Editor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.element.click(e => { + e.stopPropagation(); + + return false; + }); + if (isKey(this.options.value) || isEmptyString(this.options.value)) { + this._checkError(); + this._checkWaterMark(); + } else { + this._checkWaterMark(); + } + } + + _checkToolTip() { + let errorText = this.options.errorText; + if (isFunction(errorText)) { + errorText = errorText(this.editor.getValue()); + } + if (isKey(errorText)) { + if (!this.isEnabled() || this.isValid() || Bubbles.has(this.getName())) { + this.setTitle(""); + } else { + this.setTitle(errorText); + } + } + } + + _assertWaterMark() { + const { height, vgap, tgap } = this.options; + if (isNull(this.watermark)) { + this.watermark = createWidget({ + type: Label.xtype, + cls: "bi-water-mark", + text: this.options.watermark, + height: height - 2 * vgap - tgap, + hgap: 2, + whiteSpace: "nowrap", + textAlign: "left", + }); + this.watermark.element.bind({ + mousedown: e => { + if (this.isEnabled()) { + this.editor.isEditing() || this.editor.focus(); + } else { + this.editor.isEditing() && this.editor.blur(); + } + e.stopEvent(); + }, + }); + this.watermark.element.bind("click", e => { + if (this.isEnabled()) { + this.editor.isEditing() || this.editor.focus(); + } else { + this.editor.isEditing() && this.editor.blur(); + } + e.stopEvent(); + }); + } + } + + _checkError() { + this._setErrorVisible(this.isEnabled() && !this.isValid()); + this._checkToolTip(); + } + + _checkWaterMark() { + const { watermark } = this.options; + if (!this.disabledWaterMark && this.editor.getValue() === "" && isKey(watermark)) { + this.watermark && this.watermark.visible(); + } else { + this.watermark && this.watermark.invisible(); + } + } + + setErrorText(text) { + this.options.errorText = text; + } + + getErrorText() { + return this.options.errorText; + } + + setWaterMark(v) { + this.options.watermark = v; + + if (isNull(this.watermark)) { + this._assertWaterMark(); + createWidget({ + type: AbsoluteLayout.xtype, + element: this.contentWrapper, + items: [ + { + el: this.watermark, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + } + this.watermark.setText(v); + this._checkWaterMark(); + } + + _setErrorVisible(b) { + const { autoTrim, simple } = this.options; + let errorText = this.options.errorText; + if (isFunction(errorText)) { + errorText = errorText(autoTrim ? trim(this.editor.getValue()) : this.editor.getValue()); + } + if (!this.disabledError && isKey(errorText)) { + Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { + adjustYOffset: simple ? 1 : 2, + }); + this._checkToolTip(); + } + } + + disableError() { + this.disabledError = true; + this._checkError(); + } + + enableError() { + this.disabledError = false; + this._checkError(); + } + + disableWaterMark() { + this.disabledWaterMark = true; + this._checkWaterMark(); + } + + enableWaterMark() { + this.disabledWaterMark = false; + this._checkWaterMark(); + } + + focus() { + this.element.addClass("text-editor-focus"); + this.editor.focus(); + } + + blur() { + this.element.removeClass("text-editor-focus"); + this.editor.blur(); + } + + selectAll() { + this.editor.selectAll(); + } + + onKeyDown(k) { + this.editor.onKeyDown(k); + } + + setValue(v) { + super.setValue(v); + this.editor.setValue(v); + this._checkError(); + this._checkWaterMark(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + getValue() { + if (!this.isValid()) { + return this.options.autoTrim ? trim(this.editor.getLastValidValue()) : this.editor.getLastValidValue(); + } + + return this.options.autoTrim ? trim(this.editor.getValue()) : this.editor.getValue(); + } + + isEditing() { + return this.editor.isEditing(); + } + + isValid() { + return this.editor.isValid(); + } + + destroyed() { + Bubbles.remove(this.getName()); + } +} diff --git a/packages/fineui/src/base/single/editor/editor.multifile.js b/packages/fineui/src/base/single/editor/editor.multifile.js new file mode 100644 index 000000000..44b56c8e8 --- /dev/null +++ b/packages/fineui/src/base/single/editor/editor.multifile.js @@ -0,0 +1,124 @@ +import { File } from "../input"; +import { AbsoluteLayout, AdaptiveLayout, shortcut, Widget, createWidget, extend } from "@/core"; + +/** + * 多文件 + * + * Created by GUY on 2016/4/13. + * @class MultifileEditor + * @extends Single + * @abstract + */ + +@shortcut() +export class MultifileEditor extends Widget { + static xtype = "bi.multifile_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_PROGRESS = "EVENT_PROGRESS"; + static EVENT_UPLOADED = "EVENT_UPLOADED"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-multifile-editor`, + multiple: false, + maxSize: -1, // 1024 * 1024 + accept: "", + url: "", + }); + } + + render() { + const { name, url, multiple, accept, maxSize, maxLength, title, errorText } = this.options; + this.file = createWidget({ + type: File.xtype, + cls: "multifile-editor", + width: "100%", + height: "100%", + name, + url, + multiple, + accept, + maxSize, + maxLength, + title, + errorText, + }); + this.file.on(File.EVENT_CHANGE, (...args) => { + this.fireEvent(MultifileEditor.EVENT_CHANGE, ...args); + }); + this.file.on(File.EVENT_UPLOADSTART, (...args) => { + this.fireEvent(MultifileEditor.EVENT_UPLOADSTART, ...args); + }); + this.file.on(File.EVENT_ERROR, (...args) => { + this.fireEvent(MultifileEditor.EVENT_ERROR, ...args); + }); + this.file.on(File.EVENT_PROGRESS, (...args) => { + this.fireEvent(MultifileEditor.EVENT_PROGRESS, ...args); + }); + this.file.on(File.EVENT_UPLOADED, (...args) => { + this.fireEvent(MultifileEditor.EVENT_UPLOADED, ...args); + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: AdaptiveLayout.xtype, + scrollable: false, + items: [this.file], + }, + top: 0, + right: 0, + left: 0, + bottom: 0, + } + ], + }); + } + + _reset() { + this.file.reset(); + } + + setUrl(v) { + this.file.setUrl(v); + } + + setMaxFileLength(v) { + this.file.setMaxFileLength(v); + } + + select() { + this.file.select(); + } + + getQueue() { + return this.file.getQueue(); + } + + getValue() { + return this.file.getValue(); + } + + upload() { + this._reset(); + this.file.upload(); + } + + sendFiles(files) { + this._reset(); + + this.file.sendFiles(files); + } + + reset() { + this._reset(); + } +} diff --git a/packages/fineui/src/base/single/editor/editor.textarea.js b/packages/fineui/src/base/single/editor/editor.textarea.js new file mode 100644 index 000000000..f0d306bbd --- /dev/null +++ b/packages/fineui/src/base/single/editor/editor.textarea.js @@ -0,0 +1,291 @@ +import { + Layout, + AbsoluteLayout, + AdaptiveLayout, + shortcut, + Widget, + Controller, + createWidget, + extend, + isEmptyString, + isKey, + isNotEmptyString, + isNotNull, + trim, + isFunction, + Events, + DOM +} from "@/core"; +import { Label } from "../label"; +import { Single } from "../0.single"; +import { Bubbles } from "@/base/0.base"; + +/** + * + * Created by GUY on 2016/1/18. + * @class TextAreaEditor + * @extends Single + */ + +@shortcut() +export class TextAreaEditor extends Single { + static xtype = "bi.textarea_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_EMPTY = "EVENT_EMPTY"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + + _defaultConfig(conf) { + return extend(super._defaultConfig(), { + baseCls: "bi-textarea-editor", + value: "", + errorText: "", + adjustYOffset: conf.simple ? 0 : 2, + adjustXOffset: 0, + offsetStyle: "left", + validationChecker: () => true, + scrolly: true, + }); + } + + render() { + const { scrolly, value, style } = this.options; + this.content = createWidget({ + type: Layout.xtype, + tagName: "textarea", + width: "100%", + height: "100%", + cls: "bi-textarea textarea-editor-content display-block", + css: scrolly + ? null + : { + overflowY: "hidden", + }, + }); + this.content.element.css({ resize: "none" }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: AdaptiveLayout.xtype, + items: [this.content], + }, + left: 4, + right: 4, + top: 2, + bottom: 2, + } + ], + }); + + this.content.element.on("input propertychange", e => { + this._checkError(); + this._checkWaterMark(); + this.fireEvent(Controller.EVENT_CHANGE, Events.CHANGE, this.getValue(), this); + this.fireEvent(TextAreaEditor.EVENT_CHANGE); + if (isEmptyString(this.getValue())) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + } + }); + + this.content.element.focus(() => { + this._checkError(); + this._focus(); + this.fireEvent(TextAreaEditor.EVENT_FOCUS); + Widget._renderEngine.createElement(document).bind(`mousedown.${this.getName()}`, e => { + if (DOM.isExist(this) && !this.element.__isMouseInBounds__(e)) { + Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`); + this.content.element.blur(); + } + }); + }); + this.content.element.blur(() => { + this._setErrorVisible(false); + this._blur(); + if (!this._isError()) { + this.fireEvent(TextAreaEditor.EVENT_CONFIRM); + } + this.fireEvent(TextAreaEditor.EVENT_BLUR); + Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`); + }); + this.content.element.keydown(() => { + // 水印快速消失 + this._checkWaterMark(); + }); + this.content.element.keyup(e => { + this.fireEvent(TextAreaEditor.EVENT_KEY_DOWN, e.keyCode); + }); + this.content.element.click(e => { + e.stopPropagation(); + }); + if (isKey(value)) { + this.setValue(value); + } + if (isNotNull(style)) { + this.setStyle(style); + } + this._checkWaterMark(); + } + + _checkWaterMark() { + const { watermark, scrolly, invalid, disabled, height } = this.options; + const val = this.getValue(); + if (isNotEmptyString(val)) { + this.watermark && this.watermark.destroy(); + this.watermark = null; + } else { + if (isNotEmptyString(watermark)) { + if (!this.watermark) { + this.watermark = createWidget({ + type: Label.xtype, + cls: "bi-water-mark textarea-watermark", + textAlign: "left", + whiteSpace: scrolly ? "normal" : "nowrap", + text: watermark, + invalid, + disabled, + hgap: 6, + vgap: height > 24 ? 4 : 2, + height: height > 24 ? "" : height, + }); + this.watermark.element.bind({ + mousedown: e => { + if (this.isEnabled()) { + this.focus(); + } else { + this.blur(); + } + e.stopEvent(); + }, + click: e => { + e.stopPropagation(); + }, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.watermark, + left: 0, + top: 0, + right: 0, + } + ], + }); + } else { + this.watermark.setText(watermark); + this.watermark.setValid(!invalid); + this.watermark.setEnable(!disabled); + } + } + } + } + + _isError() { + return this.isEnabled() && !this.options.validationChecker(this.getValue()); + } + + _checkError() { + const isError = this._isError(); + this._setErrorVisible(isError); + this.element[isError ? "addClass" : "removeClass"]("error"); + } + + _focus() { + this.content.element.addClass("textarea-editor-focus"); + this._checkWaterMark(); + if (isEmptyString(this.getValue())) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + } + } + + _blur() { + this.content.element.removeClass("textarea-editor-focus"); + this._checkWaterMark(); + } + + _setErrorVisible(b) { + const { adjustYOffset, adjustXOffset, offsetStyle } = this.options; + let errorText = this.options.errorText; + if (isFunction(errorText)) { + errorText = errorText(trim(this.getValue())); + } + if (!this.disabledError && isKey(errorText)) { + Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { + adjustYOffset, + adjustXOffset, + offsetStyle, + }); + } + } + + _defaultState() { + if (isEmptyString(this.getValue())) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + this.fireEvent(TextAreaEditor.EVENT_EMPTY); + } + } + + focus() { + this._focus(); + this.content.element.focus(); + } + + blur() { + this._blur(); + this.content.element.blur(); + } + + getValue() { + return this.content.element.val(); + } + + setValue(value) { + this.content.element.val(value); + this._checkError(); + this._checkWaterMark(); + this._defaultState(); + } + + setStyle(style) { + this.style = style; + this.element.css(style); + this.content.element.css( + extend({}, style, { + color: + style.color || + DOM.getContrastColor( + DOM.isRGBColor(style.backgroundColor) + ? DOM.rgb2hex(style.backgroundColor) + : style.backgroundColor + ), + }) + ); + } + + getStyle() { + return this.style; + } + + setWatermark(v) { + this.options.watermark = v; + this._checkWaterMark(); + } + + _setValid(b) { + super._setValid(...arguments); + // this.content.setValid(b); + // this.watermark && this.watermark.setValid(b); + } + + _setEnable(b) { + super._setEnable(b); + this.content && (this.content.element[0].disabled = !b); + } +} diff --git a/packages/fineui/src/base/single/editor/index.js b/packages/fineui/src/base/single/editor/index.js new file mode 100644 index 000000000..bb303a1a0 --- /dev/null +++ b/packages/fineui/src/base/single/editor/index.js @@ -0,0 +1,3 @@ +export { Editor } from "./editor"; +export { MultifileEditor } from "./editor.multifile"; +export { TextAreaEditor } from "./editor.textarea"; diff --git a/src/base/single/html/__test__/html.test.js b/packages/fineui/src/base/single/html/__test__/html.test.js similarity index 100% rename from src/base/single/html/__test__/html.test.js rename to packages/fineui/src/base/single/html/__test__/html.test.js diff --git a/packages/fineui/src/base/single/html/html.js b/packages/fineui/src/base/single/html/html.js new file mode 100644 index 000000000..41faf2ef8 --- /dev/null +++ b/packages/fineui/src/base/single/html/html.js @@ -0,0 +1,137 @@ +import { Layout, DefaultLayout, shortcut, isNumber, createWidget, isWidthOrHeight, isKey, pixFormat } from "@/core"; +import { Single } from "../0.single"; + +/** + * guy 表示一行数据,通过position来定位位置的数据 + * @class Html + * @extends Single + */ + +@shortcut() +export class Html extends Single { + static xtype = "bi.html"; + + props = { + baseCls: "bi-html", + textAlign: "left", + whiteSpace: "normal", + lineHeight: null, + handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的 + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + text: "", + highLight: false, + }; + + render() { + const { + vgap, + hgap, + lgap, + rgap, + tgap, + bgap, + height, + lineHeight, + maxWidth, + textAlign, + whiteSpace, + handler, + text, + value, + highLight, + } = this.options; + if (hgap + lgap > 0) { + this.element.css({ + "padding-left": pixFormat(hgap + lgap), + }); + } + if (hgap + rgap > 0) { + this.element.css({ + "padding-right": pixFormat(hgap + rgap), + }); + } + if (vgap + tgap > 0) { + this.element.css({ + "padding-top": pixFormat(vgap + tgap), + }); + } + if (vgap + bgap > 0) { + this.element.css({ + "padding-bottom": pixFormat(vgap + bgap), + }); + } + if (isNumber(height)) { + this.element.css({ lineHeight: pixFormat(height) }); + } + if (isNumber(lineHeight)) { + this.element.css({ lineHeight: pixFormat(lineHeight) }); + } + if (isWidthOrHeight(maxWidth)) { + this.element.css({ maxWidth }); + } + if (isNumber(maxWidth)) { + this.element.css({ maxWidth: pixFormat(maxWidth) }); + } + this.element.css({ + textAlign, + whiteSpace, + textOverflow: whiteSpace === "nowrap" ? "ellipsis" : "", + overflow: whiteSpace === "nowrap" ? "" : "auto", + }); + if (handler) { + this.text = createWidget({ + type: Layout.xtype, + tagName: "span", + }); + this.text.element.click(() => { + handler(this.getValue()); + }); + createWidget({ + type: DefaultLayout.xtype, + element: this, + items: [this.text], + }); + } else { + this.text = this; + } + + if (isKey(text)) { + this.setText(text); + } else if (isKey(value)) { + this.setText(value); + } + if (highLight) { + this.doHighLight(); + } + } + + doHighLight() { + this.text.element.addClass("bi-high-light"); + } + + unHighLight() { + this.text.element.removeClass("bi-high-light"); + } + + setValue(text) { + super.setValue(text); + if (!this.isReadOnly()) { + this.setText(text); + } + } + + setStyle(css) { + this.text.element.css(css); + } + + setText(text) { + super.setText(text); + this.options.text = text; + this.text.element.html(text); + } +} diff --git a/packages/fineui/src/base/single/icon/icon.js b/packages/fineui/src/base/single/icon/icon.js new file mode 100644 index 000000000..84a0d6889 --- /dev/null +++ b/packages/fineui/src/base/single/icon/icon.js @@ -0,0 +1,28 @@ +import { Single } from "../0.single"; +import { shortcut, extend, isIE9Below } from "@/core"; + +/** + * guy 图标 + * @class Icon + * @extends Single + */ + +@shortcut() +export class Icon extends Single { + static xtype = "bi.icon"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + tagName: "i", + baseCls: `${conf.baseCls || ""} x-icon b-font horizon-center display-block`, + }); + } + + render() { + if (isIE9Below && isIE9Below()) { + this.element.addClass("hack"); + } + } +} diff --git a/src/base/single/iframe/__test__/iframe.test.js b/packages/fineui/src/base/single/iframe/__test__/iframe.test.js similarity index 100% rename from src/base/single/iframe/__test__/iframe.test.js rename to packages/fineui/src/base/single/iframe/__test__/iframe.test.js diff --git a/packages/fineui/src/base/single/iframe/iframe.js b/packages/fineui/src/base/single/iframe/iframe.js new file mode 100644 index 000000000..bc537c1e5 --- /dev/null +++ b/packages/fineui/src/base/single/iframe/iframe.js @@ -0,0 +1,65 @@ +import { Single } from "../0.single"; +import { shortcut, extend } from "@/core"; + +/** + * @class Iframe + * @extends Single + * @abstract + * Created by GameJian on 2016/3/2. + */ + +@shortcut() +export class Iframe extends Single { + static xtype = "bi.iframe"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + tagName: "iframe", + baseCls: `${conf.baseCls || ""} bi-iframe`, + src: "", + name: "", + attributes: {}, + width: "100%", + height: "100%", + }); + } + + render() { + this.element.on("load", () => { + this.fireEvent("EVENT_LOADED"); + }); + } + + _initProps() { + super._initProps(...arguments); + const { src, name } = this.options; + this.options.attributes = extend( + { + frameborder: 0, + src, + name, + }, + this.options.attributes + ); + } + + setSrc(src) { + this.options.src = src; + this.element.attr("src", src); + } + + getSrc() { + return this.options.src; + } + + setName(name) { + this.options.name = name; + this.element.attr("name", name); + } + + getName() { + return this.options.name; + } +} diff --git a/src/base/single/img/__test__/img.test.js b/packages/fineui/src/base/single/img/__test__/img.test.js similarity index 100% rename from src/base/single/img/__test__/img.test.js rename to packages/fineui/src/base/single/img/__test__/img.test.js diff --git a/packages/fineui/src/base/single/img/img.js b/packages/fineui/src/base/single/img/img.js new file mode 100644 index 000000000..f045ac5fd --- /dev/null +++ b/packages/fineui/src/base/single/img/img.js @@ -0,0 +1,40 @@ +import { Single } from "../0.single"; +import { shortcut, extend } from "@/core"; + +@shortcut() +export class Img extends Single { + static xtype = "bi.img"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + tagName: "img", + baseCls: `${conf.baseCls || ""} bi-img display-block`, + src: "", + attributes: config.src ? { src: config.src } : {}, + width: "100%", + height: "100%", + }); + } + + _initProps() { + super._initProps(...arguments); + const { src } = this.options; + this.options.attributes = extend( + { + src, + }, + this.options.attributes + ); + } + + setSrc(src) { + this.options.src = src; + this.element.attr("src", src); + } + + getSrc() { + return this.options.src; + } +} diff --git a/packages/fineui/src/base/single/index.js b/packages/fineui/src/base/single/index.js new file mode 100644 index 000000000..1d0bf1a61 --- /dev/null +++ b/packages/fineui/src/base/single/index.js @@ -0,0 +1,17 @@ +export { Single } from "./0.single"; +export { Text } from "./1.text"; +export { PureText } from "./text.pure"; +export { Icon } from "./icon/icon"; +export { Html } from "./html/html"; +export { A } from "./a/a"; +export { Iframe } from "./iframe/iframe"; +export { Link } from "./link/link"; +export { Instruction } from "./instruction/instruction"; +export { Img } from "./img/img"; +export { Trigger } from "./trigger/trigger"; +export { LoadingBar } from "./bar/bar.loading"; +export * from "./tip"; +export * from "./label"; +export * from "./input"; +export * from "./editor"; +export * from "./button"; diff --git a/packages/fineui/src/base/single/input/checkbox/checkbox.image.js b/packages/fineui/src/base/single/input/checkbox/checkbox.image.js new file mode 100644 index 000000000..61786512a --- /dev/null +++ b/packages/fineui/src/base/single/input/checkbox/checkbox.image.js @@ -0,0 +1,29 @@ +import { IconButton } from "../../button"; +import { shortcut, extend, emptyFn } from "@/core"; + +/** + * guy + * @extends Single + * @type {*|void|Object} + */ + +@shortcut() +export class ImageCheckbox extends IconButton { + static xtype = "bi.image_checkbox"; + + static EVENT_CHANGE = IconButton.EVENT_CHANGE; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-image-checkbox check-box-icon`, + selected: false, + handler: emptyFn, + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16, + }); + } +} diff --git a/packages/fineui/src/base/single/input/checkbox/checkbox.js b/packages/fineui/src/base/single/input/checkbox/checkbox.js new file mode 100644 index 000000000..e943c00ad --- /dev/null +++ b/packages/fineui/src/base/single/input/checkbox/checkbox.js @@ -0,0 +1,69 @@ +import { CenterAdaptLayout, DefaultLayout, shortcut, emptyFn } from "@/core"; +import { BasicButton } from "../../button"; + +/** + * guy + * @extends Single + * @type {*|void|Object} + */ + +@shortcut() +export class Checkbox extends BasicButton { + static xtype = "bi.checkbox"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-checkbox", + selected: false, + handler: emptyFn, + width: 14, + height: 14, + iconWidth: 14, + iconHeight: 14, + }; + + render() { + const { iconWidth, iconHeight } = this.options; + + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: DefaultLayout.xtype, + ref: _ref => { + this.checkbox = _ref; + }, + cls: "checkbox-content", + width: iconWidth, + height: iconHeight, + } + ], + }; + } + + _setEnable(enable) { + super._setEnable(enable); + if (enable === true) { + this.checkbox.element.removeClass("base-disabled disabled"); + } else { + this.checkbox.element.addClass("base-disabled disabled"); + } + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(Checkbox.EVENT_CHANGE); + } + } + + setSelected(b) { + super.setSelected(b); + if (b) { + this.checkbox.element.addClass("bi-high-light-background"); + } else { + this.checkbox.element.removeClass("bi-high-light-background"); + } + } +} diff --git a/packages/fineui/src/base/single/input/file.js b/packages/fineui/src/base/single/input/file.js new file mode 100644 index 000000000..5c33d99b0 --- /dev/null +++ b/packages/fineui/src/base/single/input/file.js @@ -0,0 +1,769 @@ +import { Msg } from "../../foundation/message"; +import { shortcut, Widget, some, extend, jsonDecode, appendQuery, emptyFn, i18nText } from "@/core"; + +/** + * 文件 + * + * Created by GUY on 2016/1/27. + * @class File + * @extends Single + * @abstract + */ + +const document = _global.document || {}; + +/** + * @description normalize input.files. create if not present, add item method if not present + * @param Object generated wrap object + * @return Object the wrap object itself + */ +const F = (item => input => { + const files = input.files || [input]; + if (!files.item) { + files.item = item; + } + + return files; +})(i => this[i]); + +const event = { + + /** + * @description add an event via addEventListener or attachEvent + * @param DOMElement the element to add event + * @param String event name without "on" (e.g. "mouseover") + * @param Function the callback to associate as event + * @return Object noswfupload.event + */ + add: document.addEventListener + ? (node, name, callback) => { + node.addEventListener(name, callback, false); + + return this; + } + : (node, name, callback) => { + node.attachEvent(`on${name}`, callback); + + return this; + }, + + /** + * @description remove an event via removeEventListener or detachEvent + * @param DOMElement the element to remove event + * @param String event name without "on" (e.g. "mouseover") + * @param Function the callback associated as event + * @return Object noswfupload.event + */ + del: document.removeEventListener + ? (node, name, callback) => { + node.removeEventListener(name, callback, false); + + return this; + } + : (node, name, callback) => { + node.detachEvent(`on${name}`, callback); + + return this; + }, + + /** + * @description to block event propagation and prevent event default + * @param void generated event or undefined + * @return Boolean false + */ + stop(e) { + if (!e) { + if (self.event) { + event.returnValue = !(event.cancelBubble = true); + } + } else { + e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true); + e.preventDefault ? e.preventDefault() : (e.returnValue = false); + } + + return false; + }, +}; + +const sendFile = (toString => { + const split = "onabort.onerror.onloadstart.onprogress".split("."), + length = split.length, + CRLF = "\r\n"; + let xhr = new XMLHttpRequest(), + sendFile; + const multipart = (boundary, name, file) => + "--".concat( + boundary, + CRLF, + "Content-Disposition: form-data; name=\"", + name, + "\"; filename=\"", + _global.encodeURIComponent(file.fileName), + "\"", + CRLF, + "Content-Type: application/octet-stream", + CRLF, + CRLF, + file.getAsBinary(), + CRLF, + "--", + boundary, + "--", + CRLF + ); + const isFunction = Function => toString.call(Function) === "[object Function]"; + + // FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work) + if (xhr.upload || xhr.sendAsBinary) { + sendFile = (handler, maxSize, width, height) => { + const current = handler.current; + if (-1 < maxSize && maxSize < handler.file.fileSize) { + if (isFunction(handler.onerror)) { + handler.onerror(); + } + + return; + } + const xhr = new XMLHttpRequest(), + upload = xhr.upload || { + addEventListener(event, callback) { + this[`on${event}`] = callback; + }, + }; + for (let i = 0; i < length; i++) { + upload.addEventListener( + split[i].substring(2), + // eslint-disable-next-line no-loop-func + (event => rpe => { + if (isFunction(handler[event])) { + handler[event](rpe, xhr); + } + })(split[i]), + false + ); + } + upload.addEventListener( + "load", + rpe => { + if (handler.onreadystatechange === false) { + if (isFunction(handler.onload)) { + handler.onload(rpe, xhr); + } + } else { + const callback = () => { + if (xhr.readyState === 4) { + if (isFunction(handler.onload)) { + handler.onload(rpe, xhr); + } + } else { + setTimeout(callback, 15); + } + }; + setTimeout(callback, 15); + } + }, + false + ); + xhr.open( + "post", + appendQuery(handler.url, { + filename: _global.encodeURIComponent(handler.file.fileName), + }), + true + ); + if (!xhr.upload) { + const rpe = { loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true }; + rpe.interval = setInterval(() => { + rpe.loaded += 1024 / 4; + if (rpe.total <= rpe.loaded) { + rpe.loaded = rpe.total; + } + upload.onprogress(rpe); + }, 100); + xhr.onabort = () => { + upload.onabort({}); + }; + xhr.onerror = () => { + upload.onerror({}); + }; + xhr.onreadystatechange = () => { + switch (xhr.readyState) { + case 2: + case 3: + if (rpe.total <= rpe.loaded) { + rpe.loaded = rpe.total; + } + upload.onprogress(rpe); + break; + case 4: + clearInterval(rpe.interval); + rpe.interval = 0; + rpe.loaded = rpe.total; + upload.onprogress(rpe); + if (199 < xhr.status && xhr.status < 400) { + upload.onload({}); + const attachO = jsonDecode(xhr.responseText); + attachO.filename = handler.file.fileName; + if (handler.file.type.indexOf("image") !== -1) { + attachO.attach_type = "image"; + } + handler.attach_array[current] = attachO; + } else { + upload.onerror({}); + } + break; + default: + break; + } + }; + upload.onloadstart(rpe); + } else { + xhr.onreadystatechange = () => { + switch (xhr.readyState) { + case 4: { + const attachO = jsonDecode(xhr.responseText); + if (handler.file.type.indexOf("image") !== -1) { + attachO.attach_type = "image"; + } + attachO.filename = handler.file.fileName; + if (handler.maxLength === 1) { + handler.attach_array[0] = attachO; + // handler.attach_array.push(attachO); + } else { + handler.attach_array[current] = attachO; + } + break; + } + default: + break; + } + }; + if (isFunction(upload.onloadstart)) { + upload.onloadstart(); + } + } + const boundary = `AjaxUploadBoundary${new Date().getTime()}`; + xhr.setRequestHeader("Content-Type", `multipart/form-data; boundary=${boundary}`); + if (handler.file.getAsBinary) { + xhr[xhr.sendAsBinary ? "sendAsBinary" : "send"](multipart(boundary, handler.name, handler.file)); + } else { + xhr.setRequestHeader("Content-Type", "multipart/form-data"); + // xhr.setRequestHeader("X-Name", handler.name); + // xhr.setRequestHeader("X-File-Name", handler.file.fileName); + const form = new FormData(); + form.append("FileData", handler.file); + xhr.send(form); + } + + return handler; + }; + } else { + // Internet Explorer, Opera, others + sendFile = (handler, maxSize, width, height) => { + const current = handler.current; + let iframe, form; + const url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"), + rpe = { + loaded: 1, + total: 100, + simulation: true, + interval: setInterval(() => { + if (rpe.loaded < rpe.total) { + ++rpe.loaded; + } + if (isFunction(handler.onprogress)) { + handler.onprogress(rpe, {}); + } + }, 100), + }, + target = ["AjaxUpload", new Date().getTime(), String(Math.random()).substring(2)].join("_"); + const onload = () => { + iframe.onreadystatechange = iframe.onload = iframe.onerror = null; + form.parentNode.removeChild(form); + form = null; + clearInterval(rpe.interval); + // rpe.loaded = rpe.total; + const responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body + .innerHTML; + try { + const attachO = jsonDecode(responseText); + if (handler.file.type.indexOf("image") !== -1) { + attachO.attach_type = "image"; + } + + // attachO.fileSize = responseText.length; + try { + // decodeURIComponent特殊字符可能有问题, catch一下,保证能正常上传 + attachO.filename = _global.decodeURIComponent(handler.file.fileName); + } catch (e) { + attachO.filename = handler.file.fileName; + } + if (handler.maxLength === 1) { + handler.attach_array[0] = attachO; + } else { + handler.attach_array[current] = attachO; + } + } catch (e) { + if (isFunction(handler.onerror)) { + handler.onerror(rpe, event || _global.event); + } + } + if (isFunction(handler.onload)) { + handler.onload(rpe, { responseText }); + } + }; + + try { + // IE < 8 does not accept enctype attribute ... + // eslint-disable-next-line no-unused-vars + const form = document.createElement("
"), + // eslint-disable-next-line no-unused-vars + iframe = + handler.iframe || + (handler.iframe = document.createElement( + `` + )); + } catch (e) { + const form = document.createElement("form"), + iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); + form.setAttribute("enctype", "multipart/form-data"); + iframe.setAttribute("name", (iframe.id = target)); + iframe.setAttribute("src", url); + } + iframe.style.position = "absolute"; + iframe.style.left = iframe.style.top = "-10000px"; + iframe.onload = onload; + iframe.onerror = event => { + if (isFunction(handler.onerror)) { + handler.onerror(rpe, event || _global.event); + } + }; + iframe.onreadystatechange = () => { + if (/loaded|complete/i.test(iframe.readyState)) { + onload(); + + // wei : todo,将附件信息放到handler.attach + } else if (isFunction(handler.onloadprogress)) { + if (rpe.loaded < rpe.total) { + ++rpe.loaded; + } + handler.onloadprogress(rpe, { + readyState: + { + loading: 2, + interactive: 3, + loaded: 4, + complete: 4, + }[iframe.readyState] || 1, + }); + } + }; + form.setAttribute("action", `${handler.url}&filename=${_global.encodeURIComponent(handler.file.fileName)}`); + form.setAttribute("target", iframe.id); + form.setAttribute("method", "post"); + form.appendChild(handler.file); + form.style.display = "none"; + if (isFunction(handler.onloadstart)) { + handler.onloadstart(rpe, {}); + } + const d = document.body || document.documentElement; + d.appendChild(iframe); + d.appendChild(form); + form.submit(); + + return handler; + }; + } + xhr = null; + + return sendFile; +})(Object.prototype.toString); + +const sendFiles = (handler, maxSize, width, height) => { + const length = handler.files.length, + onload = handler.onload, + onloadstart = handler.onloadstart; + handler.current = 0; + handler.total = 0; + handler.sent = 0; + while (handler.current < length) { + handler.total += handler.files[handler.current].fileSize || handler.files[handler.current].size; + handler.current++; + } + handler.current = 0; + if (length && handler.files[0].fileSize !== -1) { + handler.file = handler.files[handler.current]; + const callback = (rpe, xhr) => { + handler.onloadstart = null; + handler.sent += handler.files[handler.current].fileSize || handler.files[handler.current].size; + if (++handler.current < length) { + handler.file = handler.files[handler.current]; + sendFile(handler, maxSize, width, height).onload = callback; + } else if (onload) { + handler.onloadstart = onloadstart; + handler.onload = onload; + handler.onload(rpe, xhr); + } + }; + sendFile(handler, maxSize, width, height).onload = callback; + } else if (length) { + handler.total = length * 100; + handler.file = handler.files[handler.current]; + const callback = (rpe, xhr) => { + handler.onloadstart = null; + handler.sent += 100; + if (++handler.current < length) { + if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { + handler.iframe.parentNode.removeChild(handler.iframe); + handler.iframe = null; + } + setTimeout(() => { + handler.file = handler.files[handler.current]; + sendFile(handler, maxSize, width, height).onload = callback; + }, 15); + } else if (onload) { + setTimeout(() => { + handler.iframe.parentNode.removeChild(handler.iframe); + handler.iframe = null; + handler.onloadstart = onloadstart; + handler.onload = onload; + handler.onload(rpe, xhr); + }, 15); + } + }; + sendFile(handler, maxSize, width, height).onload = callback; + } + + return handler; +}; + +const r1 = /\.([^.]+)$/; // .png +const r2 = /\/([^/]+)$/; // image/png + +/** + * 校验文件类型是否合法,同时兼容旧版形式 + * @param fileName + * @param fileType + * @returns {boolean} + */ +const fileTypeValidate = (fileName, fileType) => { + if (!fileType) { + return true; + } + let mimes = fileType.split(","); + if (mimes[0] === fileType) { + mimes = `${fileType}`.split(";"); + } + + return some(mimes, (index, mime) => { + let matches; + matches = mime.match(r1); + if (matches) { + return fileName.toLowerCase().endsWith(matches[0]); + } + matches = mime.match(r2); + if (matches) { + return matches[1] === "*" ? true : fileName.toLowerCase().endsWith(`.${matches[1]}`); + } + }); +}; + +@shortcut() +export class File extends Widget { + static xtype = "bi.file"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_PROGRESS = "EVENT_PROGRESS"; + static EVENT_UPLOADED = "EVENT_UPLOADED"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-file display-block`, + tagName: "input", + attributes: { + type: "file", + }, + name: "", + url: "", + multiple: true, + accept: "", // .png,.pdf,image/jpg,image/* 等 + maxSize: -1, // 1024 * 1024 单位b + maxLength: -1, // 无限制, 与multiple配合使用 + errorText: emptyFn, + }); + } + + render() { + const { multiple, name, title, accept } = this.options; + if (multiple === true) { + this.element.attr("multiple", "multiple"); + } + this.element.attr("name", name || this.getName()); + this.element.attr("title", title || ""); + this.element.attr("accept", accept); + } + + created() { + const { maxSize, url, accept } = this.options; + // create the noswfupload.wrap Object + // wrap.maxSize 文件大小限制 + // wrap.maxLength 文件个数限制 + const _wrap = (this.wrap = this._wrap(this.element[0], maxSize)); + // fileType could contain whatever text but filter checks *.{extension} + // if present + + // handlerszhe + + _wrap.onloadstart = (...args) => { + this.fireEvent(File.EVENT_UPLOADSTART, ...args); + }; + + _wrap.onprogress = (rpe, xhr) => { + // percent for each bar + + // fileSize is -1 only if browser does not support file info access + // this if splits recent browsers from others + if (_wrap.file.fileSize !== -1) { + // simulation property indicates when the progress event is fake + if (rpe.simulation) { + // empty + } else { + // empty + } + } else { + // if fileSIze is -1 browser is using an iframe because it does + // not support + // files sent via Ajax (XMLHttpRequest) + // We can still show some information + } + this.fireEvent(File.EVENT_PROGRESS, { + file: this.file, + total: rpe.total, + loaded: rpe.loaded, + simulation: rpe.simulation, + }); + }; + + // generated if there is something wrong during upload + _wrap.onerror = () => { + // just inform the user something was wrong + this.fireEvent(File.EVENT_ERROR); + }; + + // generated when every file has been sent (one or more, it does not + // matter) + _wrap.onload = (rpe, xhr) => { + // just show everything is fine ... + // ... and after a second reset the component + setTimeout(() => { + _wrap.clean(); // remove files from list + _wrap.hide(); // hide progress bars and enable input file + // enable again the submit button/element + }, 100); + if (200 > xhr.status || xhr.status > 399) { + Msg.toast(i18nText("BI-Upload_File_Error"), { level: "error" }); + this.fireEvent(File.EVENT_ERROR); + + return; + } + const error = some(_wrap.attach_array, (index, attach) => { + if (attach.errorCode) { + Msg.toast(i18nText(attach.errorMsg), { level: "error" }); + this.fireEvent(File.EVENT_ERROR, attach); + + return true; + } + }); + !error && this.fireEvent(File.EVENT_UPLOADED); + }; + _wrap.url = url; + _wrap.fileType = accept; // 文件类型限制 + _wrap.attach_array = []; + _wrap.attach_names = []; + _wrap.attachNum = 0; + } + + _events(wrap) { + const { maxLength, errorText } = this.options; + const callback = () => { + event.del(wrap.dom.input, "change", callback); + const input = wrap.dom.input.cloneNode(true); + const files = F(wrap.dom.input); + if (maxLength !== -1 && maxLength < files.length) { + this.fireEvent(File.EVENT_ERROR, { + errorType: 2, + }); + } else { + for (let i = 0; i < files.length; i++) { + const item = files.item(i); + const tempFile = item.value || item.name; + const value = item.fileName || (item.fileName = tempFile.split("\\").pop()), + size = item.fileSize || item.size; + const validateFileType = fileTypeValidate(value, wrap.fileType); + if (!validateFileType) { + // 文件类型不支持 + Msg.toast( + errorText({ + errorType: 0, + file: item, + }) || i18nText("BI-Upload_File_Type_Error", wrap.fileType), + { level: "error" } + ); + this.fireEvent(File.EVENT_ERROR, { + errorType: 0, + file: item, + }); + } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { + // 文件大小不支持 + Msg.toast( + errorText({ + errorType: 1, + file: item, + }) || i18nText("BI-Upload_File_Size_Error", Math.ceil(wrap.maxSize / 1024 / 1024)), + { level: "error" } + ); + this.fireEvent(File.EVENT_ERROR, { + errorType: 1, + file: item, + }); + } else { + wrap.files.unshift(item); + } + } + } + wrap.files.length > 0 && + this.fireEvent(File.EVENT_CHANGE, { + files: wrap.files, + }); + input.value = ""; + wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); + wrap.dom.input = input; + event.add(wrap.dom.input, "change", callback); + }; + event.add(wrap.dom.input, "change", callback); + + return wrap; + } + + _wrap() { + const { multiple, maxSize, maxLength } = this.options; + // be sure input accept multiple files + const input = this.element[0]; + if (multiple === true) { + this.element.attr("multiple", "multiple"); + } + input.value = ""; + + // wrap Object + return this._events({ + // DOM namespace + dom: { + input, // input file + disabled: false, // internal use, checks input file state + }, + name: input.name, // name to send for each file ($_FILES[{name}] in the server) + // maxSize is the maximum amount of bytes for each file + maxSize: maxSize ? maxSize >> 0 : -1, + maxLength, + files: [], // file list + + // remove every file from the noswfupload component + clean() { + this.files = []; + }, + + // upload one file a time (which make progress possible rather than all files in one shot) + // the handler is an object injected into the wrap one, could be the wrap itself or + // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} + upload(handler) { + if (handler) { + for (const key in handler) { + this[key] = handler[key]; + } + } + sendFiles(this, this.maxSize); + + return this; + }, + + // hide progress bar (total + current) and enable files selection + hide() { + if (this.dom.disabled) { + this.dom.disabled = false; + this.dom.input.removeAttribute("disabled"); + } + }, + + // show progress bar and disable file selection (used during upload) + // total and current are pixels used to style bars + // totalProp and currentProp are properties to change, "height" by default + show(total, current, totalProp, currentProp) { + if (!this.dom.disabled) { + this.dom.disabled = true; + this.dom.input.setAttribute("disabled", "disabled"); + } + }, + }); + } + + setUrl(v) { + this.options.url = v; + if (this.wrap) { + this.wrap.url = v; + } + } + + setMaxFileLength(v) { + this.options.maxLength = v; + if (this.wrap) { + this.wrap.maxLength = v; + } + } + + select() { + this.wrap && Widget._renderEngine.createElement(this.wrap.dom.input).click(); + } + + upload(handler) { + this.wrap && this.wrap.upload(handler); + } + + getValue() { + return this.wrap ? this.wrap.attach_array : []; + } + + getQueue() { + return this.wrap.files; + } + + reset() { + if (this.wrap) { + this.wrap.attach_array = []; + this.wrap.attach_names = []; + this.wrap.attachNum = 0; + } + } + + sendFiles(files) { + if (!this.wrap) return; + + this.wrap.dom.input.files = files; + + const event = new CustomEvent("change"); + + this.wrap.dom.input.dispatchEvent(event); + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.removeAttr("disabled"); + } else { + this.element.attr("disabled", "disabled"); + } + } +} diff --git a/packages/fineui/src/base/single/input/index.js b/packages/fineui/src/base/single/input/index.js new file mode 100644 index 000000000..32754291f --- /dev/null +++ b/packages/fineui/src/base/single/input/index.js @@ -0,0 +1,6 @@ +export { Input } from "./input"; +export { File } from "./file"; +export { Checkbox } from "./checkbox/checkbox"; +export { ImageCheckbox } from "./checkbox/checkbox.image"; +export { Radio } from "./radio/radio"; +export { ImageRadio } from "./radio/radio.image"; diff --git a/packages/fineui/src/base/single/input/input.js b/packages/fineui/src/base/single/input/input.js new file mode 100644 index 000000000..fb950aaed --- /dev/null +++ b/packages/fineui/src/base/single/input/input.js @@ -0,0 +1,365 @@ +import { Single } from "../0.single"; +import { + shortcut, + Controller, + extend, + debounce, + bind, + isNull, + isEmptyString, + isKey, + delay, + trim, + isEqual, + nextTick, + isEndWithBlank, + emptyFn, + EVENT_RESPONSE_TIME, + KeyCode, + Events +} from "@/core"; + +/** + * guy + * @class Input 一个button和一行数 组成的一行listitem + * @extends Single + * @type {*|void|Object} + */ + +@shortcut() +export class Input extends Single { + static xtype = "bi.input"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_BACKSPACE = "EVENT_BACKSPACE"; + + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_REMOVE = "EVENT_REMOVE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-input display-block overflow-dot`, + tagName: "input", + validationChecker: emptyFn, + quitChecker: emptyFn, // 按确定键能否退出编辑 + allowBlank: false, + }); + } + + render() { + let ctrlKey = false; + let keyCode = null; + let inputEventValid = false; + const _keydown = debounce(keyCode => { + this.onKeyDown(keyCode, ctrlKey); + this._keydown_ = false; + }, EVENT_RESPONSE_TIME); + const _clk = debounce(bind(this._click, this), EVENT_RESPONSE_TIME, { + leading: true, + trailing: false, + }); + this._focusDebounce = debounce(bind(this._focus, this), EVENT_RESPONSE_TIME, { + leading: true, + trailing: false, + }); + this._blurDebounce = debounce(bind(this._blur, this), EVENT_RESPONSE_TIME, { + leading: true, + trailing: false, + }); + this.element + .keydown(e => { + inputEventValid = false; + ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下 + keyCode = e.keyCode; + this.fireEvent(Input.EVENT_QUICK_DOWN, e); + }) + .keyup(e => { + keyCode = null; + if (!(inputEventValid && e.keyCode === KeyCode.ENTER)) { + this._keydown_ = true; + _keydown(e.keyCode); + } + }) + .on("input propertychange", e => { + // 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了 + // 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8 + // 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓) + const originalEvent = e.originalEvent; + if (isNull(originalEvent.propertyName) || originalEvent.propertyName === "value") { + inputEventValid = true; + this._keydown_ = true; + _keydown(keyCode); + keyCode = null; + } + }) + .click(e => { + e.stopPropagation(); + _clk(); + }) + .mousedown(e => { + this.element.val(this.element.val()); + }) + .focus(e => { + // 可以不用冒泡 + this._focusDebounce(); + }) + .blur(e => { + // DEC-14919 IE11在浏览器重新获得焦点之后会先触发focusout再触发focus,要保持先获得焦点再失去焦点的顺序不变,因此采用blur + this._blurDebounce(); + }); + if (isKey(this.options.value) || isEmptyString(this.options.value)) { + this.setValue(this.options.value); + } + } + + _focus() { + this.element.addClass("bi-input-focus"); + this._checkValidationOnValueChange(); + this._isEditing = true; + if (this.getValue() === "") { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + this.fireEvent(Input.EVENT_EMPTY); + } + this.fireEvent(Input.EVENT_FOCUS); + } + + _blur() { + const blur = () => { + if (!this.isValid() && this.options.quitChecker.apply(this, [trim(this.getValue())]) !== false) { + this.element.val(this._lastValidValue ? this._lastValidValue : ""); + this._checkValidationOnValueChange(); + this._defaultState(); + } + this.element.removeClass("bi-input-focus"); + this._isEditing = false; + this._start = false; + if (this.isValid()) { + const lastValidValue = this._lastValidValue; + this._lastValidValue = this.getValue(); + this.fireEvent(Controller.EVENT_CHANGE, Events.CONFIRM, this.getValue(), this); + this.fireEvent(Input.EVENT_CONFIRM); + if (this._lastValidValue !== lastValidValue) { + this.fireEvent(Input.EVENT_CHANGE_CONFIRM); + } + } + this.fireEvent(Input.EVENT_BLUR); + }; + + if (this._keydown_ === true) { + delay(blur, EVENT_RESPONSE_TIME); + } else { + blur(); + } + } + + _click() { + if (this._isEditing !== true) { + this.selectAll(); + this.fireEvent(Input.EVENT_CLICK); + } + } + + onClick() { + this._click(); + } + + onKeyDown(keyCode, ctrlKey) { + if (!this.isValid() || trim(this._lastChangedValue) !== trim(this.getValue())) { + this._checkValidationOnValueChange(); + } + if (this.isValid() && trim(this.getValue()) !== "") { + if ( + (trim(this.getValue()) !== this._lastValue && + (!this._start || isNull(this._lastValue) || this._lastValue === "")) || + (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue())) + ) { + this._start = true; + this._pause = false; + this.fireEvent(Controller.EVENT_CHANGE, Events.STARTEDIT, this.getValue(), this); + this.fireEvent(Input.EVENT_START); + } + } + if (isEqual(keyCode, KeyCode.ENTER)) { + if (this.isValid() || this.options.quitChecker.apply(this, [trim(this.getValue())]) !== false) { + this.blur(); + this.fireEvent(Input.EVENT_ENTER); + } else { + this.fireEvent(Input.EVENT_RESTRICT); + } + } + if (isEqual(keyCode, KeyCode.SPACE)) { + this.fireEvent(Input.EVENT_SPACE); + } + if (isEqual(keyCode, KeyCode.BACKSPACE) && this._lastValue === "") { + this.fireEvent(Input.EVENT_REMOVE); + } + if (isEqual(keyCode, KeyCode.BACKSPACE) || isEqual(keyCode, KeyCode.DELETE)) { + this.fireEvent(Input.EVENT_BACKSPACE); + } + this.fireEvent(Input.EVENT_KEY_DOWN, arguments); + + // _valueChange中会更新_lastValue, 这边缓存用以后续STOP事件服务 + const lastValue = this._lastValue; + if (trim(this.getValue()) !== trim(this._lastValue || "")) { + this._valueChange(); + } + if (isEndWithBlank(this.getValue())) { + this._pause = true; + this.fireEvent(Controller.EVENT_CHANGE, Events.PAUSE, "", this); + this.fireEvent(Input.EVENT_PAUSE); + this._defaultState(); + } else if ( + (keyCode === KeyCode.BACKSPACE || keyCode === KeyCode.DELETE) && + trim(this.getValue()) === "" && + lastValue !== null && + trim(lastValue) !== "" + ) { + this.fireEvent(Controller.EVENT_CHANGE, Events.STOPEDIT, this.getValue(), this); + this.fireEvent(Input.EVENT_STOP); + } + } + + // 初始状态 + _defaultState() { + if (this.getValue() === "") { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + this.fireEvent(Input.EVENT_EMPTY); + } + this._lastValue = this.getValue(); + this._lastSubmitValue = null; + } + + _valueChange() { + if (this.isValid() && trim(this.getValue()) !== this._lastSubmitValue) { + this.fireEvent(Controller.EVENT_CHANGE, Events.CHANGE, this.getValue(), this); + this.fireEvent(Input.EVENT_CHANGE); + this._lastSubmitValue = trim(this.getValue()); + } + if (this.getValue() === "") { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY, this.getValue(), this); + this.fireEvent(Input.EVENT_EMPTY); + } + this._lastValue = this.getValue(); + } + + _checkValidationOnValueChange(callback) { + const { allowBlank, validationChecker } = this.options; + const v = this.getValue(); + if (allowBlank === true && trim(v) === "") { + this.setValid(true); + callback && callback(); + + return; + } + if (trim(v) === "") { + this.setValid(false); + callback && callback(); + + return; + } + const checker = validationChecker.apply(this, [trim(v)]); + if (checker instanceof Promise) { + checker.then(validate => { + this.setValid(validate !== false); + callback && callback(); + }); + } else { + this.setValid(checker !== false); + callback && callback(); + } + } + + focus() { + if (!this.element.is(":visible")) { + throw new Error("input cannot be focus when it's invisible"); + } + if (!this._isEditing === true) { + this.element.focus(); + this.selectAll(); + } + } + + blur() { + if (!this.element.is(":visible")) { + throw new Error("input cannot be blur when it's invisible"); + } + if (this._isEditing === true) { + this.element.blur(); + this._blurDebounce(); + } + } + + selectAll() { + if (!this.element.is(":visible")) { + throw new Error("input cannot be select when it's invisible"); + } + this.element.select(); + this._isEditing = true; + } + + setValue(textValue) { + this.element.val(textValue); + nextTick(() => { + this._checkValidationOnValueChange(() => { + this._defaultState(); + if (this.isValid()) { + this._lastValidValue = this._lastSubmitValue = this.getValue(); + } + }); + }); + } + + getValue() { + return this.element.val() || ""; + } + + isEditing() { + return this._isEditing; + } + + getLastValidValue() { + return this._lastValidValue; + } + + getLastChangedValue() { + return this._lastChangedValue; + } + + _setValid() { + super._setValid(...arguments); + if (this.isValid()) { + this._lastChangedValue = this.getValue(); + this.element.removeClass("bi-input-error"); + this.fireEvent(Input.EVENT_VALID, trim(this.getValue()), this); + } else { + if (this._lastChangedValue === this.getValue()) { + this._lastChangedValue = null; + } + this.element.addClass("bi-input-error"); + this.fireEvent(Input.EVENT_ERROR, trim(this.getValue()), this); + } + } + + _setEnable(b) { + super._setEnable([b]); + this.element[0].disabled = !b; + } +} diff --git a/packages/fineui/src/base/single/input/radio/radio.image.js b/packages/fineui/src/base/single/input/radio/radio.image.js new file mode 100644 index 000000000..2d807cb82 --- /dev/null +++ b/packages/fineui/src/base/single/input/radio/radio.image.js @@ -0,0 +1,36 @@ +import { IconButton } from "../../button"; +import { shortcut, extend, emptyFn } from "@/core"; + +/** + * guy + * @extends Single + * @type {*|void|Object} + */ + +@shortcut() +export class ImageRadio extends IconButton { + static xtype = "bi.image_radio"; + + static EVENT_CHANGE = IconButton.EVENT_CHANGE; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-radio radio-icon`, + selected: false, + handler: emptyFn, + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16, + }); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(ImageRadio.EVENT_CHANGE); + } + } +} diff --git a/packages/fineui/src/base/single/input/radio/radio.js b/packages/fineui/src/base/single/input/radio/radio.js new file mode 100644 index 000000000..fa6a10401 --- /dev/null +++ b/packages/fineui/src/base/single/input/radio/radio.js @@ -0,0 +1,68 @@ +import { CenterAdaptLayout, Layout, shortcut, emptyFn } from "@/core"; +import { BasicButton } from "../../button"; + +/** + * guy + * @extends Single + * @type {*|void|Object} + */ + +@shortcut() +export class Radio extends BasicButton { + static xtype = "bi.radio"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-radio", + selected: false, + handler: emptyFn, + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16, + }; + + render() { + const { iconWidth, iconHeight } = this.options; + + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: Layout.xtype, + cls: "radio-content", + ref: _ref => { + this.radio = _ref; + }, + width: iconWidth, + height: iconHeight, + } + ], + }; + } + + _setEnable(enable) { + super._setEnable(enable); + if (enable === true) { + this.radio.element.removeClass("base-disabled disabled"); + } else { + this.radio.element.addClass("base-disabled disabled"); + } + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(Radio.EVENT_CHANGE); + } + } + + setSelected(b) { + super.setSelected(b); + if (b) { + this.radio.element.addClass("bi-high-light-background"); + } else { + this.radio.element.removeClass("bi-high-light-background"); + } + } +} diff --git a/packages/fineui/src/base/single/instruction/instruction.js b/packages/fineui/src/base/single/instruction/instruction.js new file mode 100644 index 000000000..bf57c435b --- /dev/null +++ b/packages/fineui/src/base/single/instruction/instruction.js @@ -0,0 +1,81 @@ +import { Label } from "../label"; +import { shortcut, Widget, extend } from "@/core"; + +@shortcut() +export class Instruction extends Widget { + static xtype = "bi.instruction"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-instruction`, + height: 20, + level: "error", + textAlign: "left", + whiteSpace: "nowrap", + hgap: 5, + }); + } + + render() { + const { level, textAlign, whiteSpace, height, hgap, rgap, lgap, vgap, text, keyword, value, py } = this.options; + + return { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: `instruction-${level}`, + textAlign, + whiteSpace, + textHeight: height, + height, + hgap, + rgap, + lgap, + vgap, + text, + keyword, + value, + py, + }; + } + + doRedMark() { + this.text.doRedMark.apply(this.text, arguments); + } + + unRedMark() { + this.text.unRedMark.apply(this.text, arguments); + } + + doHighLight() { + this.text.doHighLight.apply(this.text, arguments); + } + + unHighLight() { + this.text.unHighLight.apply(this.text, arguments); + } + + setText(v) { + this.options.text = v; + this.text.setText(v); + } + + getText() { + return this.options.text; + } + + setStyle(css) { + this.text.setStyle(css); + } + + setValue(v) { + this.text.setValue(v); + } + + getValue() { + this.text.getValue(); + } +} diff --git a/packages/fineui/src/base/single/label/abstract.label.js b/packages/fineui/src/base/single/label/abstract.label.js new file mode 100644 index 000000000..5b7803f3c --- /dev/null +++ b/packages/fineui/src/base/single/label/abstract.label.js @@ -0,0 +1,429 @@ +import { Text } from "../1.text"; +import { CenterAdaptLayout, isNumber, createWidget, extend, pixFormat } from "@/core"; +import { Single } from "../0.single"; + +/** + * Created by dailer on 2019/6/19. + */ + +export class AbstractLabel extends Single { + _defaultConfig(props) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + textAlign: "center", + whiteSpace: "nowrap", // normal or nowrap + textWidth: null, + textHeight: null, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + highLight: false, + handler: null, + enableHover: props.title !== null, + }); + } + + _createJson() { + const { textAlign, whiteSpace, textHeight, text, value, py, keyword, highLight, handler } = this.options; + + return { + type: Text.xtype, + textAlign, + whiteSpace, + lineHeight: textHeight, + maxWidth: "100%", + text, + value, + py, + keyword, + highLight, + handler, + }; + } + + render() { + if (this.options.textAlign === "center") { + this._createCenterEl(); + } else { + this._createNotCenterEl(); + } + } + + _createCenterEl() { + const { width, textWidth, height, whiteSpace, hgap, vgap, lgap, rgap, tgap, bgap, textAlign } = this.options; + const json = this._createJson(); + json.textAlign = "left"; + if (isNumber(width) && width > 0) { + if (isNumber(textWidth) && textWidth > 0) { + json.maxWidth = textWidth; + if (isNumber(height) && height > 0) { + // 1.1 + createWidget({ + type: CenterAdaptLayout.xtype, + height, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + createWidget({ + // 1.2 + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + if (whiteSpace === "normal") { + // 1.3 + extend(json, { + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }); + this.text = createWidget(json); + createWidget({ + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + element: this, + items: [this.text], + }); + + return; + } + if (isNumber(height) && height > 0) { + // 1.4 + this.element.css({ + "line-height": pixFormat(height), + }); + json.textAlign = textAlign; + delete json.maxWidth; + this.text = createWidget( + extend(json, { + element: this, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + + return; + } + extend(json, { + // 1.5 + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + maxWidth: "100%", + }); + this.text = createWidget(json); + createWidget({ + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + element: this, + items: [this.text], + }); + + return; + } + if (isNumber(textWidth) && textWidth > 0) { + // 1.6 + json.maxWidth = textWidth; + createWidget({ + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + if (whiteSpace === "normal") { + // 1.7 + extend(json, { + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }); + this.text = createWidget(json); + createWidget({ + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: true, + element: this, + items: [this.text], + }); + + return; + } + if (isNumber(height) && height > 0) { + // 1.8 + this.element.css({ + "line-height": pixFormat(height), + }); + json.textAlign = textAlign; + delete json.maxWidth; + this.text = createWidget( + extend(json, { + element: this, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + + return; + } + this.text = createWidget( + extend(json, { + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + createWidget({ + type: CenterAdaptLayout.xtype, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + element: this, + items: [this.text], + }); + } + + _createNotCenterEl() { + const { width, textWidth, height, whiteSpace, hgap, vgap, lgap, rgap, tgap, bgap, textAlign } = this.options; + const adaptLayout = "bi.vertical_adapt"; + const json = this._createJson(); + if (isNumber(width) && width > 0) { + if (isNumber(textWidth) && textWidth > 0) { + json.maxWidth = textWidth; + if (isNumber(height) && height > 0) { + // 2.1 + createWidget({ + type: adaptLayout, + horizontalAlign: textAlign, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + height, + scrollable: whiteSpace === "normal", + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + createWidget({ + // 2.2 + type: adaptLayout, + horizontalAlign: textAlign, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + if (isNumber(height) && height > 0) { + // 2.3 + if (whiteSpace !== "normal") { + this.element.css({ + "line-height": pixFormat(height - vgap * 2), + }); + } + delete json.maxWidth; + this.text = createWidget( + extend(json, { + element: this, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + + return; + } + json.maxWidth = width - 2 * hgap - lgap - rgap; + createWidget({ + // 2.4 + type: adaptLayout, + horizontalAlign: textAlign, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + if (isNumber(textWidth) && textWidth > 0) { + json.maxWidth = textWidth; + createWidget({ + // 2.5 + type: adaptLayout, + horizontalAlign: textAlign, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + scrollable: whiteSpace === "normal", + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + element: this, + items: [ + { + el: (this.text = createWidget(json)), + } + ], + }); + + return; + } + if (isNumber(height) && height > 0) { + if (whiteSpace !== "normal") { + this.element.css({ + "line-height": pixFormat(height - vgap * 2), + }); + } + delete json.maxWidth; + this.text = createWidget( + extend(json, { + // 2.6 + element: this, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + + return; + } + this.text = createWidget( + extend(json, { + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + }) + ); + createWidget({ + type: adaptLayout, + horizontalAlign: textAlign, + columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 + element: this, + scrollable: whiteSpace === "normal", + items: [this.text], + }); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setText(v) { + this.options.text = v; + this.text.setText(v); + } + + getText() { + return this.options.text; + } + + setStyle(css) { + this.text.setStyle(css); + } + + setValue(v) { + super.setValue(v); + if (!this.isReadOnly()) { + this.options.text = v; + this.text.setValue(v); + } + } +} diff --git a/packages/fineui/src/base/single/label/html.label.js b/packages/fineui/src/base/single/label/html.label.js new file mode 100644 index 000000000..9b643c3aa --- /dev/null +++ b/packages/fineui/src/base/single/label/html.label.js @@ -0,0 +1,30 @@ +import { Html } from "../html/html"; +import { AbstractLabel } from "./abstract.label"; +import { shortcut } from "@/core"; + +/** + * Created by GUY on 2015/6/26. + */ + +@shortcut() +export class HtmlLabel extends AbstractLabel { + static xtype = "bi.html_label"; + + props = { + baseCls: "bi-html-label", + }; + + _createJson() { + const { textAlign, whiteSpace, textHeight, text, value, handler } = this.options; + + return { + type: Html.xtype, + textAlign, + whiteSpace, + lineHeight: textHeight, + text, + value, + handler, + }; + } +} diff --git a/packages/fineui/src/base/single/label/icon.label.js b/packages/fineui/src/base/single/label/icon.label.js new file mode 100644 index 000000000..65b8757c1 --- /dev/null +++ b/packages/fineui/src/base/single/label/icon.label.js @@ -0,0 +1,66 @@ +import { Icon } from "../icon/icon"; +import { DefaultLayout, CenterAdaptLayout, shortcut, createWidget, isNumber, isNull, pixFormat } from "@/core"; +import { Single } from "../0.single"; + +/** + * @class IconLabel + * @extends Single + * 图标标签 + */ + +@shortcut() +export class IconLabel extends Single { + static xtype = "bi.icon_label"; + + props = { + baseCls: "bi-icon-label horizon-center", + hgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + lgap: 0, + rgap: 0, + iconWidth: null, + iconHeight: null, + lineHeight: null, + }; + + render() { + const { iconWidth, iconHeight, height, lineHeight, hgap, vgap, lgap, rgap, tgap, bgap } = this.options; + this.element.css({ + textAlign: "center", + }); + this.icon = createWidget({ + type: Icon.xtype, + width: iconWidth, + height: iconHeight, + }); + if (isNumber(height) && height > 0 && isNull(iconWidth) && isNull(iconHeight)) { + this.element.css("lineHeight", pixFormat(lineHeight || height)); + createWidget({ + type: DefaultLayout.xtype, + element: this, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + items: [this.icon], + }); + } else { + this.element.css("lineHeight", "1"); + createWidget({ + element: this, + type: CenterAdaptLayout.xtype, + hgap, + vgap, + lgap, + rgap, + tgap, + bgap, + items: [this.icon], + }); + } + } +} diff --git a/packages/fineui/src/base/single/label/index.js b/packages/fineui/src/base/single/label/index.js new file mode 100644 index 000000000..3a80cb8db --- /dev/null +++ b/packages/fineui/src/base/single/label/index.js @@ -0,0 +1,4 @@ +export { AbstractLabel } from "./abstract.label"; +export { HtmlLabel } from "./html.label"; +export { IconLabel } from "./icon.label"; +export { Label } from "./label"; diff --git a/packages/fineui/src/base/single/label/label.js b/packages/fineui/src/base/single/label/label.js new file mode 100644 index 000000000..c5a7e9774 --- /dev/null +++ b/packages/fineui/src/base/single/label/label.js @@ -0,0 +1,42 @@ +import { AbstractLabel } from "./abstract.label"; +import { shortcut, isFunction, isNotNull } from "@/core"; + +/** + * Created by GUY on 2015/6/26. + */ + +@shortcut() +export class Label extends AbstractLabel { + static xtype = "bi.label"; + + props = { + baseCls: "bi-label", + py: "", + keyword: "", + }; + + getTitle() { + const title = this.options.title; + const text = this.options.text; + if (isFunction(title)) { + return title(); + } + if (isNotNull(title)) { + return title; + } + + if (isFunction(text)) { + return text(); + } + + return text; + } + + doRedMark() { + this.text.doRedMark.apply(this.text, arguments); + } + + unRedMark() { + this.text.unRedMark.apply(this.text, arguments); + } +} diff --git a/src/base/single/link/__test__/link.test.js b/packages/fineui/src/base/single/link/__test__/link.test.js similarity index 100% rename from src/base/single/link/__test__/link.test.js rename to packages/fineui/src/base/single/link/__test__/link.test.js diff --git a/packages/fineui/src/base/single/link/link.js b/packages/fineui/src/base/single/link/link.js new file mode 100644 index 000000000..76314c589 --- /dev/null +++ b/packages/fineui/src/base/single/link/link.js @@ -0,0 +1,42 @@ +import { A } from "../a/a"; +import { Label } from "../label/label"; +import { shortcut, extend } from "@/core"; + +/** + * guy a元素 + * @class Link + * @extends Text + */ + +@shortcut() +export class Link extends Label { + static xtype = "bi.link"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-link display-block`, + tagName: "a", + href: "", + target: "_blank", + }); + } + + _createJson() { + const { textAlign, whiteSpace, textHeight, text, keyword, value, py, href, target } = this.options; + + return { + type: A.xtype, + textAlign, + whiteSpace, + lineHeight: textHeight, + text, + keyword, + value, + py, + href, + target, + }; + } +} diff --git a/packages/fineui/src/base/single/text.pure.js b/packages/fineui/src/base/single/text.pure.js new file mode 100644 index 000000000..38d7935c5 --- /dev/null +++ b/packages/fineui/src/base/single/text.pure.js @@ -0,0 +1,50 @@ +import { Text } from "./1.text"; +import { Widget, shortcut, isFunction, isKey, isNotNull } from "@/core"; + +/** + * 没有html标签的纯文本 + */ + +@shortcut() +export class PureText extends Widget { + static xtype = "bi.pure_text"; + + props = { + tagName: null, + }; + + render() { + const { text: optionsText, value } = this.options; + const text = isFunction(optionsText) + ? this.__watch(optionsText, (context, newValue) => { + this.setText(newValue); + }) + : optionsText; + if (isKey(text)) { + this.setText(text); + } else if (isKey(value)) { + this.setText(value); + } + } + + _getShowText() { + const { text: optionsText, value } = this.options; + let text = isFunction(optionsText) ? optionsText() : optionsText; + text = isKey(text) ? text : value; + if (!isKey(text)) { + return ""; + } + + return Text.formatText(`${text}`); + } + + setValue(value) { + this.options.value = value; + this.setText(value); + } + + setText(text) { + this.options.text = isNotNull(text) ? text : ""; + this.element.__textKeywordMarked__(this._getShowText()); + } +} diff --git a/packages/fineui/src/base/single/tip/0.tip.js b/packages/fineui/src/base/single/tip/0.tip.js new file mode 100644 index 000000000..b8bfa7c1a --- /dev/null +++ b/packages/fineui/src/base/single/tip/0.tip.js @@ -0,0 +1,27 @@ +import { Single } from "../0.single"; +import { extend, zIndex_tip } from "@/core"; + +/** + * guy + * tip提示 + * zIndex在10亿级别 + * @class Tip + * @extends Single + * @abstract + */ + +export class Tip extends Single { + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-tip`, + zIndex: zIndex_tip, + }); + } + + _init() { + super._init(); + this.element.css({ zIndex: this.options.zIndex }); + } +} diff --git a/packages/fineui/src/base/single/tip/index.js b/packages/fineui/src/base/single/tip/index.js new file mode 100644 index 000000000..cdbd3e751 --- /dev/null +++ b/packages/fineui/src/base/single/tip/index.js @@ -0,0 +1,3 @@ +export { Tip } from "./0.tip"; +export { Toast } from "./tip.toast"; +export { Tooltip } from "./tip.tooltip"; diff --git a/packages/fineui/src/base/single/tip/tip.toast.js b/packages/fineui/src/base/single/tip/tip.toast.js new file mode 100644 index 000000000..7081b5645 --- /dev/null +++ b/packages/fineui/src/base/single/tip/tip.toast.js @@ -0,0 +1,133 @@ +import { IconLabel, Label } from "../label"; +import { IconButton } from "../button"; +import { HorizontalLayout, shortcut, extend, isPlainObject, pixFormat, HorizontalAlign } from "@/core"; +import { Tip } from "./0.tip"; + +/** + * toast提示 + * + * Created by GUY on 2015/9/7. + * @class Toast + * @extends Tip + */ + +@shortcut() +export class Toast extends Tip { + _const = { + closableMinWidth: 146, + minWidth: 100, + closableMaxWidth: 410, + maxWidth: 400, + }; + + static EVENT_DESTORY = "EVENT_DESTORY"; + static xtype = "bi.toast"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-toast", + text: "", + level: "success", // success或warning + autoClose: true, + closable: null, + textHeight: 20, + vgap: 10, + innerHgap: 4, + hgap: 8, + }); + } + + render() { + const { closable, level, autoClose, textHeight, text, hgap, vgap, innerHgap } = this.options; + const { closableMinWidth, minWidth, maxWidth, closableMaxWidth } = this._const; + this.element.css({ + minWidth: pixFormat(closable ? closableMinWidth : minWidth), + maxWidth: pixFormat(closable ? closableMaxWidth : maxWidth), + }); + this.element.addClass(`toast-${level}`); + function fn(e) { + e.stopPropagation(); + e.stopEvent(); + + return false; + } + this.element.bind({ + click: fn, + mousedown: fn, + mouseup: fn, + mouseover: fn, + mouseenter: fn, + mouseleave: fn, + mousemove: fn, + }); + let cls; + switch (level) { + case "success": + cls = "toast-success-font"; + break; + case "error": + cls = "toast-error-font"; + break; + case "warning": + cls = "toast-warning-font"; + break; + case "loading": + cls = "toast-loading-font anim-rotate"; + break; + case "normal": + default: + cls = "toast-message-font"; + break; + } + + function hasCloseIcon() { + return closable === true || (closable === null && autoClose === false); + } + const items = [ + { + type: IconLabel.xtype, + cls: `${cls} toast-icon`, + height: textHeight, + }, + { + el: isPlainObject(text) + ? text + : { + type: Label.xtype, + whiteSpace: "normal", + text, + textHeight, + textAlign: "left", + }, + } + ]; + + const columnSize = ["", "fill"]; + + if (hasCloseIcon()) { + items.push({ + type: IconButton.xtype, + cls: "close-font toast-icon", + handler: () => { + this.destroy(); + }, + height: textHeight, + }); + columnSize.push(""); + } + + return { + type: HorizontalLayout.xtype, + horizontalAlign: HorizontalAlign.Stretch, + items, + hgap, + vgap, + innerHgap, + columnSize, + }; + } + + beforeDestroy() { + this.fireEvent(Toast.EVENT_DESTORY); + } +} diff --git a/packages/fineui/src/base/single/tip/tip.tooltip.js b/packages/fineui/src/base/single/tip/tip.tooltip.js new file mode 100644 index 000000000..0d8fbd7c2 --- /dev/null +++ b/packages/fineui/src/base/single/tip/tip.tooltip.js @@ -0,0 +1,94 @@ +import { VerticalLayout, shortcut, extend, createWidget, map, pixFormat } from "@/core"; +import { Label } from "../label"; +import { Tip } from "./0.tip"; + +/** + * title提示 + * + * Created by GUY on 2015/9/7. + * @class Tooltip + * @extends Tip + */ + +@shortcut() +export class Tooltip extends Tip { + _const = { + hgap: 8, + vgap: 4, + }; + static xtype = "bi.tooltip"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-tooltip", + text: "", + level: "success", // success或warning + stopEvent: false, + stopPropagation: false, + textAlign: "left", + }); + } + + render() { + const { level, stopPropagation, stopEvent, text, textAlign } = this.options; + this.element.addClass(`tooltip-${level}`); + function fn(e) { + stopPropagation && e.stopPropagation(); + stopEvent && e.stopEvent(); + } + this.element.bind({ + click: fn, + mousedown: fn, + mouseup: fn, + mouseover: fn, + mouseenter: fn, + mouseleave: fn, + mousemove: fn, + }); + + const texts = `${text}`.split("\n"); + if (texts.length > 1) { + createWidget({ + type: VerticalLayout.xtype, + element: this, + hgap: this._const.hgap, + innerVgap: this._const.vgap, + items: map(texts, (i, text) => { + return { + type: Label.xtype, + textAlign, + whiteSpace: "normal", + text, + textHeight: 18, + title: null, + }; + }), + }); + } else { + this.text = createWidget({ + type: Label.xtype, + element: this, + textAlign, + whiteSpace: "normal", + text, + title: null, + textHeight: 18, + hgap: this._const.hgap, + vgap: this._const.vgap, + }); + } + } + + setWidth(width) { + this.element.width(pixFormat(width - 2 * this._const.hgap)); + } + + setText(text) { + this.text && this.text.setText(text); + } + + setLevel(level) { + this.element.removeClass("tooltip-success").removeClass("tooltip-warning"); + this.element.addClass(`tooltip-${level}`); + } +} diff --git a/packages/fineui/src/base/single/trigger/trigger.js b/packages/fineui/src/base/single/trigger/trigger.js new file mode 100644 index 000000000..365858309 --- /dev/null +++ b/packages/fineui/src/base/single/trigger/trigger.js @@ -0,0 +1,24 @@ +import { Single } from "../0.single"; +import { extend } from "@/core"; + +/** + * 下拉 + * @class Trigger + * @extends Single + * @abstract + */ + +export class Trigger extends Single { + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-trigger cursor-pointer`, + height: 24, + }); + } + + setKey() {} + + getKey() {} +} diff --git a/packages/fineui/src/base/tree/customtree.js b/packages/fineui/src/base/tree/customtree.js new file mode 100644 index 000000000..491fbc96b --- /dev/null +++ b/packages/fineui/src/base/tree/customtree.js @@ -0,0 +1,182 @@ +import { ButtonTree, Expander } from "../combination"; +import { + VerticalLayout, + Widget, + shortcut, + extend, + emptyFn, + Tree, + each, + isNotEmptyArray, + deepClone, + stripEL, + isWidget, + clone, + isNotNull, + isNull, + createWidget, + Controller, + Events +} from "@/core"; + +/** + * + * 自定义树 + * + * Created by GUY on 2015/9/7. + * @class CustomTree + * @extends Single + */ + +@shortcut() +export class CustomTree extends Widget { + static xtype = "bi.custom_tree"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-custom-tree", + expander: { + el: {}, + popup: { + type: CustomTree.xtype, + }, + }, + + items: [], + itemsCreator: emptyFn, + + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }); + } + _init() { + super._init(...arguments); + this.initTree(this.options.items); + } + + _formatItems(nodes) { + const { expander, itemsCreator } = this.options; + nodes = Tree.transformToTreeFormat(nodes); + + const items = []; + each(nodes, (i, node) => { + if (isNotEmptyArray(node.children) || node.isParent === true) { + const item = extend( + { + type: Expander.xtype, + el: { + value: node.value, + }, + popup: { type: CustomTree.xtype }, + }, + deepClone(expander), + { + id: node.id, + pId: node.pId, + key: node.key, + } + ); + let el = stripEL(node); + if (!isWidget(el)) { + el = clone(el); + delete el.children; + extend(item.el, el); + } else { + item.el = el; + } + item.popup.expander = deepClone(expander); + item.items = item.popup.items = node.children; + item.itemsCreator = item.popup.itemsCreator = (op, ...arg) => { + if (isNotNull(op.node)) { + // 从子节点传过来的itemsCreator直接向上传递 + return itemsCreator(op, ...arg); + } + const args = Array.prototype.slice.call([op, ...arg], 0); + args[0].node = node; + + return itemsCreator.apply(this, args); + }; + isNull(item.popup.el) && (item.popup.el = deepClone(this.options.el)); + items.push(item); + } else { + items.push(node); + } + }); + + return items; + } + // 构造树结构, + initTree(nodes) { + const { el, itemsCreator, value } = this.options; + this.tree = createWidget(el, { + element: this, + items: this._formatItems(nodes), + itemsCreator: (op, callback) => { + itemsCreator.apply(this, [ + op, + items => { + const args = Array.prototype.slice.call(arguments, 0); + args[0] = this._formatItems(items); + callback(...args); + } + ]); + }, + value, + }); + this.tree.on(Controller.EVENT_CHANGE, (type, val, obj, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, val, obj, ...args); + if (type === Events.CLICK) { + this.fireEvent(CustomTree.EVENT_CHANGE, val, obj); + } + }); + } + + // 生成树方法 + stroke(nodes) { + this.populate(...arguments); + } + + populate(nodes) { + const args = Array.prototype.slice.call(arguments, 0); + if (arguments.length > 0) { + args[0] = this._formatItems(nodes); + } + this.tree.populate(...args); + } + + setValue(v) { + this.tree && this.tree.setValue(v); + } + + getValue() { + return this.tree ? this.tree.getValue() : []; + } + + getAllButtons() { + return this.tree ? this.tree.getAllButtons() : []; + } + + getAllLeaves() { + return this.tree ? this.tree.getAllLeaves() : []; + } + + getNodeById(id) { + return this.tree && this.tree.getNodeById(id); + } + + getNodeByValue(id) { + return this.tree && this.tree.getNodeByValue(id); + } + + empty() { + this.tree.empty(); + } +} diff --git a/packages/fineui/src/bundle.js b/packages/fineui/src/bundle.js new file mode 100644 index 000000000..a7e875954 --- /dev/null +++ b/packages/fineui/src/bundle.js @@ -0,0 +1,21 @@ +import * as fuiExport from "./index"; +import * as injectFn from "@/core/5.inject"; +import { _global } from "@/core/0.foundation"; +import {_defineVarProperties} from "@/core/constant/writable.var"; + +_global.BI = _global.BI || {}; + +// for fr, 已经有的就不对外暴露了. +// 要知道BI只有`BI.$`, 挂在全局对象上的只是为了兼容而已 +if (!_global.$ && !_global.jQuery) { + _global.jQuery = _global.$ = fuiExport.$; +} + +Object.assign(_global, { + Fix: fuiExport.Fix, + _: fuiExport._, +}); + +Object.assign(_global.BI, fuiExport, injectFn); + +_defineVarProperties(_global.BI) diff --git a/packages/fineui/src/case/button/icon/icon.change.js b/packages/fineui/src/case/button/icon/icon.change.js new file mode 100644 index 000000000..b56d7c696 --- /dev/null +++ b/packages/fineui/src/case/button/icon/icon.change.js @@ -0,0 +1,94 @@ +import { IconButton, Single } from "@/base"; +import { shortcut, extend, emptyFn, isFunction, createWidget, Controller } from "@/core"; + +/** + * 可以改变图标的button + * + * Created by GUY on 2016/2/2. + * + * @class IconChangeButton + * @extends Single + */ +@shortcut() +export class IconChangeButton extends Single { + static xtype = "bi.icon_change_button"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-icon-change-button", + iconCls: "", + iconWidth: null, + iconHeight: null, + + stopEvent: false, + stopPropagation: false, + selected: false, + once: false, // 点击一次选中有效,再点无效 + forceSelected: false, // 点击即选中, 选中了就不会被取消 + forceNotSelected: false, // 无论怎么点击都不会被选中 + disableSelected: false, // 使能选中 + + shadow: false, + isShadowShowingOnSelected: false, // 选中状态下是否显示阴影 + trigger: null, + handler: emptyFn, + }); + } + + _init() { + const o = this.options; + o.iconCls = isFunction(o.iconCls) + ? this.__watch(o.iconCls, (context, newValue) => { + this.setIcon(newValue); + }) + : o.iconCls; + super._init(...arguments); + this.button = createWidget({ + type: IconButton.xtype, + element: this, + cls: o.iconCls, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + + stopEvent: o.stopEvent, + stopPropagation: o.stopPropagation, + selected: o.selected, + once: o.once, + forceSelected: o.forceSelected, + forceNotSelected: o.forceNotSelected, + disableSelected: o.disableSelected, + + shadow: o.shadow, + isShadowShowingOnSelected: o.isShadowShowingOnSelected, + trigger: o.trigger, + handler: o.handler, + }); + + this.button.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.button.on(IconButton.EVENT_CHANGE, (...args) => { + this.fireEvent(IconChangeButton.EVENT_CHANGE, ...args); + }); + } + + isSelected() { + return this.button.isSelected(); + } + + setSelected(b) { + this.button.setSelected(b); + } + + setIcon(cls) { + const o = this.options; + if (o.iconCls !== cls) { + this.element.removeClass(o.iconCls).addClass(cls); + o.iconCls = cls; + } + } +} diff --git a/packages/fineui/src/case/button/icon/icon.trigger.js b/packages/fineui/src/case/button/icon/icon.trigger.js new file mode 100644 index 000000000..b22c54cec --- /dev/null +++ b/packages/fineui/src/case/button/icon/icon.trigger.js @@ -0,0 +1,24 @@ +import { IconButton } from "@/base"; +import { shortcut, extend } from "@/core"; + +/** + * 统一的trigger图标按钮 + * + * Created by GUY on 2015/9/16. + * @class TriggerIconButton + * @extends IconButton + */ +@shortcut() +export class TriggerIconButton extends IconButton { + static xtype = "bi.trigger_icon_button"; + static EVENT_CHANGE = IconButton.EVENT_CHANGE; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-trigger-icon-button overflow-hidden`, + extraCls: "pull-down-font", + }); + } +} diff --git a/packages/fineui/src/case/button/icon/iconhalf/icon.half.image.js b/packages/fineui/src/case/button/icon/iconhalf/icon.half.image.js new file mode 100644 index 000000000..4092a35e4 --- /dev/null +++ b/packages/fineui/src/case/button/icon/iconhalf/icon.half.image.js @@ -0,0 +1,21 @@ +import { IconButton } from "@/base"; +import { shortcut, extend } from "@/core"; + +@shortcut() +export class HalfIconButton extends IconButton { + static xtype = "bi.half_icon_button"; + static EVENT_CHANGE = IconButton.EVENT_CHANGE; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: "bi-half-icon-button check-half-select-icon", + height: 16, + width: 16, + iconWidth: 16, + iconHeight: 16, + selected: false, + }); + } +} diff --git a/packages/fineui/src/case/button/icon/iconhalf/icon.half.js b/packages/fineui/src/case/button/icon/iconhalf/icon.half.js new file mode 100644 index 000000000..057799115 --- /dev/null +++ b/packages/fineui/src/case/button/icon/iconhalf/icon.half.js @@ -0,0 +1,43 @@ +import { CenterAdaptLayout, DefaultLayout, shortcut, extend } from "@/core"; +import { BasicButton } from "@/base"; + +@shortcut() +export class HalfButton extends BasicButton { + static xtype = "bi.half_button"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + selected: false, + width: 14, + height: 14, + iconWidth: 14, + iconHeight: 14, + }); + } + + render() { + const o = this.options; + + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: DefaultLayout.xtype, + cls: "bi-half-button bi-high-light-border", + width: o.iconWidth, + height: o.iconHeight, + }, + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(HalfButton.EVENT_CHANGE); + } + } +} diff --git a/packages/fineui/src/case/button/index.js b/packages/fineui/src/case/button/index.js new file mode 100644 index 000000000..0f144f94e --- /dev/null +++ b/packages/fineui/src/case/button/index.js @@ -0,0 +1,27 @@ +export { MultiSelectItem } from "./item.multiselect"; +export { SingleSelectIconTextItem } from "./item.singleselect.icontext"; +export { SingleSelectItem } from "./item.singleselect"; +export { SingleSelectRadioItem } from "./item.singleselect.radio"; +export { Switch } from "./switch"; + +export { IconChangeButton } from "./icon/icon.change"; +export { TriggerIconButton } from "./icon/icon.trigger"; +export { HalfIconButton } from "./icon/iconhalf/icon.half.image"; +export { HalfButton } from "./icon/iconhalf/icon.half"; + +export { ArrowNode } from "./node/node.arrow"; +export { IconArrowNode } from "./node/node.icon.arrow"; +export { MultiLayerIconArrowNode } from "./node/node.multilayer.icon.arrow"; +export { PlusGroupNode } from "./node/node.plus"; +export { TreeNodeSwitcher } from "./node/siwtcher.tree.node"; +export { BasicTreeNode } from "./node/treenode"; + +export { IconTreeLeafItem } from "./treeitem/item.icon.treeleaf"; +export { MultiLayerIconTreeLeafItem } from "./treeitem/item.multilayer.icon.treeleaf"; + + +export { + BasicTreeItem, FirstTreeLeafItem, MidTreeLeafItem, LastTreeLeafItem, RootTreeLeafItem +} from "./treeitem/treeitem"; + +export * from "./node/treenode"; diff --git a/packages/fineui/src/case/button/item.multiselect.js b/packages/fineui/src/case/button/item.multiselect.js new file mode 100644 index 000000000..2d4879079 --- /dev/null +++ b/packages/fineui/src/case/button/item.multiselect.js @@ -0,0 +1,92 @@ +import { Checkbox, Label, BasicButton } from "@/base"; +import { VerticalAdaptLayout, CenterAdaptLayout, shortcut, extend, createWidget, SIZE_CONSANTS } from "@/core"; + +/** + * guy + * 复选框item + * @type {*|void|Object} + */ +@shortcut() +export class MultiSelectItem extends BasicButton { + static xtype = "bi.multi_select_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multi-select-item", + attributes: { + tabIndex: 1, + }, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + iconWrapperWidth: 26, + }); + } + + render() { + const o = this.options; + this.checkbox = createWidget({ + type: Checkbox.xtype, + }); + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + { + type: CenterAdaptLayout.xtype, + items: [this.checkbox], + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.textHgap, + rgap: o.textRgap, + lgap: o.textLgap, + vgap: o.textVgap, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + }, + } + ], + }; + } + + // _setEnable: function (enable) { + // MultiSelectItem.superclass._setEnable.apply(this, arguments); + // if (enable === true) { + // this.element.attr("tabIndex", 1); + // } else if (enable === false) { + // this.element.removeAttr("tabIndex"); + // } + // }, + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(MultiSelectItem.EVENT_CHANGE, this.getValue(), this); + } + } + + setSelected(v) { + super.setSelected(...arguments); + this.checkbox.setSelected(v); + } +} diff --git a/packages/fineui/src/case/button/item.singleselect.icontext.js b/packages/fineui/src/case/button/item.singleselect.icontext.js new file mode 100644 index 000000000..7d219725c --- /dev/null +++ b/packages/fineui/src/case/button/item.singleselect.icontext.js @@ -0,0 +1,75 @@ +import { IconTextItem, Single } from "@/base"; +import { shortcut, extend, createWidget, Controller, SIZE_CONSANTS } from "@/core"; + +/** + * Created by GUY on 2016/2/2. + * + * @class SingleSelectIconTextItem + * @extends BasicButton + */ +@shortcut() +export class SingleSelectIconTextItem extends Single { + static xtype = "bi.single_select_icon_text_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-single-select-icon-text-item bi-list-item-active", + attributes: { + tabIndex: 1, + }, + iconCls: "", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: IconTextItem.xtype, + element: this, + cls: o.iconCls, + once: o.once, + iconWrapperWidth: o.iconWrapperWidth, + selected: o.selected, + height: o.height, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + textHgap: o.textHgap, + textVgap: o.textVgap, + textLgap: o.textLgap, + textRgap: o.textRgap, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + }); + this.text.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.attr("tabIndex", 1); + } else if (enable === false) { + this.element.removeAttr("tabIndex"); + } + } + + isSelected() { + return this.text.isSelected(); + } + + setSelected(b) { + this.text.setSelected(b); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } +} diff --git a/packages/fineui/src/case/button/item.singleselect.js b/packages/fineui/src/case/button/item.singleselect.js new file mode 100644 index 000000000..d86c87531 --- /dev/null +++ b/packages/fineui/src/case/button/item.singleselect.js @@ -0,0 +1,68 @@ +import { Label, BasicButton } from "@/base"; +import { shortcut, extend, createWidget, SIZE_CONSANTS } from "@/core"; + +@shortcut() +export class SingleSelectItem extends BasicButton { + static xtype = "bi.single_select_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-single-select-item bi-list-item-active", + attributes: { + tabIndex: 1, + }, + textHgap: 10, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + textAlign: "left", + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + element: this, + textAlign: o.textAlign, + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap || o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + }); + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.attr("tabIndex", 1); + } else if (enable === false) { + this.element.removeAttr("tabIndex"); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(SingleSelectItem.EVENT_CHANGE, this.isSelected(), this); + } + } + + setSelected(v) { + super.setSelected(...arguments); + } +} diff --git a/packages/fineui/src/case/button/item.singleselect.radio.js b/packages/fineui/src/case/button/item.singleselect.radio.js new file mode 100644 index 000000000..b39996632 --- /dev/null +++ b/packages/fineui/src/case/button/item.singleselect.radio.js @@ -0,0 +1,98 @@ +import { VerticalAdaptLayout, CenterAdaptLayout, shortcut, extend, SIZE_CONSANTS } from "@/core"; +import { Radio, Label, BasicButton } from "@/base"; + +/** + * guy + * 单选框item + * @type {*|void|Object} + */ +@shortcut() +export class SingleSelectRadioItem extends BasicButton { + static xtype = "bi.single_select_radio_item"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-single-select-radio-item", + attributes: { + tabIndex: 1, + }, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + iconWrapperWidth: 16, + textHgap: 10, + }); + } + + render() { + const o = this.options; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + { + type: CenterAdaptLayout.xtype, + items: [ + { + type: Radio.xtype, + once: o.once, + ref: _ref => { + this.radio = _ref; + }, + } + ], + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: "list-item-text", + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap || o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + }, + } + ], + }; + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.attr("tabIndex", 1); + } else if (enable === false) { + this.element.removeAttr("tabIndex"); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(SingleSelectRadioItem.EVENT_CHANGE, this.isSelected(), this); + } + } + + setSelected(v) { + super.setSelected(...arguments); + this.radio.setSelected(v); + } +} diff --git a/src/case/button/node/__test__/node.arrow.test.js b/packages/fineui/src/case/button/node/__test__/node.arrow.test.js similarity index 100% rename from src/case/button/node/__test__/node.arrow.test.js rename to packages/fineui/src/case/button/node/__test__/node.arrow.test.js diff --git a/src/case/button/node/__test__/node.first.plus.test.js b/packages/fineui/src/case/button/node/__test__/node.first.plus.test.js similarity index 100% rename from src/case/button/node/__test__/node.first.plus.test.js rename to packages/fineui/src/case/button/node/__test__/node.first.plus.test.js diff --git a/src/case/button/node/__test__/node.icon.arrow.test.js b/packages/fineui/src/case/button/node/__test__/node.icon.arrow.test.js similarity index 100% rename from src/case/button/node/__test__/node.icon.arrow.test.js rename to packages/fineui/src/case/button/node/__test__/node.icon.arrow.test.js diff --git a/src/case/button/node/__test__/node.last.plus.test.js b/packages/fineui/src/case/button/node/__test__/node.last.plus.test.js similarity index 100% rename from src/case/button/node/__test__/node.last.plus.test.js rename to packages/fineui/src/case/button/node/__test__/node.last.plus.test.js diff --git a/src/case/button/node/__test__/node.mid.plus.test.js b/packages/fineui/src/case/button/node/__test__/node.mid.plus.test.js similarity index 100% rename from src/case/button/node/__test__/node.mid.plus.test.js rename to packages/fineui/src/case/button/node/__test__/node.mid.plus.test.js diff --git a/src/case/button/node/__test__/node.multilayer.icon.arrow.test.js b/packages/fineui/src/case/button/node/__test__/node.multilayer.icon.arrow.test.js similarity index 100% rename from src/case/button/node/__test__/node.multilayer.icon.arrow.test.js rename to packages/fineui/src/case/button/node/__test__/node.multilayer.icon.arrow.test.js diff --git a/src/case/button/node/__test__/node.plus.test.js b/packages/fineui/src/case/button/node/__test__/node.plus.test.js similarity index 100% rename from src/case/button/node/__test__/node.plus.test.js rename to packages/fineui/src/case/button/node/__test__/node.plus.test.js diff --git a/packages/fineui/src/case/button/node/node.arrow.js b/packages/fineui/src/case/button/node/node.arrow.js new file mode 100644 index 000000000..7d1d0118b --- /dev/null +++ b/packages/fineui/src/case/button/node/node.arrow.js @@ -0,0 +1,84 @@ +import { ArrowTreeGroupNodeCheckbox } from "../../checkbox"; +import { VerticalAdaptLayout, shortcut, extend, createWidget } from "@/core"; +import { Label, NodeButton } from "@/base"; + +/** + * Created by roy on 15/10/16. + */ +@shortcut() +export class ArrowNode extends NodeButton { + static xtype = "bi.arrow_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-arrow-group-node bi-list-item`, + id: "", + pId: "", + open: false, + height: 24, + iconWrapperWidth: 16, + }); + } + + render() { + const o = this.options; + this.checkbox = createWidget({ + type: ArrowTreeGroupNodeCheckbox.xtype, + expandIcon: o.expandIcon, + collapseIcon: o.collapseIcon, + }); + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + this.checkbox, + { + el: { + type: Label.xtype, + ref: (_ref) => { + this.text = _ref; + }, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap || o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + }, + }, + ], + }; + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + this.checkbox.setSelected(this.isOpened()); + } + + setText(text) { + super.setText(...arguments); + this.text.setText(text); + } + + setOpened(v) { + super.setOpened(...arguments); + this.checkbox.setSelected(v); + } +} diff --git a/packages/fineui/src/case/button/node/node.icon.arrow.js b/packages/fineui/src/case/button/node/node.icon.arrow.js new file mode 100644 index 000000000..b9d8d9bea --- /dev/null +++ b/packages/fineui/src/case/button/node/node.icon.arrow.js @@ -0,0 +1,136 @@ +import { ArrowTreeGroupNodeCheckbox } from "../../checkbox"; +import { IconLabel, Label, NodeButton } from "@/base"; +import { shortcut, extend, createWidget, Controller, isNotNull, Events, LogicFactory, Direction } from "@/core"; + +/** + * Created by User on 2016/3/31. + * + * > + icon + 文本 + * @class IconArrowNode + * @extends NodeButton + */ +@shortcut() +export class IconArrowNode extends NodeButton { + static xtype = "bi.icon_arrow_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-icon-arrow-node bi-list-item`, + logic: { + dynamic: false, + }, + id: "", + pId: "", + open: false, + height: 24, + iconHeight: 12, + iconWidth: 12, + iconCls: "", + iconWrapperWidth: 16, + }); + } + + _init() { + super._init.apply(this, arguments); + const o = this.options; + this.checkbox = createWidget({ + type: ArrowTreeGroupNodeCheckbox.xtype, + expandIcon: o.expandIcon, + collapseIcon: o.collapseIcon, + width: 24, + stopPropagation: true, + }); + + const icon = createWidget({ + type: IconLabel.xtype, + width: 24, + cls: o.iconCls, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }); + + this.text = createWidget({ + type: "bi.label", + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword + }); + + createWidget({ + type: Label.xtype, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + }); + this.checkbox.on(Controller.EVENT_CHANGE, type => { + if (type === Events.CLICK) { + if (this.checkbox.isSelected()) { + this.triggerExpand(); + } else { + this.triggerCollapse(); + } + } + }); + const type = LogicFactory.createLogicTypeByDirection(Direction.Left); + const items = LogicFactory.createLogicItemsByDirection( + Direction.Left, + { + width: o.iconWrapperWidth, + el: this.checkbox, + }, + { + width: 16, + el: icon, + }, + this.text + ); + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + type, + extend(o.logic, { + items, + rgap: 5, + }) + ) + ) + ); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + this.checkbox.setSelected(this.isSelected()); + } + + setOpened(v) { + super.setOpened(...arguments); + if (isNotNull(this.checkbox)) { + this.checkbox.setSelected(v); + } + } +} diff --git a/packages/fineui/src/case/button/node/node.multilayer.icon.arrow.js b/packages/fineui/src/case/button/node/node.multilayer.icon.arrow.js new file mode 100644 index 000000000..fb4554741 --- /dev/null +++ b/packages/fineui/src/case/button/node/node.multilayer.icon.arrow.js @@ -0,0 +1,96 @@ +import { IconArrowNode } from "./node.icon.arrow"; +import { Layout, HorizontalAdaptLayout, shortcut, extend, createWidget, Controller, count, makeArray } from "@/core"; +import { NodeButton } from "@/base"; + +@shortcut() +export class MultiLayerIconArrowNode extends NodeButton { + static xtype = "bi.multilayer_icon_arrow_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: "bi-multilayer-icon-arrow-node bi-list-item", + layer: 0, // 第几层级 + id: "", + pId: "", + open: false, + height: 24, + iconHeight: 16, + iconWidth: 16, + iconCls: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.node = createWidget({ + type: IconArrowNode.xtype, + iconCls: o.iconCls, + cls: "bi-list-item-none", + id: o.id, + pId: o.pId, + open: o.open, + height: o.height, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + hgap: o.hgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + }); + this.node.on(Controller.EVENT_CHANGE, (...args) => { + this.setSelected(this.isSelected()); + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + const items = []; + count(0, o.layer, () => { + items.push({ + type: Layout.xtype, + width: 15, + height: o.height, + }); + }); + items.push(this.node); + createWidget({ + type: HorizontalAdaptLayout.xtype, + element: this, + columnSize: makeArray(o.layer, 15), + items, + }); + } + + isOnce() { + return true; + } + + doRedMark() { + this.node.doRedMark(...arguments); + } + + unRedMark() { + this.node.unRedMark(...arguments); + } + + isSelected() { + return this.node.isSelected(); + } + + setSelected(b) { + super.setSelected(...arguments); + this.node.setSelected(b); + } + + doClick() { + super.doClick(...arguments); + this.node.setSelected(this.isSelected()); + } + + setOpened(v) { + super.setOpened(...arguments); + this.node.setOpened(v); + } +} diff --git a/packages/fineui/src/case/button/node/node.plus.js b/packages/fineui/src/case/button/node/node.plus.js new file mode 100644 index 000000000..d39bebe73 --- /dev/null +++ b/packages/fineui/src/case/button/node/node.plus.js @@ -0,0 +1,90 @@ +import { TreeNodeCheckbox } from "../../checkbox"; +import { VerticalAdaptLayout, shortcut, extend, createWidget, Controller, Events } from "@/core"; +import { Label, NodeButton } from "@/base"; + +/** + * 加号表示的组节点 + * Created by GUY on 2015/9/6. + * @class PlusGroupNode + * @extends NodeButton + */ +@shortcut() +export class PlusGroupNode extends NodeButton { + static xtype = "bi.plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-plus-group-node bi-list-item`, + id: "", + pId: "", + open: false, + height: 24, + }); + } + + render() { + const o = this.options; + this.checkbox = createWidget({ + type: TreeNodeCheckbox.xtype, + iconHeight: o.height, + iconWidth: o.iconWrapperWidth || o.height, + }); + this.checkbox.on(Controller.EVENT_CHANGE, (...args) => { + const [type] = args; + if (type === Events.CLICK) { + this.setSelected(this.isSelected()); + } + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + return { + type: VerticalAdaptLayout.xtype, + columnSize: [o.iconWrapperWidth || o.height, "fill"], + items: [ + this.checkbox, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap || o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + py: o.py, + }, + } + ], + }; + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + super.doClick(...arguments); + this.checkbox.setSelected(this.isSelected()); + } + + setOpened(v) { + super.setOpened(...arguments); + if (this.checkbox) { + this.checkbox.setSelected(v); + } + } +} diff --git a/packages/fineui/src/case/button/node/siwtcher.tree.node.js b/packages/fineui/src/case/button/node/siwtcher.tree.node.js new file mode 100644 index 000000000..b0a8d8dae --- /dev/null +++ b/packages/fineui/src/case/button/node/siwtcher.tree.node.js @@ -0,0 +1,70 @@ +import { IconLabel, NodeButton } from "@/base"; +import { shortcut, extend, STYLE_CONSTANTS } from "@/core"; + +@shortcut() +export class TreeNodeSwitcher extends NodeButton { + static xtype = "bi.tree_node_switcher"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-tree-node-switcher", + iconWidth: 24, + iconHeight: 24, + isFirstNode: false, + isLastNode: false, + layer: 0, + }); + } + + render() { + const [collapse, expand] = this.getIconCls(); + + return { + type: IconLabel.xtype, + iconWidth: this.options.iconWidth, + iconHeight: this.options.iconHeight, + cls: this.options.open ? expand : collapse, + }; + } + + getIconCls() { + const options = this.options; + if (options.layer === 0 && options.isFirstNode && options.isLastNode) { + // 只有一层,并且是第一个节点,并且是最后一个节点 + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] + : ["tree-collapse-icon-type1", "tree-expand-icon-type1"]; + } else if (options.layer === 0 && options.isFirstNode) { + // 第一层,并且是第一个节点 + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] + : ["tree-collapse-icon-type2", "tree-expand-icon-type2"]; + } else if (options.isLastNode) { + // 最后一个节点 + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] + : ["tree-collapse-icon-type4", "tree-expand-icon-type4"]; + } else { + // 其他情况 + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] + : ["tree-collapse-icon-type3", "tree-expand-icon-type3"]; + } + } + + setOpened(b) { + super.setOpened(...arguments); + const [collapse, expand] = this.getIconCls(); + if (b) { + this.element.addClass(expand).removeClass(collapse); + } else { + this.element.addClass(collapse).removeClass(expand); + } + } + + doClick() { + super.doClick(...arguments); + this.fireEvent(TreeNodeSwitcher.EVENT_CHANGE, this); + } +} diff --git a/packages/fineui/src/case/button/node/treenode.js b/packages/fineui/src/case/button/node/treenode.js new file mode 100644 index 000000000..0a3e64fd9 --- /dev/null +++ b/packages/fineui/src/case/button/node/treenode.js @@ -0,0 +1,340 @@ +import { IconLabel, Label, NodeButton } from "@/base"; +import { shortcut, extend, VerticalAdaptLayout, isKey, compact, SIZE_CONSANTS } from "@/core"; +import { TreeNodeSwitcher } from "@/case"; + +@shortcut() +export class BasicTreeNode extends NodeButton { + static xtype = "bi.tree_node"; + + _defaultConfig(props) { + const conf = super._defaultConfig.apply(this, arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-tree-node ${props.selectable ? "bi-list-item-active" : "bi-list-item"}`, + id: "", + pId: "", + open: false, + height: 24, + readonly: true, + isFirstNode: false, + isLastNode: false, + switcherIcon: {}, + selectable: true, + disabled: false // disabled不会影响展开收起功能 + }); + } + + render() { + const { + open, + layer, + height, + hgap, + textHgap, + textVgap, + textLgap, + textRgap, + text, + value, + isFirstNode, + isLastNode, + keyword, + iconWrapperWidth, + iconCls, + switcherIcon, + selectable + } = this.options; + + const checkbox = { + type: TreeNodeSwitcher.xtype, + ref: _ref => { + this.switcher = _ref; + }, + iconHeight: height, + iconWidth: iconWrapperWidth || height, + open, + isFirstNode, + isLastNode, + layer, + ...switcherIcon, + stopPropagation: selectable, + mounted() { + this.setEnable(true); + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + if (!this.isEnabled() || selectable) { + this.isOpened() ? this.triggerCollapse() : this.triggerExpand(); + } + } + } + ] + }; + + // const indent = { + // el: { + // type: Layout.xtype, + // height, + // width: height, + // cls: this.getLineCls(), + // }, + // lgap: layer * SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, // 偏移公式为每一层的偏移量为节点高度的一半 + // width: "", + // }; + + + const icon = isKey(iconCls) ? { + el: { + type: IconLabel.xtype, + // iconWidth, + // iconHeight, + cls: iconCls + } + // width: 24, + } : null; + + + return { + type: VerticalAdaptLayout.xtype, + items: compact([ + { + el: checkbox, + lgap: layer * SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, // 偏移公式为每一层的偏移量为节点高度的一半 + width: iconWrapperWidth || height + }, + icon, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: height, + height, + hgap: hgap || textHgap, + vgap: textVgap, + lgap: textLgap, + rgap: textRgap, + text, + value, + keyword + }, + width: "fill" + } + ]) + }; + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doClick() { + if (this.options.selectable) { + return; + } + super.doClick(...arguments); + } + + setOpened(v) { + super.setOpened(...arguments); + this.switcher.setOpened(v); + } + + setValue() { + super.setValue(...arguments); + } +} + + +/** + * 下面的全是兼容,正常开发不要用 + */ + +/** + * @deprecated + */ +@shortcut() +export class FirstPlusGroupNode extends BasicTreeNode { + static xtype = "bi.first_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-first-plus-group-node`, + isFirstNode: true, + isLastNode: false + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MidPlusGroupNode extends BasicTreeNode { + static xtype = "bi.mid_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-mid-plus-group-node`, + isFirstNode: false, + isLastNode: false + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class LastPlusGroupNode extends BasicTreeNode { + static xtype = "bi.last_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-last-plus-group-node`, + isFirstNode: false, + isLastNode: true + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class SelectTreeRootPlusGroupNode extends BasicTreeNode { + static xtype = "bi.select_tree_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-select-tree-plus-group-node`, + isFirstNode: true, + isLastNode: true + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class SelectTreeFirstPlusGroupNode extends BasicTreeNode { + static xtype = "bi.select_tree_first_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-select-tree-first-plus-group-node`, + isFirstNode: true, + isLastNode: false + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class SelectTreeMidPlusGroupNode extends BasicTreeNode { + static xtype = "bi.select_tree_mid_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-select-tree-mid-plus-group-node`, + isFirstNode: false, + isLastNode: false + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class SelectTreeLastPlusGroupNode extends BasicTreeNode { + static xtype = "bi.select_tree_last_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-select-tree-last-plus-group-node`, + isFirstNode: false, + isLastNode: true + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeFirstPlusGroupNode extends BasicTreeNode { + static xtype = "bi.multilayer_single_tree_first_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-multilayer-single-tree-last-plus-group-node`, + isFirstNode: true, + isLastNode: false + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeLastPlusGroupNode extends BasicTreeNode { + static xtype = "bi.multilayer_single_tree_last_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-multilayer-single-tree-last-plus-group-node`, + isFirstNode: false, + isLastNode: true + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeMidPlusGroupNode extends BasicTreeNode { + static xtype = "bi.multilayer_single_tree_mid_plus_group_node"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-multilayer-single-tree-mid-plus-group-node`, + isFirstNode: false, + isLastNode: false + }); + } +} diff --git a/packages/fineui/src/case/button/switch.js b/packages/fineui/src/case/button/switch.js new file mode 100644 index 000000000..68a5c556a --- /dev/null +++ b/packages/fineui/src/case/button/switch.js @@ -0,0 +1,91 @@ +import { AbsoluteLayout, shortcut, i18nText } from "@/core"; +import { TextButton, Label, BasicButton } from "@/base"; + +@shortcut() +export class Switch extends BasicButton { + static xtype = "bi.switch"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + constants = { + CIRCLE_SIZE: 12, + }; + + props = { + extraCls: "bi-switch", + attributes: { + tabIndex: 1, + }, + height: 20, + width: 44, + showTip: false, + }; + + render() { + const o = this.options, + c = this.constants; + const tgap = (o.height - c.CIRCLE_SIZE) / 2; + + return { + type: AbsoluteLayout.xtype, + ref: _ref => { + this.layout = _ref; + }, + items: [ + { + el: { + type: TextButton.xtype, + cls: "circle-button", + }, + width: 12, + height: 12, + top: tgap, + left: o.selected ? 28 : 4, + }, + { + type: Label.xtype, + text: i18nText("BI-Basic_Simple_Open"), + cls: "content-tip", + left: 8, + top: tgap - 2, + invisible: !(o.showTip && o.selected), + ref: _ref => { + this.openTip = _ref; + }, + }, + { + type: Label.xtype, + text: i18nText("BI-Basic_Simple_Close"), + cls: "content-tip", + right: 8, + top: tgap - 2, + invisible: !(o.showTip && !o.selected), + ref: _ref => { + this.closeTip = _ref; + }, + } + ], + }; + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.attr("tabIndex", 1); + } else if (enable === false) { + this.element.removeAttr("tabIndex"); + } + } + + setSelected(v) { + super.setSelected(...arguments); + this.layout.attr("items")[0].left = v ? 28 : 4; + this.layout.resize(); + this.options.showTip && this.openTip.setVisible(v); + this.options.showTip && this.closeTip.setVisible(!v); + } + + doClick() { + super.doClick(...arguments); + this.fireEvent(Switch.EVENT_CHANGE, this.isSelected()); + } +} diff --git a/src/case/button/treeitem/__test__/item.treeleaf.test.js b/packages/fineui/src/case/button/treeitem/__test__/item.treeleaf.test.js similarity index 100% rename from src/case/button/treeitem/__test__/item.treeleaf.test.js rename to packages/fineui/src/case/button/treeitem/__test__/item.treeleaf.test.js diff --git a/packages/fineui/src/case/button/treeitem/item.icon.treeleaf.js b/packages/fineui/src/case/button/treeitem/item.icon.treeleaf.js new file mode 100644 index 000000000..186dacd2d --- /dev/null +++ b/packages/fineui/src/case/button/treeitem/item.icon.treeleaf.js @@ -0,0 +1,100 @@ +import { CenterAdaptLayout, shortcut, extend, createWidget, LogicFactory, Direction } from "@/core"; +import { Icon, Label, BasicButton } from "@/base"; + +@shortcut() +export class IconTreeLeafItem extends BasicButton { + static xtype = "bi.icon_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-icon-tree-leaf-item bi-list-item-active", + logic: { + dynamic: false, + }, + height: 24, + iconWidth: 16, + iconHeight: 16, + iconCls: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + const icon = createWidget({ + type: CenterAdaptLayout.xtype, + width: 24, + cls: o.iconCls, + items: [ + { + type: Icon.xtype, + width: o.iconWidth, + height: o.iconHeight, + } + ], + }); + + this.text = createWidget({ + type: Label.xtype, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + }); + const type = LogicFactory.createLogicTypeByDirection(Direction.Left); + const items = LogicFactory.createLogicItemsByDirection( + Direction.Left, + { + width: 16, + el: icon, + }, + { + el: this.text, + } + ); + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + type, + extend(o.logic, { + items, + hgap: 5, + }) + ) + ) + ); + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + getId() { + return this.options.id; + } + + getPId() { + return this.options.pId; + } +} diff --git a/packages/fineui/src/case/button/treeitem/item.multilayer.icon.treeleaf.js b/packages/fineui/src/case/button/treeitem/item.multilayer.icon.treeleaf.js new file mode 100644 index 000000000..cd2eb820d --- /dev/null +++ b/packages/fineui/src/case/button/treeitem/item.multilayer.icon.treeleaf.js @@ -0,0 +1,102 @@ +import { IconTreeLeafItem } from "./item.icon.treeleaf"; +import { Layout, HorizontalAdaptLayout, shortcut, extend, createWidget, Controller, makeArray, count, Events } from "@/core"; +import { BasicButton } from "@/base"; + +@shortcut() +export class MultiLayerIconTreeLeafItem extends BasicButton { + static xtype = "bi.multilayer_icon_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multilayer-icon-tree-leaf-item bi-list-item-active", + layer: 0, + height: 24, + iconCls: "", + iconHeight: 16, + iconWidth: 16, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.item = createWidget({ + type: IconTreeLeafItem.xtype, + cls: "bi-list-item-none", + iconCls: o.iconCls, + id: o.id, + pId: o.pId, + isFront: true, + height: o.height, + hgap: o.hgap, + text: o.text, + value: o.value, + py: o.py, + keyword: o.keyword, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }); + this.item.on(Controller.EVENT_CHANGE, (...args) => { + const [type] = args; + if (type === Events.CLICK) { + // 本身实现click功能 + return; + } + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + const items = []; + count(0, o.layer, () => { + items.push({ + type: Layout.xtype, + width: 15, + height: o.height, + }); + }); + items.push(this.item); + createWidget({ + type: HorizontalAdaptLayout.xtype, + element: this, + columnSize: makeArray(o.layer, 15), + items, + }); + } + + doRedMark() { + this.item.doRedMark(...arguments); + } + + unRedMark() { + this.item.unRedMark(...arguments); + } + + doHighLight() { + this.item.doHighLight(...arguments); + } + + unHighLight() { + this.item.unHighLight(...arguments); + } + + getId() { + return this.options.id; + } + + getPId() { + return this.options.pId; + } + + doClick() { + super.doClick(...arguments); + this.item.setSelected(this.isSelected()); + } + + setSelected(v) { + super.setSelected(...arguments); + this.item.setSelected(v); + } + + getValue() { + return this.options.value; + } +} diff --git a/packages/fineui/src/case/button/treeitem/treeitem.js b/packages/fineui/src/case/button/treeitem/treeitem.js new file mode 100644 index 000000000..722694d34 --- /dev/null +++ b/packages/fineui/src/case/button/treeitem/treeitem.js @@ -0,0 +1,235 @@ +import { shortcut, extend, VerticalAdaptLayout, Layout, compact, isKey, SIZE_CONSANTS, STYLE_CONSTANTS } from "@/core"; +import { NodeButton, Label, IconLabel } from "@/base"; + +@shortcut() +export class BasicTreeItem extends NodeButton { + static xtype = "bi.tree_item"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-tree-item bi-list-item-active`, + id: "", + pId: "", + height: 24, + readonly: true, + isFirstNode: false, + isLastNode: false, + layer: 0, + iconWidth: null, + iconHeight: null, + iconCls: "", + }); + } + + render() { + const { + layer, + height, + hgap, + textHgap, + textVgap, + textLgap, + textRgap, + text, + value, + py, + keyword, + iconCls, + } = this.options; + + const indent = { + el: { + type: Layout.xtype, + height, + width: height, + cls: this.getLineCls(), + }, + lgap: layer * SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, // 偏移公式为每一层的偏移量为节点高度的一半 + width: "", + }; + + + const icon = isKey(iconCls) ? { + el: { + type: IconLabel.xtype, + // iconWidth, + // iconHeight, + cls: iconCls, + }, + // width: 24, + } : null; + + return { + type: VerticalAdaptLayout.xtype, + items: compact([ + indent, + icon, + { + el: { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: height, + height, + hgap: hgap || textHgap, + vgap: textVgap, + lgap: textLgap, + rgap: textRgap, + text, + value, + keyword, + py, + }, + width: "fill", + } + ]), + }; + } + + getLineCls() { + const options = this.options; + if (options.layer === 0 && options.isFirstNode && options.isLastNode) { + return ""; + } else if (options.layer === 0 && options.isFirstNode) { + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-first-solid-line-conn-background" : "first-line-conn-background"; + } else if (options.isLastNode) { + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-last-solid-line-conn-background" : "last-line-conn-background"; + } else { + return STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-mid-solid-line-conn-background" : "mid-line-conn-background"; + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + getId() { + return this.options.id; + } + + getPId() { + return this.options.pId; + } +} + + +/** + * 下面的全是兼容,正常开发不要用 + */ + +export class FirstTreeLeafItem extends BasicTreeItem { + static xtype = "bi.first_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-first-tree-leaf-item", + isFirstNode: true, + isLastNode: false, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MidTreeLeafItem extends BasicTreeItem { + static xtype = "bi.mid_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-mid-tree-leaf-item", + isFirstNode: false, + isLastNode: false, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class LastTreeLeafItem extends BasicTreeItem { + static xtype = "bi.last_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-last-tree-leaf-item", + isFirstNode: false, + isLastNode: true, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class RootTreeLeafItem extends BasicTreeItem { + static xtype = "bi.root_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-root-tree-leaf-item", + isFirstNode: false, + isLastNode: false, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeFirstTreeLeafItem extends BasicTreeItem { + static xtype = "bi.multilayer_single_tree_first_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multilayer-single-tree-first-tree-leaf-item", + isFirstNode: true, + isLastNode: false, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeLastTreeLeafItem extends BasicTreeItem { + static xtype = "bi.multilayer_single_tree_last_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multilayer-single-tree-last-tree-leaf-item", + isFirstNode: false, + isLastNode: true, + }); + } +} + +/** + * @deprecated + */ +@shortcut() +export class MultiLayerSingleTreeMidTreeLeafItem extends BasicTreeItem { + static xtype = "bi.multilayer_single_tree_mid_tree_leaf_item"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multilayer-single-tree-mid-tree-leaf-item", + isFirstNode: false, + isLastNode: false, + }); + } +} diff --git a/packages/fineui/src/case/calendar/calendar.date.item.js b/packages/fineui/src/case/calendar/calendar.date.item.js new file mode 100644 index 000000000..15244f315 --- /dev/null +++ b/packages/fineui/src/case/calendar/calendar.date.item.js @@ -0,0 +1,66 @@ +import { AbsoluteLayout, shortcut, SIZE_CONSANTS } from "@/core"; +import { TextItem, BasicButton } from "@/base"; + +/** + * 专门为calendar的视觉加的button,作为私有button,不能配置任何属性,也不要用这个玩意 + */ +@shortcut() +export class CalendarDateItem extends BasicButton { + props() { + return { + baseCls: "bi-calendar-date-item", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 8, + }; + } + + static xtype = "bi.calendar_date_item"; + + render() { + const { text, value, lgap, rgap, tgap, bgap } = this.options; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: TextItem.xtype, + cls: "bi-border-radius bi-list-item-select", + textAlign: "center", + text, + value, + ref: _ref => { + this.text = _ref; + }, + }, + left: lgap, + right: rgap, + top: tgap, + bottom: bgap, + } + ], + }; + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + setSelected(b) { + super.setSelected(...arguments); + this.text.setSelected(b); + } + + getValue() { + return this.text.getValue(); + } +} diff --git a/packages/fineui/src/case/calendar/calendar.js b/packages/fineui/src/case/calendar/calendar.js new file mode 100644 index 000000000..0821dc2b3 --- /dev/null +++ b/packages/fineui/src/case/calendar/calendar.js @@ -0,0 +1,301 @@ +import { Label, ButtonGroup } from "@/base"; +import { + CenterLayout, + shortcut, + Widget, + getDate, + each, + range, + extend, + isLeapYear, + Date, + StartOfWeek, + checkDateVoid, + map, + createWidget, + createItems, + LogicFactory, + Controller, + getShortDayName, + getOffsetDate, + isNotEmptyString, + parseInt, + SIZE_CONSANTS +} from "@/core"; +import { CalendarDateItem } from "./calendar.date.item"; + +/** + * Created by GUY on 2015/8/28. + * @class Calendar + * @extends Widget + */ +@shortcut() +export class Calendar extends Widget { + static xtype = "bi.calendar"; + + static getPageByDateJSON(json) { + const year = getDate().getFullYear(); + const month = getDate().getMonth(); + let page = (json.year - year) * 12; + page += json.month - 1 - month; + + return page; + } + + static getDateJSONByPage(v) { + const months = getDate().getMonth(); + let page = v; + + // 对当前page做偏移,使到当前年初 + page = page + months; + + let year = parseInt(page / 12); + if (page < 0 && page % 12 !== 0) { + year--; + } + const month = page >= 0 ? page % 12 : (12 + (page % 12)) % 12; + + return { + year: getDate().getFullYear() + year, + month: month + 1, + }; + } + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-calendar", + logic: { + dynamic: false, + }, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + year: 2015, + month: 8, + day: 25, + }); + } + _dateCreator(Y, M, D) { + const { min, max } = this.options, + log = {}, + De = getDate(); + const mins = min.match(/\d+/g); + const maxs = max.match(/\d+/g); + + De.setFullYear(Y, M, D); + log.ymd = [De.getFullYear(), De.getMonth(), De.getDate()]; + + const MD = Date._MD.slice(0); + MD[1] = isLeapYear(log.ymd[0]) ? 29 : 28; + + // 日期所在月第一天 + De.setFullYear(log.ymd[0], log.ymd[1], 1); + // 是周几 + log.FDay = De.getDay(); + + // 当前BI.StartOfWeek与周日对齐后的FDay是周几 + const offSetFDay = (7 - StartOfWeek + log.FDay) % 7; + + // 当前月页第一天是几号 + log.PDay = MD[M === 0 ? 11 : M - 1] - offSetFDay + 1; + log.NDay = 1; + + const items = []; + each(range(42), i => { + const td = {}; + let YY = log.ymd[0], + MM = log.ymd[1] + 1, + DD; + // 上个月的日期 + if (i < offSetFDay) { + td.lastMonth = true; + DD = i + log.PDay; + // 上一年 + MM === 1 && (YY -= 1); + MM = MM === 1 ? 12 : MM - 1; + } else if (i >= offSetFDay && i < offSetFDay + MD[log.ymd[1]]) { + DD = i - offSetFDay + 1; + if (i - offSetFDay + 1 === log.ymd[2]) { + td.currentDay = true; + } + } else { + td.nextMonth = true; + DD = log.NDay++; + MM === 12 && (YY += 1); + MM = MM === 12 ? 1 : MM + 1; + } + if (checkDateVoid(YY, MM, DD, mins, maxs)[0]) { + td.disabled = true; + } + td.text = DD; + items.push(td); + }); + + return items; + } + + _init() { + super._init(...arguments); + const { year, month, day, logic } = this.options; + const items = map(this._getWeekLabel(), (i, value) => { + return { + type: Label.xtype, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + text: value, + }; + }); + const title = createWidget({ + type: ButtonGroup.xtype, + height: 44, + items, + layouts: [ + { + type: CenterLayout.xtype, + hgap: 5, + vgap: 10, + } + ], + }); + + this.days = createWidget({ + type: ButtonGroup.xtype, + items: createItems(this._getItems(), {}), + value: `${year}-${month}-${day}`, + layouts: [ + LogicFactory.createLogic( + "table", + extend({}, logic, { + columns: 7, + rows: 6, + columnSize: [1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7], + rowSize: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 8, + }) + ) + ], + }); + this.days.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + "vertical", + extend({}, logic, { + items: LogicFactory.createLogicItemsByDirection("top", title, { + el: this.days, + tgap: -5, + }), + }) + ) + ) + ); + } + + _getWeekLabel() { + return map(range(0, 7), (idx, v) => getShortDayName((v + StartOfWeek) % 7)); + } + + isFrontDate() { + const { year, month, min, max } = this.options; + let Y = year; + const M = month, + De = getDate(), + day = De.getDay(); + Y = Y | 0; + De.setFullYear(Y, M, 1); + const newDate = getOffsetDate(De, -1 * (day + 1)); + + return !!checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), min, max)[0]; + } + + isFinalDate() { + const { year, month, min, max } = this.options; + let Y = year; + const M = month, + De = getDate(), + day = De.getDay(); + Y = Y | 0; + De.setFullYear(Y, M, 1); + const newDate = getOffsetDate(De, 42 - day); + + return !!checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), min, max)[0]; + } + + _getItems() { + const o = this.options; + const days = this._dateCreator(o.year, o.month - 1, o.day); + const items = []; + items.push(days.slice(0, 7)); + items.push(days.slice(7, 14)); + items.push(days.slice(14, 21)); + items.push(days.slice(21, 28)); + items.push(days.slice(28, 35)); + items.push(days.slice(35, 42)); + + return map(items, (i, item) => + map(item, (j, td) => { + let month = td.lastMonth ? o.month - 1 : td.nextMonth ? o.month + 1 : o.month; + let year = o.year; + if (month > 12) { + month = 1; + year++; + } else if (month < 1) { + month = 12; + year--; + } + + return extend(td, { + type: CalendarDateItem.xtype, + once: false, + forceSelected: true, + value: `${year}-${month}-${td.text}`, + disabled: td.disabled, + cls: td.lastMonth || td.nextMonth ? "bi-tips" : "", + lgap: 2, + rgap: 2, + tgap: 4, + bgap: 4, + // selected: td.currentDay + }); + }) + ); + } + + _populate() { + this.days.populate(this._getItems()); + } + + setMinDate(minDate) { + const o = this.options; + if (isNotEmptyString(o.min)) { + o.min = minDate; + this._populate(); + } + } + + setMaxDate(maxDate) { + const o = this.options; + if (isNotEmptyString(o.max)) { + o.max = maxDate; + this._populate(); + } + } + + setValue(ob) { + this.days.setValue([`${ob.year}-${ob.month}-${ob.day}`]); + } + + getValue() { + const date = this.days.getValue()[0].match(/\d+/g); + + return { + year: date[0] | 0, + month: date[1] | 0, + day: date[2] | 0, + }; + } +} diff --git a/packages/fineui/src/case/calendar/calendar.year.js b/packages/fineui/src/case/calendar/calendar.year.js new file mode 100644 index 000000000..7da473113 --- /dev/null +++ b/packages/fineui/src/case/calendar/calendar.year.js @@ -0,0 +1,220 @@ +import { ButtonGroup, TextItem } from "@/base"; +import { + CenterAdaptLayout, + shortcut, + Widget, + extend, + parseDateTime, + range, + checkDateVoid, + print, + getDate, + each, + createWidget, + createItems, + LogicFactory, + Controller, + makeArray, + map, + isNotEmptyString, + SIZE_CONSANTS +} from "@/core"; + +/** + * Created by GUY on 2015/8/28. + * @class YearCalendar + * @extends Widget + */ +@shortcut() +export class YearCalendar extends Widget { + static xtype = "bi.year_calendar"; + static INTERVAL = 12; + + // 获取显示的第一年 + static getStartYear(year) { + const cur = getDate().getFullYear(); + + return year - ((((year - cur + 3) % YearCalendar.INTERVAL) + 12) % YearCalendar.INTERVAL); + } + + static getEndYear(year) { + return YearCalendar.getStartYear(year) + YearCalendar.INTERVAL - 1; + } + + static getPageByYear(year) { + const cur = getDate().getFullYear(); + year = YearCalendar.getStartYear(year); + + return (year - cur + 3) / YearCalendar.INTERVAL; + } + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-year-calendar", + behaviors: {}, + logic: { + dynamic: false, + }, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + year: null, + }); + } + + _yearCreator(Y) { + const { min, max } = this.options; + Y = Y | 0; + const start = YearCalendar.getStartYear(Y); + const items = []; + // 对于年控件来说,只要传入的minDate和maxDate的year区间包含v就是合法的 + const startDate = parseDateTime(min, "%Y-%X-%d"); + const endDate = parseDateTime(max, "%Y-%X-%d"); + each(range(YearCalendar.INTERVAL), i => { + const td = {}; + if ( + checkDateVoid( + start + i, + 1, + 1, + print(getDate(startDate.getFullYear(), 0, 1), "%Y-%X-%d"), + print(getDate(endDate.getFullYear(), 0, 1), "%Y-%X-%d") + )[0] + ) { + td.disabled = true; + } + td.text = start + i; + items.push(td); + }); + + return items; + } + _init() { + super._init(...arguments); + const { behaviors, logic } = this.options; + this.currentYear = getDate().getFullYear(); + + this.years = createWidget({ + type: ButtonGroup.xtype, + behaviors, + items: createItems(this._getItems(), {}), + layouts: [ + LogicFactory.createLogic( + "table", + extend({}, logic, { + columns: 2, + rows: 6, + columnSize: [1 / 2, 1 / 2], + rowSize: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }) + ), + { + type: CenterAdaptLayout.xtype, + vgap: 2, + } + ], + }); + this.years.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + "vertical", + extend({}, logic, { + scrolly: true, + vgap: 5, + hgap: 6, + items: LogicFactory.createLogicItemsByDirection("top", this.years), + }) + ) + ) + ); + } + + isFrontYear() { + const { min, max } = this.options; + let Y = this.options.year; + Y = Y | 0; + + return !!checkDateVoid(YearCalendar.getStartYear(Y) - 1, 1, 1, min, max)[0]; + } + + isFinalYear() { + const { min, max } = this.options; + let Y = this.options.year; + Y = Y | 0; + + return !!checkDateVoid(YearCalendar.getEndYear(Y) + 1, 1, 1, min, max)[0]; + } + + _getItems() { + const { year } = this.options; + const years = this._yearCreator(year || this.currentYear); + + // 纵向排列年 + const len = years.length, + tyears = makeArray(len, ""); + const mapArr = [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11]; + each(years, (i, y) => { + tyears[i] = years[mapArr[i]]; + }); + + const items = []; + items.push(tyears.slice(0, 2)); + items.push(tyears.slice(2, 4)); + items.push(tyears.slice(4, 6)); + items.push(tyears.slice(6, 8)); + items.push(tyears.slice(8, 10)); + items.push(tyears.slice(10, 12)); + + return map(items, (i, item) => + map(item, (j, td) => + extend(td, { + type: TextItem.xtype, + cls: "bi-list-item-select bi-border-radius", + textAlign: "center", + whiteSpace: "normal", + once: false, + forceSelected: true, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + width: 45, + value: td.text, + disabled: td.disabled, + }) + ) + ); + } + + _populate() { + this.years.populate(this._getItems()); + } + + setMinDate(minDate) { + const o = this.options; + if (isNotEmptyString(o.min)) { + o.min = minDate; + this._populate(); + } + } + + setMaxDate(maxDate) { + const o = this.options; + if (isNotEmptyString(this.options.max)) { + o.max = maxDate; + this._populate(); + } + } + + setValue(val) { + this.years.setValue([val]); + } + + getValue() { + return this.years.getValue()[0]; + } +} diff --git a/packages/fineui/src/case/calendar/index.js b/packages/fineui/src/case/calendar/index.js new file mode 100644 index 000000000..d07f7b8ef --- /dev/null +++ b/packages/fineui/src/case/calendar/index.js @@ -0,0 +1,3 @@ +export { CalendarDateItem } from "./calendar.date.item"; +export { Calendar } from "./calendar"; +export { YearCalendar } from "./calendar.year"; diff --git a/packages/fineui/src/case/checkbox/check.arrownode.js b/packages/fineui/src/case/checkbox/check.arrownode.js new file mode 100644 index 000000000..b34751edc --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.arrownode.js @@ -0,0 +1,30 @@ +import { shortcut } from "@/core"; +import { IconButton } from "@/base"; + +/** + * Created by roy on 15/10/16. + * 右与下箭头切换的树节点 + */ + +@shortcut() +export class ArrowTreeGroupNodeCheckbox extends IconButton { + static xtype = "bi.arrow_group_node_checkbox"; + + props(conf) { + return { + extraCls: `bi-arrow-group-node-checkbox ${conf.collapseIcon || "expander-right-font"}`, + expandIcon: "expander-down-font", + collapseIcon: "expander-right-font", + }; + } + + setSelected(v) { + const o = this.options; + super.setSelected(...arguments); + if (v) { + this.element.removeClass(o.collapseIcon).addClass(o.expandIcon); + } else { + this.element.removeClass(o.expandIcon).addClass(o.collapseIcon); + } + } +} diff --git a/packages/fineui/src/case/checkbox/check.checkingmarknode.js b/packages/fineui/src/case/checkbox/check.checkingmarknode.js new file mode 100644 index 000000000..eafb4c666 --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.checkingmarknode.js @@ -0,0 +1,26 @@ +import { extend, shortcut } from "@/core"; +import { IconButton } from "@/base"; + +/** + * 十字型的树节点 + * @class CheckingMarkNode + * @extends IconButton + */ + +@shortcut() +export class CheckingMarkNode extends IconButton { + static xtype = "bi.checking_mark_node"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), {}); + } + + setSelected(v) { + super.setSelected(...arguments); + if (v === true) { + this.element.addClass("check-mark-font"); + } else { + this.element.removeClass("check-mark-font"); + } + } +} diff --git a/packages/fineui/src/case/checkbox/check.first.treenode.js b/packages/fineui/src/case/checkbox/check.first.treenode.js new file mode 100644 index 000000000..0efaab374 --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.first.treenode.js @@ -0,0 +1,42 @@ +import { extend, shortcut, STYLE_CONSTANTS } from "@/core"; +import { IconButton } from "@/base"; + +/** + * 十字型的树节点 + * @class FirstTreeNodeCheckbox + * @extends IconButton + */ + +@shortcut() +export class FirstTreeNodeCheckbox extends IconButton { + static xtype = "bi.first_tree_node_checkbox"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: + STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? "tree-solid-collapse-icon-type2" + : "tree-collapse-icon-type2", + iconWidth: 24, + iconHeight: 24, + }); + } + + getLineCls() { + switch (STYLE_CONSTANTS.LINK_LINE_TYPE) { + case "solid": + return "tree-solid-expand-icon-type2"; + default: + return "tree-expand-icon-type2"; + } + } + + setSelected(v) { + super.setSelected(...arguments); + if (v === true) { + this.element.addClass(this.getLineCls()); + } else { + this.element.removeClass(this.getLineCls()); + } + } +} diff --git a/packages/fineui/src/case/checkbox/check.last.treenode.js b/packages/fineui/src/case/checkbox/check.last.treenode.js new file mode 100644 index 000000000..37008e75a --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.last.treenode.js @@ -0,0 +1,42 @@ +import { extend, shortcut, STYLE_CONSTANTS } from "@/core"; +import { IconButton } from "@/base"; + +/** + * 十字型的树节点 + * @class LastTreeNodeCheckbox + * @extends IconButton + */ + +@shortcut() +export class LastTreeNodeCheckbox extends IconButton { + static xtype = "bi.last_tree_node_checkbox"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: + STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? "tree-solid-collapse-icon-type4" + : "tree-collapse-icon-type4", + iconWidth: 24, + iconHeight: 24, + }); + } + + getLineCls() { + switch (STYLE_CONSTANTS.LINK_LINE_TYPE) { + case "solid": + return "tree-solid-expand-icon-type4"; + default: + return "tree-expand-icon-type4"; + } + } + + setSelected(v) { + super.setSelected(...arguments); + if (v === true) { + this.element.addClass(this.getLineCls()); + } else { + this.element.removeClass(this.getLineCls()); + } + } +} diff --git a/packages/fineui/src/case/checkbox/check.mid.treenode.js b/packages/fineui/src/case/checkbox/check.mid.treenode.js new file mode 100644 index 000000000..508024066 --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.mid.treenode.js @@ -0,0 +1,42 @@ +import { extend, shortcut, STYLE_CONSTANTS } from "@/core"; +import { IconButton } from "@/base"; + +/** + * 十字型的树节点 + * @class MidTreeNodeCheckbox + * @extends IconButton + */ + +@shortcut() +export class MidTreeNodeCheckbox extends IconButton { + static xtype = "bi.mid_tree_node_checkbox"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: + STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? "tree-solid-collapse-icon-type3" + : "tree-collapse-icon-type3", + iconWidth: 24, + iconHeight: 24, + }); + } + + getLineCls() { + switch (STYLE_CONSTANTS.LINK_LINE_TYPE) { + case "solid": + return "tree-solid-expand-icon-type3"; + default: + return "tree-expand-icon-type3"; + } + } + + setSelected(v) { + super.setSelected(...arguments); + if (v === true) { + this.element.addClass(this.getLineCls()); + } else { + this.element.removeClass(this.getLineCls()); + } + } +} diff --git a/packages/fineui/src/case/checkbox/check.treenode.js b/packages/fineui/src/case/checkbox/check.treenode.js new file mode 100644 index 000000000..d746695d6 --- /dev/null +++ b/packages/fineui/src/case/checkbox/check.treenode.js @@ -0,0 +1,42 @@ +import { extend, shortcut, STYLE_CONSTANTS } from "@/core"; +import { IconButton } from "@/base"; + +/** + * 十字型的树节点 + * @class TreeNodeCheckbox + * @extends IconButton + */ + +@shortcut() +export class TreeNodeCheckbox extends IconButton { + static xtype = "bi.tree_node_checkbox"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: + STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" + ? "tree-solid-collapse-icon-type1" + : "tree-collapse-icon-type1", + iconWidth: 24, + iconHeight: 24, + }); + } + + getLineCls() { + switch (STYLE_CONSTANTS.LINK_LINE_TYPE) { + case "solid": + return "tree-solid-expand-icon-type1"; + default: + return "tree-expand-icon-type1"; + } + } + + setSelected(v) { + super.setSelected(...arguments); + if (v) { + this.element.addClass(this.getLineCls()); + } else { + this.element.removeClass(this.getLineCls()); + } + } +} diff --git a/packages/fineui/src/case/checkbox/index.js b/packages/fineui/src/case/checkbox/index.js new file mode 100644 index 000000000..aaaf21a68 --- /dev/null +++ b/packages/fineui/src/case/checkbox/index.js @@ -0,0 +1,6 @@ +export { ArrowTreeGroupNodeCheckbox } from "./check.arrownode"; +export { CheckingMarkNode } from "./check.checkingmarknode"; +export { FirstTreeNodeCheckbox } from "./check.first.treenode"; +export { LastTreeNodeCheckbox } from "./check.last.treenode"; +export { MidTreeNodeCheckbox } from "./check.mid.treenode"; +export { TreeNodeCheckbox } from "./check.treenode"; diff --git a/src/case/colorchooser/__test__/colorchooser.test.js b/packages/fineui/src/case/colorchooser/__test__/colorchooser.test.js similarity index 100% rename from src/case/colorchooser/__test__/colorchooser.test.js rename to packages/fineui/src/case/colorchooser/__test__/colorchooser.test.js diff --git a/packages/fineui/src/case/colorchooser/colorchooser.custom.js b/packages/fineui/src/case/colorchooser/colorchooser.custom.js new file mode 100644 index 000000000..3b260d339 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.custom.js @@ -0,0 +1,85 @@ +import { SimpleHexColorPickerEditor, ColorPickerEditor } from "./colorpicker"; +import { Farbtastic } from "./farbtastic/farbtastic"; +import { VTapeLayout, AbsoluteLayout, shortcut, Widget, extend, createWidget } from "@/core"; + + +/** + * 自定义选色 + * + * Created by GUY on 2015/11/17. + * @class CustomColorChooser + * @extends Widget + */ +@shortcut() +export class CustomColorChooser extends Widget { + static xtype = "bi.custom_color_chooser"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-custom-color-chooser", + width: 292, + height: 265, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget(o.editor, { + type: SimpleHexColorPickerEditor.xtype, + value: o.value, + }); + this.editor.on(ColorPickerEditor.EVENT_CHANGE, () => { + this.setValue(this.editor.getValue()); + }); + this.farbtastic = createWidget({ + type: Farbtastic.xtype, + value: o.value, + }); + this.farbtastic.on(Farbtastic.EVENT_CHANGE, () => { + this.setValue(this.farbtastic.getValue()); + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.editor, + left: 10, + top: 0, + right: 10, + }, + ], + height: 50, + }, + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.farbtastic, + left: 46, + right: 46, + top: 7, + }, + ], + height: 215, + }, + ], + }); + } + + setValue(color) { + this.editor.setValue(color); + this.farbtastic.setValue(color); + } + + getValue() { + return this.editor.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.js b/packages/fineui/src/case/colorchooser/colorchooser.js new file mode 100644 index 000000000..7b075eae0 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.js @@ -0,0 +1,129 @@ +import { Combo } from "@/base"; +import { HexColorChooserPopup } from "./colorchooser.popup.hex"; +import { shortcut, Widget, extend, createWidget, toPix, isNotEmptyString } from "@/core"; +import { ColorChooserPopup } from "./colorchooser.popup"; + +/** + * 选色控件 + * + * Created by GUY on 2015/11/17. + * @class ColorChooser + * @extends Widget + */ +@shortcut() +export class ColorChooser extends Widget { + static xtype = "bi.color_chooser"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-color-chooser", + value: "", + height: 24, + el: {}, + simple: false, + }); + } + + _init() { + const o = this.options; + const fn = () => { + const color = this.colorPicker.getValue(); + this.setValue(color); + }; + + super._init(...arguments); + o.value = (o.value || "").toLowerCase(); + this.combo = createWidget({ + type: Combo.xtype, + element: this, + container: o.container, + adjustLength: 1, + destroyWhenHide: o.destroyWhenHide, + isNeedAdjustWidth: false, + isNeedAdjustHeight: false, + el: extend( + { + type: o.width <= 24 ? "bi.color_chooser_trigger" : "bi.long_color_chooser_trigger", + simple: o.simple, + ref: _ref => { + this.trigger = _ref; + }, + value: o.value, + width: o.el.type ? o.width : toPix(o.width, 2), + height: o.el.type ? o.height : toPix(o.height, 2), + }, + o.el + ), + popup: () => { + return { + el: extend( + { + type: HexColorChooserPopup.xtype, + recommendColorsGetter: o.recommendColorsGetter, + ref: _ref => { + this.colorPicker = _ref; + }, + listeners: [ + { + eventName: ColorChooserPopup.EVENT_VALUE_CHANGE, + action: () => { + fn(); + if (!this._isRGBColor(this.colorPicker.getValue())) { + this.combo.hideView(); + } + }, + }, + { + eventName: ColorChooserPopup.EVENT_CHANGE, + action: () => { + fn(); + this.combo.hideView(); + }, + } + ], + }, + o.popup + ), + value: o.value, + width: 300, + }; + }, + value: o.value, + }); + + this.combo.on(Combo.EVENT_BEFORE_HIDEVIEW, (...args) => { + this.fireEvent(ColorChooser.EVENT_CHANGE, ...args); + }); + this.combo.on(Combo.EVENT_AFTER_POPUPVIEW, (...args) => { + this.fireEvent(ColorChooser.EVENT_AFTER_POPUPVIEW, ...args); + }); + } + + _isRGBColor(color) { + return isNotEmptyString(color) && color !== "transparent"; + } + + isViewVisible() { + return this.combo.isViewVisible(); + } + + hideView() { + this.combo.hideView(); + } + + showView() { + this.combo.showView(); + } + + setValue(color) { + this.options.value = (color || "").toLowerCase(); + this.combo.setValue(this.options.value); + } + + getValue() { + return this.combo.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.js b/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.js new file mode 100644 index 000000000..61a48946f --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.js @@ -0,0 +1,354 @@ +import { + VerticalLayout, + Layout, + AbsoluteLayout, + shortcut, + Widget, + isNotNull, + extend, + isNotEmptyString, + array2String, + map, + count, + string2Array, + filter, + isArray, + Cache, + Queue, + i18nText, + emptyFn +} from "@/core"; +import { Label, Combo, TextItem } from "@/base"; +import { PopupPanel } from "../layer"; +import { CustomColorChooser } from "./colorchooser.custom"; +import { ColorChooserPopup } from "./colorchooser.popup"; +import { ColorPickerEditor, ColorPicker, HexColorPicker } from "./colorpicker"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2020/11/10 + */ +@shortcut() +export class HexColorChooserPopup extends Widget { + static xtype = "bi.hex_color_chooser_popup"; + + static EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-chooser-popup", + width: 300, + recommendColorsGetter: emptyFn, // 推荐色获取接口 + simple: false, // 简单模式, popup中没有自动和透明 + }; + + render() { + const o = this.options; + const hasRecommendColors = isNotNull(o.recommendColorsGetter()); + + return [ + { + type: VerticalLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + hgap: 15, + items: [ + extend( + { + type: o.simple + ? "bi.simple_hex_color_picker_editor" + : "bi.hex_color_picker_editor", + value: o.value, + height: o.simple ? 36 : 70, + listeners: [ + { + eventName: ColorPickerEditor.EVENT_CHANGE, + action: (...args) => { + this.setValue(this.colorEditor.getValue()); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_VALUE_CHANGE, ...args); + }, + } + ], + ref: _ref => { + this.colorEditor = _ref; + }, + }, + o.editor + ), + { + el: { + type: HexColorPicker.xtype, + cls: "bi-border-bottom bi-border-right", + items: [this._digestStoreColors(this._getStoreColors())], + height: 22, + value: o.value, + listeners: [ + { + eventName: ColorPicker.EVENT_CHANGE, + action: (...args) => { + this.setValue(this.storeColors.getValue()[0]); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, ...args); + }, + } + ], + ref: _ref => { + this.storeColors = _ref; + }, + }, + tgap: 10, + height: 22, + }, + { + el: hasRecommendColors + ? { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + text: i18nText("BI-Basic_Recommend_Color"), + textAlign: "left", + height: 24, + }, + { + type: HexColorPicker.xtype, + cls: "bi-border-bottom bi-border-right", + items: [this._digestStoreColors(o.recommendColorsGetter())], + height: 22, + value: o.value, + listeners: [ + { + eventName: ColorPicker.EVENT_CHANGE, + action: (...args) => { + this.setValue(this.recommendColors.getValue()[0]); + this._dealStoreColors(); + this.fireEvent( + ColorChooserPopup.EVENT_CHANGE, + ...args + ); + }, + } + ], + ref: _ref => { + this.recommendColors = _ref; + }, + } + ], + } + : { type: Layout.xtype }, + tgap: hasRecommendColors ? 10 : 0, + height: hasRecommendColors ? 47 : 0, + }, + { + el: { + type: Layout.xtype, + cls: "bi-border-top", + }, + vgap: 10, + height: 1, + }, + { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: HexColorPicker.xtype, + space: true, + value: o.value, + listeners: [ + { + eventName: ColorPicker.EVENT_CHANGE, + action: (...args) => { + this.setValue(this.colorPicker.getValue()[0]); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, ...args); + }, + } + ], + ref: _ref => { + this.colorPicker = _ref; + }, + }, + top: 0, + left: 0, + right: 0, + bottom: 1, + } + ], + height: 80, + } + ], + }, + }, + { + el: { + type: Combo.xtype, + cls: "bi-border-top", + container: null, + direction: "right,top", + isNeedAdjustHeight: false, + el: { + type: TextItem.xtype, + cls: "color-chooser-popup-more bi-list-item", + textAlign: "center", + height: 24, + textLgap: 10, + text: `${i18nText("BI-Basic_More")}...`, + }, + popup: { + type: PopupPanel.xtype, + buttons: [i18nText("BI-Basic_Cancel"), i18nText("BI-Basic_Save")], + title: i18nText("BI-Custom_Color"), + el: { + type: CustomColorChooser.xtype, + value: o.value, + editor: o.editor, + ref: _ref => { + this.customColorChooser = _ref; + }, + }, + stopPropagation: false, + bgap: -1, + rgap: 1, + lgap: 1, + minWidth: 227, + listeners: [ + { + eventName: PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON, + action: (index, ...args) => { + switch (index) { + case 0: + this.more.hideView(); + break; + case 1: { + const color = this.customColorChooser.getValue(); + // farbtastic选择器没有透明和自动选项,点击保存不应该设置透明 + if (isNotEmptyString(color)) { + this.setValue(color); + this._dealStoreColors(); + } + this.more.hideView(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, index, ...args); + break; + } + default: + break; + } + }, + } + ], + }, + listeners: [ + { + eventName: Combo.EVENT_AFTER_POPUPVIEW, + action: () => { + this.customColorChooser.setValue(this.getValue()); + }, + } + ], + ref: _ref => { + this.more = _ref; + }, + }, + tgap: 10, + height: 24, + } + ], + }, + { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "disable-mask", + invisible: !o.disabled, + ref: (ref) => { + this.mask = ref; + }, + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + } + ]; + } + + // 这里就实现的不好了,setValue里面有个editor,editor的setValue会检测错误然后出bubble提示 + mounted() { + const o = this.options; + if (isNotNull(o.value)) { + this.setValue(o.value); + } + } + + _setEnable(enable) { + super._setEnable(...arguments); + this.mask.setVisible(!enable); + } + + _dealStoreColors() { + const color = this.getValue(); + const colors = this._getStoreColors(); + const que = new Queue(12); + que.fromArray(colors); + que.remove(color); + que.unshift(color); + const array = que.toArray(); + Cache.setItem("colors", array2String(array)); + this.setStoreColors(array); + } + + _digestStoreColors(colors) { + const items = map(colors.slice(0, 12), (i, color) => { + return { + value: color, + }; + }); + count(colors.length, 12, i => { + items.push({ + value: "empty", + disabled: true, + }); + }); + + return items; + } + + _getStoreColors() { + const o = this.options; + const colorsArray = string2Array(Cache.getItem("colors") || ""); + + return filter(colorsArray, (idx, color) => (o.simple ? this._isRGBColor(color) : true)); + } + + _isRGBColor(color) { + return isNotEmptyString(color) && color !== "transparent"; + } + + setStoreColors(colors) { + if (isArray(colors)) { + this.storeColors.populate([this._digestStoreColors(colors)]); + // BI-66973 选中颜色的同时选中历史 + this.storeColors.setValue(this.getValue()); + } + } + + setValue(color) { + this.colorEditor.setValue(color); + this.colorPicker.setValue(color); + this.storeColors.setValue(color); + this.recommendColors && this.recommendColors.setValue(color); + } + + getValue() { + return this.colorEditor.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.simple.js b/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.simple.js new file mode 100644 index 000000000..7ccaa9558 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.popup.hex.simple.js @@ -0,0 +1,61 @@ +import { HexColorChooserPopup } from "./colorchooser.popup.hex"; +import { shortcut, Widget } from "@/core"; +import { ColorChooserPopup } from "./colorchooser.popup"; +import { SimpleColorChooserPopup } from "./colorchooser.popup.simple"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2020/11/10 + */ +@shortcut() +export class SimpleHexColorChooserPopup extends Widget { + static xtype = "bi.simple_hex_color_chooser_popup"; + + static EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-chooser-popup", + }; + + render() { + const o = this.options; + + return { + type: HexColorChooserPopup.xtype, + recommendColorsGetter: o.recommendColorsGetter, + value: o.value, + simple: true, // 是否有自动 + listeners: [ + { + eventName: ColorChooserPopup.EVENT_CHANGE, + action: (...args) => { + this.fireEvent(SimpleColorChooserPopup.EVENT_CHANGE, ...args); + }, + }, + { + eventName: ColorChooserPopup.EVENT_VALUE_CHANGE, + action: (...args) => { + this.fireEvent(SimpleColorChooserPopup.EVENT_VALUE_CHANGE, ...args); + }, + } + ], + ref: _ref => { + this.popup = _ref; + }, + }; + } + + setStoreColors(colors) { + this.popup.setStoreColors(colors); + } + + setValue(color) { + this.popup.setValue(color); + } + + getValue() { + return this.popup.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.popup.js b/packages/fineui/src/case/colorchooser/colorchooser.popup.js new file mode 100644 index 000000000..9b1689f9a --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.popup.js @@ -0,0 +1,276 @@ +import { CustomColorChooser } from "./colorchooser.custom"; +import { PopupPanel } from "../layer"; +import { Combo, TextItem } from "@/base"; +import { + AbsoluteLayout, + VTapeLayout, + Layout, + shortcut, + Widget, + createWidget, + Cache, + string2Array, + isNotNull, + Queue, + array2String, + map, + count, + filter, + isNotEmptyString, + isArray, + i18nText +} from "@/core"; +import { ColorPickerEditor, ColorPicker } from "./colorpicker"; + +/** + * 选色控件 + * + * Created by GUY on 2015/11/17. + * @class ColorChooserPopup + * @extends Widget + */ +@shortcut() +export class ColorChooserPopup extends Widget { + static xtype = "bi.color_chooser_popup"; + + static EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-chooser-popup", + width: 230, + height: 145, + simple: false, // 简单模式, popup中没有自动和透明 + }; + + render() { + const o = this.options; + this.colorEditor = createWidget(o.editor, { + type: o.simple ? "bi.simple_color_picker_editor" : "bi.color_picker_editor", + value: o.value, + cls: "bi-header-background bi-border-bottom", + height: 30, + }); + + this.colorEditor.on(ColorPickerEditor.EVENT_CHANGE, (...args) => { + this.setValue(this.colorEditor.getValue()); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_VALUE_CHANGE, ...args); + }); + + this.storeColors = createWidget({ + type: ColorPicker.xtype, + cls: "bi-border-bottom bi-border-right", + items: [this._digestStoreColors(this._getStoreColors())], + width: 210, + height: 24, + value: o.value, + }); + this.storeColors.on(ColorPicker.EVENT_CHANGE, (...args) => { + this.setValue(this.storeColors.getValue()[0]); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, ...args); + }); + + this.colorPicker = createWidget({ + type: ColorPicker.xtype, + width: 210, + height: 50, + value: o.value, + }); + + this.colorPicker.on(ColorPicker.EVENT_CHANGE, (...args) => { + this.setValue(this.colorPicker.getValue()[0]); + this._dealStoreColors(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, ...args); + }); + + this.customColorChooser = createWidget({ + type: CustomColorChooser.xtype, + editor: o.editor, + }); + + const panel = createWidget({ + type: PopupPanel.xtype, + buttons: [i18nText("BI-Basic_Cancel"), i18nText("BI-Basic_Save")], + title: i18nText("BI-Custom_Color"), + el: this.customColorChooser, + stopPropagation: false, + bgap: -1, + rgap: 1, + lgap: 1, + minWidth: 227, + }); + + this.more = createWidget({ + type: Combo.xtype, + cls: "bi-border-top", + container: null, + direction: "right,top", + isNeedAdjustHeight: false, + el: { + type: TextItem.xtype, + cls: "color-chooser-popup-more bi-list-item", + textAlign: "center", + height: 24, + textLgap: 10, + text: `${i18nText("BI-Basic_More")}...`, + }, + popup: panel, + }); + + this.more.on(Combo.EVENT_AFTER_POPUPVIEW, () => { + this.customColorChooser.setValue(this.getValue()); + }); + panel.on(PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON, (index, ...args) => { + switch (index) { + case 0: + this.more.hideView(); + break; + case 1: + this.setValue(this.customColorChooser.getValue()); + this._dealStoreColors(); + this.more.hideView(); + this.fireEvent(ColorChooserPopup.EVENT_CHANGE, index, ...args); + break; + default: + break; + } + }); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VTapeLayout.xtype, + items: [ + this.colorEditor, + { + el: { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.storeColors, + left: 10, + right: 10, + top: 5, + } + ], + }, + height: 29, + }, + { + el: { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.colorPicker, + left: 10, + right: 10, + top: 5, + bottom: 5, + } + ], + }, + height: 60, + }, + { + el: this.more, + height: 24, + } + ], + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: Layout.xtype, + cls: "disable-mask", + invisible: !o.disabled, + ref: (ref) => { + this.mask = ref; + }, + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }; + } + + // 这里就实现的不好了,setValue里面有个editor,editor的setValue会检测错误然后出bubble提示 + mounted() { + const o = this.options; + if (isNotNull(o.value)) { + this.setValue(o.value); + } + } + + _setEnable(enable) { + super._setEnable(...arguments); + this.mask.setVisible(!enable); + } + + _dealStoreColors() { + const color = this.getValue(); + const colors = this._getStoreColors(); + const que = new Queue(8); + que.fromArray(colors); + que.remove(color); + que.unshift(color); + const array = que.toArray(); + Cache.setItem("colors", array2String(array)); + this.setStoreColors(array); + } + + _digestStoreColors(colors) { + const items = map(colors, (i, color) => { + return { + value: color, + }; + }); + count(colors.length, 8, i => { + items.push({ + value: "", + disabled: true, + }); + }); + + return items; + } + + _getStoreColors() { + const o = this.options; + const colorsArray = string2Array(Cache.getItem("colors") || ""); + + return filter(colorsArray, (idx, color) => (o.simple ? this._isRGBColor(color) : true)); + } + + _isRGBColor(color) { + return isNotEmptyString(color) && color !== "transparent"; + } + + setStoreColors(colors) { + if (isArray(colors)) { + this.storeColors.populate([this._digestStoreColors(colors)]); + // BI-66973 选中颜色的同时选中历史 + this.storeColors.setValue(this.getValue()); + } + } + + setValue(color) { + this.colorEditor.setValue(color); + this.colorPicker.setValue(color); + this.storeColors.setValue(color); + } + + getValue() { + return this.colorEditor.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.popup.simple.js b/packages/fineui/src/case/colorchooser/colorchooser.popup.simple.js new file mode 100644 index 000000000..99a66d461 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.popup.simple.js @@ -0,0 +1,52 @@ +import { shortcut, Widget, extend, createWidget } from "@/core"; +import { ColorChooserPopup } from "./colorchooser.popup"; + +/** + * 选色控件 + * + * Created by GUY on 2015/11/17. + * @class SimpleColorChooserPopup + * @extends Widget + */ +@shortcut() +export class SimpleColorChooserPopup extends Widget { + static xtype = "bi.simple_color_chooser_popup"; + + static EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-color-chooser-popup", + }); + } + + _init() { + super._init(...arguments); + const { hex, value } = this.options; + this.popup = createWidget({ + type: hex ? "bi.hex_color_chooser_popup" : "bi.color_chooser_popup", + value, + element: this, + simple: true, // 是否有自动 + }); + this.popup.on(ColorChooserPopup.EVENT_CHANGE, (...args) => { + this.fireEvent(SimpleColorChooserPopup.EVENT_CHANGE, ...args); + }); + this.popup.on(ColorChooserPopup.EVENT_VALUE_CHANGE, (...args) => { + this.fireEvent(SimpleColorChooserPopup.EVENT_VALUE_CHANGE, ...args); + }); + } + + setStoreColors(colors) { + this.popup.setStoreColors(colors); + } + + setValue(color) { + this.popup.setValue(color); + } + + getValue() { + return this.popup.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.simple.js b/packages/fineui/src/case/colorchooser/colorchooser.simple.js new file mode 100644 index 000000000..f6eaf762d --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.simple.js @@ -0,0 +1,71 @@ +import { SimpleHexColorChooserPopup } from "./colorchooser.popup.hex.simple"; +import { shortcut, Widget, extend, createWidget } from "@/core"; +import { ColorChooser } from "./colorchooser"; + +/** + * 简单选色控件,没有自动和透明 + * + * Created by GUY on 2015/11/17. + * @class SimpleColorChooser + * @extends Widget + */ +@shortcut() +export class SimpleColorChooser extends Widget { + static xtype = "bi.simple_color_chooser"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-simple-color-chooser", + value: "#ffffff", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.combo = createWidget({ + type: ColorChooser.xtype, + simple: o.simple, + element: this, + container: o.container, + value: o.value, + width: o.width, + height: o.height, + destroyWhenHide: o.destroyWhenHide, + popup: { + type: SimpleHexColorChooserPopup.xtype, + recommendColorsGetter: o.recommendColorsGetter, + }, + }); + this.combo.on(ColorChooser.EVENT_CHANGE, (...args) => { + this.fireEvent(SimpleColorChooser.EVENT_CHANGE, ...args); + }); + this.combo.on(ColorChooser.EVENT_AFTER_POPUPVIEW, (...args) => { + this.fireEvent(SimpleColorChooser.EVENT_AFTER_POPUPVIEW, ...args); + }); + } + + isViewVisible() { + return this.combo.isViewVisible(); + } + + hideView() { + this.combo.hideView(); + } + + showView() { + this.combo.showView(); + } + + setValue(color) { + this.combo.setValue(color); + } + + getValue() { + return this.combo.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.trigger.js b/packages/fineui/src/case/colorchooser/colorchooser.trigger.js new file mode 100644 index 000000000..9f44b71e8 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.trigger.js @@ -0,0 +1,85 @@ +import { Layout, AbsoluteLayout, shortcut, extend, createWidget, isNotNull, isIE9Below } from "@/core"; +import { IconButton, Trigger } from "@/base"; + +/** + * 选色控件 + * + * Created by GUY on 2015/11/17. + * @class ColorChooserTrigger + * @extends Trigger + */ +@shortcut() +export class ColorChooserTrigger extends Trigger { + static xtype = "bi.color_chooser_trigger"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-color-chooser-trigger bi-focus-shadow ${ + config.simple ? "bi-border-bottom" : "bi-border bi-border-radius" + }`, + height: 22, + }); + } + + _init() { + super._init(...arguments); + this.colorContainer = createWidget({ + type: Layout.xtype, + cls: `color-chooser-trigger-content${isIE9Below && isIE9Below() ? " hack" : ""}`, + }); + + const down = createWidget({ + type: IconButton.xtype, + disableSelected: true, + cls: "icon-combo-down-icon trigger-triangle-font icon-size-12", + width: 12, + height: 8, + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.colorContainer, + left: 2, + right: 2, + top: 2, + bottom: 2, + }, + { + el: down, + right: -1, + bottom: 1, + } + ], + }); + if (isNotNull(this.options.value)) { + this.setValue(this.options.value); + } + } + + setValue(color) { + super.setValue(...arguments); + if (color === "") { + this.colorContainer.element + .css("background-color", "") + .removeClass("trans-color-background") + .addClass("auto-color-background"); + } else if (color === "transparent") { + this.colorContainer.element + .css("background-color", "") + .removeClass("auto-color-background") + .addClass("trans-color-background"); + } else { + this.colorContainer.element + .css({ "background-color": color }) + .removeClass("auto-color-background") + .removeClass("trans-color-background"); + } + } +} diff --git a/packages/fineui/src/case/colorchooser/colorchooser.trigger.long.js b/packages/fineui/src/case/colorchooser/colorchooser.trigger.long.js new file mode 100644 index 000000000..73c9e2a88 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorchooser.trigger.long.js @@ -0,0 +1,112 @@ +import { HTapeLayout, AbsoluteLayout, shortcut, extend, createWidget, i18nText } from "@/core"; +import { IconChangeButton } from "../button"; +import { Label, IconButton, Trigger } from "@/base"; + +/** + * 选色控件 + * + * Created by GUY on 2015/11/17. + * @class LongColorChooserTrigger + * @extends Trigger + */ +@shortcut() +export class LongColorChooserTrigger extends Trigger { + static xtype = "bi.long_color_chooser_trigger"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-color-chooser-trigger bi-focus-shadow ${ + config.simple ? "bi-border-bottom" : "bi-border bi-border-radius" + }`, + height: 24, + }); + } + + _init() { + super._init(...arguments); + this.colorContainer = createWidget({ + type: HTapeLayout.xtype, + cls: "color-chooser-trigger-content", + items: [ + { + type: IconChangeButton.xtype, + ref: _ref => { + this.changeIcon = _ref; + }, + disableSelected: true, + iconCls: "auto-color-icon", + width: 24, + iconWidth: 16, + iconHeight: 16, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.label = _ref; + }, + textAlign: "left", + hgap: 5, + height: 18, + text: i18nText("BI-Basic_Auto"), + }, + } + ], + }); + + const down = createWidget({ + type: IconButton.xtype, + disableSelected: true, + cls: "icon-combo-down-icon trigger-triangle-font icon-size-12", + width: 12, + height: 8, + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.colorContainer, + left: 2, + right: 2, + top: 2, + bottom: 2, + }, + { + el: down, + right: 3, + bottom: 3, + } + ], + }); + if (this.options.value) { + this.setValue(this.options.value); + } + } + + setValue(color) { + super.setValue(...arguments); + if (color === "") { + this.colorContainer.element.css("background-color", ""); + this.changeIcon.setVisible(true); + this.label.setVisible(true); + this.changeIcon.setIcon("auto-color-icon"); + this.label.setText(i18nText("BI-Basic_Auto")); + } else if (color === "transparent") { + this.colorContainer.element.css("background-color", ""); + this.changeIcon.setVisible(true); + this.label.setVisible(true); + this.changeIcon.setIcon("trans-color-icon"); + this.label.setText(i18nText("BI-Transparent_Color")); + } else { + this.colorContainer.element.css({ "background-color": color }); + this.changeIcon.setVisible(false); + this.label.setVisible(false); + } + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorpicker.js b/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorpicker.js new file mode 100644 index 000000000..8b8702bbc --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorpicker.js @@ -0,0 +1,76 @@ +import { shortcut, isNotNull, extend } from "@/core"; +import { BasicButton, Maskers } from "@/base"; + +/** + * 简单选色控件按钮 + * + * Created by GUY on 2015/11/16. + * @class ColorPickerButton + * @extends BasicButton + */ +@shortcut() +export class ColorPickerButton extends BasicButton { + static xtype = "bi.color_picker_button"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-color-picker-button bi-background bi-border-top bi-border-left`, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.value)) { + if (o.value === "") { + this.element.addClass("auto-color-no-square-normal-background"); + } else if (o.value === "transparent") { + this.element.addClass("trans-color-background"); + } else { + this.element.css("background-color", o.value); + } + const name = this.getName(); + this.element.hover( + () => { + this._createMask(); + if (this.isEnabled()) { + Maskers.show(name); + } + }, + () => { + if (!this.isSelected()) { + Maskers.hide(name); + } + } + ); + } + } + + _createMask() { + const o = this.options, + name = this.getName(); + if (this.isEnabled() && !Maskers.has(name)) { + const w = Maskers.make(name, this, { + offset: { + left: -1, + top: -1, + right: -1, + bottom: -1, + }, + }); + w.element.addClass("color-picker-button-mask").css("background-color", o.value); + } + } + + setSelected(b) { + super.setSelected(...arguments); + if (b) { + this._createMask(); + } + Maskers[b ? "show" : "hide"](this.getName()); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorshow.js b/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorshow.js new file mode 100644 index 000000000..dd82301c0 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/button/button.colorshow.js @@ -0,0 +1,52 @@ +import { HTapeLayout, shortcut } from "@/core"; +import { IconLabel, Label, BasicButton } from "@/base"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2021/7/28 + */ +@shortcut() +export class ColorChooserShowButton extends BasicButton { + static xtype = "bi.color_picker_show_button"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-chooser-show-button bi-border bi-list-item-effect bi-border-radius", + }; + + render() { + const o = this.options; + + return { + type: HTapeLayout.xtype, + items: [ + { + el: { + type: IconLabel.xtype, + ref: _ref => { + this.icon = _ref; + }, + iconWidth: 16, + iconHeight: 16, + }, + hgap: 20, + width: 16, + }, + { + type: Label.xtype, + textAlign: "left", + text: o.text, + } + ], + }; + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(ColorChooserShowButton.EVENT_CHANGE, this); + } + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/button/index.js b/packages/fineui/src/case/colorchooser/colorpicker/button/index.js new file mode 100644 index 000000000..68da81f74 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/button/index.js @@ -0,0 +1,2 @@ +export { ColorPickerButton } from "./button.colorpicker"; +export { ColorChooserShowButton } from "./button.colorshow"; diff --git a/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.hex.js b/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.hex.js new file mode 100644 index 000000000..ef57023df --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.hex.js @@ -0,0 +1,234 @@ +import { ButtonGroup } from "@/base"; +import { GridLayout, Layout, shortcut, Widget, extend, each } from "@/core"; +import { ColorPickerButton } from "./button"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2021/7/28 + */ +@shortcut() +export class HexColorPicker extends Widget { + static xtype = "bi.hex_color_picker"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-hex-color-picker", + items: null, + }; + + _items = [ + [ + { + value: "#999999", + }, + { + value: "#FFFFFF", + }, + { + value: "#FFE5E5", + }, + { + value: "#FFF1E5", + }, + { + value: "#FFF9E5", + }, + { + value: "#E9F5E9", + }, + { + value: "#EAEEFF", + }, + { + value: "#EFEBF7", + }, + { + value: "#FCE8EF", + } + ], + [ + { + value: "#737373", + }, + { + value: "#F2F2F2", + }, + { + value: "#FFA6A6", + }, + { + value: "#FFD0A6", + }, + { + value: "#FFEDA6", + }, + { + value: "#B3DCB2", + }, + { + value: "#B9C6FF", + }, + { + value: "#CABAE6", + }, + { + value: "#F8B1C9", + } + ], + [ + { + value: "#4C4C4C", + }, + { + value: "#D9D9D9", + }, + { + value: "#FF5959", + }, + { + value: "#FFA759", + }, + { + value: "#FFDD59", + }, + { + value: "#7EBE70", + }, + { + value: "#7B95FF", + }, + { + value: "#9C7FD0", + }, + { + value: "#F06D99", + } + ], + [ + { + value: "#262626", + }, + { + value: "#BFBFBF", + }, + { + value: "#FF0000", + }, + { + value: "#FF7800", + }, + { + value: "#FFCB00", + }, + { + value: "#259B23", + }, + { + value: "#355CFF", + }, + { + value: "#673AB7", + }, + { + value: "#E91E63", + } + ], + [ + { + value: "#000000", + }, + { + value: "#A6A6A6", + }, + { + value: "#A80000", + }, + { + value: "#B65600", + }, + { + value: "#CEB000", + }, + { + value: "#0E550C", + }, + { + value: "#09269C", + }, + { + value: "#3A1A73", + }, + { + value: "#B30072", + } + ] + ]; + + render() { + const o = this.options; + + return { + type: ButtonGroup.xtype, + items: this._digest(o.items || this._items), + layouts: [ + { + type: GridLayout.xtype, + } + ], + value: o.value, + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: (...args) => { + this.fireEvent(HexColorPicker.EVENT_CHANGE, ...args); + }, + } + ], + ref: _ref => { + this.colors = _ref; + }, + }; + } + + _digest(items) { + const o = this.options; + const blocks = []; + each(items, (idx, row) => { + const bRow = []; + each(row, (idx, item) => { + bRow.push( + extend( + { + type: ColorPickerButton.xtype, + once: false, + cls: o.space ? "bi-border-right" : "", + }, + item + ) + ); + if (o.space && idx < row.length - 1) { + bRow.push({ type: Layout.xtype }); + } + }); + blocks.push(bRow); + }); + + return blocks; + } + + populate(items) { + const args = [].slice.call(arguments); + args[0] = this._digest(items); + this.colors.populate.apply(this.colors, args); + } + + setValue(color) { + this.colors.setValue(color); + } + + getValue() { + return this.colors.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.js b/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.js new file mode 100644 index 000000000..f645ec6f6 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/colorpicker.js @@ -0,0 +1,266 @@ +import { ButtonGroup } from "@/base"; +import { ColorPickerButton } from "./button"; +import { GridLayout, shortcut, Widget, extend, createItems, createWidget } from "@/core"; + +/** + * 简单选色控件 + * + * Created by GUY on 2015/11/16. + * @class ColorPicker + * @extends Widget + */ +@shortcut() +export class ColorPicker extends Widget { + static xtype = "bi.color_picker"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-color-picker", + items: null, + }); + } + + _items = [ + [ + { + value: "#ffffff", + }, + { + value: "#f2f2f2", + }, + { + value: "#e5e5e5", + }, + { + value: "#d9d9d9", + }, + { + value: "#cccccc", + }, + { + value: "#bfbfbf", + }, + { + value: "#b2b2b2", + }, + { + value: "#a6a6a6", + }, + { + value: "#999999", + }, + { + value: "#8c8c8c", + }, + { + value: "#808080", + }, + { + value: "#737373", + }, + { + value: "#666666", + }, + { + value: "#4d4d4d", + }, + { + value: "#333333", + }, + { + value: "#000000", + } + ], + [ + { + value: "#d8b5a6", + }, + { + value: "#ff9e9a", + }, + { + value: "#ffc17d", + }, + { + value: "#f5e56b", + }, + { + value: "#d8e698", + }, + { + value: "#e0ebaf", + }, + { + value: "#c3d825", + }, + { + value: "#bbe2e7", + }, + { + value: "#85d3cd", + }, + { + value: "#bde1e6", + }, + { + value: "#a0d8ef", + }, + { + value: "#89c3eb", + }, + { + value: "#bbc8e6", + }, + { + value: "#bbbcde", + }, + { + value: "#d6b4cc", + }, + { + value: "#fbc0d3", + } + ], + [ + { + value: "#bb9581", + }, + { + value: "#f37d79", + }, + { + value: "#fba74f", + }, + { + value: "#ffdb4f", + }, + { + value: "#c7dc68", + }, + { + value: "#b0ca71", + }, + { + value: "#99ab4e", + }, + { + value: "#84b9cb", + }, + { + value: "#00a3af", + }, + { + value: "#2ca9e1", + }, + { + value: "#0095d9", + }, + { + value: "#4c6cb3", + }, + { + value: "#8491c3", + }, + { + value: "#a59aca", + }, + { + value: "#cc7eb1", + }, + { + value: "#e89bb4", + } + ], + [ + { + value: "#9d775f", + }, + { + value: "#dd4b4b", + }, + { + value: "#ef8b07", + }, + { + value: "#fcc800", + }, + { + value: "#aacf53", + }, + { + value: "#82ae46", + }, + { + value: "#69821b", + }, + { + value: "#59b9c6", + }, + { + value: "#2a83a2", + }, + { + value: "#007bbb", + }, + { + value: "#19448e", + }, + { + value: "#274a78", + }, + { + value: "#4a488e", + }, + { + value: "#7058a3", + }, + { + value: "#884898", + }, + { + value: "#d47596", + } + ] + ]; + + _init() { + super._init(...arguments); + const o = this.options; + this.colors = createWidget({ + type: ButtonGroup.xtype, + element: this, + items: createItems(o.items || this._items, { + type: ColorPickerButton.xtype, + once: false, + }), + layouts: [ + { + type: GridLayout.xtype, + } + ], + value: o.value, + }); + this.colors.on(ButtonGroup.EVENT_CHANGE, (...args) => { + this.fireEvent(ColorPicker.EVENT_CHANGE, ...args); + }); + } + + populate(items) { + const args = [].slice.call(arguments); + args[0] = createItems(items, { + type: ColorPickerButton.xtype, + once: false, + }); + this.colors.populate.apply(this.colors, args); + } + + setValue(color) { + this.colors.setValue(color); + } + + getValue() { + return this.colors.getValue(); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js new file mode 100644 index 000000000..f512888be --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js @@ -0,0 +1,356 @@ +import { Label } from "@/base"; +import { + AbsoluteLayout, + VerticalLayout, + VerticalAdaptLayout, + Layout, + shortcut, + Widget, + createItems, + map, + isNumeric, + range, + extend, + isEmptyString, + isNull, + DOM, + i18nText +} from "@/core"; +import { ColorChooserShowButton } from "./button"; +import { ColorPickerEditor } from "./editor.colorpicker"; +import { SmallTextEditor } from "@/widget/editor/editor.text.small.js"; +import { TextEditor } from "@/widget/editor/editor.text"; + +const RGB_WIDTH = 32, + HEX_WIDTH = 70, + HEX_PREFIX_POSITION = 1; + +/** + * 简单选色控件 + * + * Created by GUY on 2015/11/16. + * @class HexColorPickerEditor + * @extends Widget + */ +@shortcut() +export class HexColorPickerEditor extends Widget { + static xtype = "bi.hex_color_picker_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-picker-editor", + height: 30, + }; + + render() { + this.storeValue = {}; + const RGB = createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { + type: Label.xtype, + cls: "color-picker-editor-label", + height: 20, + }); + + const checker = v => isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; + const Ws = map(range(0, 3), () => { + return { + type: SmallTextEditor.xtype, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: checker, + errorText: i18nText("BI-Color_Picker_Error_Text"), + allowBlank: true, + value: 255, + width: RGB_WIDTH, + height: 24, + listeners: [ + { + eventName: TextEditor.EVENT_CHANGE, + action: () => { + this._checkEditors(); + if ( + checker(this.storeValue.r) && + checker(this.storeValue.g) && + checker(this.storeValue.b) + ) { + this.colorShow.element.css("background-color", this.getValue()); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + } + }, + } + ], + }; + }); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + tgap: 10, + items: [ + { + type: VerticalAdaptLayout.xtype, + columnSize: ["fill", "fill"], + height: 24, + items: [ + { + type: ColorChooserShowButton.xtype, + cls: "trans-color-icon", + height: 22, + title: i18nText("BI-Transparent_Color"), + text: i18nText("BI-Transparent_Color"), + listeners: [ + { + eventName: ColorChooserShowButton.EVENT_CHANGE, + action: () => { + this.setValue("transparent"); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.transparent = _ref; + }, + }, + { + el: { + type: ColorChooserShowButton.xtype, + cls: "auto-color-icon", + height: 22, + title: i18nText("BI-Basic_Auto"), + text: i18nText("BI-Basic_Auto"), + listeners: [ + { + eventName: ColorChooserShowButton.EVENT_CHANGE, + action: () => { + this.setValue(""); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.none = _ref; + }, + }, + lgap: 10, + } + ], + }, + { + el: { + type: VerticalAdaptLayout.xtype, + columnSize: [22, 10, "fill", 12, RGB_WIDTH, 12, RGB_WIDTH, 12, RGB_WIDTH], + + rgap: 5, + items: [ + { + el: { + type: Layout.xtype, + cls: "color-picker-editor-display bi-card bi-border", + height: 22, + width: 22, + ref: _ref => { + this.colorShow = _ref; + }, + }, + width: 18, + }, + { + type: Label.xtype, + text: "#", + width: 10, + }, + { + type: SmallTextEditor.xtype, + ref: _ref => { + this.hexEditor = _ref; + }, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: this._hexChecker, + allowBlank: true, + errorText: i18nText("BI-Color_Picker_Error_Text_Hex"), + width: HEX_WIDTH, + height: 24, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._checkHexEditor(); + if ( + checker(this.storeValue.r) && + checker(this.storeValue.g) && + checker(this.storeValue.b) + ) { + this.colorShow.element.css( + "background-color", + this.getValue() + ); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + } + }, + } + ], + }, + RGB[0], + { + el: extend(Ws[0], { + ref: _ref => { + this.R = _ref; + }, + }), + width: RGB_WIDTH, + }, + RGB[1], + { + el: extend(Ws[1], { + ref: _ref => { + this.G = _ref; + }, + }), + width: RGB_WIDTH, + }, + RGB[2], + { + el: extend(Ws[2], { + ref: _ref => { + this.B = _ref; + }, + }), + rgap: -5, + width: RGB_WIDTH, + } + ], + }, + } + ], + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }; + } + + _hexChecker(v) { + return /^[0-9a-fA-F]{6}$/.test(v); + } + + _checkEditors() { + if (isEmptyString(this.R.getValue())) { + this.R.setValue(0); + } + if (isEmptyString(this.G.getValue())) { + this.G.setValue(0); + } + if (isEmptyString(this.B.getValue())) { + this.B.setValue(0); + } + this.storeValue = { + r: this.R.getValue() || 0, + g: this.G.getValue() || 0, + b: this.B.getValue() || 0, + }; + this.hexEditor.setValue(this.getValue().slice(HEX_PREFIX_POSITION)); + } + + _isEmptyRGB() { + return isEmptyString(this.storeValue.r) && isEmptyString(this.storeValue.g) && isEmptyString(this.storeValue.b); + } + + _checkHexEditor() { + if (isEmptyString(this.hexEditor.getValue())) { + this.hexEditor.setValue("000000"); + } + const json = DOM.rgb2json(DOM.hex2rgb(`#${this.hexEditor.getValue()}`)); + this.storeValue = { + r: json.r || 0, + g: json.g || 0, + b: json.b || 0, + }; + this.R.setValue(this.storeValue.r); + this.G.setValue(this.storeValue.g); + this.B.setValue(this.storeValue.b); + } + + _showPreColor(color) { + if (color === "") { + this.colorShow.element + .css("background-color", "") + .removeClass("trans-color-background") + .addClass("auto-color-square-normal-background"); + } else if (color === "transparent") { + this.colorShow.element + .css("background-color", "") + .removeClass("auto-color-square-normal-background") + .addClass("trans-color-background"); + } else { + this.colorShow.element + .css({ "background-color": color }) + .removeClass("auto-color-square-normal-background") + .removeClass("trans-color-background"); + } + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.removeClass("base-disabled disabled"); + } else if (enable === false) { + this.element.addClass("base-disabled disabled"); + } + } + + setValue(color) { + if (color === "transparent") { + this.transparent.setSelected(true); + this.none.setSelected(false); + this._showPreColor("transparent"); + this.R.setValue(""); + this.G.setValue(""); + this.B.setValue(""); + this.hexEditor.setValue(""); + this.storeValue = { + r: "", + g: "", + b: "", + }; + + return; + } + if (!color) { + color = ""; + this.none.setSelected(true); + } else { + this.none.setSelected(false); + } + this.transparent.setSelected(false); + this._showPreColor(color); + const json = DOM.rgb2json(DOM.hex2rgb(color)); + this.storeValue = { + r: isNull(json.r) ? "" : json.r, + g: isNull(json.g) ? "" : json.g, + b: isNull(json.b) ? "" : json.b, + }; + this.R.setValue(this.storeValue.r); + this.G.setValue(this.storeValue.g); + this.B.setValue(this.storeValue.b); + this.hexEditor.setValue(color.slice(HEX_PREFIX_POSITION)); + } + + getValue() { + if (this._isEmptyRGB() && this.transparent.isSelected()) { + return "transparent"; + } + + return DOM.rgb2hex( + DOM.json2rgb({ + r: this.storeValue.r, + g: this.storeValue.g, + b: this.storeValue.b, + }) + ); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js new file mode 100644 index 000000000..3c13b1aba --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js @@ -0,0 +1,217 @@ +import { Label } from "@/base"; +import { + VerticalLayout, + VerticalAdaptLayout, + Layout, + shortcut, + Widget, + extend, + isEmptyObject, + createItems, + isNull, + isNumeric, + map, + isEmptyString, + range, + DOM, + i18nText +} from "@/core"; +import { SimpleColorPickerEditor } from "./editor.colorpicker.simple"; +import { ColorPickerEditor } from "./editor.colorpicker"; +import { SmallTextEditor } from "@/widget/editor/editor.text.small.js"; +import { TextEditor } from "@/widget/editor/editor.text"; + +const RGB_WIDTH = 32, + HEX_WIDTH = 70, + HEX_PREFIX_POSITION = 1; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2020/11/10 + */ +@shortcut() +export class SimpleHexColorPickerEditor extends Widget { + static xtype = "bi.simple_hex_color_picker_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-color-picker-editor", + height: 36, + }; + + render() { + const RGB = createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { + type: Label.xtype, + cls: "color-picker-editor-label", + height: 20, + }); + + const checker = v => isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; + const Ws = map(range(0, 3), () => { + return { + type: SmallTextEditor.xtype, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: checker, + errorText: i18nText("BI-Color_Picker_Error_Text"), + allowBlank: true, + value: 255, + width: RGB_WIDTH, + height: 24, + listeners: [ + { + eventName: TextEditor.EVENT_CHANGE, + action: () => { + this._checkEditors(); + if (this.R.isValid() && this.G.isValid() && this.B.isValid()) { + this.colorShow.element.css("background-color", this.getValue()); + this.fireEvent(SimpleColorPickerEditor.EVENT_CHANGE); + } + }, + } + ], + }; + }); + + return { + type: VerticalLayout.xtype, + tgap: 10, + items: [ + { + el: { + type: VerticalAdaptLayout.xtype, + rgap: 5, + columnSize: [22, 10, "fill", 12, RGB_WIDTH, 12, RGB_WIDTH, 12, RGB_WIDTH], + items: [ + { + el: { + type: Layout.xtype, + cls: "color-picker-editor-display bi-card bi-border", + height: 22, + width: 22, + ref: _ref => { + this.colorShow = _ref; + }, + }, + width: 18, + }, + { + type: Label.xtype, + text: "#", + width: 10, + }, + { + type: SmallTextEditor.xtype, + ref: _ref => { + this.hexEditor = _ref; + }, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: this._hexChecker, + allowBlank: true, + errorText: i18nText("BI-Color_Picker_Error_Text_Hex"), + width: HEX_WIDTH, + height: 24, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._checkHexEditor(); + if ( + checker(this.storeValue.r) && + checker(this.storeValue.g) && + checker(this.storeValue.b) + ) { + this.colorShow.element.css("background-color", this.getValue()); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + } + }, + } + ], + }, + RGB[0], + { + el: extend(Ws[0], { + ref: _ref => { + this.R = _ref; + }, + }), + width: RGB_WIDTH, + }, + RGB[1], + { + el: extend(Ws[1], { + ref: _ref => { + this.G = _ref; + }, + }), + width: RGB_WIDTH, + }, + RGB[2], + { + el: extend(Ws[2], { + ref: _ref => { + this.B = _ref; + }, + }), + rgap: -5, + width: RGB_WIDTH, + } + ], + }, + } + ], + }; + } + + _hexChecker(v) { + return /^[0-9a-fA-F]{6}$/.test(v); + } + + _checkEditors() { + if (isEmptyString(this.R.getValue())) { + this.R.setValue(0); + } + if (isEmptyString(this.G.getValue())) { + this.G.setValue(0); + } + if (isEmptyString(this.B.getValue())) { + this.B.setValue(0); + } + this.hexEditor.setValue(this.getValue().slice(HEX_PREFIX_POSITION)); + } + + _checkHexEditor() { + if (isEmptyString(this.hexEditor.getValue())) { + this.hexEditor.setValue("000000"); + } + const json = DOM.rgb2json(DOM.hex2rgb(`#${this.hexEditor.getValue()}`)); + this.storeValue = { + r: json.r || 0, + g: json.g || 0, + b: json.b || 0, + }; + this.R.setValue(this.storeValue.r); + this.G.setValue(this.storeValue.g); + this.B.setValue(this.storeValue.b); + } + + setValue(color) { + this.colorShow.element.css({ "background-color": color }); + const json = DOM.rgb2json(DOM.hex2rgb(color)); + this.R.setValue(isNull(json.r) ? "" : json.r); + this.G.setValue(isNull(json.g) ? "" : json.g); + this.B.setValue(isNull(json.b) ? "" : json.b); + this.hexEditor.setValue(isEmptyObject(json) ? "" : color.slice(HEX_PREFIX_POSITION)); + } + + getValue() { + return DOM.rgb2hex( + DOM.json2rgb({ + r: this.R.getValue(), + g: this.G.getValue(), + b: this.B.getValue(), + }) + ); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.js b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.js new file mode 100644 index 000000000..34898154e --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.js @@ -0,0 +1,271 @@ +import { + Layout, + AbsoluteLayout, + VerticalAdaptLayout, + shortcut, + Widget, + extend, + createWidgets, + createItems, + createWidget, + each, + isEmptyString, + isNumeric, + isNull, + DOM, + i18nText +} from "@/core"; +import { Label, IconButton } from "@/base"; +import { SmallTextEditor } from "@/widget/editor/editor.text.small.js"; +import { TextEditor } from "@/widget/editor/editor.text"; + +const RGB_WIDTH = 32; + +/** + * 简单选色控件 + * + * Created by GUY on 2015/11/16. + * @class ColorPickerEditor + * @extends Widget + */ +@shortcut() +export class ColorPickerEditor extends Widget { + static xtype = "bi.color_picker_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-color-picker-editor", + // width: 200, + height: 30, + }); + } + + _init() { + super._init(...arguments); + this.storeValue = {}; + this.colorShow = createWidget({ + type: Layout.xtype, + cls: "color-picker-editor-display bi-card bi-border", + height: 16, + width: 16, + }); + const RGB = createWidgets( + createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { + type: Label.xtype, + cls: "color-picker-editor-label", + width: 20, + height: 20, + }) + ); + + const checker = v => isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; + const Ws = createWidgets([{}, {}, {}], { + type: SmallTextEditor.xtype, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: checker, + errorText: i18nText("BI-Color_Picker_Error_Text"), + allowBlank: true, + value: 255, + width: RGB_WIDTH, + height: 20, + }); + each(Ws, (i, w) => { + w.on(TextEditor.EVENT_CHANGE, () => { + this._checkEditors(); + if (checker(this.storeValue.r) && checker(this.storeValue.g) && checker(this.storeValue.b)) { + this.colorShow.element.css("background-color", this.getValue()); + this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + } + }); + }); + this.R = Ws[0]; + this.G = Ws[1]; + this.B = Ws[2]; + + this.none = createWidget({ + type: IconButton.xtype, + cls: "auto-color-icon", + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16, + title: i18nText("BI-Basic_Auto"), + }); + this.none.on(IconButton.EVENT_CHANGE, () => { + const value = this.getValue(); + this.setValue(""); + value !== "" && this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + }); + + this.transparent = createWidget({ + type: IconButton.xtype, + cls: "trans-color-icon", + width: 16, + height: 16, + iconWidth: 16, + iconHeight: 16, + title: i18nText("BI-Transparent_Color"), + }); + this.transparent.on(IconButton.EVENT_CHANGE, () => { + const value = this.getValue(); + this.setValue("transparent"); + value !== "transparent" && this.fireEvent(ColorPickerEditor.EVENT_CHANGE); + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: VerticalAdaptLayout.xtype, + items: [ + { + el: this.colorShow, + width: 16, + }, + { + el: RGB[0], + width: 20, + }, + { + el: this.R, + width: RGB_WIDTH, + }, + { + el: RGB[1], + width: 20, + }, + { + el: this.G, + width: RGB_WIDTH, + }, + { + el: RGB[2], + width: 20, + }, + { + el: this.B, + width: RGB_WIDTH, + }, + { + el: this.transparent, + width: 16, + lgap: 5, + }, + { + el: this.none, + width: 16, + lgap: 5, + } + ], + }, + left: 10, + right: 10, + top: 0, + bottom: 0, + } + ], + }); + } + + _checkEditors() { + if (isEmptyString(this.R.getValue())) { + this.R.setValue(0); + } + if (isEmptyString(this.G.getValue())) { + this.G.setValue(0); + } + if (isEmptyString(this.B.getValue())) { + this.B.setValue(0); + } + this.storeValue = { + r: this.R.getValue() || 0, + g: this.G.getValue() || 0, + b: this.B.getValue() || 0, + }; + } + + _isEmptyRGB() { + return isEmptyString(this.storeValue.r) && isEmptyString(this.storeValue.g) && isEmptyString(this.storeValue.b); + } + + _showPreColor(color) { + if (color === "") { + this.colorShow.element + .css("background-color", "") + .removeClass("trans-color-background") + .addClass("auto-color-normal-background"); + } else if (color === "transparent") { + this.colorShow.element + .css("background-color", "") + .removeClass("auto-color-normal-background") + .addClass("trans-color-background"); + } else { + this.colorShow.element + .css({ "background-color": color }) + .removeClass("auto-color-normal-background") + .removeClass("trans-color-background"); + } + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.removeClass("base-disabled disabled"); + } else if (enable === false) { + this.element.addClass("base-disabled disabled"); + } + } + + setValue(color) { + if (color === "transparent") { + this.transparent.setSelected(true); + this.none.setSelected(false); + this._showPreColor("transparent"); + this.R.setValue(""); + this.G.setValue(""); + this.B.setValue(""); + this.storeValue = { + r: "", + g: "", + b: "", + }; + + return; + } + if (!color) { + color = ""; + this.none.setSelected(true); + } else { + this.none.setSelected(false); + } + this.transparent.setSelected(false); + this._showPreColor(color); + const json = DOM.rgb2json(DOM.hex2rgb(color)); + this.storeValue = { + r: isNull(json.r) ? "" : json.r, + g: isNull(json.g) ? "" : json.g, + b: isNull(json.b) ? "" : json.b, + }; + this.R.setValue(this.storeValue.r); + this.G.setValue(this.storeValue.g); + this.B.setValue(this.storeValue.b); + } + + getValue() { + if (this._isEmptyRGB() && this.transparent.isSelected()) { + return "transparent"; + } + + return DOM.rgb2hex( + DOM.json2rgb({ + r: this.storeValue.r, + g: this.storeValue.g, + b: this.storeValue.b, + }) + ); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js new file mode 100644 index 000000000..70f06d96e --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js @@ -0,0 +1,152 @@ +import { + Layout, + VerticalAdaptLayout, + shortcut, + Widget, + extend, + isNull, + createWidget, + isNumeric, + createItems, + createWidgets, + each, + isEmptyString, + DOM, + i18nText +} from "@/core"; +import { Label } from "@/base"; +import { SmallTextEditor } from "@/widget/editor/editor.text.small.js"; +import { TextEditor } from "@/widget/editor/editor.text"; + +const RGB_WIDTH = 32; + +/** + * 简单选色控件 + * + * Created by GUY on 2015/11/16. + * @class SimpleColorPickerEditor + * @extends Widget + */ +@shortcut() +export class SimpleColorPickerEditor extends Widget { + static xtype = "bi.simple_color_picker_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-color-picker-editor", + // width: 200, + height: 30, + }); + } + + _init() { + super._init(...arguments); + this.colorShow = createWidget({ + type: Layout.xtype, + cls: "color-picker-editor-display bi-card bi-border", + height: 16, + width: 16, + }); + const RGB = createWidgets( + createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { + type: Label.xtype, + cls: "color-picker-editor-label", + width: 20, + height: 20, + }) + ); + + const checker = v => isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; + const Ws = createWidgets([{}, {}, {}], { + type: SmallTextEditor.xtype, + cls: "color-picker-editor-input bi-border-radius", + validationChecker: checker, + errorText: i18nText("BI-Color_Picker_Error_Text"), + allowBlank: true, + value: 255, + width: RGB_WIDTH, + height: 20, + }); + each(Ws, (i, w) => { + w.on(TextEditor.EVENT_CHANGE, () => { + this._checkEditors(); + if (this.R.isValid() && this.G.isValid() && this.B.isValid()) { + this.colorShow.element.css("background-color", this.getValue()); + this.fireEvent(SimpleColorPickerEditor.EVENT_CHANGE); + } + }); + }); + this.R = Ws[0]; + this.G = Ws[1]; + this.B = Ws[2]; + + createWidget({ + type: VerticalAdaptLayout.xtype, + element: this, + items: [ + { + el: this.colorShow, + width: 16, + lgap: 20, + rgap: 15, + }, + { + el: RGB[0], + width: 20, + }, + { + el: this.R, + width: RGB_WIDTH, + }, + { + el: RGB[1], + width: 20, + }, + { + el: this.G, + width: RGB_WIDTH, + }, + { + el: RGB[2], + width: 20, + }, + { + el: this.B, + width: RGB_WIDTH, + } + ], + }); + } + + _checkEditors() { + if (isEmptyString(this.R.getValue())) { + this.R.setValue(0); + } + if (isEmptyString(this.G.getValue())) { + this.G.setValue(0); + } + if (isEmptyString(this.B.getValue())) { + this.B.setValue(0); + } + } + + setValue(color) { + this.colorShow.element.css({ "background-color": color }); + const json = DOM.rgb2json(DOM.hex2rgb(color)); + this.R.setValue(isNull(json.r) ? "" : json.r); + this.G.setValue(isNull(json.g) ? "" : json.g); + this.B.setValue(isNull(json.b) ? "" : json.b); + } + + getValue() { + return DOM.rgb2hex( + DOM.json2rgb({ + r: this.R.getValue(), + g: this.G.getValue(), + b: this.B.getValue(), + }) + ); + } +} diff --git a/packages/fineui/src/case/colorchooser/colorpicker/index.js b/packages/fineui/src/case/colorchooser/colorpicker/index.js new file mode 100644 index 000000000..dc05c0270 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/colorpicker/index.js @@ -0,0 +1,7 @@ +export { ColorPicker } from "./colorpicker"; +export { HexColorPicker } from "./colorpicker.hex"; +export { ColorPickerEditor } from "./editor.colorpicker"; +export { HexColorPickerEditor } from "./editor.colorpicker.hex"; +export { SimpleHexColorPickerEditor } from "./editor.colorpicker.hex.simple"; +export { SimpleColorPickerEditor } from "./editor.colorpicker.simple"; +export * from "./button"; diff --git a/src/case/colorchooser/farbtastic/__test__/farbtastic.test.js b/packages/fineui/src/case/colorchooser/farbtastic/__test__/farbtastic.test.js similarity index 100% rename from src/case/colorchooser/farbtastic/__test__/farbtastic.test.js rename to packages/fineui/src/case/colorchooser/farbtastic/__test__/farbtastic.test.js diff --git a/packages/fineui/src/case/colorchooser/farbtastic/farbtastic.js b/packages/fineui/src/case/colorchooser/farbtastic/farbtastic.js new file mode 100644 index 000000000..527d5529b --- /dev/null +++ b/packages/fineui/src/case/colorchooser/farbtastic/farbtastic.js @@ -0,0 +1,277 @@ +import { AbsoluteLayout, Layout, shortcut, isKey, DOM } from "@/core"; +import { BasicButton } from "@/base"; + +const RADIUS = 84, + SQUARE = 100, + WIDTH = 194; + +@shortcut() +export class Farbtastic extends BasicButton { + static xtype = "bi.farbtastic"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-farbtastic", + width: 195, + height: 195, + stopPropagation: true, + value: "#000000", + }; + + render() { + this._defaultState(); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "", + ref: _ref => { + this.colorWrapper = _ref; + }, + }, + top: 47, + left: 47, + width: 101, + height: 101, + }, + { + el: { + type: Layout.xtype, + cls: "wheel", + ref: _ref => { + this.wheel = _ref; + }, + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: Layout.xtype, + cls: "overlay", + ref: _ref => { + this.overlay = _ref; + }, + }, + top: 47, + left: 47, + width: 101, + height: 101, + }, + { + el: { + type: Layout.xtype, + cls: "marker", + ref: _ref => { + this.hMarker = _ref; + }, + scrollable: false, + width: 17, + height: 17, + }, + }, + { + el: { + type: Layout.xtype, + cls: "marker", + ref: _ref => { + this.slMarker = _ref; + }, + scrollable: false, + width: 17, + height: 17, + }, + } + ], + }; + } + + created() { + const o = this.options; + if (isKey(o.value)) { + this.setValue(o.value); + } + } + + _defaultState() { + this.hsl = [0, 0, 0]; + } + + _unpack(color) { + if (color.length === 7) { + return [ + parseInt(`0x${color.substring(1, 3)}`) / 255, + parseInt(`0x${color.substring(3, 5)}`) / 255, + parseInt(`0x${color.substring(5, 7)}`) / 255 + ]; + } else if (color.length === 4) { + return [ + parseInt(`0x${color.substring(1, 2)}`) / 15, + parseInt(`0x${color.substring(2, 3)}`) / 15, + parseInt(`0x${color.substring(3, 4)}`) / 15 + ]; + } + } + + _pack(rgb) { + const r = Math.round(rgb[0] * 255); + const g = Math.round(rgb[1] * 255); + const b = Math.round(rgb[2] * 255); + + return ( + `#${ + r < 16 ? "0" : "" + }${r.toString(16) + }${g < 16 ? "0" : "" + }${g.toString(16) + }${b < 16 ? "0" : "" + }${b.toString(16)}` + ); + } + + _setColor(color) { + const unpack = this._unpack(color); + if (this.value !== color && unpack) { + this.value = color; + this.rgb = unpack; + this.hsl = this._RGBToHSL(this.rgb); + this._updateDisplay(); + } + } + + _setHSL(hsl) { + this.hsl = hsl; + this.rgb = this._HSLToRGB(hsl); + this.value = this._pack(this.rgb); + this._updateDisplay(); + + return this; + } + + _HSLToRGB(hsl) { + return DOM.hsl2rgb(hsl); + } + + _RGBToHSL(rgb) { + return DOM.rgb2hsl(rgb); + } + + _updateDisplay() { + const angle = this.hsl[0] * 6.28; + this.hMarker.element.css({ + left: `${Math.round(Math.sin(angle) * RADIUS + WIDTH / 2)}px`, + top: `${Math.round(-Math.cos(angle) * RADIUS + WIDTH / 2)}px`, + }); + + this.slMarker.element.css({ + left: `${Math.round(SQUARE * (0.5 - this.hsl[1]) + WIDTH / 2)}px`, + top: `${Math.round(SQUARE * (0.5 - this.hsl[2]) + WIDTH / 2)}px`, + }); + + // Saturation/Luminance gradient + this.colorWrapper.element.css("backgroundColor", this._pack(this._HSLToRGB([this.hsl[0], 1, 0.5]))); + } + + _absolutePosition(el) { + const r = { x: el.offsetLeft, y: el.offsetTop }; + // Resolve relative to offsetParent + if (el.offsetParent) { + const tmp = this._absolutePosition(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + + return r; + } + + _widgetCoords(event) { + let x, y; + const el = event.target || event.srcElement; + const reference = this.wheel.element[0]; + + if (typeof event.offsetX !== "undefined") { + // Use offset coordinates and find common offsetParent + const pos = { x: event.offsetX, y: event.offsetY }; + + // Send the coordinates upwards through the offsetParent chain. + let e = el; + while (e) { + e.mouseX = pos.x; + e.mouseY = pos.y; + pos.x += e.offsetLeft; + pos.y += e.offsetTop; + e = e.offsetParent; + } + + // Look for the coordinates starting from the wheel widget. + e = reference; + const offset = { x: 0, y: 0 }; + while (e) { + if (typeof e.mouseX !== "undefined") { + x = e.mouseX - offset.x; + y = e.mouseY - offset.y; + break; + } + offset.x += e.offsetLeft; + offset.y += e.offsetTop; + e = e.offsetParent; + } + + // Reset stored coordinates + e = el; + while (e) { + e.mouseX = undefined; + e.mouseY = undefined; + e = e.offsetParent; + } + } else { + // Use absolute coordinates + const pos = this._absolutePosition(reference); + x = (event.pageX || 0) - pos.x; + y = (event.pageY || 0) - pos.y; + } + + // Subtract distance to middle + return { x: x - WIDTH / 2, y: y - WIDTH / 2 }; + } + + _doMouseMove(event) { + const pos = this._widgetCoords(event); + + // Set new HSL parameters + if (this.circleDrag) { + let hue = Math.atan2(pos.x, -pos.y) / 6.28; + if (hue < 0) hue += 1; + this._setHSL([hue, this.hsl[1], this.hsl[2]]); + } else { + const sat = Math.max(0, Math.min(1, -(pos.x / SQUARE) + 0.5)); + const lum = Math.max(0, Math.min(1, -(pos.y / SQUARE) + 0.5)); + this._setHSL([this.hsl[0], sat, lum]); + } + this.fireEvent(Farbtastic.EVENT_CHANGE, this.getValue(), this); + } + + doClick(event) { + const pos = this._widgetCoords(event); + this.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > SQUARE; + + // Process + this._doMouseMove(event); + + return false; + } + + setValue(color) { + this._setColor(color); + } + + getValue() { + return this.value; + } +} diff --git a/packages/fineui/src/case/colorchooser/index.js b/packages/fineui/src/case/colorchooser/index.js new file mode 100644 index 000000000..24d8bc806 --- /dev/null +++ b/packages/fineui/src/case/colorchooser/index.js @@ -0,0 +1,11 @@ +export { ColorChooser } from "./colorchooser"; +export { CustomColorChooser } from "./colorchooser.custom"; +export { ColorChooserPopup } from "./colorchooser.popup"; +export { HexColorChooserPopup } from "./colorchooser.popup.hex"; +export { SimpleHexColorChooserPopup } from "./colorchooser.popup.hex.simple"; +export { SimpleColorChooserPopup } from "./colorchooser.popup.simple"; +export { SimpleColorChooser } from "./colorchooser.simple"; +export { ColorChooserTrigger } from "./colorchooser.trigger"; +export { LongColorChooserTrigger } from "./colorchooser.trigger.long"; +export { Farbtastic } from "./farbtastic/farbtastic"; +export * from "./colorpicker"; diff --git a/src/case/combo/bubblecombo/__test__/combo.bubble.test.js b/packages/fineui/src/case/combo/bubblecombo/__test__/combo.bubble.test.js similarity index 100% rename from src/case/combo/bubblecombo/__test__/combo.bubble.test.js rename to packages/fineui/src/case/combo/bubblecombo/__test__/combo.bubble.test.js diff --git a/packages/fineui/src/case/combo/bubblecombo/combo.bubble.js b/packages/fineui/src/case/combo/bubblecombo/combo.bubble.js new file mode 100644 index 000000000..df03267e4 --- /dev/null +++ b/packages/fineui/src/case/combo/bubblecombo/combo.bubble.js @@ -0,0 +1,129 @@ +import { BubblePopupView } from "./popup.bubble"; +import { shortcut, Widget, extend, emptyFn, createWidget, isFunction } from "@/core"; +import { Combo } from "@/base"; + +@shortcut() +export class BubbleCombo extends Widget { + static xtype = "bi.bubble_combo"; + + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_EXPAND = "EVENT_EXPAND"; + static EVENT_COLLAPSE = "EVENT_COLLAPSE"; + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; + static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-bubble-combo", + trigger: "click", + toggle: true, + primary: false, + direction: "bottom,left", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right + isDefaultInit: false, + destroyWhenHide: false, + hideWhenClickOutside: true, + hideWhenBlur: true, + isNeedAdjustHeight: true, // 是否需要高度调整 + isNeedAdjustWidth: true, + stopPropagation: false, + adjustLength: 0, // 调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + hideChecker: emptyFn, + offsetStyle: "left", // left,right,center + el: {}, + popup: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.combo = createWidget({ + type: Combo.xtype, + element: this, + trigger: o.trigger, + toggle: o.toggle, + logic: o.logic, + container: o.container, + direction: o.direction, + isDefaultInit: o.isDefaultInit, + hideWhenBlur: o.hideWhenBlur, + hideWhenClickOutside: o.hideWhenClickOutside, + destroyWhenHide: o.destroyWhenHide, + hideWhenAnotherComboOpen: o.hideWhenAnotherComboOpen, + isNeedAdjustHeight: o.isNeedAdjustHeight, + isNeedAdjustWidth: o.isNeedAdjustWidth, + stopPropagation: o.stopPropagation, + adjustXOffset: o.adjustXOffset, + adjustYOffset: o.adjustYOffset, + hideChecker: o.hideChecker, + offsetStyle: o.offsetStyle, + showArrow: true, + comboClass: o.comboClass, + supportCSSTransform: o.supportCSSTransform, + el: o.el, + popup: () => + extend( + { + type: BubblePopupView.xtype, + animation: "bi-zoom-big", + animationDuring: 200, + primary: o.primary, + }, + isFunction(this.options.popup) ? this.options.popup() : this.options.popup + ), + }); + this.combo.on(Combo.EVENT_TRIGGER_CHANGE, (...args) => { + this.fireEvent(BubbleCombo.EVENT_TRIGGER_CHANGE, ...args); + }); + this.combo.on(Combo.EVENT_CHANGE, (...args) => { + this.fireEvent(BubbleCombo.EVENT_CHANGE, ...args); + }); + this.combo.on(Combo.EVENT_EXPAND, (...args) => { + this.fireEvent(BubbleCombo.EVENT_EXPAND, ...args); + }); + this.combo.on(Combo.EVENT_COLLAPSE, (...args) => { + this.fireEvent(BubbleCombo.EVENT_COLLAPSE, ...args); + }); + this.combo.on(Combo.EVENT_AFTER_INIT, (...args) => { + this.fireEvent(BubbleCombo.EVENT_AFTER_INIT, ...args); + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, (...args) => { + this.fireEvent(BubbleCombo.EVENT_BEFORE_POPUPVIEW, ...args); + }); + this.combo.on(Combo.EVENT_AFTER_POPUPVIEW, (...args) => { + this.fireEvent(BubbleCombo.EVENT_AFTER_POPUPVIEW, ...args); + }); + this.combo.on(Combo.EVENT_BEFORE_HIDEVIEW, (...args) => { + this.fireEvent(BubbleCombo.EVENT_BEFORE_HIDEVIEW, ...args); + }); + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, (...args) => { + this.fireEvent(BubbleCombo.EVENT_AFTER_HIDEVIEW, ...args); + }); + } + + hideView() { + this.combo && this.combo.hideView(); + } + + showView() { + this.combo && this.combo.showView(); + } + + isViewVisible() { + return this.combo.isViewVisible(); + } + + adjustWidth() { + this.combo.adjustWidth(); + } + + adjustHeight() { + this.combo.adjustHeight(); + } +} diff --git a/packages/fineui/src/case/combo/bubblecombo/popup.bubble.js b/packages/fineui/src/case/combo/bubblecombo/popup.bubble.js new file mode 100644 index 000000000..c571ca9ed --- /dev/null +++ b/packages/fineui/src/case/combo/bubblecombo/popup.bubble.js @@ -0,0 +1,131 @@ +import { shortcut, extend, i18nText, each, isWidget, createWidget } from "@/core"; +import { PopupView } from "@/base/layer/layer.popup"; +import { Button } from "@/base"; +import { Label } from "@/base/single/label/label"; + + +@shortcut() +export class BubblePopupView extends PopupView { + static xtype = "bi.bubble_popup_view"; + + _defaultConfig() { + const config = super._defaultConfig(...arguments); + + return extend(config, { + baseCls: `${config.baseCls} bi-bubble-popup-view`, + minWidth: 70, + maxWidth: 300, + // minHeight: 50, + showArrow: true, + }); + } +} + +@shortcut() +export class BubblePopupBarView extends BubblePopupView { + static xtype = "bi.bubble_bar_popup_view"; + + static EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-bubble-bar-popup-view", + buttons: [{ + value: false, + text: i18nText("BI-Basic_Cancel"), + light: true, + }, { + text: i18nText(i18nText("BI-Basic_OK")), + value: true, + }], + innerVgap: 16, + innerHgap: 16, + }); + } + + _createToolBar() { + const o = this.options; + + const items = []; + each(o.buttons, (i, buttonOpt) => { + if (isWidget(buttonOpt)) { + items.push({ + el: buttonOpt, + lgap: 12, + }); + } else { + items.push({ + el: extend({ + type: Button.xtype, + height: 24, + handler: v => { + this.fireEvent(BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, v); + }, + }, buttonOpt), + lgap: 12, + }); + } + }); + + return createWidget({ + type: "bi.right_vertical_adapt", + innerVgap: o.innerVgap, + innerHgap: o.innerHgap, + items, + }); + } + + _createContent() { + return this.options.el; + } + + _createView() { + const o = this.options; + + const view = createWidget({ + type: "bi.vertical", + items: [this._createContent()], + cls: "bar-popup-container", + hgap: o.innerHgap, + tgap: o.innerVgap, + }); + + view.element.css("min-height", o.minHeight); + + return view; + } +} + +@shortcut() +export class TextBubblePopupBarView extends BubblePopupBarView { + static xtype = "bi.text_bubble_bar_popup_view"; + + static EVENT_CHANGE = "EVENT_CLICK_TOOLBAR_BUTTON"; + + _defaultConfig() { + const config = super._defaultConfig(...arguments); + + return extend(config, { + baseCls: `${config.baseCls} bi-text-bubble-bar-popup-view`, + text: "", + }); + } + + _createContent() { + const o = this.options; + + return { + type: Label.xtype, + text: o.text, + whiteSpace: "normal", + textAlign: "left", + ref: _ref => { + this.text = _ref; + }, + }; + } + + populate(v) { + this.text.setText(v || this.options.text); + } +} diff --git a/src/case/combo/editoriconcheckcombo/__test__/combo.editiconcheck.test.js b/packages/fineui/src/case/combo/editoriconcheckcombo/__test__/combo.editiconcheck.test.js similarity index 100% rename from src/case/combo/editoriconcheckcombo/__test__/combo.editiconcheck.test.js rename to packages/fineui/src/case/combo/editoriconcheckcombo/__test__/combo.editiconcheck.test.js diff --git a/packages/fineui/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js b/packages/fineui/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js new file mode 100644 index 000000000..4d06ab584 --- /dev/null +++ b/packages/fineui/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js @@ -0,0 +1,101 @@ +import { TextValueCheckComboPopup } from "../textvaluecheckcombo/popup.textvaluecheck"; +import { shortcut, Widget, extend, emptyFn, createWidget, Controller } from "@/core"; +import { ButtonGroup, Combo } from "@/base"; +import { EditorTrigger } from "../../trigger"; + +@shortcut() +export class EditorIconCheckCombo extends Widget { + static xtype = "bi.editor_icon_check_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_EMPTY = "EVENT_EMPTY"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseClass: "bi-check-editor-combo", + width: 100, + height: 24, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: true, + watermark: "", + errorText: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.trigger = createWidget({ + type: EditorTrigger.xtype, + items: o.items, + height: o.height, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + value: o.value, + }); + this.trigger.on(EditorTrigger.EVENT_CHANGE, (...args) => { + this.popup.setValue(this.getValue()); + this.fireEvent(EditorIconCheckCombo.EVENT_CHANGE, ...args); + }); + this.trigger.on(EditorTrigger.EVENT_FOCUS, (...args) => { + this.fireEvent(EditorIconCheckCombo.EVENT_FOCUS, ...args); + }); + this.trigger.on(EditorTrigger.EVENT_EMPTY, (...args) => { + this.fireEvent(EditorIconCheckCombo.EVENT_EMPTY, ...args); + }); + this.trigger.on(EditorTrigger.EVENT_VALID, (...args) => { + this.fireEvent(EditorIconCheckCombo.EVENT_VALID, ...args); + }); + this.trigger.on(EditorTrigger.EVENT_ERROR, (...args) => { + this.fireEvent(EditorIconCheckCombo.EVENT_ERROR, ...args); + }); + + this.popup = createWidget({ + type: TextValueCheckComboPopup.xtype, + chooseType: o.chooseType, + items: o.items, + value: o.value, + }); + this.popup.on(TextValueCheckComboPopup.EVENT_CHANGE, () => { + this.setValue(this.popup.getValue()); + this.editorIconCheckCombo.hideView(); + this.fireEvent(EditorIconCheckCombo.EVENT_CHANGE); + }); + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editorIconCheckCombo = createWidget({ + type: Combo.xtype, + container: o.container, + direction: o.direction, + element: this, + adjustLength: 2, + el: this.trigger, + popup: { + el: this.popup, + maxHeight: 300, + }, + }); + } + + setValue(v) { + this.editorIconCheckCombo.setValue(v); + } + + getValue() { + return this.trigger.getValue(); + } + + populate(items) { + this.options.items = items; + this.editorIconCheckCombo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/iconcombo/combo.icon.js b/packages/fineui/src/case/combo/iconcombo/combo.icon.js new file mode 100644 index 000000000..d7aaf3f63 --- /dev/null +++ b/packages/fineui/src/case/combo/iconcombo/combo.icon.js @@ -0,0 +1,116 @@ +import { IconComboTrigger } from "./trigger.iconcombo"; +import { shortcut, Widget, extend, isFunction, createWidget, Controller, isNull, isArray } from "@/core"; +import { ButtonGroup, Combo } from "@/base"; +import { IconComboPopup } from "./popup.iconcombo"; + +@shortcut() +export class IconCombo extends Widget { + static xtype = "bi.icon_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-icon-combo", + width: 24, + height: 24, + el: {}, + popup: {}, + minWidth: 100, + maxWidth: "auto", + maxHeight: 300, + direction: "bottom", + adjustLength: 3, // 调整的距离 + adjustXOffset: 0, + adjustYOffset: 0, + offsetStyle: "left", + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + isShowDown: true, + hideWhenAnotherComboOpen: false, + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + super._init(...arguments); + this.trigger = createWidget(o.el, { + type: IconComboTrigger.xtype, + iconCls: o.iconCls, + title: o.title, + items: o.items, + width: o.width, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + value: o.value, + isShowDown: o.isShowDown, + }); + this.popup = createWidget(o.popup, { + type: IconComboPopup.xtype, + chooseType: o.chooseType, + items: o.items, + value: o.value, + }); + this.popup.on(IconComboPopup.EVENT_CHANGE, () => { + this.setValue(this.popup.getValue()); + this.iconCombo.hideView(); + this.fireEvent(IconCombo.EVENT_CHANGE); + }); + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.iconCombo = createWidget({ + type: Combo.xtype, + element: this, + direction: o.direction, + trigger: o.trigger, + container: o.container, + adjustLength: o.adjustLength, + adjustXOffset: o.adjustXOffset, + adjustYOffset: o.adjustYOffset, + offsetStyle: o.offsetStyle, + el: this.trigger, + hideWhenAnotherComboOpen: o.hideWhenAnotherComboOpen, + popup: { + el: this.popup, + maxWidth: o.maxWidth, + maxHeight: o.maxHeight, + minWidth: o.minWidth, + }, + }); + } + + showView() { + this.iconCombo.showView(); + } + + hideView() { + this.iconCombo.hideView(); + } + + setValue(v) { + this.trigger.setValue(v); + this.popup.setValue(v); + } + + getValue() { + const value = this.popup.getValue(); + + return isNull(value) ? [] : isArray(value) ? value : [value]; + } + + populate(items) { + this.options.items = items; + this.iconCombo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/iconcombo/popup.iconcombo.js b/packages/fineui/src/case/combo/iconcombo/popup.iconcombo.js new file mode 100644 index 000000000..6b28bdd81 --- /dev/null +++ b/packages/fineui/src/case/combo/iconcombo/popup.iconcombo.js @@ -0,0 +1,66 @@ +import { shortcut, extend, createWidget, createItems, Controller, Events, VerticalLayout } from "@/core"; +import { Pane, ButtonGroup } from "@/base"; +import { SingleSelectIconTextItem } from "../../button"; + +@shortcut() +export class IconComboPopup extends Pane { + static xtype = "bi.icon_combo_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi.icon-combo-popup", + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.popup = createWidget({ + type: ButtonGroup.xtype, + items: createItems(o.items, { + type: SingleSelectIconTextItem.xtype, + }), + chooseType: o.chooseType, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value: o.value, + }); + + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + const [type, val, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(IconComboPopup.EVENT_CHANGE, val, obj); + } + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + vgap: 5, + items: [this.popup], + }); + } + + populate(items) { + super.populate(...arguments); + items = createItems(items, { + type: SingleSelectIconTextItem.xtype, + }); + this.popup.populate(items); + } + + getValue() { + return this.popup.getValue(); + } + + setValue(v) { + this.popup.setValue(v); + } +} diff --git a/packages/fineui/src/case/combo/iconcombo/trigger.iconcombo.js b/packages/fineui/src/case/combo/iconcombo/trigger.iconcombo.js new file mode 100644 index 000000000..4a94241e5 --- /dev/null +++ b/packages/fineui/src/case/combo/iconcombo/trigger.iconcombo.js @@ -0,0 +1,108 @@ +import { shortcut, extend, isKey, createWidget, isNotEmptyString, AbsoluteLayout, isArray, any } from "@/core"; +import { Trigger, IconButton } from "@/base"; +import { IconChangeButton } from "../../button"; + +@shortcut() +export class IconComboTrigger extends Trigger { + static xtype = "bi.icon_combo_trigger"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-icon-combo-trigger", + el: {}, + items: [], + iconCls: "", + width: 24, + height: 24, + isShowDown: true, + value: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + let iconCls = ""; + if (isKey(o.value)) { + iconCls = this._digest(o.value, o.items); + } + this.button = createWidget(o.el, { + type: IconChangeButton.xtype, + cls: "icon-combo-trigger-icon", + iconCls, + disableSelected: true, + width: o.isShowDown ? o.width - 12 : o.width, + height: o.height, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + selected: isNotEmptyString(iconCls), + }); + this.down = createWidget({ + type: IconButton.xtype, + disableSelected: true, + cls: "icon-combo-down-icon trigger-triangle-font font-size-12", + width: 12, + height: 8, + selected: isNotEmptyString(iconCls), + invisible: !o.isShowDown, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.button, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: this.down, + right: 3, + bottom: 0, + } + ], + }); + } + + _digest(v, items) { + let iconCls = ""; + v = isArray(v) ? v[0] : v; + any(items, (i, item) => { + if (v === item.value) { + iconCls = item.iconCls; + + return true; + } + }); + + return iconCls; + } + + populate(items) { + const o = this.options; + this.options.items = items || []; + this.button.setIcon(o.iconCls); + this.button.setSelected(false); + this.down.setSelected(false); + } + + setValue(v) { + super.setValue(...arguments); + const o = this.options; + const iconCls = this._digest(v, this.options.items); + v = isArray(v) ? v[0] : v; + if (isNotEmptyString(iconCls)) { + this.button.setIcon(iconCls); + this.button.setSelected(true); + this.down.setSelected(true); + } else { + this.button.setIcon(o.iconCls); + this.button.setSelected(false); + this.down.setSelected(false); + } + } +} diff --git a/src/case/combo/icontextvaluecombo/__test__/combo.icontextvalue.test.js b/packages/fineui/src/case/combo/icontextvaluecombo/__test__/combo.icontextvalue.test.js similarity index 100% rename from src/case/combo/icontextvaluecombo/__test__/combo.icontextvalue.test.js rename to packages/fineui/src/case/combo/icontextvaluecombo/__test__/combo.icontextvalue.test.js diff --git a/packages/fineui/src/case/combo/icontextvaluecombo/combo.icontextvalue.js b/packages/fineui/src/case/combo/icontextvaluecombo/combo.icontextvalue.js new file mode 100644 index 000000000..6080de4ea --- /dev/null +++ b/packages/fineui/src/case/combo/icontextvaluecombo/combo.icontextvalue.js @@ -0,0 +1,133 @@ +import { IconTextValueComboPopup } from "./popup.icontextvalue"; +import { + shortcut, + Widget, + extend, + isFunction, + createWidget, + toPix, + Controller, + isKey, + isNull, + isEmptyArray, + isEmptyString, + isArray, + find, + contains +} from "@/core"; +import { SelectIconTextTrigger } from "../../trigger"; +import { Combo } from "@/base"; + +@shortcut() +export class IconTextValueCombo extends Widget { + static xtype = "bi.icon_text_value_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(config) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-icon-text-value-combo ${config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"}`, + height: 24, + iconHeight: null, + iconWidth: null, + value: "", + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + super._init(...arguments); + this.trigger = createWidget({ + type: SelectIconTextTrigger.xtype, + cls: "icon-text-value-trigger", + items: o.items, + height: toPix(o.height, 2), + text: o.text, + iconCls: o.iconCls, + value: o.value, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + iconWrapperWidth: o.iconWrapperWidth, + title: o.title, + warningTitle: o.warningTitle, + }); + this.popup = createWidget({ + type: IconTextValueComboPopup.xtype, + items: o.items, + value: o.value, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + iconWrapperWidth: o.iconWrapperWidth, + }); + this.popup.on(IconTextValueComboPopup.EVENT_CHANGE, (...args) => { + this.setValue(this.popup.getValue()); + this.textIconCombo.hideView(); + this.fireEvent(IconTextValueCombo.EVENT_CHANGE, ...args); + }); + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.textIconCombo = createWidget({ + type: Combo.xtype, + height: toPix(o.height, 2), + width: toPix(o.width, 2), + element: this, + container: o.container, + direction: o.direction, + adjustLength: 2, + el: this.trigger, + popup: { + el: this.popup, + maxHeight: 240, + minHeight: 25, + }, + }); + if (isKey(o.value)) { + this.setValue(o.value); + } + } + + _checkError(v) { + if (isNull(v) || isEmptyArray(v) || isEmptyString(v)) { + this.trigger.options.tipType = "success"; + this.element.removeClass("combo-error"); + } else { + v = isArray(v) ? v : [v]; + const result = find(this.options.items, (idx, item) => contains(v, item.value)); + if (isNull(result)) { + this.trigger.options.tipType = "warning"; + this.element.removeClass("combo-error").addClass("combo-error"); + } else { + this.trigger.options.tipType = "success"; + this.element.removeClass("combo-error"); + } + } + } + + setValue(v) { + this.trigger.setValue(v); + this.popup.setValue(v); + this._checkError(v); + } + + getValue() { + const value = this.popup.getValue(); + + return isNull(value) ? [] : isArray(value) ? value : [value]; + } + + populate(items) { + this.options.items = items; + this.textIconCombo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/icontextvaluecombo/popup.icontextvalue.js b/packages/fineui/src/case/combo/icontextvaluecombo/popup.icontextvalue.js new file mode 100644 index 000000000..98dd00b1a --- /dev/null +++ b/packages/fineui/src/case/combo/icontextvaluecombo/popup.icontextvalue.js @@ -0,0 +1,80 @@ +import { shortcut, extend, createWidget, createItems, Controller, Events, VerticalLayout } from "@/core"; +import { Pane, ButtonGroup } from "@/base"; +import { SingleSelectIconTextItem } from "../../button"; + +@shortcut() +export class IconTextValueComboPopup extends Pane { + static xtype = "bi.icon_text_value_combo_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-icon-text-icon-popup", + behaviors: { + redmark() { + return true; + }, + }, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.popup = createWidget({ + type: ButtonGroup.xtype, + items: createItems(o.items, { + type: SingleSelectIconTextItem.xtype, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + iconWrapperWidth: o.iconWrapperWidth, + }), + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + behaviors: o.behaviors, + value: o.value, + }); + + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + const [type, val, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(IconTextValueComboPopup.EVENT_CHANGE, val, obj); + } + }); + + this.check(); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + vgap: 5, + items: [this.popup], + }); + } + + populate(items, keyword) { + super.populate(...arguments); + const o = this.options; + items = createItems(items, { + type: SingleSelectIconTextItem.xtype, + iconWrapperWidth: o.iconWrapperWidth, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + }); + this.popup.populate(items, keyword); + } + + getValue() { + return this.popup.getValue(); + } + + setValue(v) { + this.popup.setValue(v); + } +} diff --git a/packages/fineui/src/case/combo/index.js b/packages/fineui/src/case/combo/index.js new file mode 100644 index 000000000..7c3ac2533 --- /dev/null +++ b/packages/fineui/src/case/combo/index.js @@ -0,0 +1,22 @@ +export { BubbleCombo } from "./bubblecombo/combo.bubble"; +export { BubblePopupView, BubblePopupBarView, TextBubblePopupBarView } from "./bubblecombo/popup.bubble"; + +export { EditorIconCheckCombo } from "./editoriconcheckcombo/combo.editiconcheck"; + +export { IconCombo } from "./iconcombo/combo.icon"; +export { IconComboPopup } from "./iconcombo/popup.iconcombo"; +export { IconComboTrigger } from "./iconcombo/trigger.iconcombo"; + +export { IconTextValueCombo } from "./icontextvaluecombo/combo.icontextvalue"; +export { IconTextValueComboPopup } from "./icontextvaluecombo/popup.icontextvalue"; + +export { SearchTextValueCombo } from "./searchtextvaluecombo/combo.searchtextvalue"; +export { SearchTextValueComboPopup } from "./searchtextvaluecombo/popup.searchtextvalue"; +export { SearchTextValueTrigger } from "./searchtextvaluecombo/trigger.searchtextvalue"; + +export { TextValueCheckCombo } from "./textvaluecheckcombo/combo.textvaluecheck"; +export { TextValueCheckComboPopup } from "./textvaluecheckcombo/popup.textvaluecheck"; + +export { TextValueCombo } from "./textvaluecombo/combo.textvalue"; +export { SmallTextValueCombo } from "./textvaluecombo/combo.textvaluesmall"; +export { TextValueComboPopup } from "./textvaluecombo/popup.textvalue"; diff --git a/src/case/combo/searchtextvaluecombo/__test__/combo.searchtextvaluecombo.test.js b/packages/fineui/src/case/combo/searchtextvaluecombo/__test__/combo.searchtextvaluecombo.test.js similarity index 100% rename from src/case/combo/searchtextvaluecombo/__test__/combo.searchtextvaluecombo.test.js rename to packages/fineui/src/case/combo/searchtextvaluecombo/__test__/combo.searchtextvaluecombo.test.js diff --git a/packages/fineui/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js b/packages/fineui/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js new file mode 100644 index 000000000..1db1dec92 --- /dev/null +++ b/packages/fineui/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js @@ -0,0 +1,180 @@ +import { SearchTextValueTrigger } from "./trigger.searchtextvalue"; +import { TextValueComboPopup } from "../textvaluecombo/popup.textvalue"; +import { + shortcut, + Widget, + isFunction, + toPix, + isKey, + isNull, + isEmptyArray, + isEmptyString, + isArray, + find, + contains +} from "@/core"; +import { ButtonGroup, Combo } from "@/base"; + +@shortcut() +export class SearchTextValueCombo extends Widget { + static xtype = "bi.search_text_value_combo"; + + props = { + baseCls: "bi-search-text-value-combo", + height: 24, + text: "", + defaultText: "", + items: [], + tipType: "", + warningTitle: "", + allowClear: false, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + render() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + + return { + type: Combo.xtype, + cls: `${o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + container: o.container, + adjustLength: 2, + height: toPix(o.height, o.simple ? 1 : 2), + width: toPix(o.width, 2), + ref: (_ref) => { + this.combo = _ref; + }, + el: { + type: SearchTextValueTrigger.xtype, + cls: "search-text-value-trigger", + watermark: o.watermark, + ref: (_ref) => { + this.trigger = _ref; + }, + items: o.items, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + defaultText: o.defaultText, + value: o.value, + tipType: o.tipType, + warningTitle: o.warningTitle, + title: o.title, + allowClear: o.allowClear, + listeners: [ + { + eventName: SearchTextValueTrigger.EVENT_CHANGE, + action: () => { + this.setValue(this.getValue()[0]); + this.combo.hideView(); + this.fireEvent(SearchTextValueCombo.EVENT_CHANGE); + }, + }, + { + eventName: SearchTextValueTrigger.EVENT_CLEAR, + action: () => { + this._clear(); + this.fireEvent(SearchTextValueCombo.EVENT_CHANGE); + }, + }, + ], + }, + popup: { + el: { + type: TextValueComboPopup.xtype, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + value: o.value, + items: o.items, + ref: (_ref) => { + this.popup = _ref; + this.trigger.getSearcher().setAdapter(this.popup); + }, + listeners: [ + { + eventName: TextValueComboPopup.EVENT_CHANGE, + action: () => { + this.setValue(this.getValue()[0]); + this.combo.hideView(); + this.fireEvent(SearchTextValueCombo.EVENT_CHANGE); + }, + }, + ], + }, + value: o.value, + maxHeight: 252, + minHeight: 25, + }, + listeners: [ + { + eventName: Combo.EVENT_AFTER_HIDEVIEW, + action: () => { + this.trigger.stopEditing(); + this.fireEvent(SearchTextValueCombo.EVENT_AFTER_HIDEVIEW); + }, + }, + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(SearchTextValueCombo.EVENT_BEFORE_POPUPVIEW); + }, + }, + ], + }; + } + + created() { + const o = this.options; + if (isKey(o.value)) { + this._checkError(o.value); + } + } + + _clear() { + this.setValue(); + } + + _checkError(v) { + if (isNull(v) || isEmptyArray(v) || isEmptyString(v)) { + this.trigger.options.tipType = "success"; + this.element.removeClass("combo-error"); + } else { + v = isArray(v) ? v : [v]; + const result = find(this.options.items, (idx, item) => contains(v, item.value)); + if (isNull(result)) { + this.element.removeClass("combo-error").addClass("combo-error"); + this.trigger.attr("tipType", "warning"); + } else { + this.element.removeClass("combo-error"); + this.trigger.attr("tipType", "success"); + } + } + } + + populate(items) { + this.options.items = items; + this.combo.populate(items); + } + + setValue(v) { + this.combo.setValue(v); + this._checkError(v); + } + + getValue() { + const value = this.combo.getValue(); + + return isNull(value) ? [] : isArray(value) ? value : [value]; + } +} diff --git a/packages/fineui/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js b/packages/fineui/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js new file mode 100644 index 000000000..64baf06d7 --- /dev/null +++ b/packages/fineui/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js @@ -0,0 +1,87 @@ +import { shortcut, Controller, Events, VerticalLayout, map, extend, concat } from "@/core"; +import { ButtonGroup, Pane } from "@/base"; +import { SingleSelectItem } from "../../button"; + +@shortcut() +export class SearchTextValueComboPopup extends Pane { + static xtype = "bi.search_text_value_combo_popup"; + + props = { baseCls: "bi-search-text-value-popup" }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + const o = this.options; + + return { + type: VerticalLayout.xtype, + vgap: 5, + items: [ + { + type: ButtonGroup.xtype, + ref: _ref => { + this.popup = _ref; + }, + items: this._formatItems(o.items), + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + behaviors: { + redmark() { + return true; + }, + }, + value: o.value, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action: (...args) => { + const [type, val, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(SearchTextValueComboPopup.EVENT_CHANGE, val, obj); + } + }, + } + ], + } + ], + }; + } + + _formatItems(items) { + const o = this.options; + + return map(items, (i, item) => + extend( + { + type: SingleSelectItem.xtype, + textAlign: o.textAlign, + title: item.title || item.text, + }, + item + ) + ); + } + + mounted() { + this.check(); + } + + populate(find, match, keyword) { + const items = concat(find, match); + super.populate.apply(this, items); + this.popup.populate(this._formatItems(items), keyword); + } + + getValue() { + return this.popup.getValue(); + } + + setValue(v) { + this.popup.setValue(v); + } +} diff --git a/packages/fineui/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js b/packages/fineui/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js new file mode 100644 index 000000000..818cf438d --- /dev/null +++ b/packages/fineui/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js @@ -0,0 +1,153 @@ +import { HorizontalFillLayout, shortcut, find, i18nText, isNotEmptyString, VerticalAdaptLayout, Func } from "@/core"; +import { SearchTextValueComboPopup } from "./popup.searchtextvalue"; +import { ButtonGroup, Trigger, Searcher, IconButton } from "@/base"; +import { TriggerIconButton } from "../../button"; +import { DefaultTextEditor } from "../../editor"; + +@shortcut() +export class SearchTextValueTrigger extends Trigger { + static xtype = "bi.search_text_value_trigger"; + + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_START = "EVENT_START"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLEAR = "EVENT_CLEAR"; + + props() { + return { + baseCls: "bi-search-text-value-trigger", + height: 24, + watermark: i18nText("BI-Basic_Search"), + allowClear: false, + title: () => this.editor.getText(), + }; + } + + render() { + const o = this.options; + + const triggerButton = { + type: TriggerIconButton.xtype, + cls: "trigger-icon-button", + ref: _ref => { + this.triggerBtn = _ref; + }, + width: o.height, + height: o.height, + }; + + const stateText = this._digest(o.value, o.items) || o.text; + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", 24], + items: [ + { + el: { + type: Searcher.xtype, + ref: _ref => { + this.searcher = _ref; + }, + isAutoSearch: false, + el: { + type: DefaultTextEditor.xtype, + ref: _ref => { + this.editor = _ref; + }, + watermark: o.watermark, + defaultText: o.defaultText, + text: stateText, + value: o.value, + height: o.height, + }, + popup: { + type: SearchTextValueComboPopup.xtype, + cls: "bi-card", + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + tipText: i18nText("BI-No_Select"), + }, + onSearch(obj, callback) { + const keyword = obj.keyword; + const finding = Func.getSearchResult(o.items, keyword); + const matched = finding.match, + find = finding.find; + callback(matched, find); + }, + listeners: [ + { + eventName: Searcher.EVENT_CHANGE, + action: () => { + this.fireEvent(SearchTextValueTrigger.EVENT_CHANGE); + }, + } + ], + }, + }, + { + el: o.allowClear + ? { + type: VerticalAdaptLayout.xtype, + horizontalAlign: "left", + scrollable: false, + items: [ + { + el: { + type: IconButton.xtype, + ref: _ref => { + this.clearBtn = _ref; + }, + cls: `close-h-font ${o.allowClear ? "clear-button" : ""}`, + stopPropagation: true, + invisible: !isNotEmptyString(stateText), + width: o.height, + height: o.height, + handler: () => { + this.fireEvent(SearchTextValueTrigger.EVENT_CLEAR); + }, + }, + }, + { + el: triggerButton, + } + ], + } + : triggerButton, + width: 24, + } + ], + }; + } + + _setState(v) { + this.editor.setState(v); + } + + _digest(value, items) { + const result = find(items, (i, item) => item.value === value); + + return result?.text; + } + + stopEditing() { + this.searcher.stopSearch(); + } + + getSearcher() { + return this.searcher; + } + + populate(items) { + this.options.items = items; + } + + setValue(vals) { + const digestText = this._digest(vals, this.options.items); + this._setState(digestText); + this.options.allowClear && this.clearBtn.setVisible(isNotEmptyString(digestText)); + } + + getValue() { + return this.searcher.getValue(); + } +} diff --git a/src/case/combo/textvaluecheckcombo/__test__/combo.textvaluecheck.test.js b/packages/fineui/src/case/combo/textvaluecheckcombo/__test__/combo.textvaluecheck.test.js similarity index 100% rename from src/case/combo/textvaluecheckcombo/__test__/combo.textvaluecheck.test.js rename to packages/fineui/src/case/combo/textvaluecheckcombo/__test__/combo.textvaluecheck.test.js diff --git a/packages/fineui/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js b/packages/fineui/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js new file mode 100644 index 000000000..f69a894ad --- /dev/null +++ b/packages/fineui/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js @@ -0,0 +1,104 @@ +import { shortcut, Widget, extend, isFunction, createWidget, toPix, Controller, isKey, isNull, isArray } from "@/core"; +import { ButtonGroup, Combo } from "@/base"; +import { TextValueCheckComboPopup } from "./popup.textvaluecheck"; +import { SelectTextTrigger } from "../../trigger"; + +@shortcut() +export class TextValueCheckCombo extends Widget { + static xtype = "bi.text_value_check_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(config) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-text-value-check-combo ${config.simple ? "bi-border-bottom" : "bi-border"}`, + width: 100, + height: 24, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + value: "", + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + super._init(...arguments); + this.trigger = createWidget({ + type: SelectTextTrigger.xtype, + cls: "text-value-trigger", + items: o.items, + height: toPix(o.height, 2), + text: o.text, + value: o.value, + defaultText: o.defaultText + }); + this.popup = createWidget({ + type: TextValueCheckComboPopup.xtype, + chooseType: o.chooseType, + items: o.items, + value: o.value, + }); + this.popup.on(TextValueCheckComboPopup.EVENT_CHANGE, () => { + this.setValue(this.popup.getValue()); + this.textIconCheckCombo.hideView(); + this.fireEvent(TextValueCheckCombo.EVENT_CHANGE); + }); + this.popup.on( + Controller.EVENT_CHANGE, + (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + } + ); + this.textIconCheckCombo = createWidget({ + type: Combo.xtype, + container: o.container, + direction: o.direction, + element: this, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + adjustLength: 2, + el: this.trigger, + popup: { + el: this.popup, + maxHeight: 300, + }, + }); + + if (isKey(o.value)) { + this.setValue(o.value); + } + } + + setTitle(title) { + this.trigger.setTitle(title); + } + + setValue(v) { + this.trigger.setValue(v); + this.popup.setValue(v); + } + + setWarningTitle(title) { + this.trigger.setWarningTitle(title); + } + + getValue() { + const value = this.popup.getValue(); + + return isNull(value) ? [] : isArray(value) ? value : [value]; + } + + populate(items) { + this.options.items = items; + this.textIconCheckCombo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js b/packages/fineui/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js new file mode 100644 index 000000000..6520d1099 --- /dev/null +++ b/packages/fineui/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js @@ -0,0 +1,77 @@ +import { shortcut, extend, createWidget, Controller, Events, VerticalLayout, map } from "@/core"; +import { Pane, ButtonGroup } from "@/base"; +import { SingleSelectItem } from "../../button"; + +@shortcut() +export class TextValueCheckComboPopup extends Pane { + static xtype = "bi.text_value_check_combo_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-text-icon-popup", + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.popup = createWidget({ + type: ButtonGroup.xtype, + items: this._formatItems(o.items), + chooseType: o.chooseType, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value: o.value, + }); + + this.popup.on(Controller.EVENT_CHANGE, (...args) => { + const [type, val, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(TextValueCheckComboPopup.EVENT_CHANGE, val, obj); + } + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + vgap: 5, + items: [this.popup], + }); + } + + _formatItems(items) { + const o = this.options; + + return map(items, (i, item) => + extend( + { + type: SingleSelectItem.xtype, + cls: "bi-list-item", + textAlign: o.textAlign, + title: item.title || item.text, + }, + item + ) + ); + } + + populate(items) { + super.populate(...arguments); + this.popup.populate(this._formatItems(items)); + } + + getValue() { + return this.popup.getValue(); + } + + setValue(v) { + this.popup.setValue(v); + } +} diff --git a/src/case/combo/textvaluecombo/__test__/combo.textvalue.test.js b/packages/fineui/src/case/combo/textvaluecombo/__test__/combo.textvalue.test.js similarity index 100% rename from src/case/combo/textvaluecombo/__test__/combo.textvalue.test.js rename to packages/fineui/src/case/combo/textvaluecombo/__test__/combo.textvalue.test.js diff --git a/packages/fineui/src/case/combo/textvaluecombo/combo.textvalue.js b/packages/fineui/src/case/combo/textvaluecombo/combo.textvalue.js new file mode 100644 index 000000000..8139a1524 --- /dev/null +++ b/packages/fineui/src/case/combo/textvaluecombo/combo.textvalue.js @@ -0,0 +1,239 @@ +import { TextValueComboPopup } from "./popup.textvalue"; +import { + shortcut, + Widget, + extend, + isFunction, + toPix, + isEmptyArray, + Controller, + isKey, + isObject, + isNull, + isArray, + intersection, + map +} from "@/core"; +import { ButtonGroup, Combo } from "@/base"; +import { SelectTextTrigger } from "../../trigger"; + +@shortcut() +export class TextValueCombo extends Widget { + static xtype = "bi.text_value_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig(config) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-text-value-combo ${config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"}`, + height: 24, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + text: "", + value: "", + defaultText: "", + el: {}, + allowClear: false, + status: "success", // success | warning | error, + title: null, + allowSelectAll: true, + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + o.items = isFunction(o.items) + ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) + : o.items; + super._init(...arguments); + } + + render() { + const o = this.options; + + const title = () => { + if (isFunction(o.title)) { + return o.title(); + } + if (this.options.status === "error") { + return { + level: "warning", + text: o.warningTitle, + }; + } + + return { + level: "success", + }; + }; + + const trigger = { + type: SelectTextTrigger.xtype, + ref: ref => (this.trigger = ref), + cls: "text-value-trigger", + items: o.items, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + value: o.value, + title, + allowClear: o.allowClear, + defaultText: o.defaultText, + listeners: [ + { + eventName: SelectTextTrigger.EVENT_CLEAR, + action: () => { + this._clear(); + this.fireEvent(TextValueCombo.EVENT_CHANGE); + }, + } + ], + ...o.el, + }; + let changeTag = false; + const popup = { + type: TextValueComboPopup.xtype, + ref: ref => (this.popup = ref), + chooseType: o.chooseType, + items: o.items, + allowSelectAll: o.allowSelectAll, + listeners: [ + { + eventName: TextValueComboPopup.EVENT_CHANGE, + action: (...args) => { + changeTag = true; + const value = this.popup.getValue(); + this.setValue(value); + if (o.chooseType === ButtonGroup.CHOOSE_TYPE_SINGLE) { + this.combo.hideView(...args); + this.fireEvent(TextValueCombo.EVENT_CHANGE, ...args); + } + if (o.chooseType === ButtonGroup.CHOOSE_TYPE_MULTI && isEmptyArray(value)) { + this._clear(); + } + }, + }, + { + eventName: Controller.EVENT_CHANGE, + action: (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }, + }, + { + eventName: TextValueComboPopup.EVENT_CLEAR, + action: (...args) => { + changeTag = true; + this._clear(); + this.combo.hideView(); + }, + }, + { + eventName: TextValueComboPopup.EVENT_CONFIRM, + action: (...args) => { + this.combo.hideView(); + }, + } + ], + }; + + return { + type: Combo.xtype, + height: toPix(o.height, 2), + width: toPix(o.width, 2), + ref: ref => (this.combo = ref), + container: o.container, + direction: o.direction, + adjustLength: 2, + el: trigger, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action: () => { + changeTag = false; + this.fireEvent(TextValueCombo.EVENT_BEFORE_POPUPVIEW); + }, + }, { + eventName: Combo.EVENT_AFTER_HIDEVIEW, + action: (...args) => { + if (o.chooseType !== ButtonGroup.CHOOSE_TYPE_SINGLE && changeTag) { + this.fireEvent(TextValueCombo.EVENT_CHANGE, ...args); + } + }, + } + ], + popup: { + el: popup, + value: o.value, + maxHeight: 240, + minHeight: o.chooseType === ButtonGroup.CHOOSE_TYPE_MULTI && o.allowSelectAll ? 55 : 25, + }, + }; + } + + mounted() { + const o = this.options; + if (isKey(o.value) || isObject(o.value)) { + this._checkError(o.value); + } + } + + _clear() { + this.trigger.setText(""); + this.combo.setValue(); + this.setStatus("success"); + } + + _checkError(v) { + if (isNull(v)) { + this.setStatus("success"); + + return; + } + + const vals = isArray(v) ? v : [v]; + + const result = intersection(map(this.options.items, "value"), vals); + + if (result.length !== vals.length) { + this.setStatus("error"); + } else { + this.setStatus("success"); + } + } + + clear() { + this._clear(); + } + + setText(text) { + this.trigger.setText(text); + } + + setValue(v) { + this.combo.setValue(v); + this._checkError(v); + } + + setStatus(status) { + this.element.removeClass(`bi-status-${this.options.status}`); + this.element.addClass(`bi-status-${status}`); + this.options.status = status; + } + + getValue() { + const value = this.combo.getValue(); + + return isNull(value) ? [] : isArray(value) ? value : [value]; + } + + populate(items) { + this.options.items = items; + this.combo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/textvaluecombo/combo.textvaluesmall.js b/packages/fineui/src/case/combo/textvaluecombo/combo.textvaluesmall.js new file mode 100644 index 000000000..7e4f416ba --- /dev/null +++ b/packages/fineui/src/case/combo/textvaluecombo/combo.textvaluesmall.js @@ -0,0 +1,65 @@ +import { TextValueCombo } from "./combo.textvalue"; +import { shortcut, Widget, extend } from "@/core"; +import { ButtonGroup } from "@/base"; +import { SmallSelectTextTrigger } from "../../trigger"; + +@shortcut() +export class SmallTextValueCombo extends Widget { + static xtype = "bi.small_text_value_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + width: 100, + height: 20, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + el: {}, + text: "", + }); + } + + render() { + const o = this.options; + + return { + type: TextValueCombo.xtype, + ref: (_ref) => { + this.combo = _ref; + }, + height: o.height, + chooseType: o.chooseType, + el: { + type: SmallSelectTextTrigger.xtype, + ...o.el, + }, + items: o.items, + text: o.text, + value: o.value, + defaultText: o.defaultText, + allowClear: o.allowClear, + status: o.status, + title: o.title, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: (...args) => { + this.fireEvent(SmallTextValueCombo.EVENT_CHANGE, ...args); + }, + }, + ], + }; + } + + setValue(v) { + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + populate(items) { + this.combo.populate(items); + } +} diff --git a/packages/fineui/src/case/combo/textvaluecombo/popup.textvalue.js b/packages/fineui/src/case/combo/textvaluecombo/popup.textvalue.js new file mode 100644 index 000000000..7ad922069 --- /dev/null +++ b/packages/fineui/src/case/combo/textvaluecombo/popup.textvalue.js @@ -0,0 +1,228 @@ +import { + shortcut, + extend, + Controller, + map, + Events, + VerticalAlign, + createItems, + i18nText, + VerticalLayout, + CenterLayout +} from "@/core"; +import { ButtonGroup, Pane, TextButton } from "@/base"; +import { SelectList } from "../../list/list.select"; +import { ListPane } from "../../layer"; +import { SingleSelectItem, MultiSelectItem } from "../../button"; + +@shortcut() +export class TextValueComboPopup extends Pane { + static xtype = "bi.text_value_combo_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLEAR = "EVENT_CLEAR"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-text-icon-popup", + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + allowSelectAll: true, + }); + } + + render() { + const o = this.options; + if (o.chooseType !== ButtonGroup.CHOOSE_TYPE_MULTI) { + return { + type: VerticalLayout.xtype, + vgap: 5, + items: [ + { + type: ListPane.xtype, + ref: _ref => { + this.popup = _ref; + }, + items: this._formatItems(o.items), + chooseType: o.chooseType, + el: { + type: ButtonGroup.xtype, + chooseType: o.chooseType, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + value: o.value, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action: (...args) => { + const [type, val, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(TextValueComboPopup.EVENT_CHANGE, val, obj); + } + }, + } + ], + } + ], + }; + } + + return { + type: VerticalLayout.xtype, + verticalAlign: VerticalAlign.Stretch, + items: o.allowSelectAll + ? [ + { + type: SelectList.xtype, + logic: { + dynamic: true, + innerVgap: 5, + rowSize: ["", "fill"], + verticalAlign: VerticalAlign.Stretch, + }, + ref: _ref => { + this.popup = _ref; + }, + el: { + el: { + chooseType: o.chooseType, + }, + }, + items: this._formatItems(o.items), + value: { + type: ButtonGroup.CHOOSE_TYPE_MULTI, + value: o.value, + }, + height: "fill", + listeners: [ + { + eventName: SelectList.EVENT_CHANGE, + action: (val) => { + this.fireEvent(TextValueComboPopup.EVENT_CHANGE, val); + }, + } + ], + }, + { + type: CenterLayout.xtype, + cls: "list-view-toolbar bi-high-light bi-split-top", + height: 24, + items: createItems( + [ + { + type: TextButton.xtype, + text: i18nText("BI-Basic_Clears"), + handler: () => { + this.fireEvent(TextValueComboPopup.EVENT_CLEAR); + }, + }, + { + type: TextButton.xtype, + text: i18nText("BI-Basic_OK"), + handler: () => { + this.fireEvent(TextValueComboPopup.EVENT_CONFIRM); + }, + } + ], + { + once: false, + shadow: true, + isShadowShowingOnSelected: true, + } + ), + } + ] + : [ + { + type: ListPane.xtype, + logic: { + dynamic: true, + innerVgap: 5, + rowSize: ["", "fill"], + verticalAlign: VerticalAlign.Stretch, + }, + ref: _ref => { + this.popup = _ref; + }, + el: { + chooseType: o.chooseType, + }, + items: this._formatItems(o.items), + value: o.value, + height: "fill", + listeners: [ + { + eventName: ListPane.EVENT_CHANGE, + action: val => { + this.fireEvent(TextValueComboPopup.EVENT_CHANGE, val); + }, + } + ], + } + ], + }; + } + + beforeMount() { + if (this.options.chooseType !== ButtonGroup.CHOOSE_TYPE_MULTI) { + this.check(); + } + } + + _formatItems(items) { + const o = this.options; + + return map(items, (i, item) => + extend( + { + type: + o.chooseType !== ButtonGroup.CHOOSE_TYPE_MULTI ? SingleSelectItem.xtype : MultiSelectItem.xtype, + iconWrapperWidth: 36, + textAlign: o.textAlign, + title: item.title || item.text, + }, + item + ) + ); + } + + populate(items) { + super.populate(...arguments); + this.popup.populate(this._formatItems(items)); + } + + getValue() { + if (this.options.chooseType !== ButtonGroup.CHOOSE_TYPE_MULTI) { + return this.popup.getValue(); + } + const val = this.popup.getValue(); + if (!this.options.allowSelectAll) { + return val; + } + if (val.type === ButtonGroup.CHOOSE_TYPE_MULTI) { + return val.value; + } else { + return val.assist; + } + } + + setValue(v) { + if (this.options.chooseType !== ButtonGroup.CHOOSE_TYPE_MULTI) { + return this.popup.setValue(v); + } + if (!this.options.allowSelectAll) { + this.popup.setValue(v); + + return; + } + this.popup.setValue({ + type: ButtonGroup.CHOOSE_TYPE_MULTI, + value: v, + }); + } +} diff --git a/src/case/editor/__test__/editor.clear.test.js b/packages/fineui/src/case/editor/__test__/editor.clear.test.js similarity index 100% rename from src/case/editor/__test__/editor.clear.test.js rename to packages/fineui/src/case/editor/__test__/editor.clear.test.js diff --git a/src/case/editor/__test__/editor.sign.test.js b/packages/fineui/src/case/editor/__test__/editor.sign.test.js similarity index 100% rename from src/case/editor/__test__/editor.sign.test.js rename to packages/fineui/src/case/editor/__test__/editor.sign.test.js diff --git a/src/case/editor/__test__/editor.state.simple.test.js b/packages/fineui/src/case/editor/__test__/editor.state.simple.test.js similarity index 100% rename from src/case/editor/__test__/editor.state.simple.test.js rename to packages/fineui/src/case/editor/__test__/editor.state.simple.test.js diff --git a/src/case/editor/__test__/editor.state.test.js b/packages/fineui/src/case/editor/__test__/editor.state.test.js similarity index 100% rename from src/case/editor/__test__/editor.state.test.js rename to packages/fineui/src/case/editor/__test__/editor.state.test.js diff --git a/packages/fineui/src/case/editor/editor.clear.js b/packages/fineui/src/case/editor/editor.clear.js new file mode 100644 index 000000000..a35a4302e --- /dev/null +++ b/packages/fineui/src/case/editor/editor.clear.js @@ -0,0 +1,202 @@ +import { Editor, IconButton } from "@/base"; +import { + HTapeLayout, + shortcut, + Widget, + extend, + emptyFn, + isKey, + isFunction, + createWidget, + Controller, + Events +} from "@/core"; + +/** + * 有清除按钮的文本框 + * Created by GUY on 2015/9/29. + * @class ClearEditor + * @extends Widget + */ +@shortcut() +export class ClearEditor extends Widget { + static xtype = "bi.clear_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_BACKSPACE = "EVENT_BACKSPACE"; + static EVENT_CLEAR = "EVENT_CLEAR"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_REMOVE = "EVENT_REMOVE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-clear-editor", + height: 24, + errorText: "", + watermark: "", + validationChecker: emptyFn, + quitChecker: emptyFn, + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + super._init(...arguments); + this.editor = createWidget({ + type: Editor.xtype, + simple: o.simple, + height: o.height, + watermark: o.watermark, + allowBlank: true, + errorText: o.errorText, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + value: o.value, + autoTrim: o.autoTrim, + }); + this.clear = createWidget({ + type: IconButton.xtype, + stopEvent: true, + invisible: !isKey(o.value), + cls: "search-close-h-font", + }); + this.clear.on(IconButton.EVENT_CHANGE, () => { + this.setValue(""); + this.fireEvent(Controller.EVENT_CHANGE, Events.STOPEDIT); + this.fireEvent(ClearEditor.EVENT_CLEAR); + }); + createWidget({ + element: this, + type: HTapeLayout.xtype, + items: [ + { + el: this.editor, + }, + { + el: this.clear, + width: 24, + } + ], + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.editor.on(Editor.EVENT_FOCUS, () => { + this.fireEvent(ClearEditor.EVENT_FOCUS); + }); + this.editor.on(Editor.EVENT_BLUR, () => { + this.fireEvent(ClearEditor.EVENT_BLUR); + }); + this.editor.on(Editor.EVENT_CLICK, () => { + this.fireEvent(ClearEditor.EVENT_CLICK); + }); + this.editor.on(Editor.EVENT_CHANGE, () => { + this._checkClear(); + this.fireEvent(ClearEditor.EVENT_CHANGE); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, v => { + this.fireEvent(ClearEditor.EVENT_KEY_DOWN, v); + }); + this.editor.on(Editor.EVENT_SPACE, () => { + this.fireEvent(ClearEditor.EVENT_SPACE); + }); + this.editor.on(Editor.EVENT_BACKSPACE, () => { + this.fireEvent(ClearEditor.EVENT_BACKSPACE); + }); + + this.editor.on(Editor.EVENT_VALID, () => { + this.fireEvent(ClearEditor.EVENT_VALID); + }); + this.editor.on(Editor.EVENT_ERROR, () => { + this.fireEvent(ClearEditor.EVENT_ERROR); + }); + this.editor.on(Editor.EVENT_ENTER, () => { + this.fireEvent(ClearEditor.EVENT_ENTER); + }); + this.editor.on(Editor.EVENT_RESTRICT, () => { + this.fireEvent(ClearEditor.EVENT_RESTRICT); + }); + this.editor.on(Editor.EVENT_EMPTY, () => { + this._checkClear(); + this.fireEvent(ClearEditor.EVENT_EMPTY); + }); + this.editor.on(Editor.EVENT_REMOVE, () => { + this.fireEvent(ClearEditor.EVENT_REMOVE); + }); + this.editor.on(Editor.EVENT_CONFIRM, () => { + this.fireEvent(ClearEditor.EVENT_CONFIRM); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, () => { + this.fireEvent(ClearEditor.EVENT_CHANGE_CONFIRM); + }); + this.editor.on(Editor.EVENT_START, () => { + this.fireEvent(ClearEditor.EVENT_START); + }); + this.editor.on(Editor.EVENT_PAUSE, () => { + this.fireEvent(ClearEditor.EVENT_PAUSE); + }); + this.editor.on(Editor.EVENT_STOP, () => { + this.fireEvent(ClearEditor.EVENT_STOP); + }); + } + + _checkClear() { + if (!this.getValue()) { + this.clear.invisible(); + } else { + this.clear.visible(); + } + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + getValue() { + if (this.isValid()) { + return this.editor.getValue(); + } + } + + setValue(v) { + this.editor.setValue(v); + if (isKey(v)) { + this.clear.visible(); + } + } + + isValid() { + return this.editor.isValid(); + } +} diff --git a/packages/fineui/src/case/editor/editor.defaulttext.js b/packages/fineui/src/case/editor/editor.defaulttext.js new file mode 100644 index 000000000..d8db6f2da --- /dev/null +++ b/packages/fineui/src/case/editor/editor.defaulttext.js @@ -0,0 +1,302 @@ +import { Editor, TextButton } from "@/base"; +import { + AbsoluteLayout, + shortcut, + Widget, + emptyFn, + isKey, + isFunction, + createWidget, + nextTick, + Controller +} from "@/core"; + +/** + * dailer + * 有默认提示文字的输入框 + * @class DefaultTextEditor + * @extends Widget + */ +@shortcut() +export class DefaultTextEditor extends Widget { + static xtype = "bi.default_text_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + props() { + return { + baseCls: "bi-default-text-editor", + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: true, + watermark: "", + errorText: "", + height: 24, + defaultText: "", // 默认显示值,默认显示值与显示值的区别是默认显示值标记灰色 + text: "", // 显示值 + el: {}, + }; + } + + render() { + const o = this.options; + this.editor = createWidget(o.el, { + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + invisible: true, + autoTrim: o.autoTrim, + }); + + const showText = isFunction(o.text) ? o.text() : o.text; + + this.text = createWidget({ + type: TextButton.xtype, + cls: isKey(showText) ? "tip-text-style" : "bi-water-mark tip-text-style", + textAlign: "left", + height: o.height, + text: showText || o.defaultText, + hgap: o.hgap + 2, + handler: () => { + this._showInput(); + this.editor.focus(); + this.editor.setValue(""); + }, + title: o.title, + warningTitle: o.warningTitle, + tipType: o.tipType, + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + nextTick(() => { + this.fireEvent(DefaultTextEditor.EVENT_CLICK_LABEL); + }); + }); + + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_FOCUS, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_FOCUS, ...args); + }); + this.editor.on(Editor.EVENT_BLUR, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_BLUR, ...args); + }); + this.editor.on(Editor.EVENT_CLICK, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_CLICK, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_KEY_DOWN, ...args); + }); + + this.editor.on(Editor.EVENT_VALID, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_VALID, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(DefaultTextEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(DefaultTextEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_START, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_START, ...args); + }); + this.editor.on(Editor.EVENT_PAUSE, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_PAUSE, ...args); + }); + this.editor.on(Editor.EVENT_STOP, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_STOP, ...args); + }); + this.editor.on(Editor.EVENT_SPACE, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_SPACE, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_ENTER, ...args); + }); + this.editor.on(Editor.EVENT_RESTRICT, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Editor.EVENT_EMPTY, (...args) => { + this.fireEvent(DefaultTextEditor.EVENT_EMPTY, ...args); + }); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.editor, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: this.text, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }; + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + setTitle(title) { + this.text.setTitle(title); + } + + setWarningTitle(title) { + this.text.setWarningTitle(title); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + focus() { + if (this.options.disabled === false) { + this._showInput(); + this.editor.focus(); + } + } + + blur() { + this.editor.blur(); + this._showHint(); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + _setText(v) { + this.text.setText(v); + this.text.setTitle(v); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(k) { + this.editor.setValue(k); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.text.getValue(); + } + + setState(v) { + const o = this.options; + if (isKey(v)) { + this.text.setText(v); + this.text.element.removeClass("bi-water-mark"); + + return; + } + this.text.setText(o.defaultText); + this.text.element.addClass("bi-water-mark"); + } + + setTipType(v) { + this.text.options.tipType = v; + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/case/editor/editor.shelter.js b/packages/fineui/src/case/editor/editor.shelter.js new file mode 100644 index 000000000..054bb37b6 --- /dev/null +++ b/packages/fineui/src/case/editor/editor.shelter.js @@ -0,0 +1,300 @@ +import { Editor, TextButton } from "@/base"; +import { + AbsoluteLayout, + shortcut, + Widget, + extend, + emptyFn, + isFunction, + createWidget, + Controller, + isKey, + nextTick, + bind +} from "@/core"; + +/** + * 带标记的文本框 + * Created by GUY on 2016/1/25. + * @class ShelterEditor + * @extends Widget + */ +@shortcut() +export class ShelterEditor extends Widget { + static xtype = "bi.shelter_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-shelter-editor`, + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: true, + watermark: "", + errorText: "", + height: 24, + textAlign: "left", + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + super._init(...arguments); + this.editor = createWidget({ + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + autoTrim: o.autoTrim, + }); + this.text = createWidget({ + type: TextButton.xtype, + cls: "shelter-editor-text", + title: o.title, + warningTitle: o.warningTitle, + tipType: o.tipType, + textAlign: o.textAlign, + height: o.height, + hgap: o.hgap + 2, + }); + this.text.on(Controller.EVENT_CHANGE, (...args) => { + args[2] = this; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + this.fireEvent(ShelterEditor.EVENT_CLICK_LABEL); + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_FOCUS, (...args) => { + this.fireEvent(ShelterEditor.EVENT_FOCUS, ...args); + }); + this.editor.on(Editor.EVENT_BLUR, (...args) => { + this.fireEvent(ShelterEditor.EVENT_BLUR, ...args); + }); + this.editor.on(Editor.EVENT_CLICK, (...args) => { + this.fireEvent(ShelterEditor.EVENT_CLICK, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE, (...args) => { + this.fireEvent(ShelterEditor.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(ShelterEditor.EVENT_KEY_DOWN, ...args); + }); + + this.editor.on(Editor.EVENT_VALID, (...args) => { + this.fireEvent(ShelterEditor.EVENT_VALID, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(ShelterEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(ShelterEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_START, (...args) => { + this.fireEvent(ShelterEditor.EVENT_START, ...args); + }); + this.editor.on(Editor.EVENT_PAUSE, (...args) => { + this.fireEvent(ShelterEditor.EVENT_PAUSE, ...args); + }); + this.editor.on(Editor.EVENT_STOP, (...args) => { + this.fireEvent(ShelterEditor.EVENT_STOP, ...args); + }); + this.editor.on(Editor.EVENT_SPACE, (...args) => { + this.fireEvent(ShelterEditor.EVENT_SPACE, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this._checkText(); + this.fireEvent(ShelterEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, (...args) => { + this.fireEvent(ShelterEditor.EVENT_ENTER, ...args); + }); + this.editor.on(Editor.EVENT_RESTRICT, (...args) => { + this.fireEvent(ShelterEditor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Editor.EVENT_EMPTY, (...args) => { + this.fireEvent(ShelterEditor.EVENT_EMPTY, ...args); + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.text, + inset: 0, + }, + { + el: this.editor, + inset: 0, + } + ], + }); + this._showHint(); + this._checkText(); + } + + _checkText() { + const o = this.options; + nextTick( + bind(function () { + if (this.editor.getValue() === "") { + this.text.setValue(o.watermark || ""); + this.text.element.addClass("bi-water-mark"); + } else { + this.text.setValue(this.editor.getValue()); + this.text.element.removeClass("bi-water-mark"); + } + isKey(o.keyword) && this.text.doRedMark(o.keyword); + }, this) + ); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + setTitle(title) { + this.text.setTitle(title); + } + + setWarningTitle(title) { + this.text.setWarningTitle(title); + } + + focus() { + this._showInput(); + this.editor.focus(); + } + + blur() { + this.editor.blur(); + this._showHint(); + this._checkText(); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setTextStyle(style) { + this.text.setStyle(style); + } + + setValue(k) { + this.editor.setValue(k); + this._checkText(); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.text.getValue(); + } + + setState(v) { + this._showHint(); + this.text.setValue(v); + } +} diff --git a/packages/fineui/src/case/editor/editor.sign.js b/packages/fineui/src/case/editor/editor.sign.js new file mode 100644 index 000000000..f5b4712b4 --- /dev/null +++ b/packages/fineui/src/case/editor/editor.sign.js @@ -0,0 +1,308 @@ +import { Editor, TextButton } from "@/base"; +import { + AbsoluteLayout, + shortcut, + Widget, + extend, + emptyFn, + isFunction, + createWidget, + nextTick, + isKey, + bind, + Controller +} from "@/core"; + +/** + * 带标记的文本框 + * Created by GUY on 2015/8/28. + * @class SignEditor + * @extends Widget + */ +@shortcut() +export class SignEditor extends Widget { + static xtype = "bi.sign_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-sign-editor`, + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: true, + watermark: "", + errorText: "", + textAlign: "left", + height: 24, + }); + } + + _init() { + const o = this.options; + o.value = isFunction(o.value) + ? this.__watch(o.value, (context, newValue) => { + this.setValue(newValue); + }) + : o.value; + super._init(...arguments); + this.editor = createWidget({ + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + autoTrim: o.autoTrim, + }); + this.text = createWidget({ + type: TextButton.xtype, + cls: "sign-editor-text", + title: o.title, + warningTitle: o.warningTitle, + tipType: o.tipType, + textAlign: o.textAlign, + height: o.height, + hgap: o.hgap + 2, + handler: () => { + this._showInput(); + this.editor.focus(); + this.editor.selectAll(); + }, + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + nextTick(() => { + this.fireEvent(SignEditor.EVENT_CLICK_LABEL); + }); + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_FOCUS, (...args) => { + this.fireEvent(SignEditor.EVENT_FOCUS, ...args); + }); + this.editor.on(Editor.EVENT_BLUR, (...args) => { + this.fireEvent(SignEditor.EVENT_BLUR, ...args); + }); + this.editor.on(Editor.EVENT_CLICK, (...args) => { + this.fireEvent(SignEditor.EVENT_CLICK, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE, (...args) => { + this.fireEvent(SignEditor.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(SignEditor.EVENT_KEY_DOWN, ...args); + }); + this.editor.on(Editor.EVENT_QUICK_DOWN, (...args) => { + this.fireEvent(SignEditor.EVENT_QUICK_DOWN, ...args); + }); + + this.editor.on(Editor.EVENT_VALID, (...args) => { + this.fireEvent(SignEditor.EVENT_VALID, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(SignEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(SignEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_START, (...args) => { + this.fireEvent(SignEditor.EVENT_START, ...args); + }); + this.editor.on(Editor.EVENT_PAUSE, (...args) => { + this.fireEvent(SignEditor.EVENT_PAUSE, ...args); + }); + this.editor.on(Editor.EVENT_STOP, (...args) => { + this.fireEvent(SignEditor.EVENT_STOP, ...args); + }); + this.editor.on(Editor.EVENT_SPACE, (...args) => { + this.fireEvent(SignEditor.EVENT_SPACE, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this._checkText(); + this.fireEvent(SignEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, (...args) => { + this.fireEvent(SignEditor.EVENT_ENTER, ...args); + }); + this.editor.on(Editor.EVENT_RESTRICT, (...args) => { + this.fireEvent(SignEditor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Editor.EVENT_EMPTY, (...args) => { + this.fireEvent(SignEditor.EVENT_EMPTY, ...args); + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.text, + inset: 0, + }, + { + el: this.editor, + inset: 0, + } + ], + }); + this._showHint(); + this._checkText(); + } + + _checkText() { + const o = this.options; + nextTick( + bind(function () { + if (this.editor.getValue() === "") { + this.text.setValue(o.watermark || ""); + this.text.element.addClass("bi-water-mark"); + } else { + this.text.setValue(this.editor.getValue()); + this.text.element.removeClass("bi-water-mark"); + isKey(o.keyword) && this.text.doRedMark(o.keyword); + } + }, this) + ); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + setTitle(title) { + this.text.setTitle(title); + } + + setTipType(v) { + this.text.setTipType(v); + } + + setWarningTitle(title) { + this.text.setWarningTitle(title); + } + + setWaterMark(v) { + this.options.watermark = v; + this._checkText(); + this.editor.setWaterMark(v); + } + + focus() { + this._showInput(); + this.editor.focus(); + } + + blur() { + this.editor.blur(); + this._showHint(); + this._checkText(); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(k) { + this.editor.setValue(k); + this._checkText(); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.text.getValue(); + } + + setState(v) { + this._showHint(); + this.text.setValue(v); + } +} diff --git a/packages/fineui/src/case/editor/editor.state.js b/packages/fineui/src/case/editor/editor.state.js new file mode 100644 index 000000000..bdb731adc --- /dev/null +++ b/packages/fineui/src/case/editor/editor.state.js @@ -0,0 +1,344 @@ +import { Editor, TextButton } from "@/base"; +import { + AbsoluteLayout, + shortcut, + Widget, + extend, + emptyFn, + i18nText, + isArray, + createWidget, + nextTick, + Controller, + isNotNull, + isString, + isKey, + isFunction, + isNumber, + isEmpty, + Selection +} from "@/core"; + +/** + * guy + * 记录状态的输入框 + * @class StateEditor + * @extends Single + */ +@shortcut() +export class StateEditor extends Widget { + static xtype = "bi.state_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-state-editor`, + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: true, + watermark: "", + errorText: "", + height: 24, + defaultText: i18nText("BI-Basic_Unrestricted"), // 默认显示值,默认显示值与显示值的区别是默认显示值标记灰色 + text: "", // 显示值 + el: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget(o.el, { + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + autoTrim: o.autoTrim, + }); + this.text = createWidget({ + type: TextButton.xtype, + cls: "bi-water-mark tip-text-style", + textAlign: "left", + height: o.height, + text: o.text, + hgap: o.hgap + 2, + handler: () => { + this._showInput(); + this.editor.focus(); + this.editor.setValue(""); + }, + title: isNotNull(o.tipText) + ? o.tipText + : () => { + let title = ""; + if (isString(this.stateValue)) { + title = this.stateValue; + } + if (isArray(this.stateValue) && this.stateValue.length === 1) { + title = this.stateValue[0]; + } + + return title; + }, + warningTitle: o.warningTitle, + tipType: o.tipType, + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + nextTick(() => { + this.fireEvent(StateEditor.EVENT_CLICK_LABEL); + }); + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_FOCUS, (...args) => { + this.fireEvent(StateEditor.EVENT_FOCUS, ...args); + }); + this.editor.on(Editor.EVENT_BLUR, (...args) => { + this.fireEvent(StateEditor.EVENT_BLUR, ...args); + }); + this.editor.on(Editor.EVENT_CLICK, (...args) => { + this.fireEvent(StateEditor.EVENT_CLICK, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE, (...args) => { + this.fireEvent(StateEditor.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(StateEditor.EVENT_KEY_DOWN, ...args); + }); + + this.editor.on(Editor.EVENT_VALID, (...args) => { + this.fireEvent(StateEditor.EVENT_VALID, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(StateEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(StateEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_START, (...args) => { + this.fireEvent(StateEditor.EVENT_START, ...args); + }); + this.editor.on(Editor.EVENT_PAUSE, (...args) => { + this.fireEvent(StateEditor.EVENT_PAUSE, ...args); + }); + this.editor.on(Editor.EVENT_STOP, (...args) => { + this.fireEvent(StateEditor.EVENT_STOP, ...args); + }); + this.editor.on(Editor.EVENT_SPACE, (...args) => { + this.fireEvent(StateEditor.EVENT_SPACE, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this.fireEvent(StateEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, (...args) => { + this.fireEvent(StateEditor.EVENT_ENTER, ...args); + }); + this.editor.on(Editor.EVENT_RESTRICT, (...args) => { + this.fireEvent(StateEditor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Editor.EVENT_EMPTY, (...args) => { + this.fireEvent(StateEditor.EVENT_EMPTY, ...args); + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.text, + inset: 0, + }, + { + el: this.editor, + inset: 0, + } + ], + }); + this._showHint(); + if (isNotNull(o.text)) { + this.setState(o.text); + } + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + focus() { + if (this.options.disabled === false) { + this._showInput(); + this.editor.focus(); + } + } + + blur() { + this.editor.blur(); + this._showHint(); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + _setText(v) { + this.text.setText(v); + this.text.setTitle(v); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(k) { + this.editor.setValue(k); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.editor.getValue().match(/[^\s]+/g); + } + + setState(v) { + const o = this.options; + const defaultText = isFunction(o.defaultText) ? o.defaultText() : o.defaultText; + super.setValue(...arguments); + this.stateValue = v; + if (isNumber(v)) { + if (v === Selection.All) { + this._setText(i18nText("BI-Select_All")); + this.text.element.removeClass("bi-water-mark"); + } else if (v === Selection.Multi) { + this._setText(i18nText("BI-Select_Part")); + this.text.element.removeClass("bi-water-mark"); + } else { + this._setText(isKey(defaultText) ? defaultText : o.text); + isKey(defaultText) + ? this.text.element.addClass("bi-water-mark") + : this.text.element.removeClass("bi-water-mark"); + } + + return; + } + if (isString(v)) { + this._setText(v); + // 配置了defaultText才判断标灰,其他情况不标灰 + isKey(defaultText) && defaultText === v + ? this.text.element.addClass("bi-water-mark") + : this.text.element.removeClass("bi-water-mark"); + + return; + } + if (isArray(v)) { + if (isEmpty(v)) { + this._setText(isKey(defaultText) ? defaultText : o.text); + isKey(defaultText) + ? this.text.element.addClass("bi-water-mark") + : this.text.element.removeClass("bi-water-mark"); + } else if (v.length === 1) { + this._setText(v[0]); + this.text.element.removeClass("bi-water-mark"); + } else { + this._setText(i18nText("BI-Select_Part")); + this.text.element.removeClass("bi-water-mark"); + } + } + } + + setTipType(v) { + this.text.options.tipType = v; + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/case/editor/editor.state.simple.js b/packages/fineui/src/case/editor/editor.state.simple.js new file mode 100644 index 000000000..367b3a34e --- /dev/null +++ b/packages/fineui/src/case/editor/editor.state.simple.js @@ -0,0 +1,312 @@ +import { Editor, TextButton } from "@/base"; +import { + AbsoluteLayout, + VerticalLayout, + shortcut, + Widget, + extend, + emptyFn, + i18nText, + Controller, + createWidget, + nextTick, + isNotNull, + isKey, + isFunction, + isArray, + isNumber, + isEmpty, + Selection +} from "@/core"; + +/** + * 无限制-已选择状态输入框 + * Created by GUY on 2016/5/18. + * @class SimpleStateEditor + * @extends Single + */ +@shortcut() +export class SimpleStateEditor extends Widget { + static xtype = "bi.simple_state_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-simple-state-editor`, + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + mouseOut: false, + allowBlank: true, + watermark: "", + errorText: "", + height: 24, + text: "", + defaultText: i18nText("BI-Basic_Unrestricted"), + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget({ + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + autoTrim: o.autoTrim, + }); + this.text = createWidget({ + type: TextButton.xtype, + cls: "bi-water-mark", + textAlign: "left", + text: o.text, + height: o.height, + hgap: o.hgap + 2, + handler: () => { + this._showInput(); + this.editor.focus(); + this.editor.setValue(""); + }, + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + nextTick(() => { + this.fireEvent(SimpleStateEditor.EVENT_CLICK_LABEL); + }); + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.text, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_FOCUS, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_FOCUS, ...args); + }); + this.editor.on(Editor.EVENT_BLUR, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_BLUR, ...args); + }); + this.editor.on(Editor.EVENT_CLICK, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_CLICK, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_KEY_DOWN, ...args); + }); + + this.editor.on(Editor.EVENT_VALID, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_VALID, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(SimpleStateEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this.fireEvent(SimpleStateEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_START, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_START, ...args); + }); + this.editor.on(Editor.EVENT_PAUSE, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_PAUSE, ...args); + }); + this.editor.on(Editor.EVENT_STOP, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_STOP, ...args); + }); + this.editor.on(Editor.EVENT_SPACE, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_SPACE, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_ENTER, ...args); + }); + this.editor.on(Editor.EVENT_RESTRICT, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_RESTRICT, ...args); + }); + this.editor.on(Editor.EVENT_EMPTY, (...args) => { + this.fireEvent(SimpleStateEditor.EVENT_EMPTY, ...args); + }); + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [this.editor], + }); + this._showHint(); + if (isNotNull(o.text)) { + this.setState(o.text); + } + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + focus() { + this._showInput(); + this.editor.focus(); + } + + blur() { + this.editor.blur(); + this._showHint(); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + _setText(v) { + this.text.setText(v); + this.text.setTitle(v); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(k) { + this.editor.setValue(k); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.editor.getValue().match(/[^\s]+/g); + } + + setState(v) { + const o = this.options; + super.setValue(...arguments); + const defaultText = isFunction(o.defaultText) ? o.defaultText() : o.defaultText; + if (isNumber(v)) { + if (v === Selection.All) { + this._setText(i18nText("BI-Already_Selected")); + this.text.element.removeClass("bi-water-mark"); + } else if (v === Selection.Multi) { + this._setText(i18nText("BI-Already_Selected")); + this.text.element.removeClass("bi-water-mark"); + } else { + this._setText(isKey(defaultText) ? defaultText : o.text); + this.text.element.addClass("bi-water-mark"); + } + + return; + } + if (!isArray(v) || v.length === 1) { + this._setText(v); + this.text.element.removeClass("bi-water-mark"); + } else if (isEmpty(v)) { + this._setText(o.text); + this.text.element.addClass("bi-water-mark"); + } else { + this._setText(i18nText("BI-Already_Selected")); + this.text.element.removeClass("bi-water-mark"); + } + } + + getText() { + return this.text.getText(); + } +} diff --git a/packages/fineui/src/case/editor/index.js b/packages/fineui/src/case/editor/index.js new file mode 100644 index 000000000..487c0f3f6 --- /dev/null +++ b/packages/fineui/src/case/editor/index.js @@ -0,0 +1,6 @@ +export { ClearEditor } from "./editor.clear"; +export { DefaultTextEditor } from "./editor.defaulttext"; +export { ShelterEditor } from "./editor.shelter"; +export { SignEditor } from "./editor.sign"; +export { StateEditor } from "./editor.state"; +export { SimpleStateEditor } from "./editor.state.simple"; diff --git a/packages/fineui/src/case/index.js b/packages/fineui/src/case/index.js new file mode 100644 index 000000000..4e025e7de --- /dev/null +++ b/packages/fineui/src/case/index.js @@ -0,0 +1,18 @@ +export { MultiSelectBar } from "./toolbar/toolbar.multiselect"; +export { SelectList } from "./list/list.select"; + +export * from "./combo"; +export * from "./button"; +export * from "./calendar"; +export * from "./pager"; +export * from "./editor"; +export * from "./tree"; +export * from "./ztree"; +export * from "./trigger"; +export * from "./loader"; +export * from "./segment"; +export * from "./layer"; +export * from "./linearsegment"; +export * from "./checkbox"; +export * from "./colorchooser"; + diff --git a/packages/fineui/src/case/layer/index.js b/packages/fineui/src/case/layer/index.js new file mode 100644 index 000000000..2737f6b07 --- /dev/null +++ b/packages/fineui/src/case/layer/index.js @@ -0,0 +1,4 @@ +export { MultiPopupView } from "./layer.multipopup"; +export { PopupPanel } from "./layer.panel"; +export { ListPane } from "./pane.list"; +export { Panel } from "./panel"; diff --git a/packages/fineui/src/case/layer/layer.multipopup.js b/packages/fineui/src/case/layer/layer.multipopup.js new file mode 100644 index 000000000..1808d1bf7 --- /dev/null +++ b/packages/fineui/src/case/layer/layer.multipopup.js @@ -0,0 +1,63 @@ +import { ButtonGroup, TextButton, PopupView } from "@/base"; +import { CenterLayout, shortcut, extend, i18nText, each, createWidget, createItems, SIZE_CONSANTS } from "@/core"; + +/** + * 下拉框弹出层的多选版本,toolbar带有若干按钮, zIndex在1000w + * @class MultiPopupView + * @extends Widget + */ + +@shortcut() +export class MultiPopupView extends PopupView { + static xtype = "bi.multi_popup_view"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + _baseCls: `${conf._baseCls || ""} bi-multi-list-view`, + buttons: [i18nText("BI-Basic_OK")], + }); + } + + _createToolBar() { + const o = this.options; + if (o.buttons.length === 0) { + return; + } + + const text = []; // 构造[{text:content},……] + each(o.buttons, (idx, item) => { + text.push({ + text: item, + value: idx, + }); + }); + + this.buttongroup = createWidget({ + type: ButtonGroup.xtype, + cls: "list-view-toolbar bi-high-light bi-split-top", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + items: createItems(text, { + type: TextButton.xtype, + once: false, + shadow: true, + isShadowShowingOnSelected: true, + }), + layouts: [ + { + type: CenterLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + }); + + this.buttongroup.on(ButtonGroup.EVENT_CHANGE, (value, obj) => { + this.fireEvent(MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, value, obj); + }); + + return this.buttongroup; + } +} diff --git a/packages/fineui/src/case/layer/layer.panel.js b/packages/fineui/src/case/layer/layer.panel.js new file mode 100644 index 000000000..0b4218684 --- /dev/null +++ b/packages/fineui/src/case/layer/layer.panel.js @@ -0,0 +1,60 @@ +import { IconButton, Label } from "@/base"; +import { HTapeLayout, shortcut, extend, createWidget } from "@/core"; +import { MultiPopupView } from "./layer.multipopup"; + +/** + * 可以理解为MultiPopupView和Panel两个面板的结合体 + * @class PopupPanel + * @extends MultiPopupView + */ + +@shortcut() +export class PopupPanel extends MultiPopupView { + static xtype = "bi.popup_panel"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLOSE = "EVENT_CLOSE"; + static EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-popup-panel`, + title: "", + }); + } + + _createTool() { + const o = this.options; + const close = createWidget({ + type: IconButton.xtype, + cls: "close-h-font", + width: 25, + height: 25, + }); + close.on(IconButton.EVENT_CHANGE, () => { + this.setVisible(false); + this.fireEvent(PopupPanel.EVENT_CLOSE); + }); + + return createWidget({ + type: HTapeLayout.xtype, + cls: "popup-panel-title bi-header-background", + height: 25, + items: [ + { + el: { + type: Label.xtype, + textAlign: "left", + text: o.title, + height: 25, + lgap: 10, + }, + }, + { + el: close, + width: 25, + } + ], + }); + } +} diff --git a/packages/fineui/src/case/layer/pane.list.js b/packages/fineui/src/case/layer/pane.list.js new file mode 100644 index 000000000..161ae449b --- /dev/null +++ b/packages/fineui/src/case/layer/pane.list.js @@ -0,0 +1,246 @@ +import { + shortcut, + extend, + each, + createWidget, + emptyFn, + nextTick, + concat, + get, + Controller, + Events, + LogicFactory, + Direction, + isNull, + removeAt, + isFunction, + isNotEmptyString, + isEmptyArray, + VerticalLayout +} from "@/core"; +import { Pane, ButtonGroup } from "@/base"; + +/** + * list面板 + * + * Created by GUY on 2015/10/30. + * @class ListPane + * @extends Pane + */ + +@shortcut() +export class ListPane extends Pane { + static xtype = "bi.list_pane"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-list-pane`, + logic: { + dynamic: true, + }, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + hgap: 0, + items: [], + itemsCreator: emptyFn, + hasNext: emptyFn, + onLoaded: emptyFn, + el: { + type: ButtonGroup.xtype, + }, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.button_group = createWidget(o.el, { + type: ButtonGroup.xtype, + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + behaviors: {}, + items: o.items, + value: o.value, + itemsCreator: (op, callback) => { + if (op.times === 1) { + this.empty(); + nextTick(() => { + this.loading(); + }); + } + o.itemsCreator(op, (...args) => { + callback(...args); + o.items = concat(o.items, get(args, [0], [])); + if (op.times === 1) { + o.items = get(args, [0], []); + nextTick(() => { + this.loaded(); + // callback可能在loading之前执行, check保证显示正确 + this.check(); + }); + } + }); + }, + hasNext: o.hasNext, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }); + + this.button_group.on(Controller.EVENT_CHANGE, (...args) => { + const [type, value, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(ListPane.EVENT_CHANGE, value, obj); + } + }); + this.check(); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(Direction.Top), + extend( + { + scrolly: true, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + vgap: o.vgap, + hgap: o.hgap, + }, + o.logic, + { + items: LogicFactory.createLogicItemsByDirection(Direction.Top, this.button_group), + } + ) + ) + ) + ); + } + + hasPrev() { + return this.button_group.hasPrev && this.button_group.hasPrev(); + } + + hasNext() { + return this.button_group.hasNext && this.button_group.hasNext(); + } + + prependItems(items) { + this.options.items = items.concat(this.options.items); + this.button_group.prependItems(...arguments); + this.check(); + } + + addItems(items) { + this.options.items = this.options.items.concat(items); + this.button_group.addItems(...arguments); + this.check(); + } + + removeItemAt(indexes) { + indexes = isNull(indexes) ? [] : indexes; + removeAt(this.options.items, indexes); + this.button_group.removeItemAt(...arguments); + this.check(); + } + + populate(items) { + const o = this.options; + if (arguments.length === 0 && isFunction(this.button_group.attr("itemsCreator"))) { + // 接管loader的populate方法 + this.button_group.attr("itemsCreator").apply(this, [ + { times: 1 }, + (...args) => { + if (args.length === 0) { + throw new Error("Parameter cannot be empty"); + } + this.populate(...args); + } + ]); + + return; + } + + const context = get(arguments, [2], {}); + const tipText = context.tipText || ""; + if (isNotEmptyString(tipText)) { + super.populate.apply(this, []); + this.setTipText(tipText); + } else { + super.populate(...arguments); + this.button_group.populate(...arguments); + isEmptyArray(get(arguments, [0], [])) && this.setTipText(o.tipText); + } + } + + empty() { + this.button_group.empty(); + } + + setNotSelectedValue() { + this.button_group.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.button_group.getNotSelectedValue(); + } + + setValue() { + this.button_group.setValue(...arguments); + } + + setAllSelected(v) { + if (this.button_group.setAllSelected) { + this.button_group.setAllSelected(v); + } else { + each(this.getAllButtons(), (i, btn) => { + (btn.setSelected || btn.setAllSelected).apply(btn, [v]); + }); + } + } + + getValue() { + return this.button_group.getValue(...arguments); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + getAllLeaves() { + return this.button_group.getAllLeaves(); + } + + getSelectedButtons() { + return this.button_group.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.button_group.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.button_group.getIndexByValue(value); + } + + getNodeById(id) { + return this.button_group.getNodeById(id); + } + + getNodeByValue(value) { + return this.button_group.getNodeByValue(value); + } +} diff --git a/packages/fineui/src/case/layer/panel.js b/packages/fineui/src/case/layer/panel.js new file mode 100644 index 000000000..2ce1be1ac --- /dev/null +++ b/packages/fineui/src/case/layer/panel.js @@ -0,0 +1,88 @@ +import { + VerticalFillLayout, + CenterAdaptLayout, + LeftRightVerticalAdaptLayout, + shortcut, + Widget, + extend, + toPix, + Controller, + createWidget +} from "@/core"; +import { Label, ButtonGroup } from "@/base"; + +@shortcut() +export class Panel extends Widget { + static xtype = "bi.panel"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-panel bi-border", + title: "", + titleHeight: 30, + titleButtons: [], + el: {}, + // logic: { + // dynamic: false + // } + }); + } + + render() { + return { + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + items: [this._createTitle(), this.options.el], + }; + } + + _createTitle() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + cls: "panel-title-text", + text: o.title, + height: o.titleHeight, + }); + + this.button_group = createWidget({ + type: ButtonGroup.xtype, + items: o.titleButtons, + layouts: [ + { + type: CenterAdaptLayout.xtype, + lgap: 10, + } + ], + }); + + this.button_group.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.button_group.on(ButtonGroup.EVENT_CHANGE, (value, obj) => { + this.fireEvent(Panel.EVENT_CHANGE, value, obj); + }); + + return { + // el: { + type: LeftRightVerticalAdaptLayout.xtype, + cls: "panel-title bi-header-background bi-border-bottom", + height: toPix(o.titleHeight, 1), + items: { + left: [this.text], + right: [this.button_group], + }, + lhgap: 10, + rhgap: 10, + // }, + // height: toPix(o.titleHeight, 1) + }; + } + + setTitle(title) { + this.text.setValue(title); + } +} diff --git a/packages/fineui/src/case/linearsegment/button.linear.segment.js b/packages/fineui/src/case/linearsegment/button.linear.segment.js new file mode 100644 index 000000000..44316cb76 --- /dev/null +++ b/packages/fineui/src/case/linearsegment/button.linear.segment.js @@ -0,0 +1,64 @@ +import { Label, BasicButton } from "@/base"; +import { AbsoluteLayout, Layout, shortcut, toPix } from "@/core"; + +@shortcut() +export class LinearSegmentButton extends BasicButton { + static xtype = "bi.linear_segment_button"; + + props = { + extraCls: "bi-line-segment-button bi-list-item-effect", + once: true, + readonly: true, + hgap: 10, + height: 24, + }; + + render() { + const o = this.options; + + return [ + { + type: Label.xtype, + text: o.text, + height: o.height, + textHeight: toPix(o.height, 2), + value: o.value, + hgap: o.hgap, + ref: _ref => { + this.text = _ref; + }, + }, + { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "line-segment-button-line", + height: 2, + ref: _ref => { + this.line = _ref; + }, + }, + left: 0, + right: 0, + bottom: 0, + } + ], + } + ]; + } + + setSelected(v) { + super.setSelected(...arguments); + if (v) { + this.line.element.addClass("bi-high-light-background"); + } else { + this.line.element.removeClass("bi-high-light-background"); + } + } + + setText(text) { + this.text.setText(text); + } +} diff --git a/packages/fineui/src/case/linearsegment/index.js b/packages/fineui/src/case/linearsegment/index.js new file mode 100644 index 000000000..339335d84 --- /dev/null +++ b/packages/fineui/src/case/linearsegment/index.js @@ -0,0 +1,2 @@ +export { LinearSegmentButton } from "./button.linear.segment"; +export { LinearSegment } from "./linear.segment"; diff --git a/packages/fineui/src/case/linearsegment/linear.segment.js b/packages/fineui/src/case/linearsegment/linear.segment.js new file mode 100644 index 000000000..98c5a5bb8 --- /dev/null +++ b/packages/fineui/src/case/linearsegment/linear.segment.js @@ -0,0 +1,70 @@ +import { ButtonGroup } from "@/base"; +import { LinearSegmentButton } from "./button.linear.segment"; +import { TableLayout, shortcut, Widget, createItems, makeArrayByArray } from "@/core"; + +@shortcut() +export class LinearSegment extends Widget { + static xtype = "bi.linear_segment"; + + props = { baseCls: "bi-linear-segment", items: [], height: 30 }; + + render() { + const o = this.options; + + return { + type: ButtonGroup.xtype, + items: [ + createItems(o.items, { + type: LinearSegmentButton.xtype, + height: o.height, + }) + ], + layouts: [ + { + type: TableLayout.xtype, + columnSize: makeArrayByArray(o.items, "fill"), + } + ], + value: o.value, + listeners: [ + { + eventName: "__EVENT_CHANGE__", + action: (...args) => { + this.fireEvent("__EVENT_CHANGE__", ...args); + }, + }, + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + ref: _ref => { + this.buttonGroup = _ref; + }, + }; + } + + setValue(v) { + this.buttonGroup.setValue(v); + } + + setEnabledValue(v) { + this.buttonGroup.setEnabledValue(v); + } + + getValue() { + return this.buttonGroup.getValue(); + } + + populate(buttons) { + const o = this.options; + this.buttonGroup.populate([ + createItems(buttons, { + type: LinearSegmentButton.xtype, + height: o.height, + }) + ]); + } +} diff --git a/packages/fineui/src/case/list/list.select.js b/packages/fineui/src/case/list/list.select.js new file mode 100644 index 000000000..4301aff57 --- /dev/null +++ b/packages/fineui/src/case/list/list.select.js @@ -0,0 +1,270 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + Controller, + createWidget, + Events, + isNotNull, + isEmptyString, + isEmptyArray, + Direction, + get, + LogicFactory, + each, + pixFormat +} from "@/core"; +import { ButtonGroup } from "@/base"; +import { MultiSelectBar } from "../toolbar/toolbar.multiselect"; +import { ListPane } from "../layer/pane.list"; + +/* eslint-disable no-mixed-spaces-and-tabs */ + +@shortcut() +export class SelectList extends Widget { + static xtype = "bi.select_list"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-list", + direction: Direction.Top, // toolbar的位置 + logic: { + dynamic: true, + }, + items: [], + itemsCreator: emptyFn, + hasNext: emptyFn, + onLoaded: emptyFn, + toolbar: { + type: MultiSelectBar.xtype, + iconWrapperWidth: 36, + }, + el: { + type: ListPane.xtype, + }, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + // 全选 + this.toolbar = createWidget(o.toolbar); + this.allSelected = false; + this.toolbar.on(Controller.EVENT_CHANGE, (...args) => { + const [type, value, obj] = args; + this.allSelected = this.toolbar.isSelected(); + if (type === Events.CLICK) { + this.setAllSelected(this.allSelected); + this.fireEvent(SelectList.EVENT_CHANGE, value, obj); + } + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.list = createWidget(o.el, { + type: ListPane.xtype, + items: o.items, + itemsCreator: (op, callback) => { + op.times === 1 && this.toolbar.setVisible(false); + o.itemsCreator(op, (items, keywords, context, ...args) => { + callback(items, keywords, context, ...args); + if (op.times === 1) { + const tipText = get(context, "tipText", ""); + const visible = isEmptyString(tipText) && items && items.length > 0; + this.toolbar.setVisible(visible); + this.toolbar.setEnable(this.isEnabled() && visible); + } + this._checkAllSelected(); + }); + }, + onLoaded: o.onLoaded, + hasNext: o.hasNext, + }); + + this.list.on(Controller.EVENT_CHANGE, (...args) => { + const [type, value, obj] = args; + if (type === Events.CLICK) { + this._checkAllSelected(); + this.fireEvent(SelectList.EVENT_CHANGE, value, obj); + } + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(o.direction), + extend( + { + scrolly: true, + }, + o.logic, + { + items: LogicFactory.createLogicItemsByDirection(o.direction, this.toolbar, this.list), + } + ) + ) + ) + ); + + if (o.items.length <= 0) { + this.toolbar.setVisible(false); + this.toolbar.setEnable(false); + } + if (isNotNull(o.value)) { + this.setValue(o.value); + } + } + + _checkAllSelected() { + const selectLength = this.list.getValue().length; + const notSelectLength = this.getAllLeaves().length - selectLength; + const hasNext = this.list.hasNext(); + const isAlreadyAllSelected = this.toolbar.isSelected(); + let isHalf = selectLength > 0 && notSelectLength > 0; + let allSelected = selectLength > 0 && notSelectLength <= 0 && (!hasNext || isAlreadyAllSelected); + + if (this.isAllSelected() === false) { + hasNext && (isHalf = selectLength > 0); + if (!isAlreadyAllSelected && notSelectLength === 0 && !hasNext) { + allSelected = true; + } + } else { + hasNext && (isHalf = notSelectLength > 0); + if (!isAlreadyAllSelected && notSelectLength === 0) { + allSelected = true; + } + } + + this.toolbar.setHalfSelected(isHalf); + !isHalf && this.toolbar.setSelected(allSelected); + } + + setAllSelected(v) { + if (this.list.setAllSelected) { + this.list.setAllSelected(v); + } else { + each(this.getAllButtons(), (i, btn) => { + (btn.setSelected || btn.setAllSelected).apply(btn, [v]); + }); + } + this.allSelected = !!v; + this.toolbar.setSelected(v); + this.toolbar.setHalfSelected(false); + } + + setToolBarVisible(b) { + this.toolbar.setVisible(b); + } + + isAllSelected() { + return this.allSelected; + // return this.toolbar.isSelected(); + } + + hasPrev() { + return this.list.hasPrev(); + } + + hasNext() { + return this.list.hasNext(); + } + + prependItems(items) { + this.list.prependItems(...arguments); + } + + addItems(items) { + this.list.addItems(...arguments); + } + + setValue(data) { + const selectAll = data.type === ButtonGroup.CHOOSE_TYPE_ALL; + this.setAllSelected(selectAll); + this.list[selectAll ? "setNotSelectedValue" : "setValue"](data.value); + this._checkAllSelected(); + } + + getValue() { + if (this.isAllSelected() === false) { + return { + type: ButtonGroup.CHOOSE_TYPE_MULTI, + value: this.list.getValue(), + assist: this.list.getNotSelectedValue(), + }; + } + + return { + type: ButtonGroup.CHOOSE_TYPE_ALL, + value: this.list.getNotSelectedValue(), + assist: this.list.getValue(), + }; + } + + empty() { + this.list.empty(); + } + + populate(items) { + this.toolbar.setVisible(!isEmptyArray(items)); + this.toolbar.setEnable(this.isEnabled() && !isEmptyArray(items)); + this.list.populate(...arguments); + this._checkAllSelected(); + } + + _setEnable(enable) { + super._setEnable(...arguments); + this.toolbar.setEnable(enable); + } + + resetHeight(h) { + const toolHeight = (this.toolbar.element.outerHeight() || 25) * (this.toolbar.isVisible() ? 1 : 0); + this.list.resetHeight + ? this.list.resetHeight(h - toolHeight) + : this.list.element.css({ "max-height": pixFormat(h - toolHeight) }); + } + + setNotSelectedValue() { + this.list.setNotSelectedValue(...arguments); + this._checkAllSelected(); + } + + getNotSelectedValue() { + return this.list.getNotSelectedValue(); + } + + getAllButtons() { + return this.list.getAllButtons(); + } + + getAllLeaves() { + return this.list.getAllLeaves(); + } + + getSelectedButtons() { + return this.list.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.list.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.list.getIndexByValue(value); + } + + getNodeById(id) { + return this.list.getNodeById(id); + } + + getNodeByValue(value) { + return this.list.getNodeByValue(value); + } +} diff --git a/src/case/loader/__test__/loader.lazy.test.js b/packages/fineui/src/case/loader/__test__/loader.lazy.test.js similarity index 100% rename from src/case/loader/__test__/loader.lazy.test.js rename to packages/fineui/src/case/loader/__test__/loader.lazy.test.js diff --git a/src/case/loader/__test__/loader.list.test.js b/packages/fineui/src/case/loader/__test__/loader.list.test.js similarity index 100% rename from src/case/loader/__test__/loader.list.test.js rename to packages/fineui/src/case/loader/__test__/loader.list.test.js diff --git a/packages/fineui/src/case/loader/index.js b/packages/fineui/src/case/loader/index.js new file mode 100644 index 000000000..0fe9aa242 --- /dev/null +++ b/packages/fineui/src/case/loader/index.js @@ -0,0 +1,3 @@ +export { LazyLoader } from "./loader.lazy"; +export { ListLoader } from "./loader.list"; +export { SortList } from "./sort.list"; diff --git a/packages/fineui/src/case/loader/loader.lazy.js b/packages/fineui/src/case/loader/loader.lazy.js new file mode 100644 index 000000000..eddfa82c6 --- /dev/null +++ b/packages/fineui/src/case/loader/loader.lazy.js @@ -0,0 +1,106 @@ +import { Loader } from "@/base"; +import { shortcut, Widget, extend, createWidget, takeRight, take } from "@/core"; + +@shortcut() +export class LazyLoader extends Widget { + static xtype = "bi.lazy_loader"; + + _const = { + PAGE: 100, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-lazy-loader", + el: {}, + items: [], + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + const all = o.items.length; + this.loader = createWidget({ + type: Loader.xtype, + element: this, + // 下面是button_group的属性 + el: o.el, + itemsCreator: (options, populate) => { + populate(this._getNextItems(options)); + }, + hasNext: option => option.count < all, + }); + + this.loader.on(Loader.EVENT_CHANGE, obj => { + this.fireEvent(LazyLoader.EVENT_CHANGE, obj); + }); + } + + _getNextItems(options) { + const o = this.options; + const lastNum = o.items.length - this._const.PAGE * (options.times - 1); + const lastItems = takeRight(o.items, lastNum); + const nextItems = take(lastItems, this._const.PAGE); + + return nextItems; + } + + populate(items) { + this.loader.populate(items); + } + + addItems(items) { + this.loader.addItems(items); + } + + empty() { + this.loader.empty(); + } + + setNotSelectedValue() { + this.loader.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.loader.getNotSelectedValue(); + } + + setValue() { + this.loader.setValue(...arguments); + } + + getValue() { + return this.loader.getValue(...arguments); + } + + getAllButtons() { + return this.loader.getAllButtons(); + } + + getAllLeaves() { + return this.loader.getAllLeaves(); + } + + getSelectedButtons() { + return this.loader.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.loader.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.loader.getIndexByValue(value); + } + + getNodeById(id) { + return this.loader.getNodeById(id); + } + + getNodeByValue(value) { + return this.loader.getNodeByValue(value); + } +} diff --git a/packages/fineui/src/case/loader/loader.list.js b/packages/fineui/src/case/loader/loader.list.js new file mode 100644 index 000000000..b521b7e6c --- /dev/null +++ b/packages/fineui/src/case/loader/loader.list.js @@ -0,0 +1,242 @@ +import { ButtonGroup, LoadingBar } from "@/base"; +import { + VerticalLayout, + shortcut, + Widget, + extend, + emptyFn, + Controller, + createWidget, + Events, + nextTick, + bind, + isEmpty, + isNumber, + isObject, + isFunction, + each, + isNotEmptyArray, + DOM +} from "@/core"; + +/** + * 恶心的加载控件, 为解决排序问题引入的控件 + * + * Created by GUY on 2015/11/12. + * @class ListLoader + * @extends Widget + */ +@shortcut() +export class ListLoader extends Widget { + static xtype = "bi.list_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-list-loader", + isDefaultInit: true, // 是否默认初始化数据 + // 下面是button_group的属性 + el: { + type: ButtonGroup.xtype, + }, + items: [], + itemsCreator: emptyFn, + onLoaded: emptyFn, + // 下面是分页信息 + count: false, + next: {}, + hasNext: emptyFn, + }); + } + + _nextLoad() { + const o = this.options; + this.next.setLoading(); + o.itemsCreator.apply(this, [ + { + times: ++this.times, + }, + (...args) => { + this.next.setLoaded(); + this.addItems(...args); + } + ]); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (o.itemsCreator === false) { + o.next = false; + } + + this.button_group = createWidget(o.el, { + type: ButtonGroup.xtype, + element: this, + chooseType: 0, + items: o.items, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }); + this.button_group.on(Controller.EVENT_CHANGE, (...args) => { + const [type, , obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(ListLoader.EVENT_CHANGE, obj); + } + }); + + if (o.next !== false) { + this.next = createWidget( + extend( + { + type: LoadingBar.xtype, + }, + o.next + ) + ); + this.next.on(Controller.EVENT_CHANGE, type => { + if (type === Events.CLICK) { + this._nextLoad(); + } + }); + } + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.next], + }); + + o.isDefaultInit && + isEmpty(o.items) && + nextTick( + bind(function () { + this.populate(); + }, this) + ); + if (isNotEmptyArray(o.items)) { + this.populate(o.items); + } + } + + hasNext() { + const o = this.options; + if (isNumber(o.count)) { + return this.count < o.count; + } + + return !!o.hasNext.apply(this, [ + { + times: this.times, + count: this.count, + } + ]); + } + + addItems(items) { + this.count += items.length; + if (isObject(this.next)) { + this.options.items = this.options.items.concat(items); + if (this.hasNext()) { + this.next.setLoaded(); + } else { + this.next.setEnd(); + } + } + this.button_group.addItems(...arguments); + this.next.element.appendTo(this.element); + } + + populate(items) { + const o = this.options; + if (arguments.length === 0 && isFunction(o.itemsCreator)) { + o.itemsCreator.apply(this, [ + { + times: 1, + }, + (...args) => { + if (args.length === 0) { + throw new Error("parameter cannot be empty"); + } + this.populate(...args); + o.onLoaded(); + } + ]); + + return; + } + this.options.items = items; + this.times = 1; + this.count = 0; + this.count += items.length; + if (isObject(this.next)) { + if (this.hasNext()) { + this.next.setLoaded(); + } else { + this.next.invisible(); + } + } + DOM.hang([this.next]); + this.button_group.populate(...arguments); + this.next.element.appendTo(this.element); + } + + empty() { + DOM.hang([this.next]); + this.button_group.empty(); + this.next.element.appendTo(this.element); + each([this.next], (i, ob) => { + ob && ob.setVisible(false); + }); + } + + setNotSelectedValue() { + this.button_group.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.button_group.getNotSelectedValue(); + } + + setValue() { + this.button_group.setValue(...arguments); + } + + getValue() { + return this.button_group.getValue(...arguments); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + getAllLeaves() { + return this.button_group.getAllLeaves(); + } + + getSelectedButtons() { + return this.button_group.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.button_group.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.button_group.getIndexByValue(value); + } + + getNodeById(id) { + return this.button_group.getNodeById(id); + } + + getNodeByValue(value) { + return this.button_group.getNodeByValue(value); + } +} diff --git a/packages/fineui/src/case/loader/sort.list.js b/packages/fineui/src/case/loader/sort.list.js new file mode 100644 index 000000000..66482aae9 --- /dev/null +++ b/packages/fineui/src/case/loader/sort.list.js @@ -0,0 +1,177 @@ +import { ButtonGroup } from "@/base"; +import { ListLoader } from "./loader.list"; +import { Layout, shortcut, Widget, extend, emptyFn, Controller, createWidget, Events, each, stripEL } from "@/core"; + +/** + * Created by GUY on 2016/4/29. + * + * @class SortList + * @extends Widget + */ +@shortcut() +export class SortList extends Widget { + static xtype = "bi.sort_list"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-sort-list", + isDefaultInit: true, // 是否默认初始化数据 + // 下面是button_group的属性 + el: { + type: ButtonGroup.xtype, + }, + items: [], + itemsCreator: emptyFn, + onLoaded: emptyFn, + // 下面是分页信息 + count: false, + next: {}, + hasNext: emptyFn, + // containment: this.element, + // connectWith: ".bi-sort-list", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.loader = createWidget({ + type: ListLoader.xtype, + element: this, + isDefaultInit: o.isDefaultInit, + el: o.el, + items: this._formatItems(o.items), + itemsCreator: (op, callback) => { + o.itemsCreator(op, items => { + callback(this._formatItems(items)); + }); + }, + onLoaded: o.onLoaded, + count: o.count, + next: o.next, + hasNext: o.hasNext, + }); + this.loader.on(Controller.EVENT_CHANGE, (...args) => { + const [type, value, obj] = args; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(SortList.EVENT_CHANGE, value, obj); + } + }); + + this.loader.element.sortable({ + containment: o.containment || this.element, + connectWith: o.connectWith || ".bi-sort-list", + items: ".sort-item", + cursor: o.cursor || "drag", + tolerance: o.tolerance || "intersect", + placeholder: { + element($currentItem) { + const holder = createWidget({ + type: Layout.xtype, + cls: "bi-sortable-holder", + height: $currentItem.outerHeight(), + }); + holder.element.css({ + "margin-left": $currentItem.css("margin-left"), + "margin-right": $currentItem.css("margin-right"), + "margin-top": $currentItem.css("margin-top"), + "margin-bottom": $currentItem.css("margin-bottom"), + margin: $currentItem.css("margin"), + }); + + return holder.element; + }, + update() {}, + }, + start(event, ui) {}, + stop: (event, ui) => { + this.fireEvent(SortList.EVENT_CHANGE); + }, + over(event, ui) {}, + }); + } + + _formatItems(items) { + each(items, (i, item) => { + item = stripEL(item); + item.cls = item.cls ? `${item.cls} sort-item` : "sort-item"; + item.attributes = { + sorted: item.value, + }; + }); + + return items; + } + + hasNext() { + return this.loader.hasNext(); + } + + addItems(items) { + this.loader.addItems(items); + } + + populate(items) { + if (items) { + arguments[0] = this._formatItems(items); + } + this.loader.populate(...arguments); + } + + empty() { + this.loader.empty(); + } + + setNotSelectedValue() { + this.loader.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.loader.getNotSelectedValue(); + } + + setValue() { + this.loader.setValue(...arguments); + } + + getValue() { + return this.loader.getValue(); + } + + getAllButtons() { + return this.loader.getAllButtons(); + } + + getAllLeaves() { + return this.loader.getAllLeaves(); + } + + getSelectedButtons() { + return this.loader.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.loader.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.loader.getIndexByValue(value); + } + + getNodeById(id) { + return this.loader.getNodeById(id); + } + + getNodeByValue(value) { + return this.loader.getNodeByValue(value); + } + + getSortedValues() { + return this.loader.element.sortable("toArray", { + attribute: "sorted", + }); + } +} diff --git a/src/case/pager/__test__/pager.test.js b/packages/fineui/src/case/pager/__test__/pager.test.js similarity index 100% rename from src/case/pager/__test__/pager.test.js rename to packages/fineui/src/case/pager/__test__/pager.test.js diff --git a/packages/fineui/src/case/pager/index.js b/packages/fineui/src/case/pager/index.js new file mode 100644 index 000000000..222ce3940 --- /dev/null +++ b/packages/fineui/src/case/pager/index.js @@ -0,0 +1,3 @@ +export { AllCountPager } from "./pager.all.count"; +export { DetailPager } from "./pager.detail"; +export { DirectionPager } from "./pager.direction"; diff --git a/packages/fineui/src/case/pager/pager.all.count.js b/packages/fineui/src/case/pager/pager.all.count.js new file mode 100644 index 000000000..3478902ff --- /dev/null +++ b/packages/fineui/src/case/pager/pager.all.count.js @@ -0,0 +1,264 @@ +import { Pager, IconButton, Label } from "@/base"; +import { + HorizontalLayout, + VerticalAdaptLayout, + FloatLeftLayout, + shortcut, + Widget, + extend, + isPositiveInteger, + createWidget, + parseInt, + HorizontalAlign, + isNotEmptyObject, + i18nText +} from "@/core"; +import { SmallTextEditor } from "@/widget/editor/editor.text.small"; +import { TextEditor } from "@/widget/editor/editor.text"; + +/** + * 有总页数和总行数的分页控件 + * Created by Young's on 2016/10/13. + */ + +// + +@shortcut() +export class AllCountPager extends Widget { + static xtype = "bi.all_count_pager"; + static EVENT_CHANGE = "EVENT_CHANGE"; + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-all-count-pager", + pagerDirection: "vertical", // 翻页按钮方向,可选值:vertical/horizontal + height: 24, + pages: 1, // 必选项 + curr: 1, // 初始化当前页, pages为数字时可用, + count: 1, // 总行数 + rowInfoObject: null, + showRowCount: true, + showRowInfo: true, + }); + } + _init() { + super._init(...arguments); + const { pages, curr, hasPrev, hasNext, firstPage, lastPage, height, showRowCount } = this.options, + pagerIconCls = this._getPagerIconCls(); + this.editor = createWidget({ + type: SmallTextEditor.xtype, + cls: "pager-editor bi-border-radius", + validationChecker(v) { + return (pages === 0 && v === "0") || isPositiveInteger(v); + }, + hgap: 4, + vgap: 0, + value: curr, + errorText: i18nText("BI-Please_Input_Positive_Integer"), + width: 40, + height: 24, + invisible: pages <= 1, + }); + + this.pager = createWidget({ + type: Pager.xtype, + width: 58, + layouts: [ + { + type: HorizontalLayout.xtype, + lgap: 5, + } + ], + + dynamicShow: false, + pages, + curr, + groups: 0, + + first: false, + last: false, + prev: { + type: IconButton.xtype, + value: "prev", + title: i18nText("BI-Previous_Page"), + warningTitle: i18nText("BI-Current_Is_First_Page"), + height: 22, + width: 22, + cls: `bi-border bi-border-radius all-pager-prev bi-list-item-select2 ${pagerIconCls.preCls}`, + }, + next: { + type: IconButton.xtype, + value: "next", + title: i18nText("BI-Next_Page"), + warningTitle: i18nText("BI-Current_Is_Last_Page"), + height: 22, + width: 22, + cls: `bi-border bi-border-radius all-pager-next bi-list-item-select2 ${pagerIconCls.nextCls}`, + }, + + hasPrev, + hasNext, + firstPage, + lastPage, + invisible: pages <= 1, + }); + + this.editor.on(TextEditor.EVENT_CONFIRM, () => { + this.pager.setValue(parseInt(this.editor.getValue())); + this.fireEvent(AllCountPager.EVENT_CHANGE); + }); + this.pager.on(Pager.EVENT_CHANGE, () => { + this.fireEvent(AllCountPager.EVENT_CHANGE); + }); + this.pager.on(Pager.EVENT_AFTER_POPULATE, () => { + this.editor.setValue(this.pager.getCurrentPage()); + }); + + this.allPages = createWidget({ + type: Label.xtype, + title: pages, + height, + text: `/${pages}`, + lgap: 5, + invisible: pages <= 1, + }); + + createWidget( + showRowCount + ? { + type: VerticalAdaptLayout.xtype, + element: this, + scrollx: false, + columnSize: ["fill", ""], + horizontalAlign: HorizontalAlign.Right, + items: [this._getRowCountObject(), this.editor, this.allPages, this.pager], + } + : { + type: VerticalAdaptLayout.xtype, + element: this, + items: [this.editor, this.allPages, this.pager], + } + ); + } + + _getPagerIconCls() { + const { pagerDirection } = this.options; + switch (pagerDirection) { + case "horizontal": + return { + preCls: "row-pre-page-h-font ", + nextCls: "row-next-page-h-font ", + }; + case "vertical": + default: + return { + preCls: "column-pre-page-h-font ", + nextCls: "column-next-page-h-font ", + }; + } + } + + _getRowCountObject() { + const { height, count, rowInfoObject } = this.options; + + return { + type: FloatLeftLayout.xtype, + height, + scrollable: false, + ref: _ref => { + this.rowCountObject = _ref; + }, + items: [ + { + type: Label.xtype, + height, + text: i18nText("BI-Basic_Total"), + ref: _ref => { + this.prevText = _ref; + }, + }, + { + el: { + type: Label.xtype, + ref: _ref => { + this.rowCount = _ref; + }, + cls: "row-count", + height, + text: count, + title: count, + }, + hgap: 5, + }, + { + type: Label.xtype, + height, + text: i18nText("BI-Tiao_Data"), + textAlign: "left", + }, + isNotEmptyObject(rowInfoObject) ? rowInfoObject : null + ], + }; + } + + setAllPages(v) { + this.allPages.setText(`/${v}`); + this.allPages.setTitle(v); + this.options.pages = v; + this.pager.setAllPages(v); + this.editor.setEnable(v >= 1); + this.setPagerVisible(v > 1); + } + + setShowRowInfo(b) { + this.options.showRowInfo = b; + this.rowCountObject.setVisible(b); + } + + setValue(v) { + this.pager.setValue(v); + } + + setVPage(v) { + this.pager.setValue(v); + } + + setCount(count) { + if (this.options.showRowCount) { + this.rowCount.setText(count); + this.rowCount.setTitle(count); + } + } + + setCountPrevText(text) { + if (this.options.showRowCount) { + this.prevText.setText(text); + } + } + + getCurrentPage() { + return this.pager.getCurrentPage(); + } + + hasPrev() { + return this.pager.hasPrev(); + } + + hasNext() { + return this.pager.hasNext(); + } + + isShowPager() { + return this.options.showRowInfo || this.options.pages > 1; + } + + setPagerVisible(b) { + this.editor.setVisible(b); + this.allPages.setVisible(b); + this.pager.setVisible(b); + } + + populate() { + this.pager.populate(); + this.setPagerVisible(this.options.pages > 1); + } +} diff --git a/packages/fineui/src/case/pager/pager.detail.js b/packages/fineui/src/case/pager/pager.detail.js new file mode 100644 index 000000000..5da61c224 --- /dev/null +++ b/packages/fineui/src/case/pager/pager.detail.js @@ -0,0 +1,335 @@ +import { + HorizontalLayout, + shortcut, + Widget, + extend, + emptyFn, + result, + debounce, + isKey, + createWidget, + createItems, + Controller, + Events, + MIN, + MAX, + i18nText +} from "@/core"; +import { Label, ButtonGroup } from "@/base"; + +/** + * 分页控件 + * + * Created by GUY on 2015/8/31. + * @class DetailPager + * @extends Widget + */ + +@shortcut() +export class DetailPager extends Widget { + static xtype = "bi.detail_pager"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-detail-pager", + behaviors: {}, + layouts: [ + { + type: HorizontalLayout.xtype, + } + ], + + dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 + // dynamicShow为false时以下两个有用 + dynamicShowFirstLast: false, // 是否动态显示首页、尾页 + dynamicShowPrevNext: false, // 是否动态显示上一页、下一页 + pages: false, // 总页数 + curr() { + return 1; + }, // 初始化当前页 + groups: 0, // 连续显示分页数 + jump: emptyFn, // 分页的回调函数 + + first: false, // 是否显示首页 + last: false, // 是否显示尾页 + prev: i18nText("BI-Previous_Page"), + next: i18nText("BI-Next_Page"), + + firstPage: 1, + lastPage() { + // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 + return 1; + }, + hasPrev: emptyFn, // pages不可用时有效 + hasNext: emptyFn, // pages不可用时有效 + }); + } + _init() { + super._init(...arguments); + this.currPage = result(this.options, "curr"); + // 翻页太灵敏 + this._lock = false; + this._debouce = debounce(() => { + this._lock = false; + }, 300); + this._populate(); + } + _populate() { + const o = this.options, + view = [], + dict = {}; + const { dynamicShow, dynamicShowPrevNext, hasPrev, dynamicShowFirstLast, hasNext, behaviors, layouts, jump } = + this.options; + this.empty(); + const pages = result(o, "pages"); + const curr = result(this, "currPage"); + let groups = result(o, "groups"); + let first = result(o, "first"); + let last = result(o, "last"); + const prev = result(o, "prev"); + const next = result(o, "next"); + + if (pages === false) { + groups = 0; + first = false; + last = false; + } else { + groups > pages && (groups = pages); + } + + // 计算当前组 + dict.index = Math.ceil((curr + (groups > 1 && groups !== pages ? 1 : 0)) / (groups === 0 ? 1 : groups)); + + // 当前页非首页,则输出上一页 + if (((!dynamicShow && !dynamicShowPrevNext) || curr > 1) && prev !== false) { + if (isKey(prev)) { + view.push({ + text: prev, + value: "prev", + disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false), + }); + } else { + view.push( + extend( + { + disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false), + }, + prev + ) + ); + } + } + + // 当前组非首组,则输出首页 + if (((!dynamicShow && !dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { + view.push({ + text: first, + value: "first", + disabled: !(dict.index > 1 && groups !== 0), + }); + if (dict.index > 1 && groups !== 0) { + view.push({ + type: Label.xtype, + cls: "page-ellipsis", + text: "\u2026", + }); + } + } + + // 输出当前页组 + dict.poor = Math.floor((groups - 1) / 2); + dict.start = dict.index > 1 ? curr - dict.poor : 1; + dict.end = + dict.index > 1 + ? (function () { + const max = curr + (groups - dict.poor - 1); + + return max > pages ? pages : max; + }()) + : groups; + if (dict.end - dict.start < groups - 1) { + // 最后一组状态 + dict.start = dict.end - groups + 1; + } + let s = dict.start, + e = dict.end; + if (first && last && dict.index > 1 && groups !== 0 && pages > groups && dict.end < pages && groups !== 0) { + s++; + e--; + } + for (; s <= e; s++) { + if (s === curr) { + view.push({ + text: s, + value: s, + selected: true, + }); + } else { + view.push({ + text: s, + value: s, + }); + } + } + + // 总页数大于连续分页数,且当前组最大页小于总页,输出尾页 + if (((!dynamicShow && !dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { + if (pages > groups && dict.end < pages && groups !== 0) { + view.push({ + type: Label.xtype, + cls: "page-ellipsis", + text: "\u2026", + }); + } + view.push({ + text: last, + value: "last", + disabled: !(pages > groups && dict.end < pages && groups !== 0), + }); + } + + // 当前页不为尾页时,输出下一页 + dict.flow = !prev && groups === 0; + if ((!dynamicShow && !dynamicShowPrevNext && next) || (curr !== pages && next) || dict.flow) { + view.push( + (function () { + if (isKey(next)) { + if (pages === false) { + return { text: next, value: "next", disabled: hasNext(curr) === false }; + } + + return dict.flow && curr === pages + ? { text: next, value: "next", disabled: true } + : { text: next, value: "next", disabled: !((curr !== pages && next) || dict.flow) }; + } + + return extend( + { + disabled: + pages === false ? hasNext(curr) === false : !((curr !== pages && next) || dict.flow), + }, + next + ); + })() + ); + } + + this.button_group = createWidget({ + type: ButtonGroup.xtype, + element: this, + items: createItems(view, { + cls: "page-item bi-border bi-list-item-active", + height: 23, + }), + behaviors, + layouts, + }); + this.button_group.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { + if (this._lock === true) { + return; + } + this._lock = true; + this._debouce(); + if (type === Events.CLICK) { + const v = this.button_group.getValue()[0]; + switch (v) { + case "first": + this.currPage = 1; + break; + case "last": + this.currPage = pages; + break; + case "prev": + this.currPage--; + break; + case "next": + this.currPage++; + break; + default: + this.currPage = v; + break; + } + jump.apply(this, [ + { + pages, + curr: this.currPage, + } + ]); + this._populate(); + this.fireEvent(DetailPager.EVENT_CHANGE, obj); + } + this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); + }); + this.fireEvent(DetailPager.EVENT_AFTER_POPULATE); + } + + getCurrentPage() { + return this.currPage; + } + + setAllPages(pages) { + this.options.pages = pages; + this._populate(); + } + + hasPrev(v) { + v || (v = 1); + const { hasPrev } = this.options; + const pages = this.options.pages; + + return pages === false ? hasPrev(v) : v > 1; + } + + hasNext(v) { + v || (v = 1); + const { hasNext } = this.options; + const pages = this.options.pages; + + return pages === false ? hasNext(v) : v < pages; + } + + setValue(v) { + const o = this.options; + const { pages } = this.options; + v = v || 0; + v = v < 1 ? 1 : v; + if (pages === false) { + const lastPage = result(o, "lastPage"); + let firstPage = 1; + this.currPage = + v > lastPage ? lastPage : ((firstPage = result(o, "firstPage")), v < firstPage ? firstPage : v); + } else { + v = v > pages ? pages : v; + this.currPage = v; + } + this._populate(); + } + + getValue() { + const val = this.button_group.getValue()[0]; + switch (val) { + case "prev": + return -1; + case "next": + return 1; + case "first": + return MIN; + case "last": + return MAX; + default: + return val; + } + } + + attr(key, value) { + super.attr(...arguments); + if (key === "curr") { + this.currPage = result(this.options, "curr"); + } + } + + populate() { + this._populate(); + } +} diff --git a/packages/fineui/src/case/pager/pager.direction.js b/packages/fineui/src/case/pager/pager.direction.js new file mode 100644 index 000000000..53cc51b82 --- /dev/null +++ b/packages/fineui/src/case/pager/pager.direction.js @@ -0,0 +1,286 @@ +import { AbsoluteLayout, HorizontalLayout, shortcut, Widget, extend, emptyFn, createWidget, i18nText } from "@/core"; +import { Label, Pager, IconButton } from "@/base"; + +/** + * 显示页码的分页控件 + * + * Created by GUY on 2016/6/30. + * @class DirectionPager + * @extends Widget + */ + +@shortcut() +export class DirectionPager extends Widget { + static EVENT_CHANGE = "EVENT_CHANGE"; + static xtype = "bi.direction_pager"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-direction-pager", + height: 24, + horizontal: { + pages: false, // 总页数 + curr: 1, // 初始化当前页, pages为数字时可用 + + hasPrev: emptyFn, + hasNext: emptyFn, + firstPage: 1, + lastPage: emptyFn, + }, + vertical: { + pages: false, // 总页数 + curr: 1, // 初始化当前页, pages为数字时可用 + + hasPrev: emptyFn, + hasNext: emptyFn, + firstPage: 1, + lastPage: emptyFn, + }, + }); + } + _init() { + super._init(...arguments); + this._createVPager(); + this._createHPager(); + this.layout = createWidget({ + type: AbsoluteLayout.xtype, + scrollable: false, + element: this, + items: [ + { + el: this.vpager, + top: 0, + right: 86, + }, + { + el: this.vlabel, + top: 0, + right: 110, + }, + { + el: this.hpager, + top: 0, + right: 0, + }, + { + el: this.hlabel, + top: 0, + right: 24, + } + ], + }); + } + + _createVPager() { + const v = this.options.vertical; + this.vlabel = createWidget({ + type: Label.xtype, + width: 24, + height: 24, + value: v.curr, + title: v.curr, + invisible: true, + }); + this.vpager = createWidget({ + type: Pager.xtype, + width: 72, + layouts: [ + { + type: HorizontalLayout.xtype, + scrollx: false, + rgap: 24, + } + ], + invisible: true, + + dynamicShow: false, + pages: v.pages, + curr: v.curr, + groups: 0, + + first: false, + last: false, + prev: { + type: IconButton.xtype, + value: "prev", + title: i18nText("BI-Up_Page"), + warningTitle: i18nText("BI-Current_Is_First_Page"), + height: 22, + width: 22, + cls: "bi-border bi-border-radius direction-pager-prev column-pre-page-h-font bi-list-item-select2", + }, + next: { + type: IconButton.xtype, + value: "next", + title: i18nText("BI-Down_Page"), + warningTitle: i18nText("BI-Current_Is_Last_Page"), + height: 22, + width: 22, + cls: "bi-border bi-border-radius direction-pager-next column-next-page-h-font bi-list-item-select2", + }, + + hasPrev: v.hasPrev, + hasNext: v.hasNext, + firstPage: v.firstPage, + lastPage: v.lastPage, + }); + + this.vpager.on(Pager.EVENT_CHANGE, () => { + this.fireEvent(DirectionPager.EVENT_CHANGE); + }); + this.vpager.on(Pager.EVENT_AFTER_POPULATE, () => { + this.vlabel.setValue(this.vpager.getCurrentPage()); + this.vlabel.setTitle(this.vpager.getCurrentPage()); + }); + } + _createHPager() { + const h = this.options.horizontal; + this.hlabel = createWidget({ + type: Label.xtype, + width: 24, + height: 24, + value: h.curr, + title: h.curr, + invisible: true, + }); + this.hpager = createWidget({ + type: Pager.xtype, + width: 72, + layouts: [ + { + type: HorizontalLayout.xtype, + scrollx: false, + rgap: 24, + } + ], + invisible: true, + + dynamicShow: false, + pages: h.pages, + curr: h.curr, + groups: 0, + + first: false, + last: false, + prev: { + type: IconButton.xtype, + value: "prev", + title: i18nText("BI-Left_Page"), + warningTitle: i18nText("BI-Current_Is_First_Page"), + height: 22, + width: 22, + cls: "bi-border bi-border-radius direction-pager-prev row-pre-page-h-font bi-list-item-select2", + }, + next: { + type: IconButton.xtype, + value: "next", + title: i18nText("BI-Right_Page"), + warningTitle: i18nText("BI-Current_Is_Last_Page"), + height: 22, + width: 22, + cls: "bi-border bi-border-radius direction-pager-next row-next-page-h-font bi-list-item-select2", + }, + + hasPrev: h.hasPrev, + hasNext: h.hasNext, + firstPage: h.firstPage, + lastPage: h.lastPage, + }); + + this.hpager.on(Pager.EVENT_CHANGE, () => { + this.fireEvent(DirectionPager.EVENT_CHANGE); + }); + this.hpager.on(Pager.EVENT_AFTER_POPULATE, () => { + this.hlabel.setValue(this.hpager.getCurrentPage()); + this.hlabel.setTitle(this.hpager.getCurrentPage()); + }); + } + + getVPage() { + return this.vpager.getCurrentPage(); + } + + getHPage() { + return this.hpager.getCurrentPage(); + } + + setVPage(v) { + this.vpager.setValue(v); + this.vlabel.setValue(v); + this.vlabel.setTitle(v); + } + + setHPage(v) { + this.hpager.setValue(v); + this.hlabel.setValue(v); + this.hlabel.setTitle(v); + } + + hasVNext() { + return this.vpager.hasNext(); + } + + hasHNext() { + return this.hpager.hasNext(); + } + + hasVPrev() { + return this.vpager.hasPrev(); + } + + hasHPrev() { + return this.hpager.hasPrev(); + } + + setHPagerVisible(b) { + this.hpager.setVisible(b); + this.hlabel.setVisible(b); + } + + setVPagerVisible(b) { + this.vpager.setVisible(b); + this.vlabel.setVisible(b); + } + + populate() { + this.vpager.populate(); + this.hpager.populate(); + let vShow = false, + hShow = false; + if (!this.hasHNext() && !this.hasHPrev()) { + this.setHPagerVisible(false); + } else { + this.setHPagerVisible(true); + hShow = true; + } + if (!this.hasVNext() && !this.hasVPrev()) { + this.setVPagerVisible(false); + } else { + this.setVPagerVisible(true); + vShow = true; + } + this.setVisible(hShow || vShow); + const num = [86, 110, 0, 24]; + const items = this.layout.attr("items"); + + if (vShow === true && hShow === true) { + items[0].right = num[0]; + items[1].right = num[1]; + items[2].right = num[2]; + items[3].right = num[3]; + } else if (vShow === true) { + items[0].right = num[2]; + items[1].right = num[3]; + } else if (hShow === true) { + items[2].right = num[2]; + items[3].right = num[3]; + } + this.layout.attr("items", items); + this.layout.resize(); + } + + clear() { + this.vpager.attr("curr", 1); + this.hpager.attr("curr", 1); + } +} diff --git a/src/case/segment/__test__/segment.test.js b/packages/fineui/src/case/segment/__test__/segment.test.js similarity index 100% rename from src/case/segment/__test__/segment.test.js rename to packages/fineui/src/case/segment/__test__/segment.test.js diff --git a/packages/fineui/src/case/segment/button.segment.js b/packages/fineui/src/case/segment/button.segment.js new file mode 100644 index 000000000..160fb645d --- /dev/null +++ b/packages/fineui/src/case/segment/button.segment.js @@ -0,0 +1,48 @@ +import { Label, BasicButton } from "@/base"; +import { shortcut, extend, createWidget } from "@/core"; + +/** + * 分段控件使用的button + * + * Created by GUY on 2015/9/7. + * @class SegmentButton + * @extends BasicButton + */ +@shortcut() +export class SegmentButton extends BasicButton { + static xtype = "bi.segment_button"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-segment-button bi-list-item-select bi-card`, + shadow: true, + readonly: true, + hgap: 5, + }); + } + + _init() { + super._init(...arguments); + const opts = this.options; + this.text = createWidget({ + type: Label.xtype, + element: this, + textHeight: opts.height, + whiteSpace: opts.whiteSpace, + text: opts.text, + value: opts.value, + hgap: opts.hgap, + }); + } + + setSelected() { + super.setSelected(...arguments); + } + + setText(text) { + super.setText(...arguments); + this.text.setText(text); + } +} diff --git a/packages/fineui/src/case/segment/index.js b/packages/fineui/src/case/segment/index.js new file mode 100644 index 000000000..59c90b855 --- /dev/null +++ b/packages/fineui/src/case/segment/index.js @@ -0,0 +1,2 @@ +export { SegmentButton } from "./button.segment"; +export { Segment } from "./segment"; diff --git a/packages/fineui/src/case/segment/segment.js b/packages/fineui/src/case/segment/segment.js new file mode 100644 index 000000000..d62baec9c --- /dev/null +++ b/packages/fineui/src/case/segment/segment.js @@ -0,0 +1,94 @@ +import { ButtonGroup } from "@/base"; +import { SegmentButton } from "./button.segment"; +import { + TableLayout, + shortcut, + Widget, + extend, + toPix, + Controller, + createWidget, + createItems, + makeArrayByArray +} from "@/core"; + +/** + * 单选按钮组 + * + * Created by GUY on 2015/9/7. + * @class Segment + * @extends Widget + */ +@shortcut() +export class Segment extends Widget { + static xtype = "bi.segment"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-segment", + items: [], + height: 24, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.buttonGroup = createWidget({ + element: this, + type: ButtonGroup.xtype, + value: o.value, + items: [ + createItems(o.items, { + type: SegmentButton.xtype, + whiteSpace: o.whiteSpace, + }) + ], + layouts: [ + { + type: TableLayout.xtype, + columnSize: makeArrayByArray(o.items, "fill"), + } + ], + }); + this.buttonGroup.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.buttonGroup.on(ButtonGroup.EVENT_CHANGE, (value, obj) => { + this.fireEvent(Segment.EVENT_CHANGE, value, obj); + }); + } + + _setEnable(enable) { + super._setEnable(...arguments); + if (enable === true) { + this.element.removeClass("base-disabled disabled"); + } else if (enable === false) { + this.element.addClass("base-disabled disabled"); + } + } + + setValue(v) { + this.buttonGroup.setValue(v); + } + + setEnabledValue(v) { + this.buttonGroup.setEnabledValue(v); + } + + getValue() { + return this.buttonGroup.getValue(); + } + + populate(buttons) { + const o = this.options; + this.buttonGroup.populate([ + createItems(buttons, { + type: SegmentButton.xtype, + whiteSpace: o.whiteSpace, + }) + ]); + } +} diff --git a/packages/fineui/src/case/toolbar/toolbar.multiselect.js b/packages/fineui/src/case/toolbar/toolbar.multiselect.js new file mode 100644 index 000000000..f0df9ce78 --- /dev/null +++ b/packages/fineui/src/case/toolbar/toolbar.multiselect.js @@ -0,0 +1,166 @@ +import { Checkbox, Label, BasicButton } from "@/base"; +import { HalfIconButton } from "../button"; +import { + HTapeLayout, + CenterAdaptLayout, + shortcut, + extend, + emptyFn, + i18nText, + Controller, + createWidget, + Events +} from "@/core"; + +/** + * guy + * 复选导航条 + * Created by GUY on 2015/8/25. + * @class MultiSelectBar + * @extends BasicButton + */ +@shortcut() +export class MultiSelectBar extends BasicButton { + static xtype = "bi.multi_select_bar"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-multi-select-bar", + height: 25, + text: i18nText("BI-Select_All"), + isAllCheckedBySelectedValue: emptyFn, + // 手动控制选中 + disableSelected: true, + isHalfCheckedBySelectedValue(selectedValues) { + return selectedValues.length > 0; + }, + halfSelected: false, + iconWrapperWidth: 26, + iconWidth: 14, + iconHeight: 14, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + const isSelect = o.selected === true; + const isHalfSelect = !o.selected && o.halfSelected; + this.checkbox = createWidget({ + type: Checkbox.xtype, + stopPropagation: true, + handler: () => { + this.setSelected(this.isSelected()); + }, + selected: isSelect, + invisible: isHalfSelect, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }); + this.half = createWidget({ + type: HalfIconButton.xtype, + stopPropagation: true, + handler: () => { + this.setSelected(true); + }, + invisible: isSelect || !isHalfSelect, + iconWidth: o.iconWidth, + iconHeight: o.iconHeight, + }); + this.checkbox.on(Controller.EVENT_CHANGE, () => { + this.fireEvent(Controller.EVENT_CHANGE, Events.CLICK, this.isSelected(), this); + }); + this.checkbox.on(Checkbox.EVENT_CHANGE, () => { + this.fireEvent(MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); + }); + this.half.on(Controller.EVENT_CHANGE, () => { + this.fireEvent(Controller.EVENT_CHANGE, Events.CLICK, this.isSelected(), this); + }); + this.half.on(HalfIconButton.EVENT_CHANGE, () => { + this.fireEvent(MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); + }); + this.text = createWidget({ + type: Label.xtype, + textAlign: "left", + whiteSpace: "nowrap", + textHeight: o.height, + height: o.height, + hgap: o.hgap, + text: o.text, + keyword: o.keyword, + value: o.value, + py: o.py, + }); + createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + width: o.iconWrapperWidth, + el: { + type: CenterAdaptLayout.xtype, + items: [this.checkbox, this.half], + }, + }, + { + el: this.text, + } + ], + }); + } + + _setSelected(v) { + this.checkbox.setSelected(!!v); + } + + beforeClick() { + const isHalf = this.isHalfSelected(), + isSelected = this.isSelected(); + if (isHalf === true) { + this.setSelected(true); + } else { + this.setSelected(!isSelected); + } + } + + setSelected(v) { + this.checkbox.setSelected(v); + this.setHalfSelected(false); + } + + setHalfSelected(b) { + this.halfSelected = !!b; + if (b === true) { + this.checkbox.setSelected(false); + this.half.visible(); + this.checkbox.invisible(); + } else { + this.half.invisible(); + this.checkbox.visible(); + } + } + + isHalfSelected() { + return !this.isSelected() && !!this.halfSelected; + } + + isSelected() { + return this.checkbox.isSelected(); + } + + setValue(selectedValues) { + super.setValue(...arguments); + const isAllChecked = this.options.isAllCheckedBySelectedValue.apply(this, arguments); + this.setSelected(isAllChecked); + !isAllChecked && this.setHalfSelected(this.options.isHalfCheckedBySelectedValue.apply(this, arguments)); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); + } + } +} diff --git a/packages/fineui/src/case/tree/index.js b/packages/fineui/src/case/tree/index.js new file mode 100644 index 000000000..2e24e6651 --- /dev/null +++ b/packages/fineui/src/case/tree/index.js @@ -0,0 +1,3 @@ +export * from "./tree.level"; +export * from "./treeexpander/tree.expander"; +export * from "./treeexpander/tree.expander.popup"; diff --git a/packages/fineui/src/case/tree/tree.level.js b/packages/fineui/src/case/tree/tree.level.js new file mode 100644 index 000000000..a0e0fe3c4 --- /dev/null +++ b/packages/fineui/src/case/tree/tree.level.js @@ -0,0 +1,153 @@ +import { + shortcut, + Widget, + extend, + isKey, + each, + UUID, + defaults, + isNotEmptyArray, + Tree, + createWidget, + VerticalLayout, + Controller, + Events, + SIZE_CONSANTS +} from "@/core"; +import { ButtonTree, CustomTree } from "@/base"; +import { TreeExpander } from "./treeexpander/tree.expander"; +import { BasicTreeItem } from "@/case/button/treeitem/treeitem"; +import { BasicTreeNode } from "@/case/button/node/treenode"; + +@shortcut() +export class LevelTree extends Widget { + static xtype = "bi.level_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { + baseCls: "bi-level-tree", + el: { + chooseType: 0, + }, + expander: {}, + items: [], + value: "", + }; + + _init() { + super._init(...arguments); + + this.initTree(this.options.items); + } + + _formatItems(nodes, layer, pNode) { + const self = this; + each(nodes, (i, node) => { + const extend = { + layer, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + isFirstNode: i === 0, + isLastNode: i === nodes.length - 1, + }; + if (!isKey(node.id)) { + node.id = UUID(); + } + extend.pNode = pNode; + if (node.isParent === true || node.parent === true || isNotEmptyArray(node.children)) { + extend.type = BasicTreeNode.xtype; + extend.selectable = false; + + defaults(node, extend); + self._formatItems(node.children, layer + 1, node); + } else { + extend.type = BasicTreeItem.xtype; + defaults(node, extend); + } + }); + + return nodes; + } + + _assertId(sNodes) { + each(sNodes, (i, node) => { + if (!isKey(node.id)) { + node.id = UUID(); + } + }); + } + + initTree(nodes) { + const self = this, + o = this.options; + this.empty(); + this._assertId(nodes); + this.tree = createWidget({ + type: CustomTree.xtype, + element: this, + expander: extend( + { + type: TreeExpander.xtype, + el: {}, + isDefaultInit: false, + selectable: false, + popup: { + type: CustomTree.xtype, + }, + }, + o.expander + ), + items: this._formatItems(Tree.transformToTreeFormat(nodes), 0), + value: o.value, + + el: extend( + { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + o.el + ), + }); + this.tree.on(Controller.EVENT_CHANGE, function (type, value, ob) { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + if (type === Events.CLICK) { + self.fireEvent(LevelTree.EVENT_CHANGE, value, ob); + self.setValue(value); + } + }); + } + + stroke(nodes) { + this.tree.stroke(nodes); + } + + populate(items, keyword) { + items = this._formatItems(Tree.transformToTreeFormat(items), 0); + this.tree.populate(items, keyword); + } + + setValue(v) { + this.tree.setValue(v); + } + + getValue() { + return this.tree.getValue(); + } + + getAllLeaves() { + return this.tree.getAllLeaves(); + } + + getNodeById(id) { + return this.tree.getNodeById(id); + } + + getNodeByValue(id) { + return this.tree.getNodeByValue(id); + } +} diff --git a/packages/fineui/src/case/tree/treeexpander/tree.expander.js b/packages/fineui/src/case/tree/treeexpander/tree.expander.js new file mode 100644 index 000000000..32f35a081 --- /dev/null +++ b/packages/fineui/src/case/tree/treeexpander/tree.expander.js @@ -0,0 +1,84 @@ +import { contains, Controller, createWidget, isArray, shortcut, Widget } from "@/core"; +import { Expander } from "@/base"; +import { TreeExpanderPopup } from "./tree.expander.popup"; + +@shortcut() +export class TreeExpander extends Widget { + static xtype = "bi.tree_expander"; + + props = { + baseCls: "bi-tree-expander", + layer: 0, // 第几层级 + isLastNode: false, // 是不是最后一个 + isFirstNode: false, // 是不是第一个 + selectable: false, + showLine: true, + }; + + render() { + const self = this; + const o = this.options; + + this.trigger = createWidget(o.el, { + forceNotSelected: !o.selectable, + }); + this.trigger.on(Controller.EVENT_CHANGE, function (type) { + o.selectable && self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + return { + type: Expander.xtype, + ref(_ref) { + self.expander = _ref; + }, + trigger: o.selectable ? "" : "click", + el: this.trigger, + isDefaultInit: o.isDefaultInit, + popup: { + type: TreeExpanderPopup.xtype, + layer: o.layer || o.el.layer, + isLastNode: o.isLastNode || o.el.isLastNode, + isFirstNode: o.isFirstNode || o.el.isFirstNode, + showLine: o.showLine, + el: o.popup, + }, + value: o.value, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action: (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }, + } + ], + }; + } + + setValue(v) { + if (contains(v, this.trigger.getValue())) { + this.trigger.setSelected(true); + this.expander.setValue([]); + } else { + this.trigger.setSelected(false); + this.expander.setValue(v); + } + } + + getValue() { + if (this.trigger.isSelected()) { + const value = this.trigger.getValue(); + + return isArray(value) ? value : [value]; + } + + return this.expander.getValue(); + } + + populate(items) { + this.expander.populate(items); + } + + getAllLeaves() { + return this.expander && this.expander.getAllLeaves(); + } +} diff --git a/packages/fineui/src/case/tree/treeexpander/tree.expander.popup.js b/packages/fineui/src/case/tree/treeexpander/tree.expander.popup.js new file mode 100644 index 000000000..020788cc7 --- /dev/null +++ b/packages/fineui/src/case/tree/treeexpander/tree.expander.popup.js @@ -0,0 +1,62 @@ +import { Controller, createWidget, pixFormat, shortcut, VerticalLayout, Widget, SIZE_CONSANTS, STYLE_CONSTANTS } from "@/core"; + +@shortcut() +export class TreeExpanderPopup extends Widget { + static xtype = "bi.tree_expander.popup"; + + props() { + return { + baseCls: "bi-tree-expander-popup", + layer: 0, // 第几层级 + el: {}, + isLastNode: false, + showLine: true, + }; + } + + render() { + const self = this; + const { el, value, layer, showLine, isLastNode } = this.options; + const offset = SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2; + + this.popupView = createWidget( + { + ...el, + value, + }, + this + ); + + this.popupView.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + if (showLine) { + this.popupView.element.css("margin-left", pixFormat(-offset * (layer + 1))); + this.element.css("margin-left", pixFormat(offset * (layer + 1))); + } + + return { + type: VerticalLayout.xtype, + cls: showLine && !isLastNode ? (STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "line solid" : "line") : "", + scrolly: null, + items: [this.popupView], + }; + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + populate(items) { + this.popupView.populate(items); + } + + getAllLeaves() { + return this.popupView && this.popupView.getAllLeaves(); + } +} diff --git a/packages/fineui/src/case/trigger/index.js b/packages/fineui/src/case/trigger/index.js new file mode 100644 index 000000000..df4e68ab5 --- /dev/null +++ b/packages/fineui/src/case/trigger/index.js @@ -0,0 +1,8 @@ +export { EditorTrigger } from "./trigger.editor"; +export { IconTrigger } from "./trigger.icon"; +export { IconTextTrigger } from "./trigger.icon.text"; +export { SelectIconTextTrigger } from "./trigger.icon.text.select"; +export { TextTrigger } from "./trigger.text"; +export { SelectTextTrigger } from "./trigger.text.select"; +export { SmallSelectTextTrigger } from "./trigger.text.select.small"; +export { SmallTextTrigger } from "./trigger.text.small"; diff --git a/packages/fineui/src/case/trigger/trigger.editor.js b/packages/fineui/src/case/trigger/trigger.editor.js new file mode 100644 index 000000000..92e29fb5b --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.editor.js @@ -0,0 +1,103 @@ +import { SignEditor } from "../editor"; +import { HorizontalFillLayout, shortcut, extend, emptyFn, createWidget, toPix, Controller } from "@/core"; +import { TriggerIconButton } from "../button"; +import { Trigger } from "@/base"; + +/** + * 文本输入框trigger + * + * Created by GUY on 2015/9/15. + * @class EditorTrigger + * @extends Trigger + */ +@shortcut() +export class EditorTrigger extends Trigger { + static xtype = "bi.editor_trigger"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_EMPTY = "EVENT_EMPTY"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: + (conf.baseCls || "") + + " bi-editor-trigger " + + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), + height: 24, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: false, + watermark: "", + errorText: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget({ + type: SignEditor.xtype, + height: toPix(o.height, 2), + value: o.value, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + title: () => this.getValue(), + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(SignEditor.EVENT_CHANGE, (...args) => { + this.fireEvent(EditorTrigger.EVENT_CHANGE, ...args); + }); + this.editor.on(SignEditor.EVENT_FOCUS, (...args) => { + this.fireEvent(EditorTrigger.EVENT_FOCUS, ...args); + }); + this.editor.on(SignEditor.EVENT_EMPTY, (...args) => { + this.fireEvent(EditorTrigger.EVENT_EMPTY, ...args); + }); + this.editor.on(SignEditor.EVENT_VALID, (...args) => { + this.fireEvent(EditorTrigger.EVENT_VALID, ...args); + }); + this.editor.on(SignEditor.EVENT_ERROR, (...args) => { + this.fireEvent(EditorTrigger.EVENT_ERROR, ...args); + }); + + createWidget({ + element: this, + type: HorizontalFillLayout.xtype, + height: toPix(o.height, 2), + items: [ + { + el: this.editor, + width: "fill", + }, + { + el: { + type: TriggerIconButton.xtype, + width: o.triggerWidth || toPix(o.height, 2), + }, + width: "", + }, + ], + }); + } + + getValue() { + return this.editor.getValue(); + } + + setValue(value) { + this.editor.setValue(value); + } + + setText(text) { + this.editor.setState(text); + } +} diff --git a/packages/fineui/src/case/trigger/trigger.icon.js b/packages/fineui/src/case/trigger/trigger.icon.js new file mode 100644 index 000000000..c1f3b1ffe --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.icon.js @@ -0,0 +1,36 @@ +import { TriggerIconButton } from "../button"; +import { shortcut, extend, createWidget } from "@/core"; +import { Trigger } from "@/base"; + +/** + * 图标按钮trigger + * + * Created by GUY on 2015/10/8. + * @class IconTrigger + * @extends Trigger + */ +@shortcut() +export class IconTrigger extends Trigger { + static xtype = "bi.icon_trigger"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-icon-trigger", + extraCls: "pull-down-font", + el: {}, + height: 24, + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + this.iconButton = createWidget(o.el, { + type: TriggerIconButton.xtype, + element: this, + width: o.width, + height: o.height, + extraCls: o.extraCls, + }); + } +} diff --git a/packages/fineui/src/case/trigger/trigger.icon.text.js b/packages/fineui/src/case/trigger/trigger.icon.text.js new file mode 100644 index 000000000..658a8ccf3 --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.icon.text.js @@ -0,0 +1,102 @@ +import { Label, Trigger } from "@/base"; +import { TriggerIconButton, IconChangeButton } from "../button"; +import { HorizontalFillLayout, shortcut, extend, isKey, createWidget, isEmptyString } from "@/core"; + +/** + * 文字trigger + * + * Created by GUY on 2015/9/15. + * @class IconTextTrigger + * @extends Trigger + */ +@shortcut() +export class IconTextTrigger extends Trigger { + static xtype = "bi.icon_text_trigger"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-trigger`, + height: 24, + iconHeight: null, + iconWidth: null, + textCls: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + cls: `select-text-label${isKey(o.textCls) ? ` ${o.textCls}` : ""}`, + textAlign: "left", + height: o.height, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + tgap: o.textTgap, + bgap: o.textBgap, + text: o.text, + }); + this.trigerButton = createWidget({ + type: TriggerIconButton.xtype, + width: o.triggerWidth || o.height, + }); + + createWidget({ + element: this, + type: HorizontalFillLayout.xtype, + columnSize: ["", "fill", ""], + ref: _ref => { + this.wrapper = _ref; + }, + items: [ + { + el: { + type: IconChangeButton.xtype, + cls: "icon-combo-trigger-icon", + width: o.triggerWidth || o.height, + iconCls: o.iconCls, + invisible: !o.iconCls, + ref: _ref => { + this.icon = _ref; + }, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + disableSelected: true, + }, + }, + { + el: this.text, + lgap: isEmptyString(o.iconCls) ? 5 : 0, + }, + { + el: this.trigerButton, + } + ], + }); + } + + setValue(value) { + this.text.setValue(value); + } + + setIcon(iconCls) { + this.icon.setIcon(iconCls); + this.icon.setVisible(!!iconCls); + } + + setTextCls(cls) { + const o = this.options; + const oldCls = o.textCls; + o.textCls = cls; + this.text.element.removeClass(oldCls).addClass(cls); + } + + setText(text) { + this.text.setText(text); + } +} diff --git a/packages/fineui/src/case/trigger/trigger.icon.text.select.js b/packages/fineui/src/case/trigger/trigger.icon.text.select.js new file mode 100644 index 000000000..76c02d519 --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.icon.text.select.js @@ -0,0 +1,86 @@ +import { IconTextTrigger } from "./trigger.icon.text"; +import { shortcut, extend, createWidget, isFunction, isArray, isNotNull, any, deepContains, Tree } from "@/core"; +import { Trigger } from "@/base"; + +/** + * Created by Windy on 2017/12/12. + */ +@shortcut() +export class SelectIconTextTrigger extends Trigger { + static xtype = "bi.select_icon_text_trigger"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-text-trigger", + height: 24, + iconHeight: null, + iconWidth: null, + iconCls: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + const obj = this._digist(o.value, o.items); + this.trigger = createWidget({ + type: IconTextTrigger.xtype, + element: this, + text: obj.text, + textCls: obj.textCls, + iconCls: obj.iconCls, + textHgap: o.textHgap, + textVgap: o.textVgap, + textLgap: o.textLgap, + textRgap: o.textRgap, + textTgap: o.textTgap, + textBgap: o.textBgap, + height: o.height, + iconHeight: o.iconHeight, + iconWidth: o.iconWidth, + iconWrapperWidth: o.iconWrapperWidth, + }); + } + + _digist(vals, items) { + const o = this.options; + vals = isArray(vals) ? vals : [vals]; + let result; + const formatItems = Tree.transformToArrayFormat(items); + any(formatItems, (i, item) => { + if (deepContains(vals, item.value)) { + result = { + text: item.text || item.value, + iconCls: item.iconCls, + }; + + return true; + } + }); + + if (isNotNull(result)) { + return { + text: result.text, + textCls: "", + iconCls: result.iconCls, + }; + } else { + return { + text: isFunction(o.text) ? o.text() : o.text, + textCls: "bi-water-mark", + iconCls: o.iconCls, + }; + } + } + + setValue(vals) { + const obj = this._digist(vals, this.options.items); + this.trigger.setText(obj.text); + this.trigger.setIcon(obj.iconCls); + this.trigger.setTextCls(obj.textCls); + } + + populate(items) { + this.options.items = items; + } +} diff --git a/packages/fineui/src/case/trigger/trigger.text.js b/packages/fineui/src/case/trigger/trigger.text.js new file mode 100644 index 000000000..dfe9cef1b --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.text.js @@ -0,0 +1,154 @@ +import { Label, IconButton, Trigger } from "@/base"; +import { TriggerIconButton } from "../button"; +import { HorizontalFillLayout, VerticalAdaptLayout, shortcut, isFunction, isKey, isNotEmptyString } from "@/core"; + +/** + * 文字trigger + * + * Created by GUY on 2015/9/15. + * @class TextTrigger + * @extends Trigger + */ +@shortcut() +export class TextTrigger extends Trigger { + static xtype = "bi.text_trigger"; + + static EVENT_CLEAR = "EVENT_CLEAR"; + + props() { + return { + baseCls: "bi-text-trigger", + height: 24, + textHgap: 6, + textCls: "", + allowClear: false, + title: () => this.text.getText(), + defaultText: "", + text: "", + }; + } + + render() { + const o = this.options; + + const text = this.getText(); + + const defaultText = this.getDefaultText(); + + const label = { + type: Label.xtype, + ref: _ref => { + this.text = _ref; + }, + cls: `select-text-label ${o.textCls} ${ + !isNotEmptyString(text) && isNotEmptyString(defaultText) ? "bi-tips" : "" + }`, + textAlign: "left", + height: o.height, + text: text || o.defaultText, + tipType: o.tipType, + warningTitle: o.warningTitle, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + tgap: o.textTgap, + bgap: o.textBgap, + readonly: o.readonly, + }; + + const triggerButton = { + type: TriggerIconButton.xtype, + ref: _ref => { + this.triggerButton = _ref; + }, + width: o.triggerWidth || o.height, + }; + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + { + el: label, + width: "fill", + }, + { + el: o.allowClear + ? { + type: VerticalAdaptLayout.xtype, + width: o.triggerWidth || o.height, + height: o.height, + horizontalAlign: "left", + scrollable: false, + items: [ + { + el: { + type: IconButton.xtype, + ref: _ref => { + this.clearBtn = _ref; + }, + cls: `close-h-font ${o.allowClear ? "clear-button" : ""}`, + stopPropagation: true, + width: o.triggerWidth || o.height, + invisible: !isNotEmptyString(o.text), + handler: () => { + this.fireEvent(TextTrigger.EVENT_CLEAR); + }, + }, + }, + { + el: triggerButton, + } + ], + } + : triggerButton, + } + ], + }; + } + + getText() { + const o = this.options; + + return isFunction(o.text) ? o.text() : o.text; + } + + getDefaultText() { + const o = this.options; + + return isFunction(o.defaultText) ? o.defaultText() : o.defaultText; + } + + getTextor() { + return this.text; + } + + setTextCls(cls) { + const o = this.options; + const oldCls = o.textCls; + o.textCls = cls; + this.text.element.removeClass(oldCls).addClass(cls); + } + + setText(text) { + if (this.options.allowClear) { + this.clearBtn.setVisible(isNotEmptyString(text)); + } + if (isKey(text)) { + this.text.setText(text); + this.text.element.removeClass("bi-tips"); + } else if (isKey(this.options.defaultText)) { + this.text.setText(this.options.defaultText); + this.text.element.addClass("bi-tips"); + } else { + this.text.setText(""); + this.text.element.removeClass("bi-tips"); + } + } + + setTipType(v) { + this.text.options.tipType = v; + this.options.tipType = v; + } +} diff --git a/packages/fineui/src/case/trigger/trigger.text.select.js b/packages/fineui/src/case/trigger/trigger.text.select.js new file mode 100644 index 000000000..48af5c5de --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.text.select.js @@ -0,0 +1,113 @@ +import { TextTrigger } from "./trigger.text"; +import { shortcut, extend, emptyFn, createWidget, isFunction, isArray, Tree, each, contains, remove } from "@/core"; +import { Trigger } from "@/base"; + +/** + * 选择字段trigger + * + * Created by GUY on 2015/9/15. + * @class SelectTextTrigger + * @extends Trigger + */ +@shortcut() +export class SelectTextTrigger extends Trigger { + static xtype = "bi.select_text_trigger"; + + static EVENT_CLEAR = "EVENT_CLEAR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-text-trigger", + height: 24, + allowClear: false, + valueFormatter: emptyFn, + defaultText: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + const text = this._digest(o.value, o.items); + this.trigger = createWidget({ + type: TextTrigger.xtype, + element: this, + height: o.height, + readonly: o.readonly, + text, + defaultText: o.defaultText, + textHgap: o.textHgap, + textVgap: o.textVgap, + textLgap: o.textLgap, + textRgap: o.textRgap, + textTgap: o.textTgap, + textBgap: o.textBgap, + tipType: o.tipType, + title: null, + allowClear: o.allowClear, + listeners: [ + { + eventName: TextTrigger.EVENT_CLEAR, + action: () => { + this.setText(""); + this.fireEvent(SelectTextTrigger.EVENT_CLEAR); + }, + }, + ], + }); + } + + _digest(val, items) { + const o = this.options; + + val = isArray(val) ? val.slice() : [val]; + + const result = []; + + // 提升valueFormatter的优先级 + if (o.valueFormatter !== emptyFn && isFunction(o.valueFormatter)) { + each(val, (index, v) => { + result.push(o.valueFormatter(v)); + }); + + return result.join(","); + } + + const formatItems = Tree.transformToArrayFormat(items); + each(formatItems, (i, item) => { + if (contains(val, item.value) && !contains(result, item.text || item.value)) { + result.push(item.text || item.value); + remove(val, item.value); + } + }); + + if (result.length > 0 && val.length === 0) { + return result.join(","); + } else { + return isFunction(o.text) ? o.text() : o.text; + } + } + + setText(text) { + this.options.text = text; + this.trigger.setText(text); + } + + setValue(val) { + const formatText = this._digest(val, this.options.items); + this.trigger.setText(formatText); + } + + setTipType(v) { + this.options.tipType = v; + this.trigger.setTipType(v); + } + + getTextor() { + return this.trigger.getTextor(); + } + + populate(items) { + this.options.items = items; + } +} diff --git a/packages/fineui/src/case/trigger/trigger.text.select.small.js b/packages/fineui/src/case/trigger/trigger.text.select.small.js new file mode 100644 index 000000000..2f3106a3b --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.text.select.small.js @@ -0,0 +1,74 @@ +import { SmallTextTrigger } from "./trigger.text.small"; +import { shortcut, extend, toPix, createWidget, isArray, deepContains, each, contains, Tree } from "@/core"; +import { Trigger } from "@/base"; + +/** + * 选择字段trigger小一号的 + * + * @class SmallSelectTextTrigger + * @extends Trigger + */ +@shortcut() +export class SmallSelectTextTrigger extends Trigger { + static xtype = "bi.small_select_text_trigger"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-small-select-text-trigger bi-border", + height: 20, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + const obj = this._digest(o.value, o.items); + this.trigger = createWidget({ + type: SmallTextTrigger.xtype, + element: this, + height: toPix(o.height, 2), + text: obj.text, + cls: obj.cls, + textHgap: o.textHgap, + textVgap: o.textVgap, + textLgap: o.textLgap, + textRgap: o.textRgap, + textTgap: o.textTgap, + textBgap: o.textBgap, + }); + } + + _digest(vals, items) { + const o = this.options; + vals = isArray(vals) ? vals : [vals]; + const result = []; + const formatItems = Tree.transformToArrayFormat(items); + each(formatItems, (i, item) => { + if (deepContains(vals, item.value) && !contains(result, item.text || item.value)) { + result.push(item.text || item.value); + } + }); + + if (result.length > 0) { + return { + cls: "", + text: result.join(","), + }; + } else { + return { + cls: "bi-water-mark", + text: o.text, + }; + } + } + + setValue(vals) { + const formatValue = this._digest(vals, this.options.items); + this.trigger.element.removeClass("bi-water-mark").addClass(formatValue.cls); + this.trigger.setText(formatValue.text); + } + + populate(items) { + this.options.items = items; + } +} diff --git a/packages/fineui/src/case/trigger/trigger.text.small.js b/packages/fineui/src/case/trigger/trigger.text.small.js new file mode 100644 index 000000000..524c2e711 --- /dev/null +++ b/packages/fineui/src/case/trigger/trigger.text.small.js @@ -0,0 +1,68 @@ +import { Label, Trigger } from "@/base"; +import { TriggerIconButton } from "../button"; +import { HorizontalFillLayout, shortcut, extend, createWidget } from "@/core"; + +/** + * 文字trigger(右边小三角小一号的) == + * + * @class SmallTextTrigger + * @extends Trigger + */ +@shortcut() +export class SmallTextTrigger extends Trigger { + static xtype = "bi.small_text_trigger"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-text-trigger`, + height: 20, + textHgap: 6, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + textAlign: "left", + height: o.height, + text: o.text, + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + tgap: o.textTgap, + bgap: o.textBgap, + }); + this.trigerButton = createWidget({ + type: TriggerIconButton.xtype, + width: o.triggerWidth || o.height, + }); + + createWidget({ + element: this, + type: HorizontalFillLayout.xtype, + items: [ + { + el: this.text, + width: "fill", + }, + { + el: this.trigerButton, + width: "", + } + ], + }); + } + + setValue(value) { + this.text.setValue(value); + } + + setText(text) { + this.text.setText(text); + } +} diff --git a/packages/fineui/src/case/ztree/asynctree.js b/packages/fineui/src/case/ztree/asynctree.js new file mode 100644 index 000000000..7921ef821 --- /dev/null +++ b/packages/fineui/src/case/ztree/asynctree.js @@ -0,0 +1,310 @@ +import { + cjkEncodeDO, + deepClone, + each, + extend, + isEmpty, + isNotNull, + isNull, + shortcut, + AbsoluteLayout, + createWidget, +} from "@/core"; +import { TreeView } from "./treeview"; +import { TreeRenderPageService } from "./treerender.page.service"; +import $ from "jquery"; +import { IconLabel } from "@/base"; + +@shortcut() +export class AsyncTree extends TreeView { + static xtype = "bi.async_tree"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + showIcon: false, + showLine: true, + }); + } + + _init() { + super._init(...arguments); + const self = this; + this.service = new TreeRenderPageService({ + subNodeListGetter(tId) { + // 获取待检测的子节点列表, ztree并没有获取节点列表dom的API, 此处使用$获取 + return $(`#${self.id} #${tId}_ul`); + }, + }); + } + + // 配置属性 + _configSetting() { + const o = this.options; + const paras = this.options.paras; + const self = this; + + function onClick(event, treeId, treeNode) { + if (treeNode.disabled) { + return false; + } + const zTree = $.fn.zTree.getZTreeObj(treeId); + // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 + let checked = treeNode.checked; + const status = treeNode.getCheckStatus(); + if (status.half === true && status.checked === true) { + checked = false; + } + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeCheck(treeId, treeNode) { + if (treeNode.disabled) { + return false; + } + // 下面主动修改了node的halfCheck属性, 节点属性的判断依赖halfCheck,改之前就获取一下 + const status = treeNode.getCheckStatus(); + treeNode.halfCheck = false; + if (treeNode.checked === true) { + // 将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy + // 所有的半选状态都需要取消halfCheck=true的情况 + function track(children) { + each(children, (i, ch) => { + ch.halfCheck = false; + track(ch.children); + }); + } + + track(treeNode.children); + + const treeObj = $.fn.zTree.getZTreeObj(treeId); + const nodes = treeObj.getSelectedNodes(); + each(nodes, (index, node) => { + node.halfCheck = false; + }); + } + // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 + if (status.half === true && status.checked === true) { + treeNode.checked = false; + } + } + + function beforeExpand(treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck(event, treeId, treeNode) { + if (treeNode.disabled) { + return false; + } + self._selectTreeNode(treeId, treeNode); + } + + function onExpand(event, treeId, treeNode) { + treeNode.halfCheck = false; + } + + function onCollapse(event, treeId, treeNode) { + treeNode.halfCheck = false; + } + + return { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: cjkEncodeDO(paras), + }, + check: { + enable: true, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + view: { + showIcon: o.showIcon, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false, + showLine: o.showLine, + nodeClasses(treeId, treeNode) { + return { add: [treeNode.iconCls || ""] }; + }, + }, + callback: { + beforeCheck, + onCheck, + beforeExpand, + onExpand, + onCollapse, + onClick, + }, + }; + } + + // 用来更新this.options.paras.selectedValues, 和ztree内部无关 + _selectTreeNode(treeId, treeNode) { + const self = this; + let parentValues = deepClone(treeNode.parentValues || self._getParentValues(treeNode)); + let name = this._getNodeValue(treeNode); + // var values = parentValues.concat([name]); + if (treeNode.checked === true) { + this._addTreeNode(this.options.paras.selectedValues, parentValues, name, {}); + } else { + let tNode = treeNode; + let pNode = this._getTree(this.options.paras.selectedValues, parentValues); + if (isNotNull(pNode[name])) { + delete pNode[name]; + } + while (tNode != null && isEmpty(pNode)) { + parentValues = parentValues.slice(0, parentValues.length - 1); + tNode = tNode.getParentNode(); + if (tNode != null) { + pNode = this._getTree(this.options.paras.selectedValues, parentValues); + name = this._getNodeValue(tNode); + delete pNode[name]; + } + } + this.options.paras.selectedValues = this._getJoinValue(); + } + super._selectTreeNode(...arguments); + } + + // 展开节点 + _beforeExpandNode(treeId, treeNode) { + const self = this, + o = this.options; + + function complete(d) { + const nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + } + + function callback(nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + if (hasNext) { + self.service.pushNodeList(treeNode.tId, getNodes); + } else { + self.service.removeNodeList(treeNode.tId); + } + } + + function getNodes(options) { + // console.log(times); + options = options || {}; + const parentValues = treeNode.parentValues || self._getParentValues(treeNode); + const op = extend( + {}, + o.paras, + { + id: treeNode.id, + times: options.times, + parentValues: parentValues.concat(self._getNodeValue(treeNode)), + checkState: treeNode.getCheckStatus(), + }, + options + ); + + let loadingIcon; + createWidget({ + type: AbsoluteLayout.xtype, + element: self.element.find(`#${treeNode.tId}`), + css: { + position: "relative", + }, + items: [ + { + el: { + type: IconLabel.xtype, + width: 20, + height: 20, + cls: "button-loading-font anim-rotate bi-card", + ref: ref => { + loadingIcon = ref; + }, + }, + left: 5, + top: 5, + }, + ], + }); + o.itemsCreator(op, (...args) => { + complete.apply(this, args); + loadingIcon.destroy(); + }); + } + + // 展开节点会将halfCheck置为false以开启自动计算半选, 所以第一次展开节点的时候需要在置为false之前获取配置 + const checkState = treeNode.getCheckStatus(); + if (!treeNode.children && !treeNode.requested) { + treeNode.requested = true; + setTimeout(() => { + getNodes({ + times: 1, + checkState, + }); + }, 17); + } + } + + // a,b 两棵树 + // a->b b->a 做两次校验, 构造一个校验后的map + // e.g. 以a为基准,如果b没有此节点,则在map中添加。 如b有,且是全选的, 则在map中构造全选(为什么不添加a的值呢? 因为这次是取并集), 如果b中也有和a一样的存值,就递归 + _join(valueA, valueB) { + const self = this; + const map = {}; + track([], valueA, valueB); + track([], valueB, valueA); + + function track(parent, node, compare) { + each(node, (n, item) => { + if (isNull(compare[n])) { + self._addTreeNode(map, parent, n, item); + } else if (isEmpty(compare[n])) { + self._addTreeNode(map, parent, n, item); + } else { + track(parent.concat([n]), node[n], compare[n]); + } + }); + } + + return map; + } + + hasChecked() { + return !isEmpty(this.options.paras.selectedValues) || super.hasChecked(...arguments); + } + + _getJoinValue() { + if (!this.nodes) { + return this.options.paras.selectedValues || {}; + } + const checkedValues = this._getSelectedValues(); + if (isEmpty(checkedValues)) { + return deepClone(this.options.paras.selectedValues); + } + if (isEmpty(this.options.paras.selectedValues)) { + return checkedValues; + } + + return this._join(checkedValues, this.options.paras.selectedValues); + } + + getValue() { + return this._getJoinValue(); + } + + // 生成树方法 + stroke(config) { + delete this.options.keyword; + this.service.clear(); + extend(this.options.paras, config); + const setting = this._configSetting(); + this._initTree(setting); + } +} diff --git a/packages/fineui/src/case/ztree/index.js b/packages/fineui/src/case/ztree/index.js new file mode 100644 index 000000000..d5cbfc63a --- /dev/null +++ b/packages/fineui/src/case/ztree/index.js @@ -0,0 +1,14 @@ +import "./jquery.ztree.core-3.5"; +import "./jquery.ztree.excheck-3.5"; + +export * from "./treeview"; +export * from "./asynctree"; +export * from "./parttree"; +export * from "./tree.display"; +export * from "./tree.list.display"; +export * from "./tree.simple"; +export * from "./treerender.scroll.service"; +export * from "./treerender.page.service"; +export * from "./list/listtreeview"; +export * from "./list/listasynctree"; +export * from "./list/listparttree"; diff --git a/packages/fineui/src/case/ztree/jquery.ztree.core-3.5.js b/packages/fineui/src/case/ztree/jquery.ztree.core-3.5.js new file mode 100644 index 000000000..9179120be --- /dev/null +++ b/packages/fineui/src/case/ztree/jquery.ztree.core-3.5.js @@ -0,0 +1,2210 @@ +import $ from "jquery"; + +/* eslint-disable */ +/* + * JQuery zTree core + * v3.5.48 + * http://treejs.cn/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * Date: 2020-11-21 + */ + +(function ($) { + var settings = {}, + roots = {}, + caches = {}, + //default consts of core + _consts = { + className: { + BUTTON: "button", + ICON: "icon", + LEVEL: "level", + ICO_LOADING: "ico_loading", + SWITCH: "switch", + NAME: "node_name", + }, + event: { + NODECREATED: "ztree_nodeCreated", + CLICK: "ztree_click", + EXPAND: "ztree_expand", + COLLAPSE: "ztree_collapse", + ASYNC_SUCCESS: "ztree_async_success", + ASYNC_ERROR: "ztree_async_error", + REMOVE: "ztree_remove", + SELECTED: "ztree_selected", + UNSELECTED: "ztree_unselected", + }, + id: { + A: "_a", + ICON: "_ico", + SPAN: "_span", + SWITCH: "_switch", + UL: "_ul", + }, + line: { + ROOT: "root", + ROOTS: "roots", + CENTER: "center", + BOTTOM: "bottom", + NOLINE: "noline", + LINE: "line", + }, + folder: { + OPEN: "open", + CLOSE: "close", + DOCU: "docu", + }, + node: { + CURSELECTED: "curSelectedNode", + }, + }, + //default setting of core + _setting = { + treeId: "", + treeObj: null, + view: { + addDiyDom: null, + autoCancelSelected: true, + dblClickExpand: true, + expandSpeed: "fast", + fontCss: {}, + nodeClasses: {}, + nameIsHTML: false, + selectedMulti: true, + showIcon: true, + showLine: true, + showTitle: true, + txtSelectedEnable: false, + }, + data: { + key: { + isParent: "isParent", + children: "children", + name: "name", + title: "", + url: "url", + icon: "icon", + }, + render: { + name: null, + title: null, + }, + simpleData: { + enable: false, + idKey: "id", + pIdKey: "pId", + rootPId: null, + }, + keep: { + parent: false, + leaf: false, + }, + }, + async: { + enable: false, + contentType: "application/x-www-form-urlencoded", + type: "post", + dataType: "text", + headers: {}, + xhrFields: {}, + url: "", + autoParam: [], + otherParam: [], + dataFilter: null, + }, + callback: { + beforeAsync: null, + beforeClick: null, + beforeDblClick: null, + beforeRightClick: null, + beforeMouseDown: null, + beforeMouseUp: null, + beforeExpand: null, + beforeCollapse: null, + beforeRemove: null, + + onAsyncError: null, + onAsyncSuccess: null, + onNodeCreated: null, + onClick: null, + onDblClick: null, + onRightClick: null, + onMouseDown: null, + onMouseUp: null, + onExpand: null, + onCollapse: null, + onRemove: null, + }, + }, + //default root of core + //zTree use root to save full data + _initRoot = function (setting) { + var r = data.getRoot(setting); + if (!r) { + r = {}; + data.setRoot(setting, r); + } + data.nodeChildren(setting, r, []); + r.expandTriggerFlag = false; + r.curSelectedList = []; + r.noSelection = true; + r.createdNodes = []; + r.zId = 0; + r._ver = new Date().getTime(); + }, + //default cache of core + _initCache = function (setting) { + var c = data.getCache(setting); + if (!c) { + c = {}; + data.setCache(setting, c); + } + c.nodes = []; + c.doms = []; + }, + //default bindEvent of core + _bindEvent = function (setting) { + var o = setting.treeObj, + c = consts.event; + o.bind(c.NODECREATED, function (event, treeId, node) { + tools.apply(setting.callback.onNodeCreated, [event, treeId, node]); + }); + + o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) { + tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]); + }); + + o.bind(c.EXPAND, function (event, treeId, node) { + tools.apply(setting.callback.onExpand, [event, treeId, node]); + }); + + o.bind(c.COLLAPSE, function (event, treeId, node) { + tools.apply(setting.callback.onCollapse, [event, treeId, node]); + }); + + o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) { + tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]); + }); + + o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) { + tools.apply(setting.callback.onAsyncError, [ + event, + treeId, + node, + XMLHttpRequest, + textStatus, + errorThrown, + ]); + }); + + o.bind(c.REMOVE, function (event, treeId, treeNode) { + tools.apply(setting.callback.onRemove, [event, treeId, treeNode]); + }); + + o.bind(c.SELECTED, function (event, treeId, node) { + tools.apply(setting.callback.onSelected, [treeId, node]); + }); + o.bind(c.UNSELECTED, function (event, treeId, node) { + tools.apply(setting.callback.onUnSelected, [treeId, node]); + }); + }, + _unbindEvent = function (setting) { + var o = setting.treeObj, + c = consts.event; + o.unbind(c.NODECREATED) + .unbind(c.CLICK) + .unbind(c.EXPAND) + .unbind(c.COLLAPSE) + .unbind(c.ASYNC_SUCCESS) + .unbind(c.ASYNC_ERROR) + .unbind(c.REMOVE) + .unbind(c.SELECTED) + .unbind(c.UNSELECTED); + }, + //default event proxy of core + _eventProxy = function (event) { + var target = event.target, + setting = data.getSetting(event.data.treeId), + tId = "", + node = null, + nodeEventType = "", + treeEventType = "", + nodeEventCallback = null, + treeEventCallback = null, + tmp = null; + + if (tools.eqs(event.type, "mousedown")) { + treeEventType = "mousedown"; + } else if (tools.eqs(event.type, "mouseup")) { + treeEventType = "mouseup"; + } else if (tools.eqs(event.type, "contextmenu")) { + treeEventType = "contextmenu"; + } else if (tools.eqs(event.type, "click")) { + if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.SWITCH) !== null) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "switchNode"; + } else { + tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "clickNode"; + } + } + } else if (tools.eqs(event.type, "dblclick")) { + treeEventType = "dblclick"; + tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "switchNode"; + } + } + if (treeEventType.length > 0 && tId.length == 0) { + tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + } + } + // event to node + if (tId.length > 0) { + node = data.getNodeCache(setting, tId); + switch (nodeEventType) { + case "switchNode": + var isParent = data.nodeIsParent(setting, node); + if (!isParent) { + nodeEventType = ""; + } else if ( + tools.eqs(event.type, "click") || + (tools.eqs(event.type, "dblclick") && + tools.apply( + setting.view.dblClickExpand, + [setting.treeId, node], + setting.view.dblClickExpand + )) + ) { + nodeEventCallback = handler.onSwitchNode; + } else { + nodeEventType = ""; + } + break; + case "clickNode": + nodeEventCallback = handler.onClickNode; + break; + } + } + // event to zTree + switch (treeEventType) { + case "mousedown": + treeEventCallback = handler.onZTreeMousedown; + break; + case "mouseup": + treeEventCallback = handler.onZTreeMouseup; + break; + case "dblclick": + treeEventCallback = handler.onZTreeDblclick; + break; + case "contextmenu": + treeEventCallback = handler.onZTreeContextmenu; + break; + } + var proxyResult = { + stop: false, + node: node, + nodeEventType: nodeEventType, + nodeEventCallback: nodeEventCallback, + treeEventType: treeEventType, + treeEventCallback: treeEventCallback, + }; + return proxyResult; + }, + //default init node of core + _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { + if (!n) return; + var r = data.getRoot(setting), + children = data.nodeChildren(setting, n); + n.level = level; + n.tId = setting.treeId + "_" + ++r.zId; + n.parentTId = parentNode ? parentNode.tId : null; + n.open = typeof n.open == "string" ? tools.eqs(n.open, "true") : !!n.open; + var isParent = data.nodeIsParent(setting, n); + if (tools.isArray(children)) { + data.nodeIsParent(setting, n, true); + n.zAsync = true; + } else { + isParent = data.nodeIsParent(setting, n, isParent); + n.open = isParent && !setting.async.enable ? n.open : false; + n.zAsync = !isParent; + } + n.isFirstNode = isFirstNode; + n.isLastNode = isLastNode; + n.getParentNode = function () { + return data.getNodeCache(setting, n.parentTId); + }; + n.getPreNode = function () { + return data.getPreNode(setting, n); + }; + n.getNextNode = function () { + return data.getNextNode(setting, n); + }; + n.getIndex = function () { + return data.getNodeIndex(setting, n); + }; + n.getPath = function () { + return data.getNodePath(setting, n); + }; + n.isAjaxing = false; + data.fixPIdKeyValue(setting, n); + }, + _init = { + bind: [_bindEvent], + unbind: [_unbindEvent], + caches: [_initCache], + nodes: [_initNode], + proxys: [_eventProxy], + roots: [_initRoot], + beforeA: [], + afterA: [], + innerBeforeA: [], + innerAfterA: [], + zTreeTools: [], + }, + //method of operate data + data = { + addNodeCache: function (setting, node) { + data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node; + }, + getNodeCacheId: function (tId) { + return tId.substring(tId.lastIndexOf("_") + 1); + }, + addAfterA: function (afterA) { + _init.afterA.push(afterA); + }, + addBeforeA: function (beforeA) { + _init.beforeA.push(beforeA); + }, + addInnerAfterA: function (innerAfterA) { + _init.innerAfterA.push(innerAfterA); + }, + addInnerBeforeA: function (innerBeforeA) { + _init.innerBeforeA.push(innerBeforeA); + }, + addInitBind: function (bindEvent) { + _init.bind.push(bindEvent); + }, + addInitUnBind: function (unbindEvent) { + _init.unbind.push(unbindEvent); + }, + addInitCache: function (initCache) { + _init.caches.push(initCache); + }, + addInitNode: function (initNode) { + _init.nodes.push(initNode); + }, + addInitProxy: function (initProxy, isFirst) { + if (!!isFirst) { + _init.proxys.splice(0, 0, initProxy); + } else { + _init.proxys.push(initProxy); + } + }, + addInitRoot: function (initRoot) { + _init.roots.push(initRoot); + }, + addNodesData: function (setting, parentNode, index, nodes) { + var children = data.nodeChildren(setting, parentNode), + params; + if (!children) { + children = data.nodeChildren(setting, parentNode, []); + index = -1; + } else if (index >= children.length) { + index = -1; + } + + if (children.length > 0 && index === 0) { + children[0].isFirstNode = false; + view.setNodeLineIcos(setting, children[0]); + } else if (children.length > 0 && index < 0) { + children[children.length - 1].isLastNode = false; + view.setNodeLineIcos(setting, children[children.length - 1]); + } + data.nodeIsParent(setting, parentNode, true); + + if (index < 0) { + data.nodeChildren(setting, parentNode, children.concat(nodes)); + } else { + params = [index, 0].concat(nodes); + children.splice.apply(children, params); + } + }, + addSelectedNode: function (setting, node) { + var root = data.getRoot(setting); + if (!data.isSelectedNode(setting, node)) { + root.curSelectedList.push(node); + } + }, + addCreatedNode: function (setting, node) { + if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { + var root = data.getRoot(setting); + root.createdNodes.push(node); + } + }, + addZTreeTools: function (zTreeTools) { + _init.zTreeTools.push(zTreeTools); + }, + exSetting: function (s) { + $.extend(true, _setting, s); + }, + fixPIdKeyValue: function (setting, node) { + if (setting.data.simpleData.enable) { + node[setting.data.simpleData.pIdKey] = node.parentTId + ? node.getParentNode()[setting.data.simpleData.idKey] + : setting.data.simpleData.rootPId; + } + }, + getAfterA: function (setting, node, array) { + for (var i = 0, j = _init.afterA.length; i < j; i++) { + _init.afterA[i].apply(this, arguments); + } + }, + getBeforeA: function (setting, node, array) { + for (var i = 0, j = _init.beforeA.length; i < j; i++) { + _init.beforeA[i].apply(this, arguments); + } + }, + getInnerAfterA: function (setting, node, array) { + for (var i = 0, j = _init.innerAfterA.length; i < j; i++) { + _init.innerAfterA[i].apply(this, arguments); + } + }, + getInnerBeforeA: function (setting, node, array) { + for (var i = 0, j = _init.innerBeforeA.length; i < j; i++) { + _init.innerBeforeA[i].apply(this, arguments); + } + }, + getCache: function (setting) { + return caches[setting.treeId]; + }, + getNodeIndex: function (setting, node) { + if (!node) return null; + var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), + children = data.nodeChildren(setting, p); + for (var i = 0, l = children.length - 1; i <= l; i++) { + if (children[i] === node) { + return i; + } + } + return -1; + }, + getNextNode: function (setting, node) { + if (!node) return null; + var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), + children = data.nodeChildren(setting, p); + for (var i = 0, l = children.length - 1; i <= l; i++) { + if (children[i] === node) { + return i == l ? null : children[i + 1]; + } + } + return null; + }, + getNodeByParam: function (setting, nodes, key, value) { + if (!nodes || !key) return null; + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (node[key] == value) { + return nodes[i]; + } + var children = data.nodeChildren(setting, node); + var tmp = data.getNodeByParam(setting, children, key, value); + if (tmp) return tmp; + } + return null; + }, + getNodeCache: function (setting, tId) { + if (!tId) return null; + var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)]; + return n ? n : null; + }, + getNodePath: function (setting, node) { + if (!node) return null; + + var path; + if (node.parentTId) { + path = node.getParentNode().getPath(); + } else { + path = []; + } + + if (path) { + path.push(node); + } + + return path; + }, + getNodes: function (setting) { + return data.nodeChildren(setting, data.getRoot(setting)); + }, + getNodesByParam: function (setting, nodes, key, value) { + if (!nodes || !key) return []; + var result = []; + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (node[key] == value) { + result.push(node); + } + var children = data.nodeChildren(setting, node); + result = result.concat(data.getNodesByParam(setting, children, key, value)); + } + return result; + }, + getNodesByParamFuzzy: function (setting, nodes, key, value) { + if (!nodes || !key) return []; + var result = []; + value = value.toLowerCase(); + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (typeof node[key] == "string" && nodes[i][key].toLowerCase().indexOf(value) > -1) { + result.push(node); + } + var children = data.nodeChildren(setting, node); + result = result.concat(data.getNodesByParamFuzzy(setting, children, key, value)); + } + return result; + }, + getNodesByFilter: function (setting, nodes, filter, isSingle, invokeParam) { + if (!nodes) return isSingle ? null : []; + var result = isSingle ? null : []; + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (tools.apply(filter, [node, invokeParam], false)) { + if (isSingle) { + return node; + } + result.push(node); + } + var children = data.nodeChildren(setting, node); + var tmpResult = data.getNodesByFilter(setting, children, filter, isSingle, invokeParam); + if (isSingle && !!tmpResult) { + return tmpResult; + } + result = isSingle ? tmpResult : result.concat(tmpResult); + } + return result; + }, + getPreNode: function (setting, node) { + if (!node) return null; + var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), + children = data.nodeChildren(setting, p); + for (var i = 0, l = children.length; i < l; i++) { + if (children[i] === node) { + return i == 0 ? null : children[i - 1]; + } + } + return null; + }, + getRoot: function (setting) { + return setting ? roots[setting.treeId] : null; + }, + getRoots: function () { + return roots; + }, + getSetting: function (treeId) { + return settings[treeId]; + }, + getSettings: function () { + return settings; + }, + getZTreeTools: function (treeId) { + var r = this.getRoot(this.getSetting(treeId)); + return r ? r.treeTools : null; + }, + initCache: function (setting) { + for (var i = 0, j = _init.caches.length; i < j; i++) { + _init.caches[i].apply(this, arguments); + } + }, + initNode: function (setting, level, node, parentNode, preNode, nextNode) { + for (var i = 0, j = _init.nodes.length; i < j; i++) { + _init.nodes[i].apply(this, arguments); + } + }, + initRoot: function (setting) { + for (var i = 0, j = _init.roots.length; i < j; i++) { + _init.roots[i].apply(this, arguments); + } + }, + isSelectedNode: function (setting, node) { + var root = data.getRoot(setting); + for (var i = 0, j = root.curSelectedList.length; i < j; i++) { + if (node === root.curSelectedList[i]) return true; + } + return false; + }, + nodeChildren: function (setting, node, newChildren) { + if (!node) { + return null; + } + var key = setting.data.key.children; + if (typeof newChildren !== "undefined") { + node[key] = newChildren; + } + return node[key]; + }, + nodeIsParent: function (setting, node, newIsParent) { + if (!node) { + return false; + } + var key = setting.data.key.isParent; + if (typeof newIsParent !== "undefined") { + if (typeof newIsParent === "string") { + newIsParent = tools.eqs(newIsParent, "true"); + } + newIsParent = !!newIsParent; + node[key] = newIsParent; + } else if (typeof node[key] == "string") { + node[key] = tools.eqs(node[key], "true"); + } else { + node[key] = !!node[key]; + } + return node[key]; + }, + nodeName: function (setting, node, newName) { + var key = setting.data.key.name; + if (typeof newName !== "undefined") { + node[key] = newName; + } + var rawName = "" + node[key]; + if (typeof setting.data.render.name === "function") { + return setting.data.render.name.call(this, rawName, node); + } + return rawName; + }, + nodeTitle: function (setting, node) { + var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title; + var rawTitle = "" + node[t]; + if (typeof setting.data.render.title === "function") { + return setting.data.render.title.call(this, rawTitle, node); + } + return rawTitle; + }, + removeNodeCache: function (setting, node) { + var children = data.nodeChildren(setting, node); + if (children) { + for (var i = 0, l = children.length; i < l; i++) { + data.removeNodeCache(setting, children[i]); + } + } + data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null; + }, + removeSelectedNode: function (setting, node) { + var root = data.getRoot(setting); + for (var i = 0, j = root.curSelectedList.length; i < j; i++) { + if (node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) { + root.curSelectedList.splice(i, 1); + setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, node]); + i--; + j--; + } + } + }, + setCache: function (setting, cache) { + caches[setting.treeId] = cache; + }, + setRoot: function (setting, root) { + roots[setting.treeId] = root; + }, + setZTreeTools: function (setting, zTreeTools) { + for (var i = 0, j = _init.zTreeTools.length; i < j; i++) { + _init.zTreeTools[i].apply(this, arguments); + } + }, + transformToArrayFormat: function (setting, nodes) { + if (!nodes) return []; + var r = []; + if (tools.isArray(nodes)) { + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + _do(node); + } + } else { + _do(nodes); + } + return r; + + function _do(_node) { + r.push(_node); + var children = data.nodeChildren(setting, _node); + if (children) { + r = r.concat(data.transformToArrayFormat(setting, children)); + } + } + }, + transformTozTreeFormat: function (setting, sNodes) { + var i, + l, + key = setting.data.simpleData.idKey, + parentKey = setting.data.simpleData.pIdKey; + if (!key || key == "" || !sNodes) return []; + + if (tools.isArray(sNodes)) { + var r = []; + var tmpMap = {}; + for (i = 0, l = sNodes.length; i < l; i++) { + tmpMap[sNodes[i][key]] = sNodes[i]; + } + for (i = 0, l = sNodes.length; i < l; i++) { + var p = tmpMap[sNodes[i][parentKey]]; + if (p && sNodes[i][key] != sNodes[i][parentKey]) { + var children = data.nodeChildren(setting, p); + if (!children) { + children = data.nodeChildren(setting, p, []); + } + children.push(sNodes[i]); + } else { + r.push(sNodes[i]); + } + } + return r; + } else { + return [sNodes]; + } + }, + }, + //method of event proxy + event = { + bindEvent: function (setting) { + for (var i = 0, j = _init.bind.length; i < j; i++) { + _init.bind[i].apply(this, arguments); + } + }, + unbindEvent: function (setting) { + for (var i = 0, j = _init.unbind.length; i < j; i++) { + _init.unbind[i].apply(this, arguments); + } + }, + bindTree: function (setting) { + var eventParam = { + treeId: setting.treeId, + }, + o = setting.treeObj; + if (!setting.view.txtSelectedEnable) { + // for can't select text + o.bind("selectstart", handler.onSelectStart).css({ + "-moz-user-select": "-moz-none", + }); + } + o.bind("click", eventParam, event.proxy); + o.bind("dblclick", eventParam, event.proxy); + o.bind("mouseover", eventParam, event.proxy); + o.bind("mouseout", eventParam, event.proxy); + o.bind("mousedown", eventParam, event.proxy); + o.bind("mouseup", eventParam, event.proxy); + o.bind("contextmenu", eventParam, event.proxy); + }, + unbindTree: function (setting) { + var o = setting.treeObj; + o.unbind("selectstart", handler.onSelectStart) + .unbind("click", event.proxy) + .unbind("dblclick", event.proxy) + .unbind("mouseover", event.proxy) + .unbind("mouseout", event.proxy) + .unbind("mousedown", event.proxy) + .unbind("mouseup", event.proxy) + .unbind("contextmenu", event.proxy); + }, + doProxy: function (e) { + var results = []; + for (var i = 0, j = _init.proxys.length; i < j; i++) { + var proxyResult = _init.proxys[i].apply(this, arguments); + results.push(proxyResult); + if (proxyResult.stop) { + break; + } + } + return results; + }, + proxy: function (e) { + var setting = data.getSetting(e.data.treeId); + if (!tools.uCanDo(setting, e)) return true; + var results = event.doProxy(e), + r = true, + x = false; + for (var i = 0, l = results.length; i < l; i++) { + var proxyResult = results[i]; + if (proxyResult.nodeEventCallback) { + x = true; + r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; + } + if (proxyResult.treeEventCallback) { + x = true; + r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; + } + } + return r; + }, + }, + //method of event handler + handler = { + onSwitchNode: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (node.open) { + if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) + return true; + data.getRoot(setting).expandTriggerFlag = true; + view.switchNode(setting, node); + } else { + if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true; + data.getRoot(setting).expandTriggerFlag = true; + view.switchNode(setting, node); + } + return true; + }, + onClickNode: function (event, node) { + var setting = data.getSetting(event.data.treeId), + clickFlag = + setting.view.autoCancelSelected && + (event.ctrlKey || event.metaKey) && + data.isSelectedNode(setting, node) + ? 0 + : setting.view.autoCancelSelected && + (event.ctrlKey || event.metaKey) && + setting.view.selectedMulti + ? 2 + : 1; + if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) + return true; + if (clickFlag === 0) { + view.cancelPreSelectedNode(setting, node); + } else { + view.selectNode(setting, node, clickFlag === 2); + } + setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]); + return true; + }, + onZTreeMousedown: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) { + tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]); + } + return true; + }, + onZTreeMouseup: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) { + tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]); + } + return true; + }, + onZTreeDblclick: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) { + tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]); + } + return true; + }, + onZTreeContextmenu: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) { + tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]); + } + return typeof setting.callback.onRightClick != "function"; + }, + onSelectStart: function (e) { + var n = e.originalEvent.srcElement.nodeName.toLowerCase(); + return n === "input" || n === "textarea"; + }, + }, + //method of tools for zTree + tools = { + apply: function (fun, param, defaultValue) { + if (typeof fun == "function") { + return fun.apply(zt, param ? param : []); + } + return defaultValue; + }, + canAsync: function (setting, node) { + var children = data.nodeChildren(setting, node); + var isParent = data.nodeIsParent(setting, node); + return setting.async.enable && node && isParent && !(node.zAsync || (children && children.length > 0)); + }, + clone: function (obj) { + if (obj === null) return null; + var o = tools.isArray(obj) ? [] : {}; + for (var i in obj) { + o[i] = + obj[i] instanceof Date + ? new Date(obj[i].getTime()) + : typeof obj[i] === "object" + ? tools.clone(obj[i]) + : obj[i]; + } + return o; + }, + eqs: function (str1, str2) { + return str1.toLowerCase() === str2.toLowerCase(); + }, + isArray: function (arr) { + return Object.prototype.toString.apply(arr) === "[object Array]"; + }, + isElement: function (o) { + return typeof HTMLElement === "object" + ? o instanceof HTMLElement //DOM2 + : o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"; + }, + $: function (node, exp, setting) { + if (!!exp && typeof exp != "string") { + setting = exp; + exp = ""; + } + if (typeof node == "string") { + return $(node, setting ? setting.treeObj.get(0).ownerDocument : null); + } else { + return $("#" + node.tId + exp, setting ? setting.treeObj : null); + } + }, + getMDom: function (setting, curDom, targetExpr) { + if (!curDom) return null; + while (curDom && curDom.id !== setting.treeId) { + for (var i = 0, l = targetExpr.length; curDom.tagName && i < l; i++) { + if ( + tools.eqs(curDom.tagName, targetExpr[i].tagName) && + curDom.getAttribute(targetExpr[i].attrName) !== null + ) { + return curDom; + } + } + curDom = curDom.parentNode; + } + return null; + }, + getNodeMainDom: function (target) { + return $(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0); + }, + isChildOrSelf: function (dom, parentId) { + return $(dom).closest("#" + parentId).length > 0; + }, + uCanDo: function (setting, e) { + return true; + }, + }, + //method of operate ztree dom + view = { + addNodes: function (setting, parentNode, index, newNodes, isSilent) { + var isParent = data.nodeIsParent(setting, parentNode); + if (setting.data.keep.leaf && parentNode && !isParent) { + return; + } + if (!tools.isArray(newNodes)) { + newNodes = [newNodes]; + } + if (setting.data.simpleData.enable) { + newNodes = data.transformTozTreeFormat(setting, newNodes); + } + if (parentNode) { + var target_switchObj = $$(parentNode, consts.id.SWITCH, setting), + target_icoObj = $$(parentNode, consts.id.ICON, setting), + target_ulObj = $$(parentNode, consts.id.UL, setting); + + if (!parentNode.open) { + view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE); + view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE); + parentNode.open = false; + target_ulObj.css({ + display: "none", + }); + } + + data.addNodesData(setting, parentNode, index, newNodes); + view.createNodes(setting, parentNode.level + 1, newNodes, parentNode, index); + if (!isSilent) { + view.expandCollapseParentNode(setting, parentNode, true); + } + } else { + data.addNodesData(setting, data.getRoot(setting), index, newNodes); + view.createNodes(setting, 0, newNodes, null, index); + } + }, + appendNodes: function (setting, level, nodes, parentNode, index, initFlag, openFlag) { + if (!nodes) return []; + var html = []; + + var tmpPNode = parentNode ? parentNode : data.getRoot(setting), + tmpPChild = data.nodeChildren(setting, tmpPNode), + isFirstNode, + isLastNode; + + if (!tmpPChild || index >= tmpPChild.length - nodes.length) { + index = -1; + } + + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (initFlag) { + isFirstNode = (index === 0 || tmpPChild.length == nodes.length) && i == 0; + isLastNode = index < 0 && i == nodes.length - 1; + data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); + data.addNodeCache(setting, node); + } + var isParent = data.nodeIsParent(setting, node); + + var childHtml = []; + var children = data.nodeChildren(setting, node); + if (children && children.length > 0) { + //make child html first, because checkType + childHtml = view.appendNodes( + setting, + level + 1, + children, + node, + -1, + initFlag, + openFlag && node.open + ); + } + if (openFlag) { + view.makeDOMNodeMainBefore(html, setting, node); + view.makeDOMNodeLine(html, setting, node); + data.getBeforeA(setting, node, html); + view.makeDOMNodeNameBefore(html, setting, node); + data.getInnerBeforeA(setting, node, html); + view.makeDOMNodeIcon(html, setting, node); + data.getInnerAfterA(setting, node, html); + view.makeDOMNodeNameAfter(html, setting, node); + data.getAfterA(setting, node, html); + if (isParent && node.open) { + view.makeUlHtml(setting, node, html, childHtml.join("")); + } + view.makeDOMNodeMainAfter(html, setting, node); + data.addCreatedNode(setting, node); + } + } + return html; + }, + appendParentULDom: function (setting, node) { + var html = [], + nObj = $$(node, setting); + if (!nObj.get(0) && !!node.parentTId) { + view.appendParentULDom(setting, node.getParentNode()); + nObj = $$(node, setting); + } + var ulObj = $$(node, consts.id.UL, setting); + if (ulObj.get(0)) { + ulObj.remove(); + } + var children = data.nodeChildren(setting, node), + childHtml = view.appendNodes(setting, node.level + 1, children, node, -1, false, true); + view.makeUlHtml(setting, node, html, childHtml.join("")); + nObj.append(html.join("")); + }, + asyncNode: function (setting, node, isSilent, callback) { + var i, l; + var isParent = data.nodeIsParent(setting, node); + if (node && !isParent) { + tools.apply(callback); + return false; + } else if (node && node.isAjaxing) { + return false; + } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) { + tools.apply(callback); + return false; + } + if (node) { + node.isAjaxing = true; + var icoObj = $$(node, consts.id.ICON, setting); + icoObj.attr({ style: "", class: consts.className.BUTTON + " " + consts.className.ICO_LOADING }); + } + + var tmpParam = {}; + var autoParam = tools.apply(setting.async.autoParam, [setting.treeId, node], setting.async.autoParam); + for (i = 0, l = autoParam.length; node && i < l; i++) { + var pKey = autoParam[i].split("="), + spKey = pKey; + if (pKey.length > 1) { + spKey = pKey[1]; + pKey = pKey[0]; + } + tmpParam[spKey] = node[pKey]; + } + var otherParam = tools.apply( + setting.async.otherParam, + [setting.treeId, node], + setting.async.otherParam + ); + if (tools.isArray(otherParam)) { + for (i = 0, l = otherParam.length; i < l; i += 2) { + tmpParam[otherParam[i]] = otherParam[i + 1]; + } + } else { + for (var p in otherParam) { + tmpParam[p] = otherParam[p]; + } + } + + var _tmpV = data.getRoot(setting)._ver; + $.ajax({ + contentType: setting.async.contentType, + cache: false, + type: setting.async.type, + url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url), + data: + setting.async.contentType.indexOf("application/json") > -1 + ? JSON.stringify(tmpParam) + : tmpParam, + dataType: setting.async.dataType, + headers: setting.async.headers, + xhrFields: setting.async.xhrFields, + success: function (msg) { + if (_tmpV != data.getRoot(setting)._ver) { + return; + } + var newNodes = []; + try { + if (!msg || msg.length == 0) { + newNodes = []; + } else if (typeof msg == "string") { + newNodes = eval("(" + msg + ")"); + } else { + newNodes = msg; + } + } catch (err) { + newNodes = msg; + } + + if (node) { + node.isAjaxing = null; + node.zAsync = true; + } + view.setNodeLineIcos(setting, node); + if (newNodes && newNodes !== "") { + newNodes = tools.apply( + setting.async.dataFilter, + [setting.treeId, node, newNodes], + newNodes + ); + view.addNodes(setting, node, -1, !!newNodes ? tools.clone(newNodes) : [], !!isSilent); + } else { + view.addNodes(setting, node, -1, [], !!isSilent); + } + setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]); + tools.apply(callback); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + if (_tmpV != data.getRoot(setting)._ver) { + return; + } + if (node) node.isAjaxing = null; + view.setNodeLineIcos(setting, node); + setting.treeObj.trigger(consts.event.ASYNC_ERROR, [ + setting.treeId, + node, + XMLHttpRequest, + textStatus, + errorThrown, + ]); + }, + }); + return true; + }, + cancelPreSelectedNode: function (setting, node, excludeNode) { + var list = data.getRoot(setting).curSelectedList, + i, + n; + for (i = list.length - 1; i >= 0; i--) { + n = list[i]; + if (node === n || (!node && (!excludeNode || excludeNode !== n))) { + $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED); + if (node) { + data.removeSelectedNode(setting, node); + break; + } else { + list.splice(i, 1); + setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, n]); + } + } + } + }, + createNodeCallback: function (setting) { + if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { + var root = data.getRoot(setting); + while (root.createdNodes.length > 0) { + var node = root.createdNodes.shift(); + tools.apply(setting.view.addDiyDom, [setting.treeId, node]); + if (!!setting.callback.onNodeCreated) { + setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]); + } + } + } + }, + createNodes: function (setting, level, nodes, parentNode, index) { + if (!nodes || nodes.length == 0) return; + var root = data.getRoot(setting), + openFlag = + !parentNode || + parentNode.open || + !!$$(data.nodeChildren(setting, parentNode)[0], setting).get(0); + root.createdNodes = []; + var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, index, true, openFlag), + parentObj, + nextObj; + + if (!parentNode) { + parentObj = setting.treeObj; + //setting.treeObj.append(zTreeHtml.join('')); + } else { + var ulObj = $$(parentNode, consts.id.UL, setting); + if (ulObj.get(0)) { + parentObj = ulObj; + //ulObj.append(zTreeHtml.join('')); + } + } + if (parentObj) { + if (index >= 0) { + nextObj = parentObj.children()[index]; + } + if (index >= 0 && nextObj) { + $(nextObj).before(zTreeHtml.join("")); + } else { + parentObj.append(zTreeHtml.join("")); + } + } + + view.createNodeCallback(setting); + }, + destroy: function (setting) { + if (!setting) return; + data.initCache(setting); + data.initRoot(setting); + event.unbindTree(setting); + event.unbindEvent(setting); + setting.treeObj.empty(); + delete settings[setting.treeId]; + }, + expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) { + var root = data.getRoot(setting); + var tmpCb, _callback; + if (!node) { + tools.apply(callback, []); + return; + } + var children = data.nodeChildren(setting, node); + var isParent = data.nodeIsParent(setting, node); + if (root.expandTriggerFlag) { + _callback = callback; + tmpCb = function () { + if (_callback) _callback(); + if (node.open) { + setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]); + } else { + setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]); + } + }; + callback = tmpCb; + root.expandTriggerFlag = false; + } + if ( + !node.open && + isParent && + (!$$(node, consts.id.UL, setting).get(0) || + (children && children.length > 0 && !$$(children[0], setting).get(0))) + ) { + view.appendParentULDom(setting, node); + view.createNodeCallback(setting); + } + if (node.open == expandFlag) { + tools.apply(callback, []); + return; + } + var ulObj = $$(node, consts.id.UL, setting), + switchObj = $$(node, consts.id.SWITCH, setting), + icoObj = $$(node, consts.id.ICON, setting); + + if (isParent) { + node.open = !node.open; + if (node.iconOpen && node.iconClose) { + icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); + } + + if (node.open) { + view.replaceSwitchClass(node, switchObj, consts.folder.OPEN); + view.replaceIcoClass(node, icoObj, consts.folder.OPEN); + if (animateFlag == false || setting.view.expandSpeed == "") { + ulObj.show(); + tools.apply(callback, []); + } else { + if (children && children.length > 0) { + ulObj.slideDown(setting.view.expandSpeed, callback); + } else { + ulObj.show(); + tools.apply(callback, []); + } + } + } else { + view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE); + view.replaceIcoClass(node, icoObj, consts.folder.CLOSE); + if ( + animateFlag == false || + setting.view.expandSpeed == "" || + !(children && children.length > 0) + ) { + ulObj.hide(); + tools.apply(callback, []); + } else { + ulObj.slideUp(setting.view.expandSpeed, callback); + } + } + } else { + tools.apply(callback, []); + } + }, + expandCollapseParentNode: function (setting, node, expandFlag, animateFlag, callback) { + if (!node) return; + if (!node.parentTId) { + view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); + return; + } else { + view.expandCollapseNode(setting, node, expandFlag, animateFlag); + } + if (node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback); + } + }, + expandCollapseSonNode: function (setting, node, expandFlag, animateFlag, callback) { + var root = data.getRoot(setting), + treeNodes = node ? data.nodeChildren(setting, node) : data.nodeChildren(setting, root), + selfAnimateSign = node ? false : animateFlag, + expandTriggerFlag = data.getRoot(setting).expandTriggerFlag; + data.getRoot(setting).expandTriggerFlag = false; + if (treeNodes) { + for (var i = 0, l = treeNodes.length; i < l; i++) { + if (treeNodes[i]) + view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign); + } + } + data.getRoot(setting).expandTriggerFlag = expandTriggerFlag; + view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); + }, + isSelectedNode: function (setting, node) { + if (!node) { + return false; + } + var list = data.getRoot(setting).curSelectedList, + i; + for (i = list.length - 1; i >= 0; i--) { + if (node === list[i]) { + return true; + } + } + return false; + }, + makeDOMNodeIcon: function (html, setting, node) { + var nameStr = data.nodeName(setting, node), + name = setting.view.nameIsHTML + ? nameStr + : nameStr.replace(/&/g, "&").replace(//g, ">"); + html.push( + "", + name, + "" + ); + }, + makeDOMNodeLine: function (html, setting, node) { + html.push( + "" + ); + }, + makeDOMNodeMainAfter: function (html, setting, node) { + html.push(""); + }, + makeDOMNodeMainBefore: function (html, setting, node) { + html.push( + "
  • " + ); + }, + makeDOMNodeNameAfter: function (html, setting, node) { + html.push(""); + }, + makeDOMNodeNameBefore: function (html, setting, node) { + var title = data.nodeTitle(setting, node), + url = view.makeNodeUrl(setting, node), + fontcss = view.makeNodeFontCss(setting, node), + nodeClasses = view.makeNodeClasses(setting, node), + fontStyle = []; + for (var f in fontcss) { + fontStyle.push(f, ":", fontcss[f], ";"); + } + html.push( + " 0 ? " href='" + url + "'" : "", + " target='", + view.makeNodeTarget(node), + "' style='", + fontStyle.join(""), + "'" + ); + if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) { + html.push("title='", title.replace(/'/g, "'").replace(//g, ">"), "'"); + } + html.push(">"); + }, + makeNodeFontCss: function (setting, node) { + var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss); + return fontCss && typeof fontCss != "function" ? fontCss : {}; + }, + makeNodeClasses: function (setting, node) { + var classes = tools.apply(setting.view.nodeClasses, [setting.treeId, node], setting.view.nodeClasses); + return classes && typeof classes !== "function" ? classes : { add: [], remove: [] }; + }, + makeNodeIcoClass: function (setting, node) { + var icoCss = ["ico"]; + if (!node.isAjaxing) { + var isParent = data.nodeIsParent(setting, node); + icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0]; + if (isParent) { + icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); + } else { + icoCss.push(consts.folder.DOCU); + } + } + return "x-icon b-font " + consts.className.ICON + " " + icoCss.join("_"); + }, + makeNodeIcoStyle: function (setting, node) { + var icoStyle = []; + if (!node.isAjaxing) { + var isParent = data.nodeIsParent(setting, node); + var icon = + isParent && node.iconOpen && node.iconClose + ? node.open + ? node.iconOpen + : node.iconClose + : node[setting.data.key.icon]; + if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;"); + if ( + setting.view.showIcon == false || + !tools.apply(setting.view.showIcon, [setting.treeId, node], true) + ) { + icoStyle.push("display:none;"); + } + } + return icoStyle.join(""); + }, + makeNodeLineClass: function (setting, node) { + var lineClass = []; + if (setting.view.showLine) { + if (node.level == 0 && node.isFirstNode && node.isLastNode) { + lineClass.push(consts.line.ROOT); + } else if (node.level == 0 && node.isFirstNode) { + lineClass.push(consts.line.ROOTS); + } else if (node.isLastNode) { + lineClass.push(consts.line.BOTTOM); + } else { + lineClass.push(consts.line.CENTER); + } + } else { + lineClass.push(consts.line.NOLINE); + } + if (data.nodeIsParent(setting, node)) { + lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); + } else { + lineClass.push(consts.folder.DOCU); + } + return view.makeNodeLineClassEx(node) + lineClass.join("_"); + }, + makeNodeLineClassEx: function (node) { + return ( + consts.className.BUTTON + + " " + + consts.className.LEVEL + + node.level + + " " + + consts.className.SWITCH + + " " + ); + }, + makeNodeTarget: function (node) { + return node.target || "_blank"; + }, + makeNodeUrl: function (setting, node) { + var urlKey = setting.data.key.url; + return node[urlKey] ? node[urlKey] : null; + }, + makeUlHtml: function (setting, node, html, content) { + html.push( + "
      " + ); + html.push(content); + html.push("
    "); + }, + makeUlLineClass: function (setting, node) { + return setting.view.showLine && !node.isLastNode ? consts.line.LINE : ""; + }, + removeChildNodes: function (setting, node) { + if (!node) return; + var nodes = data.nodeChildren(setting, node); + if (!nodes) return; + + for (var i = 0, l = nodes.length; i < l; i++) { + data.removeNodeCache(setting, nodes[i]); + } + data.removeSelectedNode(setting); + delete node[setting.data.key.children]; + + if (!setting.data.keep.parent) { + data.nodeIsParent(setting, node, false); + node.open = false; + var tmp_switchObj = $$(node, consts.id.SWITCH, setting), + tmp_icoObj = $$(node, consts.id.ICON, setting); + view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU); + view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU); + $$(node, consts.id.UL, setting).remove(); + } else { + $$(node, consts.id.UL, setting).empty(); + } + }, + scrollIntoView: function (setting, dom) { + if (!dom) { + return; + } + // support IE 7 / 8 + if (typeof Element === "undefined" || typeof HTMLElement === "undefined") { + var contRect = setting.treeObj.get(0).getBoundingClientRect(), + findMeRect = dom.getBoundingClientRect(); + if ( + findMeRect.top < contRect.top || + findMeRect.bottom > contRect.bottom || + findMeRect.right > contRect.right || + findMeRect.left < contRect.left + ) { + dom.scrollIntoView(); + } + return; + } + // CC-BY jocki84@googlemail.com, https://gist.github.com/jocki84/6ffafd003387179a988e + if (!Element.prototype.scrollIntoViewIfNeeded) { + Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) { + "use strict"; + + function makeRange(start, length) { + return { start: start, length: length, end: start + length }; + } + + function coverRange(inner, outer) { + if (false === centerIfNeeded || (outer.start < inner.end && inner.start < outer.end)) { + return Math.max(inner.end - outer.length, Math.min(outer.start, inner.start)); + } + return (inner.start + inner.end - outer.length) / 2; + } + + function makePoint(x, y) { + return { + x: x, + y: y, + translate: function translate(dX, dY) { + return makePoint(x + dX, y + dY); + }, + }; + } + + function absolute(elem, pt) { + while (elem) { + pt = pt.translate(elem.offsetLeft, elem.offsetTop); + elem = elem.offsetParent; + } + return pt; + } + + var target = absolute(this, makePoint(0, 0)), + extent = makePoint(this.offsetWidth, this.offsetHeight), + elem = this.parentNode, + origin; + + while (elem instanceof HTMLElement) { + // Apply desired scroll amount. + origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop)); + elem.scrollLeft = coverRange( + makeRange(target.x - origin.x, extent.x), + makeRange(elem.scrollLeft, elem.clientWidth) + ); + elem.scrollTop = coverRange( + makeRange(target.y - origin.y, extent.y), + makeRange(elem.scrollTop, elem.clientHeight) + ); + + // Determine actual scroll amount by reading back scroll properties. + target = target.translate(-elem.scrollLeft, -elem.scrollTop); + elem = elem.parentNode; + } + }; + } + dom.scrollIntoViewIfNeeded(); + }, + setFirstNode: function (setting, parentNode) { + var children = data.nodeChildren(setting, parentNode); + if (children.length > 0) { + children[0].isFirstNode = true; + } + }, + setLastNode: function (setting, parentNode) { + var children = data.nodeChildren(setting, parentNode); + if (children.length > 0) { + children[children.length - 1].isLastNode = true; + } + }, + removeNode: function (setting, node) { + var root = data.getRoot(setting), + parentNode = node.parentTId ? node.getParentNode() : root; + + node.isFirstNode = false; + node.isLastNode = false; + node.getPreNode = function () { + return null; + }; + node.getNextNode = function () { + return null; + }; + + if (!data.getNodeCache(setting, node.tId)) { + return; + } + + $$(node, setting).remove(); + data.removeNodeCache(setting, node); + data.removeSelectedNode(setting, node); + + var children = data.nodeChildren(setting, parentNode); + for (var i = 0, l = children.length; i < l; i++) { + if (children[i].tId == node.tId) { + children.splice(i, 1); + break; + } + } + view.setFirstNode(setting, parentNode); + view.setLastNode(setting, parentNode); + + var tmp_ulObj, + tmp_switchObj, + tmp_icoObj, + childLength = children.length; + + //repair nodes old parent + if (!setting.data.keep.parent && childLength == 0) { + //old parentNode has no child nodes + data.nodeIsParent(setting, parentNode, false); + parentNode.open = false; + delete parentNode[setting.data.key.children]; + tmp_ulObj = $$(parentNode, consts.id.UL, setting); + tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting); + tmp_icoObj = $$(parentNode, consts.id.ICON, setting); + view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU); + view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU); + tmp_ulObj.css("display", "none"); + } else if (setting.view.showLine && childLength > 0) { + //old parentNode has child nodes + var newLast = children[childLength - 1]; + tmp_ulObj = $$(newLast, consts.id.UL, setting); + tmp_switchObj = $$(newLast, consts.id.SWITCH, setting); + tmp_icoObj = $$(newLast, consts.id.ICON, setting); + if (parentNode == root) { + if (children.length == 1) { + //node was root, and ztree has only one root after move node + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT); + } else { + var tmp_first_switchObj = $$(children[0], consts.id.SWITCH, setting); + view.replaceSwitchClass(children[0], tmp_first_switchObj, consts.line.ROOTS); + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); + } + } else { + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); + } + tmp_ulObj.removeClass(consts.line.LINE); + } + }, + replaceIcoClass: function (node, obj, newName) { + if (!obj || node.isAjaxing) return; + var tmpName = obj.attr("class"); + if (tmpName == undefined) return; + var tmpList = tmpName.split("_"); + switch (newName) { + case consts.folder.OPEN: + case consts.folder.CLOSE: + case consts.folder.DOCU: + tmpList[tmpList.length - 1] = newName; + break; + } + obj.attr("class", tmpList.join("_")); + }, + replaceSwitchClass: function (node, obj, newName) { + if (!obj) return; + var tmpName = obj.attr("class"); + if (tmpName == undefined) return; + var tmpList = tmpName.split("_"); + switch (newName) { + case consts.line.ROOT: + case consts.line.ROOTS: + case consts.line.CENTER: + case consts.line.BOTTOM: + case consts.line.NOLINE: + tmpList[0] = view.makeNodeLineClassEx(node) + newName; + break; + case consts.folder.OPEN: + case consts.folder.CLOSE: + case consts.folder.DOCU: + tmpList[1] = newName; + break; + } + obj.attr("class", tmpList.join("_")); + if (newName !== consts.folder.DOCU) { + obj.removeAttr("disabled"); + } else { + obj.attr("disabled", "disabled"); + } + }, + selectNode: function (setting, node, addFlag) { + if (!addFlag) { + view.cancelPreSelectedNode(setting, null, node); + } + $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED); + data.addSelectedNode(setting, node); + setting.treeObj.trigger(consts.event.SELECTED, [setting.treeId, node]); + }, + setNodeFontCss: function (setting, treeNode) { + var aObj = $$(treeNode, consts.id.A, setting), + fontCss = view.makeNodeFontCss(setting, treeNode); + if (fontCss) { + aObj.css(fontCss); + } + }, + setNodeClasses: function (setting, treeNode) { + var aObj = $$(treeNode, consts.id.A, setting), + classes = view.makeNodeClasses(setting, treeNode); + if ("add" in classes && classes.add.length) { + aObj.addClass(classes.add.join(" ")); + } + if ("remove" in classes && classes.remove.length) { + aObj.removeClass(classes.remove.join(" ")); + } + }, + setNodeLineIcos: function (setting, node) { + if (!node) return; + var switchObj = $$(node, consts.id.SWITCH, setting), + ulObj = $$(node, consts.id.UL, setting), + icoObj = $$(node, consts.id.ICON, setting), + ulLine = view.makeUlLineClass(setting, node); + if (ulLine.length == 0) { + ulObj.removeClass(consts.line.LINE); + } else { + ulObj.addClass(ulLine); + } + switchObj.attr("class", view.makeNodeLineClass(setting, node)); + if (data.nodeIsParent(setting, node)) { + switchObj.removeAttr("disabled"); + } else { + switchObj.attr("disabled", "disabled"); + } + icoObj.removeAttr("style"); + icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); + icoObj.attr("class", view.makeNodeIcoClass(setting, node)); + }, + setNodeName: function (setting, node) { + var title = data.nodeTitle(setting, node), + nObj = $$(node, consts.id.SPAN, setting); + nObj.empty(); + if (setting.view.nameIsHTML) { + nObj.html(data.nodeName(setting, node)); + } else { + nObj.text(data.nodeName(setting, node)); + } + if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) { + var aObj = $$(node, consts.id.A, setting); + aObj.attr("title", !title ? "" : title); + } + }, + setNodeTarget: function (setting, node) { + var aObj = $$(node, consts.id.A, setting); + aObj.attr("target", view.makeNodeTarget(node)); + }, + setNodeUrl: function (setting, node) { + var aObj = $$(node, consts.id.A, setting), + url = view.makeNodeUrl(setting, node); + if (url == null || url.length == 0) { + aObj.removeAttr("href"); + } else { + aObj.attr("href", url); + } + }, + switchNode: function (setting, node) { + if (node.open || !tools.canAsync(setting, node)) { + view.expandCollapseNode(setting, node, !node.open); + } else if (setting.async.enable) { + if (!view.asyncNode(setting, node)) { + view.expandCollapseNode(setting, node, !node.open); + return; + } + } else if (node) { + view.expandCollapseNode(setting, node, !node.open); + } + }, + }; + // zTree defind + $.fn.zTree = { + consts: _consts, + _z: { + tools: tools, + view: view, + event: event, + data: data, + }, + getZTreeObj: function (treeId) { + var o = data.getZTreeTools(treeId); + return o ? o : null; + }, + destroy: function (treeId) { + if (!!treeId && treeId.length > 0) { + view.destroy(data.getSetting(treeId)); + } else { + for (var s in settings) { + view.destroy(settings[s]); + } + } + }, + init: function (obj, zSetting, zNodes) { + var setting = tools.clone(_setting); + $.extend(true, setting, zSetting); + setting.treeId = obj.attr("id"); + setting.treeObj = obj; + setting.treeObj.empty(); + settings[setting.treeId] = setting; + //For some older browser,(e.g., ie6) + if (typeof document.body.style.maxHeight === "undefined") { + setting.view.expandSpeed = ""; + } + data.initRoot(setting); + var root = data.getRoot(setting); + zNodes = zNodes ? tools.clone(tools.isArray(zNodes) ? zNodes : [zNodes]) : []; + if (setting.data.simpleData.enable) { + data.nodeChildren(setting, root, data.transformTozTreeFormat(setting, zNodes)); + } else { + data.nodeChildren(setting, root, zNodes); + } + + data.initCache(setting); + event.unbindTree(setting); + event.bindTree(setting); + event.unbindEvent(setting); + event.bindEvent(setting); + + var zTreeTools = { + setting: setting, + addNodes: function (parentNode, index, newNodes, isSilent) { + if (!parentNode) parentNode = null; + var isParent = data.nodeIsParent(setting, parentNode); + if (parentNode && !isParent && setting.data.keep.leaf) return null; + + var i = parseInt(index, 10); + if (isNaN(i)) { + isSilent = !!newNodes; + newNodes = index; + index = -1; + } else { + index = i; + } + if (!newNodes) return null; + + var xNewNodes = tools.clone(tools.isArray(newNodes) ? newNodes : [newNodes]); + + function addCallback() { + view.addNodes(setting, parentNode, index, xNewNodes, isSilent == true); + } + + if (tools.canAsync(setting, parentNode)) { + view.asyncNode(setting, parentNode, isSilent, addCallback); + } else { + addCallback(); + } + return xNewNodes; + }, + cancelSelectedNode: function (node) { + view.cancelPreSelectedNode(setting, node); + }, + destroy: function () { + view.destroy(setting); + }, + expandAll: function (expandFlag) { + expandFlag = !!expandFlag; + view.expandCollapseSonNode(setting, null, expandFlag, true); + return expandFlag; + }, + expandNode: function (node, expandFlag, sonSign, focus, callbackFlag) { + if (!node || !data.nodeIsParent(setting, node)) return null; + if (expandFlag !== true && expandFlag !== false) { + expandFlag = !node.open; + } + callbackFlag = !!callbackFlag; + + if ( + callbackFlag && + expandFlag && + tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false + ) { + return null; + } else if ( + callbackFlag && + !expandFlag && + tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false + ) { + return null; + } + if (expandFlag && node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false); + } + if (expandFlag === node.open && !sonSign) { + return null; + } + + data.getRoot(setting).expandTriggerFlag = callbackFlag; + if (!tools.canAsync(setting, node) && sonSign) { + view.expandCollapseSonNode(setting, node, expandFlag, true, showNodeFocus); + } else { + node.open = !expandFlag; + view.switchNode(this.setting, node); + showNodeFocus(); + } + return expandFlag; + + function showNodeFocus() { + var a = $$(node, consts.id.A, setting).get(0); + if (a && focus !== false) { + view.scrollIntoView(setting, a); + } + } + }, + getNodes: function () { + return data.getNodes(setting); + }, + getNodeByParam: function (key, value, parentNode) { + if (!key) return null; + return data.getNodeByParam( + setting, + parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), + key, + value + ); + }, + getNodeByTId: function (tId) { + return data.getNodeCache(setting, tId); + }, + getNodesByParam: function (key, value, parentNode) { + if (!key) return null; + return data.getNodesByParam( + setting, + parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), + key, + value + ); + }, + getNodesByParamFuzzy: function (key, value, parentNode) { + if (!key) return null; + return data.getNodesByParamFuzzy( + setting, + parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), + key, + value + ); + }, + getNodesByFilter: function (filter, isSingle, parentNode, invokeParam) { + isSingle = !!isSingle; + if (!filter || typeof filter != "function") return isSingle ? null : []; + return data.getNodesByFilter( + setting, + parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), + filter, + isSingle, + invokeParam + ); + }, + getNodeIndex: function (node) { + if (!node) return null; + var parentNode = node.parentTId ? node.getParentNode() : data.getRoot(setting); + var children = data.nodeChildren(setting, parentNode); + for (var i = 0, l = children.length; i < l; i++) { + if (children[i] == node) return i; + } + return -1; + }, + getSelectedNodes: function () { + var r = [], + list = data.getRoot(setting).curSelectedList; + for (var i = 0, l = list.length; i < l; i++) { + r.push(list[i]); + } + return r; + }, + isSelectedNode: function (node) { + return data.isSelectedNode(setting, node); + }, + reAsyncChildNodesPromise: function (parentNode, reloadType, isSilent) { + var promise = new Promise(function (resolve, reject) { + try { + zTreeTools.reAsyncChildNodes(parentNode, reloadType, isSilent, function () { + resolve(parentNode); + }); + } catch (e) { + reject(e); + } + }); + return promise; + }, + reAsyncChildNodes: function (parentNode, reloadType, isSilent, callback) { + if (!this.setting.async.enable) return; + var isRoot = !parentNode; + if (isRoot) { + parentNode = data.getRoot(setting); + } + if (reloadType == "refresh") { + var children = data.nodeChildren(setting, parentNode); + for (var i = 0, l = children ? children.length : 0; i < l; i++) { + data.removeNodeCache(setting, children[i]); + } + data.removeSelectedNode(setting); + data.nodeChildren(setting, parentNode, []); + if (isRoot) { + this.setting.treeObj.empty(); + } else { + var ulObj = $$(parentNode, consts.id.UL, setting); + ulObj.empty(); + } + } + view.asyncNode(this.setting, isRoot ? null : parentNode, !!isSilent, callback); + }, + refresh: function () { + this.setting.treeObj.empty(); + var root = data.getRoot(setting), + nodes = data.nodeChildren(setting, root); + data.initRoot(setting); + data.nodeChildren(setting, root, nodes); + data.initCache(setting); + view.createNodes(setting, 0, data.nodeChildren(setting, root), null, -1); + }, + removeChildNodes: function (node) { + if (!node) return null; + var nodes = data.nodeChildren(setting, node); + view.removeChildNodes(setting, node); + return nodes ? nodes : null; + }, + removeNode: function (node, callbackFlag) { + if (!node) return; + callbackFlag = !!callbackFlag; + if ( + callbackFlag && + tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false + ) + return; + view.removeNode(setting, node); + if (callbackFlag) { + this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); + } + }, + selectNode: function (node, addFlag, isSilent) { + if (!node) return; + if (tools.uCanDo(setting)) { + addFlag = setting.view.selectedMulti && addFlag; + if (node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), true, false, showNodeFocus); + } else if (!isSilent) { + try { + $$(node, setting).focus().blur(); + } catch (e) {} + } + view.selectNode(setting, node, addFlag); + } + + function showNodeFocus() { + if (isSilent) { + return; + } + var a = $$(node, setting).get(0); + view.scrollIntoView(setting, a); + } + }, + transformTozTreeNodes: function (simpleNodes) { + return data.transformTozTreeFormat(setting, simpleNodes); + }, + transformToArray: function (nodes) { + return data.transformToArrayFormat(setting, nodes); + }, + updateNode: function (node, checkTypeFlag) { + if (!node) return; + var nObj = $$(node, setting); + if (nObj.get(0) && tools.uCanDo(setting)) { + view.setNodeName(setting, node); + view.setNodeTarget(setting, node); + view.setNodeUrl(setting, node); + view.setNodeLineIcos(setting, node); + view.setNodeFontCss(setting, node); + view.setNodeClasses(setting, node); + } + }, + }; + root.treeTools = zTreeTools; + data.setZTreeTools(setting, zTreeTools); + var children = data.nodeChildren(setting, root); + if (children && children.length > 0) { + view.createNodes(setting, 0, children, null, -1); + } else if (setting.async.enable && setting.async.url && setting.async.url !== "") { + view.asyncNode(setting); + } + return zTreeTools; + }, + }; + + var zt = $.fn.zTree, + $$ = tools.$, + consts = zt.consts; +})($); diff --git a/packages/fineui/src/case/ztree/jquery.ztree.excheck-3.5.js b/packages/fineui/src/case/ztree/jquery.ztree.excheck-3.5.js new file mode 100644 index 000000000..24f66b5ac --- /dev/null +++ b/packages/fineui/src/case/ztree/jquery.ztree.excheck-3.5.js @@ -0,0 +1,723 @@ +import $ from "jquery"; + +/* eslint-disable */ +/* + * JQuery zTree excheck v3.5.18 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2015-06-18 + */ +(function ($) { + //default consts of excheck + var _consts = { + event: { + CHECK: "ztree_check", + }, + id: { + CHECK: "_check", + }, + checkbox: { + STYLE: "checkbox", + DEFAULT: "chk", + DISABLED: "disable", + FALSE: "false", + TRUE: "true", + FULL: "full", + PART: "part", + FOCUS: "focus", + }, + radio: { + STYLE: "radio", + TYPE_ALL: "all", + TYPE_LEVEL: "level", + }, + }, + //default setting of excheck + _setting = { + check: { + enable: false, + autoCheckTrigger: false, + chkStyle: _consts.checkbox.STYLE, + nocheckInherit: false, + chkDisabledInherit: false, + radioType: _consts.radio.TYPE_LEVEL, + chkboxType: { + Y: "ps", + N: "ps", + }, + }, + data: { + key: { + checked: "checked", + }, + }, + callback: { + beforeCheck: null, + onCheck: null, + }, + }, + //default root of excheck + _initRoot = function (setting) { + var r = data.getRoot(setting); + r.radioCheckedList = []; + }, + //default cache of excheck + _initCache = function (treeId) {}, + //default bind event of excheck + _bindEvent = function (setting) { + var o = setting.treeObj, + c = consts.event; + o.bind(c.CHECK, function (event, srcEvent, treeId, node) { + event.srcEvent = srcEvent; + tools.apply(setting.callback.onCheck, [event, treeId, node]); + }); + }, + _unbindEvent = function (setting) { + var o = setting.treeObj, + c = consts.event; + o.unbind(c.CHECK); + }, + //default event proxy of excheck + _eventProxy = function (e) { + var target = e.target, + setting = data.getSetting(e.data.treeId), + tId = "", + node = null, + nodeEventType = "", + treeEventType = "", + nodeEventCallback = null, + treeEventCallback = null; + + if (tools.eqs(e.type, "mouseover")) { + if ( + setting.check.enable && + tools.eqs(target.tagName, "span") && + target.getAttribute("treeNode" + consts.id.CHECK) !== null + ) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "mouseoverCheck"; + } + } else if (tools.eqs(e.type, "mouseout")) { + if ( + setting.check.enable && + tools.eqs(target.tagName, "span") && + target.getAttribute("treeNode" + consts.id.CHECK) !== null + ) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "mouseoutCheck"; + } + } else if (tools.eqs(e.type, "click")) { + if ( + setting.check.enable && + tools.eqs(target.tagName, "span") && + target.getAttribute("treeNode" + consts.id.CHECK) !== null + ) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "checkNode"; + } + } + if (tId.length > 0) { + node = data.getNodeCache(setting, tId); + switch (nodeEventType) { + case "checkNode": + nodeEventCallback = _handler.onCheckNode; + break; + case "mouseoverCheck": + nodeEventCallback = _handler.onMouseoverCheck; + break; + case "mouseoutCheck": + nodeEventCallback = _handler.onMouseoutCheck; + break; + } + } + var proxyResult = { + stop: nodeEventType === "checkNode", + node: node, + nodeEventType: nodeEventType, + nodeEventCallback: nodeEventCallback, + treeEventType: treeEventType, + treeEventCallback: treeEventCallback, + }; + return proxyResult; + }, + //default init node of excheck + _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { + if (!n) return; + var checkedKey = setting.data.key.checked; + if (typeof n[checkedKey] == "string") n[checkedKey] = tools.eqs(n[checkedKey], "true"); + n[checkedKey] = !!n[checkedKey]; + n.checkedOld = n[checkedKey]; + if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true"); + n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck); + if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true"); + n.chkDisabled = + !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled); + if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true"); + n.halfCheck = !!n.halfCheck; + n.check_Child_State = -1; + n.check_Focus = false; + n.getCheckStatus = function () { + return data.getCheckStatus(setting, n); + }; + + if ( + setting.check.chkStyle == consts.radio.STYLE && + setting.check.radioType == consts.radio.TYPE_ALL && + n[checkedKey] + ) { + var r = data.getRoot(setting); + r.radioCheckedList.push(n); + } + }, + //add dom for check + _beforeA = function (setting, node, html) { + var checkedKey = setting.data.key.checked; + if (setting.check.enable) { + data.makeChkFlag(setting, node); + html.push( + "" + ); + } + }, + //update zTreeObj, add method of check + _zTreeTools = function (setting, zTreeTools) { + zTreeTools.checkNode = function (node, checked, checkTypeFlag, callbackFlag) { + var checkedKey = this.setting.data.key.checked; + if (node.chkDisabled === true) return; + if (checked !== true && checked !== false) { + checked = !node[checkedKey]; + } + callbackFlag = !!callbackFlag; + + if (node[checkedKey] === checked && !checkTypeFlag) { + return; + } else if ( + callbackFlag && + tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false + ) { + return; + } + if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) { + node[checkedKey] = checked; + var checkObj = $$(node, consts.id.CHECK, this.setting); + if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) + view.checkNodeRelation(this.setting, node); + view.setChkClass(this.setting, checkObj, node); + view.repairParentChkClassWithSelf(this.setting, node); + if (callbackFlag) { + this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]); + } + } + }; + + zTreeTools.checkAllNodes = function (checked) { + view.repairAllChk(this.setting, !!checked); + }; + + zTreeTools.getCheckedNodes = function (checked) { + var childKey = this.setting.data.key.children; + checked = checked !== false; + return data.getTreeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey], checked); + }; + + zTreeTools.getChangeCheckedNodes = function () { + var childKey = this.setting.data.key.children; + return data.getTreeChangeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey]); + }; + + zTreeTools.setChkDisabled = function (node, disabled, inheritParent, inheritChildren) { + disabled = !!disabled; + inheritParent = !!inheritParent; + inheritChildren = !!inheritChildren; + view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren); + view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent); + }; + + var _updateNode = zTreeTools.updateNode; + zTreeTools.updateNode = function (node, checkTypeFlag) { + if (_updateNode) _updateNode.apply(zTreeTools, arguments); + if (!node || !this.setting.check.enable) return; + var nObj = $$(node, this.setting); + if (nObj.get(0) && tools.uCanDo(this.setting)) { + var checkObj = $$(node, consts.id.CHECK, this.setting); + if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) + view.checkNodeRelation(this.setting, node); + view.setChkClass(this.setting, checkObj, node); + view.repairParentChkClassWithSelf(this.setting, node); + } + }; + }, + //method of operate data + _data = { + getRadioCheckedList: function (setting) { + var checkedList = data.getRoot(setting).radioCheckedList; + for (var i = 0, j = checkedList.length; i < j; i++) { + if (!data.getNodeCache(setting, checkedList[i].tId)) { + checkedList.splice(i, 1); + i--; + j--; + } + } + return checkedList; + }, + getCheckStatus: function (setting, node) { + if (!setting.check.enable || node.nocheck || node.chkDisabled) return null; + var checkedKey = setting.data.key.checked, + r = { + checked: node[checkedKey], + half: node.halfCheck + ? node.halfCheck + : setting.check.chkStyle == consts.radio.STYLE + ? node.check_Child_State === 2 + : node[checkedKey] + ? node.check_Child_State > -1 && node.check_Child_State < 2 + : node.check_Child_State > 0, + }; + return r; + }, + getTreeCheckedNodes: function (setting, nodes, checked, results) { + if (!nodes) return []; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + onlyOne = + checked && + setting.check.chkStyle == consts.radio.STYLE && + setting.check.radioType == consts.radio.TYPE_ALL; + results = !results ? [] : results; + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] == checked) { + results.push(nodes[i]); + if (onlyOne) { + break; + } + } + data.getTreeCheckedNodes(setting, nodes[i][childKey], checked, results); + if (onlyOne && results.length > 0) { + break; + } + } + return results; + }, + getTreeChangeCheckedNodes: function (setting, nodes, results) { + if (!nodes) return []; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked; + results = !results ? [] : results; + for (var i = 0, l = nodes.length; i < l; i++) { + if ( + nodes[i].nocheck !== true && + nodes[i].chkDisabled !== true && + nodes[i][checkedKey] != nodes[i].checkedOld + ) { + results.push(nodes[i]); + } + data.getTreeChangeCheckedNodes(setting, nodes[i][childKey], results); + } + return results; + }, + makeChkFlag: function (setting, node) { + if (!node) return; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + chkFlag = -1; + if (node[childKey]) { + for (var i = 0, l = node[childKey].length; i < l; i++) { + var cNode = node[childKey][i]; + var tmp = -1; + if (setting.check.chkStyle == consts.radio.STYLE) { + if (cNode.nocheck === true || cNode.chkDisabled === true) { + tmp = cNode.check_Child_State; + } else if (cNode.halfCheck === true) { + tmp = 2; + } else if (cNode[checkedKey]) { + tmp = 2; + } else { + tmp = cNode.check_Child_State > 0 ? 2 : 0; + } + if (tmp == 2) { + chkFlag = 2; + break; + } else if (tmp == 0) { + chkFlag = 0; + } + } else if (setting.check.chkStyle == consts.checkbox.STYLE) { + if (cNode.nocheck === true || cNode.chkDisabled === true) { + tmp = cNode.check_Child_State; + } else if (cNode.halfCheck === true) { + tmp = 1; + } else if (cNode[checkedKey]) { + tmp = cNode.check_Child_State === -1 || cNode.check_Child_State === 2 ? 2 : 1; + } else { + tmp = cNode.check_Child_State > 0 ? 1 : 0; + } + if (tmp === 1) { + chkFlag = 1; + break; + } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) { + chkFlag = 1; + break; + } else if (chkFlag === 2 && tmp > -1 && tmp < 2) { + chkFlag = 1; + break; + } else if (tmp > -1) { + chkFlag = tmp; + } + } + } + } + node.check_Child_State = chkFlag; + }, + }, + //method of event proxy + _event = {}, + //method of event handler + _handler = { + onCheckNode: function (event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkedKey = setting.data.key.checked; + if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true; + node[checkedKey] = !node[checkedKey]; + view.checkNodeRelation(setting, node); + var checkObj = $$(node, consts.id.CHECK, setting); + view.setChkClass(setting, checkObj, node); + view.repairParentChkClassWithSelf(setting, node); + setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]); + return true; + }, + onMouseoverCheck: function (event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkObj = $$(node, consts.id.CHECK, setting); + node.check_Focus = true; + view.setChkClass(setting, checkObj, node); + return true; + }, + onMouseoutCheck: function (event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkObj = $$(node, consts.id.CHECK, setting); + node.check_Focus = false; + view.setChkClass(setting, checkObj, node); + return true; + }, + }, + //method of tools for zTree + _tools = {}, + //method of operate ztree dom + _view = { + checkNodeRelation: function (setting, node) { + var pNode, + i, + l, + childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + r = consts.radio; + if (setting.check.chkStyle == r.STYLE) { + var checkedList = data.getRadioCheckedList(setting); + if (node[checkedKey]) { + if (setting.check.radioType == r.TYPE_ALL) { + for (i = checkedList.length - 1; i >= 0; i--) { + pNode = checkedList[i]; + if (pNode[checkedKey] && pNode != node) { + pNode[checkedKey] = false; + checkedList.splice(i, 1); + + view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); + if (pNode.parentTId != node.parentTId) { + view.repairParentChkClassWithSelf(setting, pNode); + } + } + } + checkedList.push(node); + } else { + var parentNode = node.parentTId ? node.getParentNode() : data.getRoot(setting); + for (i = 0, l = parentNode[childKey].length; i < l; i++) { + pNode = parentNode[childKey][i]; + if (pNode[checkedKey] && pNode != node) { + pNode[checkedKey] = false; + view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); + } + } + } + } else if (setting.check.radioType == r.TYPE_ALL) { + for (i = 0, l = checkedList.length; i < l; i++) { + if (node == checkedList[i]) { + checkedList.splice(i, 1); + break; + } + } + } + } else { + if ( + node[checkedKey] && + (!node[childKey] || node[childKey].length == 0 || setting.check.chkboxType.Y.indexOf("s") > -1) + ) { + view.setSonNodeCheckBox(setting, node, true); + } + if ( + !node[checkedKey] && + (!node[childKey] || node[childKey].length == 0 || setting.check.chkboxType.N.indexOf("s") > -1) + ) { + view.setSonNodeCheckBox(setting, node, false); + } + if (node[checkedKey] && setting.check.chkboxType.Y.indexOf("p") > -1) { + view.setParentNodeCheckBox(setting, node, true); + } + if (!node[checkedKey] && setting.check.chkboxType.N.indexOf("p") > -1) { + view.setParentNodeCheckBox(setting, node, false); + } + } + }, + makeChkClass: function (setting, node) { + var checkedKey = setting.data.key.checked, + c = consts.checkbox, + r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = checkboxType.Y === "" && checkboxType.N === ""; + var fullStyle = ""; + if (node.chkDisabled === true) { + fullStyle = c.DISABLED; + } else if (node.halfCheck) { + fullStyle = c.PART; + } else if (setting.check.chkStyle == r.STYLE) { + fullStyle = node.check_Child_State < 1 ? c.FULL : c.PART; + } else { + fullStyle = node[checkedKey] + ? node.check_Child_State === 2 || node.check_Child_State === -1 || notEffectByOtherNode + ? c.FULL + : c.PART + : node.check_Child_State < 1 || notEffectByOtherNode + ? c.FULL + : c.PART; + } + var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; + chkName = node.check_Focus && node.chkDisabled !== true ? chkName + "_" + c.FOCUS : chkName; + var chClass = consts.className.BUTTON + " " + c.DEFAULT + " " + chkName; + switch (chkName) { + case "checkbox_true_part": + case "checkbox_true_part_focus": + chClass += " bi-half-button bi-high-light-border"; + break; + case "checkbox_true_full": + case "checkbox_true_full_focus": + chClass += " bi-checkbox checkbox-content bi-high-light-background active"; + break; + case "checkbox_false_full": + case "checkbox_false_full_focus": + default: + chClass += " bi-checkbox checkbox-content"; + break; + } + return chClass + (node.disabled ? " disabled" : ""); + }, + repairAllChk: function (setting, checked) { + if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) { + var checkedKey = setting.data.key.checked, + childKey = setting.data.key.children, + root = data.getRoot(setting); + for (var i = 0, l = root[childKey].length; i < l; i++) { + var node = root[childKey][i]; + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = checked; + } + view.setSonNodeCheckBox(setting, node, checked); + } + } + }, + repairChkClass: function (setting, node) { + if (!node) return; + data.makeChkFlag(setting, node); + if (node.nocheck !== true) { + var checkObj = $$(node, consts.id.CHECK, setting); + view.setChkClass(setting, checkObj, node); + } + }, + repairParentChkClass: function (setting, node) { + if (!node || !node.parentTId) return; + var pNode = node.getParentNode(); + view.repairChkClass(setting, pNode); + view.repairParentChkClass(setting, pNode); + }, + repairParentChkClassWithSelf: function (setting, node) { + if (!node) return; + var childKey = setting.data.key.children; + if (node[childKey] && node[childKey].length > 0) { + view.repairParentChkClass(setting, node[childKey][0]); + } else { + view.repairParentChkClass(setting, node); + } + }, + repairSonChkDisabled: function (setting, node, chkDisabled, inherit) { + if (!node) return; + var childKey = setting.data.key.children; + if (node.chkDisabled != chkDisabled) { + node.chkDisabled = chkDisabled; + } + view.repairChkClass(setting, node); + if (node[childKey] && inherit) { + for (var i = 0, l = node[childKey].length; i < l; i++) { + var sNode = node[childKey][i]; + view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit); + } + } + }, + repairParentChkDisabled: function (setting, node, chkDisabled, inherit) { + if (!node) return; + if (node.chkDisabled != chkDisabled && inherit) { + node.chkDisabled = chkDisabled; + } + view.repairChkClass(setting, node); + view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit); + }, + setChkClass: function (setting, obj, node) { + if (!obj) return; + if (node.nocheck === true) { + obj.hide(); + } else { + obj.show(); + } + obj.attr("class", view.makeChkClass(setting, node)); + }, + setParentNodeCheckBox: function (setting, node, value, srcNode) { + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + checkObj = $$(node, consts.id.CHECK, setting); + if (!srcNode) srcNode = node; + data.makeChkFlag(setting, node); + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = value; + view.setChkClass(setting, checkObj, node); + if (setting.check.autoCheckTrigger && node != srcNode) { + setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); + } + } + if (node.parentTId) { + var pSign = true; + if (!value) { + var pNodes = node.getParentNode()[childKey]; + for (var i = 0, l = pNodes.length; i < l; i++) { + if ( + (pNodes[i].nocheck !== true && + pNodes[i].chkDisabled !== true && + pNodes[i][checkedKey]) || + ((pNodes[i].nocheck === true || pNodes[i].chkDisabled === true) && + pNodes[i].check_Child_State > 0) + ) { + pSign = false; + break; + } + } + } + if (pSign) { + view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode); + } + } + }, + setSonNodeCheckBox: function (setting, node, value, srcNode) { + if (!node) return; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + checkObj = $$(node, consts.id.CHECK, setting); + if (!srcNode) srcNode = node; + + var hasDisable = false; + if (node[childKey]) { + for (var i = 0, l = node[childKey].length; i < l && node.chkDisabled !== true; i++) { + var sNode = node[childKey][i]; + view.setSonNodeCheckBox(setting, sNode, value, srcNode); + if (sNode.chkDisabled === true) hasDisable = true; + } + } + + if (node != data.getRoot(setting) && node.chkDisabled !== true) { + if (hasDisable && node.nocheck !== true) { + data.makeChkFlag(setting, node); + } + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = value; + if (!hasDisable) + node.check_Child_State = node[childKey] && node[childKey].length > 0 ? (value ? 2 : 0) : -1; + } else { + node.check_Child_State = -1; + } + view.setChkClass(setting, checkObj, node); + if ( + setting.check.autoCheckTrigger && + node != srcNode && + node.nocheck !== true && + node.chkDisabled !== true + ) { + setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); + } + } + }, + }, + _z = { + tools: _tools, + view: _view, + event: _event, + data: _data, + }; + $.extend(true, $.fn.zTree.consts, _consts); + $.extend(true, $.fn.zTree._z, _z); + + var zt = $.fn.zTree, + tools = zt._z.tools, + consts = zt.consts, + view = zt._z.view, + data = zt._z.data, + event = zt._z.event, + $$ = tools.$; + + data.exSetting(_setting); + data.addInitBind(_bindEvent); + data.addInitUnBind(_unbindEvent); + data.addInitCache(_initCache); + data.addInitNode(_initNode); + data.addInitProxy(_eventProxy, true); + data.addInitRoot(_initRoot); + data.addBeforeA(_beforeA); + data.addZTreeTools(_zTreeTools); + + var _createNodes = view.createNodes; + view.createNodes = function (setting, level, nodes, parentNode) { + if (_createNodes) _createNodes.apply(view, arguments); + if (!nodes) return; + view.repairParentChkClassWithSelf(setting, parentNode); + }; + var _removeNode = view.removeNode; + view.removeNode = function (setting, node) { + var parentNode = node.getParentNode(); + if (_removeNode) _removeNode.apply(view, arguments); + if (!node || !parentNode) return; + view.repairChkClass(setting, parentNode); + view.repairParentChkClass(setting, parentNode); + }; + + var _appendNodes = view.appendNodes; + view.appendNodes = function (setting, level, nodes, parentNode, initFlag, openFlag) { + var html = ""; + if (_appendNodes) { + html = _appendNodes.apply(view, arguments); + } + if (parentNode) { + data.makeChkFlag(setting, parentNode); + } + return html; + }; +})($); diff --git a/packages/fineui/src/case/ztree/list/listasynctree.js b/packages/fineui/src/case/ztree/list/listasynctree.js new file mode 100644 index 000000000..7efbf4f16 --- /dev/null +++ b/packages/fineui/src/case/ztree/list/listasynctree.js @@ -0,0 +1,123 @@ +import { ListTreeView } from "./listtreeview"; +import { cjkEncodeDO, delay, isEmpty, shortcut, extend } from "@/core"; +import $ from "jquery"; + +/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class ListListAsyncTree + * @extends TreeView + */ + +@shortcut() +export class ListAsyncTree extends ListTreeView { + static xtype = "bi.list_async_tree"; + + // 配置属性 + _configSetting() { + const paras = this.options.paras; + const self = this; + + function beforeCheck(treeId, treeNode) { + treeNode.half = false; + } + + function onClick(event, treeId, treeNode) { + const zTree = $.fn.zTree.getZTreeObj(treeId); + const checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand(treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck(event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: cjkEncodeDO(paras), + }, + check: { + enable: true, + chkboxType: { Y: "", N: "" }, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false, + }, + callback: { + onCheck, + beforeExpand, + beforeCheck, + onClick, + }, + }; + } + + // 展开节点 + _beforeExpandNode(treeId, treeNode) { + const self = this, + o = this.options; + const parentValues = treeNode.parentValues || self._getParentValues(treeNode); + const op = extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)), + }); + + function complete(d) { + const nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + } + let times = 1; + + function callback(nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + delay(() => { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(() => { + o.itemsCreator(op, complete); + }, 17); + } + } + + hasChecked() { + return !isEmpty(this.options.paras.selectedValues) || super.hasChecked(...arguments); + } + + // 生成树方法 + stroke(config) { + delete this.options.keyword; + extend(this.options.paras, config); + const setting = this._configSetting(); + this._initTree(setting); + } +} diff --git a/packages/fineui/src/case/ztree/list/listparttree.js b/packages/fineui/src/case/ztree/list/listparttree.js new file mode 100644 index 000000000..a9719478f --- /dev/null +++ b/packages/fineui/src/case/ztree/list/listparttree.js @@ -0,0 +1,96 @@ +import { ListAsyncTree } from "./listasynctree"; +import { shortcut, extend, Events, delay } from "@/core"; +import { TreeView } from "../treeview"; +import $ from "jquery"; + +/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class ListPartTree + * @extends AsyncTree + */ + +@shortcut() +export class ListPartTree extends ListAsyncTree { + static xtype = "bi.list_part_tree"; + + _loadMore() { + const self = this, + o = this.options; + const op = extend({}, o.paras, { + type: TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times, + }); + this.tip.setLoading(); + o.itemsCreator(op, d => { + const hasNext = !!d.hasNext, + nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + } + + _initTree(setting, keyword) { + const self = this, + o = this.options; + this.times = 1; + const tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + const op = extend({}, o.paras, { + type: TreeView.REQ_TYPE_INIT_DATA, + times: this.times, + }); + + function complete(d) { + if (self._stop === true || keyword !== o.paras.keyword) { + return; + } + const hasNext = !!d.hasNext, + nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(Events.AFTERINIT); + } + + function callback(nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + delay(() => { + o.itemsCreator(op, complete); + }, 100); + } + + // 生成树方法 + stroke(config) { + const o = this.options; + delete o.paras.keyword; + extend(o.paras, config); + delete o.paras.lastSearchValue; + const setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +} diff --git a/packages/fineui/src/case/ztree/list/listtreeview.js b/packages/fineui/src/case/ztree/list/listtreeview.js new file mode 100644 index 000000000..b6955e3de --- /dev/null +++ b/packages/fineui/src/case/ztree/list/listtreeview.js @@ -0,0 +1,122 @@ +import { TreeView } from "../treeview"; +import { extend, isNotNull, concat, each, shortcut } from "@/core"; +import $ from "jquery"; + +/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class ListTreeView + * @extends TreeView + */ + +@shortcut() +export class ListTreeView extends TreeView { + static xtype = "bi.list_tree_view"; + + _constants = { + SPLIT: "<|>", + }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + value: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.value)) { + this.setSelectedValue(o.value); + } + } + + // 配置属性 + _configSetting() { + const self = this; + + function onClick(event, treeId, treeNode) { + const zTree = $.fn.zTree.getZTreeObj(treeId); + const checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck(event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return { + async: { + enable: false, + }, + check: { + enable: true, + chkboxType: { Y: "", N: "" }, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false, + }, + callback: { + onCheck, + onClick, + }, + }; + } + + _selectTreeNode(treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + super._selectTreeNode(...arguments); + } + + _transArrayToMap(treeArrays) { + const map = {}; + each(treeArrays, (idx, array) => { + const key = array.join(this._constants.SPLIT); + map[key] = true; + }); + + return map; + } + + _transMapToArray(treeMap) { + const array = []; + each(treeMap, key => { + const item = key.split(this._constants.SPLIT); + array.push(item); + }); + + return array; + } + + _checkValue(treeNode, checked) { + const key = concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if (checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + } + + setSelectedValue(value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + } + + getValue() { + return this._transMapToArray(this.storeValue); + } +} diff --git a/packages/fineui/src/case/ztree/parttree.js b/packages/fineui/src/case/ztree/parttree.js new file mode 100644 index 000000000..d31610099 --- /dev/null +++ b/packages/fineui/src/case/ztree/parttree.js @@ -0,0 +1,236 @@ +import { isEmpty, shortcut, extend, deepClone, each, isNotEmptyArray, Events, delay, isNull } from "@/core"; +import { AsyncTree } from "./asynctree"; +import { TreeView } from "./treeview"; +import $ from "jquery"; + +/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class PartTree + * @extends AsyncTree + */ + +@shortcut() +export class PartTree extends AsyncTree { + static xtype = "bi.part_tree"; + + static EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + isSelectedAny: true, //是否返回所有被checked的结点(包括被checked的结点的子结点) + }); + } + + constructor(...args) { + super(...args); + this.seMethos = AsyncTree.superclass._selectTreeNode; + } + + _loadMore() { + const self = this, + o = this.options; + const op = extend({}, o.paras, { + type: TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times, + }); + this.tip.setLoading(); + o.itemsCreator(op, d => { + const hasNext = !!d.hasNext, + nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + } + + _selectTreeNode(...args) { + const self = this, + o = this.options; + const [treeId, treeNode] = args; + const parentValues = deepClone(treeNode.parentValues || self._getParentValues(treeNode)); + const name = this._getNodeValue(treeNode); + this.fireEvent(PartTree.EVENT_CLICK_TREE_NODE); + if (treeNode.checked === true) { + if (this.options.isSelectedAny) { + this.options.paras.selectedValues = this._getUnionValue(); //获取所有被selected的结点 + } else { + this._addTreeNode(this.options.paras.selectedValues, parentValues, name, {});//给selectedValues增加被click的结点(不包含该节点的子结点) + } + o.itemsCreator( + extend({}, o.paras, { + type: TreeView.REQ_TYPE_ADJUST_DATA, + curSelectedValue: name, + parentValues, + }), + function (res) { + self.options.paras.selectedValues = res; + // 看起来应该是 self + self.seMethos(...args); + } + ); + } else { + // 如果选中的值中不存在该值不处理 + // 因为反正是不选中,没必要管 + let t = this.options.paras.selectedValues; + const p = parentValues.concat(name); + for (let i = 0, len = p.length; i < len; i++) { + t = t[p[i]]; + if (t == null) { + return; + } + // 选中中国-江苏, 搜索南京,取消勾选 + if (isEmpty(t)) { + break; + } + } + o.itemsCreator( + extend({}, o.paras, { + type: TreeView.REQ_TYPE_SELECT_DATA, + notSelectedValue: name, + parentValues, + }), + new_values => { + self.options.paras.selectedValues = new_values; + this.seMethos(...args); + } + ); + } + } + + _getSelectedValues() { + const self = this; + const hashMap = {}; + const rootNodes = this.nodes.getNodes(); + track(rootNodes); + + function track(nodes) { + each(nodes, (i, node) => { + const checkState = node.getCheckStatus(); + if (checkState.checked === false) { + return true; + } + const parentValues = node.parentValues || self._getParentValues(node); + // 把文字中的html去掉,其实就是把文字颜色去掉 + const values = parentValues.concat([self._getNodeValue(node)]); + self._buildTree(hashMap, values); + // if(checkState.checked === true && checkState.half === false && nodes[i].flag === true){ + // continue; + // } + if (isNotEmptyArray(node.children)) { + track(node.children); + + return true; + } + if (checkState.half === true) { + self._getHalfSelectedValues(hashMap, node); + } + }); + } + + return hashMap; + } + + _initTree(setting, keyword) { + const self = this, + o = this.options; + this.times = 1; + const tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + const op = extend({}, o.paras, { + type: TreeView.REQ_TYPE_INIT_DATA, + times: this.times, + }); + + function complete(d) { + if (self._stop === true || keyword !== o.paras.keyword) { + return; + } + const hasNext = !!d.hasNext, + nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(Events.AFTERINIT); + } + + function callback(nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + delay(() => { + o.itemsCreator(op, complete); + }, 100); + } + + getValue() { + return deepClone(this.options.paras.selectedValues || {}); + } + + _getUnionValue() { + if (!this.nodes) { + return {}; + } + const checkedValues = this._getSelectedValues(); + if (isEmpty(checkedValues)) { + return deepClone(this.options.paras.selectedValues); + } + if (isEmpty(this.options.paras.selectedValues)) { + return checkedValues; + } + + return this._union(checkedValues, this.options.paras.selectedValues); + } + + _union(valueA, valueB) { + const self = this; + const map = {}; + track([], valueA, valueB); + track([], valueB, valueA); + + function track(parent, node, compare) { + each(node, (n, item) => { + if (isNull(compare[n])) { + self._addTreeNode(map, parent, n, item); + } else if (isEmpty(compare[n])) { + self._addTreeNode(map, parent, n, {}); + } else { + track(parent.concat([n]), node[n], compare[n]); + } + }); + } + + return map; + } + + // 生成树方法 + stroke(config) { + const o = this.options; + delete o.paras.keyword; + extend(o.paras, config); + delete o.paras.lastSearchValue; + const setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +} diff --git a/packages/fineui/src/case/ztree/tree.display.js b/packages/fineui/src/case/ztree/tree.display.js new file mode 100644 index 000000000..dc996dfe1 --- /dev/null +++ b/packages/fineui/src/case/ztree/tree.display.js @@ -0,0 +1,71 @@ +import { extend, shortcut, each, i18nText } from "@/core"; +import { TreeView } from "./treeview"; +import $ from "jquery"; + +/** + * guy + * 异步树 + * @class DisplayTree + * @extends TreeView + */ + +@shortcut() +export class DisplayTree extends TreeView { + static xtype = "bi.display_tree"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-display-tree", + }); + } + + // 配置属性 + _configSetting() { + function beforeCollapse(treeId, treeNode) { + return false; + } + + return { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + callback: { + beforeCollapse, + }, + }; + } + + _dealWidthNodes(nodes) { + nodes = super._dealWidthNodes(...arguments); + each(nodes, (i, node) => { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = `${node.value}(${i18nText("BI-Basic_Altogether")}${node.count}${i18nText( + "BI-Basic_Count" + )})`; + } + } + }); + + return nodes; + } + + initTree(nodes, setting) { + this.nodes = $.fn.zTree.init(this.tree.element, setting || this._configSetting(), nodes); + } +} diff --git a/packages/fineui/src/case/ztree/tree.list.display.js b/packages/fineui/src/case/ztree/tree.list.display.js new file mode 100644 index 000000000..179713c87 --- /dev/null +++ b/packages/fineui/src/case/ztree/tree.list.display.js @@ -0,0 +1,76 @@ +import { ListTreeView } from "./list/listtreeview"; +import { each, shortcut, i18nText } from "@/core"; +import $ from "jquery"; + +/** + * guy + * 异步树 + * @class ListListDisplayTree + * @extends TreeView + */ + +@shortcut() +export class ListDisplayTree extends ListTreeView { + static xtype = "bi.list_display_tree"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props() { + return { + extraCls: "bi-list-display-tree", + }; + } + + // 配置属性 + _configSetting() { + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.isLeaf ? {} : { color: "#999999" }; + } + + return { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + callback: { + beforeCollapse, + }, + }; + } + + _dealWidthNodes(nodes) { + nodes = super._dealWidthNodes(...arguments); + each(nodes, (i, node) => { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = `${node.value}(${i18nText("BI-Basic_Altogether")}${node.count}${i18nText( + "BI-Basic_Count" + )})`; + } + } + }); + + return nodes; + } + + initTree(nodes, setting) { + this.nodes = $.fn.zTree.init(this.tree.element, setting || this._configSetting(), nodes); + } +} diff --git a/packages/fineui/src/case/ztree/tree.simple.js b/packages/fineui/src/case/ztree/tree.simple.js new file mode 100644 index 000000000..8740aaab7 --- /dev/null +++ b/packages/fineui/src/case/ztree/tree.simple.js @@ -0,0 +1,155 @@ +import { + shortcut, + Widget, + Tree, + createWidget, + emptyFn, + isNotNull, + isNotEmptyArray, + each, + makeObject, + isEmpty +} from "@/core"; +import { TreeView } from "./treeview"; + +/** + * 简单的多选树 + * + * Created by GUY on 2016/2/16. + * @class SimpleTreeView + * @extends Widget + */ + +@shortcut() +export class SimpleTreeView extends Widget { + static xtype = "bi.simple_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props() { + return { + baseCls: "bi-simple-tree", + itemsCreator: emptyFn, + items: null, + }; + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.structure = new Tree(); + this.tree = createWidget({ + type: TreeView.xtype, + element: this, + itemsCreator(op, callback) { + function fn(items) { + callback({ + items, + }); + self.structure.initTree(Tree.transformToTreeFormat(items)); + } + if (isNotNull(o.items)) { + fn(o.items); + } else { + o.itemsCreator(op, fn); + } + }, + }); + this.tree.on(TreeView.EVENT_CHANGE, function () { + self.fireEvent(SimpleTreeView.EVENT_CHANGE, arguments); + }); + if (isNotEmptyArray(o.items)) { + this.populate(); + } + if (isNotNull(o.value)) { + this.setValue(o.value); + } + } + + populate(items, keyword) { + if (items) { + this.options.items = items; + } + this.tree.stroke({ + keyword, + }); + } + + _digest(v) { + v || (v = []); + const self = this, + map = {}; + const selected = []; + each(v, (i, val) => { + const node = self.structure.search(val, "value"); + if (node) { + let p = node; + p = p.getParent(); + if (p) { + if (!map[p.value]) { + map[p.value] = 0; + } + map[p.value]++; + } + + while (p && p.getChildrenLength() <= map[p.value]) { + selected.push(p.value); + p = p.getParent(); + if (p) { + if (!map[p.value]) { + map[p.value] = 0; + } + map[p.value]++; + } + } + } + }); + + return makeObject(v.concat(selected)); + } + + setValue(v) { + this.tree.setValue(this._digest(v)); + } + + _getValue() { + const result = [], + val = this.tree.getValue(); + + function track(nodes) { + each(nodes, (key, node) => { + if (isEmpty(node)) { + result.push(key); + } else { + track(node); + } + }); + } + track(val); + + return result; + } + + empty() { + this.tree.empty(); + } + + getValue() { + const self = this, + result = [], + val = this._getValue(); + each(val, (i, key) => { + const target = self.structure.search(key, "value"); + if (target) { + self.structure._traverse(target, node => { + if (node.isLeaf()) { + result.push(node.value); + } + }); + } + }); + + return result; + } +} diff --git a/packages/fineui/src/case/ztree/treerender.page.service.js b/packages/fineui/src/case/ztree/treerender.page.service.js new file mode 100644 index 000000000..799829a93 --- /dev/null +++ b/packages/fineui/src/case/ztree/treerender.page.service.js @@ -0,0 +1,73 @@ +import { createWidget, debounce, has, OB, size, each, VerticalLayout } from "@/core"; +import { LoadingBar } from "@/base"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2020/1/8 + * 提供节点分页加载方式 + */ + +export class TreeRenderPageService extends OB { + nodeLists = {}; + + _getLoadingBar(tId) { + const tip = createWidget({ + type: LoadingBar.xtype, + height: 25, + handler: () => { + this.refreshNodes(tId); + }, + }); + tip.setLoaded(); + + return tip; + } + + pushNodeList(tId, populate) { + const o = this.options; + const tip = this._getLoadingBar(tId); + if (!has(this.nodeLists, tId)) { + this.nodeLists[tId] = { + populate: debounce(populate, 0), + options: { + times: 1, + }, + loadWidget: tip, + }; + } else { + this.nodeLists[tId].loadWidget.destroy(); + this.nodeLists[tId].loadWidget = tip; + } + createWidget({ + type: VerticalLayout.xtype, + element: o.subNodeListGetter(tId), + items: [tip], + }); + } + + refreshNodes(tId) { + const nodeList = this.nodeLists[tId]; + nodeList.options.times++; + nodeList.loadWidget.setLoading(); + nodeList.populate({ + times: nodeList.options.times, + }); + } + + removeNodeList(tId) { + this.nodeLists[tId] && this.nodeLists[tId].loadWidget.destroy(); + this.nodeLists[tId] && (this.nodeLists[tId].loadWidget = null); + delete this.nodeLists[tId]; + if (size(this.nodeLists) === 0) { + this.clear(); + } + } + + clear() { + each(this.nodeLists, tId => { + this.removeNodeList(tId); + }); + this.nodeLists = {}; + } +} diff --git a/packages/fineui/src/case/ztree/treerender.scroll.service.js b/packages/fineui/src/case/ztree/treerender.scroll.service.js new file mode 100644 index 000000000..fed397a9c --- /dev/null +++ b/packages/fineui/src/case/ztree/treerender.scroll.service.js @@ -0,0 +1,129 @@ +import { debounce, each, has, isNotNull, OB, size } from "@/core"; + +/** + * @author windy + * @version 2.0 + * Created by windy on 2020/1/8 + * 提供节点滚动加载方式 + */ + +export class TreeRenderScrollService extends OB { + _init() { + this.nodeLists = {}; + + this.id = this.options.id; + // renderService是否已经注册了滚动 + this.hasBinded = false; + + this.container = this.options.container; + } + + _getNodeListBounds(tId) { + const nodeList = this.options.subNodeListGetter(tId)[0]; + + return { + top: nodeList.offsetTop, + left: nodeList.offsetLeft, + width: nodeList.offsetWidth, + height: nodeList.offsetHeight, + }; + } + + _getTreeContainerBounds() { + const nodeList = this.container[0]; + if (isNotNull(nodeList)) { + return { + top: nodeList.offsetTop + nodeList.scrollTop, + left: nodeList.offsetLeft + nodeList.scrollLeft, + width: nodeList.offsetWidth, + height: nodeList.offsetHeight, + }; + } + + return {}; + } + + _canNodePopulate(tId) { + if (this.nodeLists[tId].locked) { + return false; + } + // 获取ul, 即子节点列表的bounds + // 是否需要继续加载,只需要看子节点列表的下边界与container是否无交集 + const bounds = this._getNodeListBounds(tId); + const containerBounds = this._getTreeContainerBounds(tId); + + // ul底部是不是漏出来了 + return bounds.top + bounds.height < containerBounds.top + containerBounds.height; + } + + _isNodeInVisible(tId) { + const nodeList = this.options.subNodeListGetter(tId); + + return nodeList.length === 0 || nodeList.css("display") === "none"; + } + + pushNodeList(tId, populate) { + const self = this; + if (!has(this.nodeLists, tId)) { + this.nodeLists[tId] = { + populate: debounce(populate, 0), + options: { + times: 1, + }, + // 在上一次请求返回前, 通过滚动再次触发加载的时候, 不应该认为是下一次分页, 需要等待上次请求返回 + // 以保证顺序和请求次数的完整 + locked: false, + }; + } else { + this.nodeLists[tId].locked = false; + } + if (!this.hasBinded) { + // console.log("绑定事件"); + this.hasBinded = true; + this.container && + this.container.on( + "scroll", + debounce(() => { + self.refreshAllNodes(); + }, 30) + ); + } + } + + refreshAllNodes() { + const self = this; + each(this.nodeLists, tId => { + // 不展开的节点就不看了 + !self._isNodeInVisible(tId) && self.refreshNodes(tId); + }); + } + + refreshNodes(tId) { + if (this._canNodePopulate(tId)) { + const nodeList = this.nodeLists[tId]; + nodeList.options.times++; + nodeList.locked = true; + nodeList.populate({ + times: nodeList.options.times, + }); + } + } + + removeNodeList(tId) { + delete this.nodeLists[tId]; + if (size(this.nodeLists) === 0) { + this.clear(); + } + } + + clear() { + const self = this; + each(this.nodeLists, tId => { + self.removeNodeList(tId); + }); + this.nodeLists = {}; + // console.log("解绑事件"); + this.container.off("scroll"); + this.hasBinded = false; + } +} diff --git a/packages/fineui/src/case/ztree/treeview.js b/packages/fineui/src/case/ztree/treeview.js new file mode 100644 index 000000000..c331fd7ea --- /dev/null +++ b/packages/fineui/src/case/ztree/treeview.js @@ -0,0 +1,619 @@ +import { + cjkEncodeDO, + Controller, + createWidget, + emptyFn, + Events, + extend, + UUID, + isNotNull, + jsonEncode, + delay, + each, + replaceAll, + isUndefined, + isNotEmptyArray, + deepClone, + map, + Tree, + isNull, + shortcut, + VerticalLayout, + Layout, + DefaultLayout, + some, + Widget, + STYLE_CONSTANTS +} from "@/core"; +import { Msg, Pane, LoadingBar, Text } from "@/base"; +import $ from "jquery"; +import "./jquery.ztree.core-3.5"; + +@shortcut() +export class TreeView extends Pane { + static xtype = "bi.tree_view"; + static REQ_TYPE_INIT_DATA = 1; + static REQ_TYPE_ADJUST_DATA = 2; + static REQ_TYPE_SELECT_DATA = 3; + static REQ_TYPE_GET_SELECTED_DATA = 4; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_INIT = Events.INIT; + static EVENT_AFTERINIT = Events.AFTERINIT; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + _baseCls: "bi-tree", + paras: { + selectedValues: {}, + }, + itemsCreator: emptyFn, + showLine: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this._stop = false; + + this._createTree(); + this.tip = createWidget({ + type: LoadingBar.xtype, + invisible: true, + handler: () => this._loadMore(), + }); + createWidget({ + type: VerticalLayout.xtype, + scrollable: true, + scrolly: false, + element: this, + items: [this.tip], + }); + if (isNotNull(o.value)) { + this.setSelectedValue(o.value); + } + } + + _createTree() { + this.id = `bi-tree${UUID()}`; + if (this.nodes) { + this.nodes.destroy(); + } + if (this.tree) { + this.tree.destroy(); + } + this.tree = createWidget({ + type: Layout.xtype, + element: ``, + }); + createWidget({ + type: DefaultLayout.xtype, + element: this, + items: [this.tree], + }); + } + + // 选择节点触发方法 + _selectTreeNode(treeId, treeNode) { + this.fireEvent(Controller.EVENT_CHANGE, Events.CLICK, treeNode, this); + this.fireEvent(TreeView.EVENT_CHANGE, treeNode, this); + } + + // 配置属性 + _configSetting() { + const paras = this.options.paras; + const self = this; + const o = this.options; + const setting = { + async: { + enable: true, + url: getUrl, + autoParam: ["id", "name"], // 节点展开异步请求自动提交id和name + otherParam: cjkEncodeDO(paras), // 静态参数 + }, + check: { + enable: true, + }, + data: { + key: { + title: "title", + name: "text", // 节点的name属性替换成text + }, + simpleData: { + enable: true, // 可以穿id,pid属性的对象数组 + }, + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, // 节点可以用html标签代替 + dblClickExpand: false, + showLine: o.showLine, + }, + callback: { + beforeExpand, + onAsyncSuccess, + onAsyncError, + beforeCheck, + onCheck, + onExpand, + onCollapse, + onClick, + }, + }; + const className = "dark", + perTime = 100; + + function onClick(event, treeId, treeNode) { + // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 + let checked = treeNode.checked; + const status = treeNode.getCheckStatus(); + if (status.half === true && status.checked === true) { + checked = false; + } + // 更新此node的check状态, 影响父子关联,并调用beforeCheck和onCheck回调 + self.nodes.checkNode(treeNode, !checked, true, true); + } + + function getUrl(treeId, treeNode) { + const parentNode = self._getParentValues(treeNode); + treeNode.times = treeNode.times || 1; + const param = `id=${treeNode.id}×=${treeNode.times++}&parentValues= ${_global.encodeURIComponent( + jsonEncode(parentNode) + )}&checkState=${_global.encodeURIComponent(jsonEncode(treeNode.getCheckStatus()))}`; + + return `&${param}`; + } + + function beforeExpand(treeId, treeNode) { + if (!treeNode.isAjaxing) { + if (!treeNode.children) { + treeNode.times = 1; + ajaxGetNodes(treeNode, "refresh"); + } + + return true; + } + Msg.toast("Please Wait.", { + level: "warning", + }); // 不展开节点,也不触发onExpand事件 + + return false; + } + + function onAsyncSuccess(event, treeId, treeNode, msg) { + treeNode.halfCheck = false; + if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) { + return; + } + const zTree = self.nodes; + const totalCount = treeNode.count || 0; + + // 尝试去获取下一组节点,若获取值为空数组,表示获取完成 + // TODO by GUY + if (treeNode.children.length > totalCount) { + treeNode.count = treeNode.children.length; + delay(() => { + ajaxGetNodes(treeNode); + }, perTime); + } else { + // treeNode.icon = ""; + zTree.updateNode(treeNode); + zTree.selectNode(treeNode.children[0]); + // className = (className === "dark" ? "":"dark"); + } + } + + function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) { + const zTree = self.nodes; + Msg.toast("Error!", "warning"); + // treeNode.icon = ""; + // zTree.updateNode(treeNode); + } + + function ajaxGetNodes(treeNode, reloadType) { + const zTree = self.nodes; + if (reloadType === "refresh") { + zTree.updateNode(treeNode); // 刷新一下当前节点,如果treeNode.xxx被改了的话 + } + zTree.reAsyncChildNodes(treeNode, reloadType, true); // 强制加载子节点,reloadType === refresh为先清空再加载,否则为追加到现有子节点之后 + } + + function beforeCheck(treeId, treeNode) { + if (treeNode.disabled) { + return false; + } + // 下面主动修改了node的halfCheck属性, 节点属性的判断依赖halfCheck,改之前就获取一下 + const status = treeNode.getCheckStatus(); + treeNode.halfCheck = false; + if (treeNode.checked === true) { + // 将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy + // 所有的半选状态都需要取消halfCheck=true的情况 + function track(children) { + each(children, (i, ch) => { + if (ch.halfCheck === true) { + ch.halfCheck = false; + track(ch.children); + } + }); + } + + track(treeNode.children); + const treeObj = self.nodes; + const nodes = treeObj.getSelectedNodes(); + $.each(nodes, (index, node) => { + node.halfCheck = false; + }); + } + // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 + if (status.half === true && status.checked === true) { + treeNode.checked = false; + } + } + + function onCheck(event, treeId, treeNode) { + if (treeNode.disabled) { + return false; + } + self._selectTreeNode(treeId, treeNode); + } + + function onExpand(event, treeId, treeNode) { + treeNode.halfCheck = false; + } + + function onCollapse(event, treeId, treeNode) {} + + return setting; + } + + _getParentValues(treeNode) { + if (!treeNode.getParentNode()) { + return []; + } + const parentNode = treeNode.getParentNode(); + let result = this._getParentValues(parentNode); + result = result.concat([this._getNodeValue(parentNode)]); + + return result; + } + + _getNodeValue(node) { + // 去除标红 + return isUndefined(node.value) ? replaceAll(node.text.replace(/<[^>]+>/g, ""), " ", " ") : node.value; + } + + // 获取半选框值 + _getHalfSelectedValues(map, node) { + const self = this; + const checkState = node.getCheckStatus(); + // 将未选的去掉 + if (checkState.checked === false && checkState.half === false) { + return; + } + // 如果节点已展开,并且是半选 + if (isNotEmptyArray(node.children) && checkState.half === true) { + const children = node.children; + each(children, (i, ch) => { + self._getHalfSelectedValues(map, ch); + }); + + return; + } + const parent = node.parentValues || self._getParentValues(node); + const path = parent.concat(this._getNodeValue(node)); + // 当前节点是全选的,因为上面的判断已经排除了不选和半选 + if (isNotEmptyArray(node.children) || checkState.half === false) { + this._buildTree(map, path); + + return; + } + // 剩下的就是半选不展开的节点,因为不知道里面是什么情况,所以借助selectedValues(这个是完整的选中情况) + const storeValues = deepClone(this.options.paras.selectedValues); + const treeNode = this._getTree(storeValues, path); + this._addTreeNode(map, parent, this._getNodeValue(node), treeNode); + } + + // 获取的是以values最后一个节点为根的子树 + _getTree(map, values) { + let cur = map; + some(values, (i, value) => { + if (cur[value] == null) { + return true; + } + cur = cur[value]; + }); + + return cur; + } + + // 以values为path一路向里补充map, 并在末尾节点添加key: value节点 + _addTreeNode(map, values, key, value) { + let cur = map; + each(values, (i, value) => { + if (cur[value] == null) { + cur[value] = {}; + } + cur = cur[value]; + }); + cur[key] = value; + } + + // 构造树节点 + _buildTree(map, values) { + let cur = map; + each(values, (i, value) => { + if (cur[value] == null) { + cur[value] = {}; + } + cur = cur[value]; + }); + } + + // 获取选中的值 + _getSelectedValues() { + const self = this; + const hashMap = {}; + const rootNoots = this.nodes.getNodes(); + track(rootNoots); // 可以看到这个方法没有递归调用,所以在_getHalfSelectedValues中需要关心全选的节点 + function track(nodes) { + each(nodes, (i, node) => { + const checkState = node.getCheckStatus(); + if (checkState.checked === true || checkState.half === true) { + if (checkState.half === true) { + self._getHalfSelectedValues(hashMap, node); + } else { + const parentValues = node.parentValues || self._getParentValues(node); + const values = parentValues.concat([self._getNodeValue(node)]); + self._buildTree(hashMap, values); + } + } + }); + } + + return hashMap; + } + + // 处理节点 + _dealWidthNodes(nodes) { + const self = this, + o = this.options; + const ns = Tree.arrayFormat(nodes); + + return map(ns, (i, n) => { + const newNode = extend({}, n); + newNode.isParent = newNode.isParent || newNode.parent; + // n.value = BI.isUndefined(n.value) ? n.text : n.value; + // n.text = BI.isUndefined(n.text) ? n.value : n.text; + // if (n.text === null) { + // n.text = ""; + // } + if (isNull(newNode.title)) { + newNode.title = newNode.text; + } + if (newNode.disabled) { + newNode.title = newNode.warningTitle || newNode.title; + } + const text = createWidget( + extend( + { + cls: "tree-node-text", + tagName: "span", + whiteSpace: "nowrap", + root: true, + keyword: o.paras.keyword, + }, + newNode, + { + type: Text.xtype, + text: replaceAll(newNode.text, "\n", " "), + } + ) + ); + const fragment = Widget._renderEngine.createElement("
    "); + fragment.append(text.element[0]); + newNode.text = fragment.html(); + // // 处理标红 + // if (BI.isNotNull(n.text)) { + // if (BI.isKey(o.paras.keyword)) { + // n.text = $("
    ").__textKeywordMarked__(BI.Text.formatText(n.text + ""), o.paras.keyword, n.py).html(); + // } else { + // n.text = BI.htmlEncode(BI.Text.formatText(n.text + "")); + // } + // } + + return newNode; + }); + } + + _loadMore() { + const self = this, + o = this.options; + this.tip.setLoading(); + const op = extend({}, o.paras, { + times: ++this.times, + }); + o.itemsCreator(op, res => { + if (self._stop === true) { + return; + } + const hasNext = !!res.hasNext, + nodes = res.items || []; + + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + } + + // 生成树内部方法 + _initTree(setting) { + const self = this, + o = this.options; + self.fireEvent(Events.INIT); + this.times = 1; + const tree = this.tree; + tree.empty(); + this.loading(); + this.tip.setVisible(false); + + function callback(nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + const op = extend({}, o.paras, { + times: 1, + }); + + o.itemsCreator(op, res => { + if (self._stop === true) { + return; + } + const hasNext = !!res.hasNext, + nodes = res.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes)); + } + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + op.times === 1 && self.fireEvent(Events.AFTERINIT); + }); + } + + // 构造树结构, + initTree(nodes, setting) { + const defaultSetting = { + async: { + enable: false, + }, + check: { + enable: false, + }, + data: { + key: { + title: "title", + name: "text", + }, + simpleData: { + enable: true, + }, + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + }, + callback: {}, + }; + this.nodes = $.fn.zTree.init(this.tree.element, setting || defaultSetting, nodes); + } + + start() { + this._stop = false; + } + + stop() { + this._stop = true; + } + + // 生成树方法 + stroke(config) { + delete this.options.keyword; + extend(this.options.paras, config); + const setting = this._configSetting(); + this._createTree(); + this.start(); + this._initTree(setting); + } + + populate() { + this.stroke(...arguments); + } + + hasChecked() { + const treeObj = this.nodes; + + return treeObj.getCheckedNodes(true).length > 0; + } + + checkAll(checked) { + function setNode(children) { + each(children, (i, child) => { + child.halfCheck = false; + setNode(child.children); + }); + } + + if (!this.nodes) { + return; + } + + each(this.nodes.getNodes(), (i, node) => { + node.halfCheck = false; + setNode(node.children); + }); + this.nodes.checkAllNodes(checked); + } + + expandAll(flag) { + this.nodes && this.nodes.expandAll(flag); + } + + // 设置树节点的状态 + setValue(value, param) { + this.checkAll(false); + this.updateValue(value, param); + this.refresh(); + } + + setSelectedValue(value) { + this.options.paras.selectedValues = deepClone(value || {}); + } + + updateValue(values, param) { + if (!this.nodes) { + return; + } + param || (param = "value"); + const treeObj = this.nodes; + each(values, (v, op) => { + const nodes = treeObj.getNodesByParam(param, v, null); + each(nodes, (j, node) => { + extend(node, { checked: true }, op); + treeObj.updateNode(node); + }); + }); + } + + refresh() { + this.nodes && this.nodes.refresh(); + } + + getValue() { + if (!this.nodes) { + return null; + } + + return this._getSelectedValues(); + } + + destroyed() { + this.stop(); + this.nodes && this.nodes.destroy(); + } +} diff --git a/src/component/allvaluechooser/__test__/combo.allvaluechooser.test.js b/packages/fineui/src/component/allvaluechooser/__test__/combo.allvaluechooser.test.js similarity index 100% rename from src/component/allvaluechooser/__test__/combo.allvaluechooser.test.js rename to packages/fineui/src/component/allvaluechooser/__test__/combo.allvaluechooser.test.js diff --git a/packages/fineui/src/component/allvaluechooser/abstract.allvaluechooser.js b/packages/fineui/src/component/allvaluechooser/abstract.allvaluechooser.js new file mode 100644 index 000000000..fd90873f5 --- /dev/null +++ b/packages/fineui/src/component/allvaluechooser/abstract.allvaluechooser.js @@ -0,0 +1,130 @@ +import { + Widget, + extend, + emptyFn, + isNotNull, + some, + isNotEmptyArray, + each, + Func, + uniq, + makeObject, + filter, + difference, + map, + Selection +} from "@/core"; +import { MultiSelectCombo } from "@/widget"; + +export class AbstractAllValueChooser extends Widget { + _const = { perPage: 100 }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + width: 200, + height: 30, + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _valueFormatter(v) { + let text = v; + if (this.options.valueFormatter) { + return this.options.valueFormatter(v); + } + if (isNotNull(this.items)) { + some(this.items, (i, item) => { + // 把value都换成字符串 + // 需要考虑到value也可能是数字 + if (item.value === v || `${item.value}` === v) { + text = item.text; + + return true; + } + }); + } + + return text; + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * this._const.perPage < items.length; + } + + _itemsCreator(options, callback) { + const self = this, + o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, items => { + self.items = items; + call(items); + }); + } else { + call(this.items); + } + + function call(items) { + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + let resultItems = items; + if (isNotEmptyArray(keywords)) { + resultItems = []; + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + resultItems = resultItems.concat(search.match).concat(search.find); + }); + resultItems = uniq(resultItems); + } + if (options.selectedValues) { + // 过滤 + const values = makeObject(options.selectedValues, true); + resultItems = filter(resultItems, (i, ob) => !values[ob.value]); + } + if (options.type === MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: resultItems, + }); + + return; + } + if (options.type === MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: resultItems.length }); + + return; + } + callback({ + items: self._getItemsByTimes(resultItems, options.times), + hasNext: self._hasNextByTimes(resultItems, options.times), + }); + } + } + + _assertValue(v) { + v = v || {}; + let value = v; + if (isNotNull(this.items)) { + const isAllSelect = difference(map(this.items, "value"), v.value).length === 0; + if (isAllSelect) { + value = { + type: Selection.All, + value: [], + }; + } + } + + return value; + } +} diff --git a/packages/fineui/src/component/allvaluechooser/combo.allvaluechooser.js b/packages/fineui/src/component/allvaluechooser/combo.allvaluechooser.js new file mode 100644 index 000000000..519218278 --- /dev/null +++ b/packages/fineui/src/component/allvaluechooser/combo.allvaluechooser.js @@ -0,0 +1,78 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind, Selection, difference, map } from "@/core"; +import { AbstractAllValueChooser } from "./abstract.allvaluechooser"; +import { MultiSelectCombo } from "@/widget"; + +@shortcut() +export class AllValueChooserCombo extends AbstractAllValueChooser { + static xtype = "bi.all_value_chooser_combo"; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-all-value-chooser-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this.items = o.items; + } + this.combo = createWidget({ + type: MultiSelectCombo.xtype, + simple: o.simple, + text: o.text, + element: this, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + defaultText: o.defaultText, + value: this._assertValue({ + type: Selection.Multi, + value: o.value || [], + }), + }); + + this.combo.on(MultiSelectCombo.EVENT_CONFIRM, () => { + this.fireEvent(AllValueChooserCombo.EVENT_CONFIRM); + }); + } + + setValue(v) { + this.combo.setValue( + this._assertValue({ + type: Selection.Multi, + value: v || [], + }) + ); + } + + getValue() { + return this.getAllValue(); + } + + getAllValue() { + const val = this.combo.getValue() || {}; + if (val.type === Selection.Multi) { + return val.value || []; + } + + return difference(map(this.items, "value"), val.value || []); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.combo.populate(); + } +} diff --git a/packages/fineui/src/component/allvaluechooser/index.js b/packages/fineui/src/component/allvaluechooser/index.js new file mode 100644 index 000000000..d69b5f254 --- /dev/null +++ b/packages/fineui/src/component/allvaluechooser/index.js @@ -0,0 +1,3 @@ +export { AbstractAllValueChooser } from "./abstract.allvaluechooser"; +export { AllValueChooserCombo } from "./combo.allvaluechooser"; +export { AllValueChooserPane } from "./pane.allvaluechooser"; diff --git a/packages/fineui/src/component/allvaluechooser/pane.allvaluechooser.js b/packages/fineui/src/component/allvaluechooser/pane.allvaluechooser.js new file mode 100644 index 000000000..6ea534af7 --- /dev/null +++ b/packages/fineui/src/component/allvaluechooser/pane.allvaluechooser.js @@ -0,0 +1,67 @@ +import { shortcut, extend, emptyFn, createWidget, bind, isNotNull, Selection, difference, map } from "@/core"; +import { AbstractAllValueChooser } from "./abstract.allvaluechooser"; +import { MultiSelectList } from "@/widget"; + +@shortcut() +export class AllValueChooserPane extends AbstractAllValueChooser { + static xtype = "bi.all_value_chooser_pane"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-all-value-chooser-pane", + width: 200, + height: 30, + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.list = createWidget({ + type: MultiSelectList.xtype, + element: this, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + }); + + this.list.on(MultiSelectList.EVENT_CHANGE, () => { + this.fireEvent(AllValueChooserPane.EVENT_CHANGE); + }); + + if (isNotNull(o.items)) { + this.items = o.items; + this.list.populate(); + } + } + + setValue(v) { + this.list.setValue({ + type: Selection.Multi, + value: v || [], + }); + } + + getValue() { + const val = this.list.getValue() || {}; + if (val.type === Selection.Multi) { + return val.value || []; + } + + return difference(map(this.items, "value"), val.value || []); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.list.populate(); + } +} diff --git a/src/component/allvaluemultitextvaluecombo/__test__/allvalue.multitextvalue.combo.test.js b/packages/fineui/src/component/allvaluemultitextvaluecombo/__test__/allvalue.multitextvalue.combo.test.js similarity index 100% rename from src/component/allvaluemultitextvaluecombo/__test__/allvalue.multitextvalue.combo.test.js rename to packages/fineui/src/component/allvaluemultitextvaluecombo/__test__/allvalue.multitextvalue.combo.test.js diff --git a/packages/fineui/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js b/packages/fineui/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js new file mode 100644 index 000000000..0bbb70397 --- /dev/null +++ b/packages/fineui/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js @@ -0,0 +1,72 @@ +import { SearchMultiTextValueCombo } from "@/widget"; +import { shortcut, Widget, Selection, each, contains } from "@/core"; + +@shortcut() +export class AllValueMultiTextValueCombo extends Widget { + static xtype = "bi.all_value_multi_text_value_combo"; + + props = { baseCls: "bi-all-value-multi-text-value-combo", width: 200, height: 24, items: [] }; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + render() { + const self = this, + o = this.options; + const value = this._digestValue(o.value); + + return { + type: SearchMultiTextValueCombo.xtype, + simple: o.simple, + text: o.text, + height: o.height, + items: o.items, + value, + numOfPage: 100, + valueFormatter: o.valueFormatter, + warningTitle: o.warningTitle, + listeners: [ + { + eventName: SearchMultiTextValueCombo.EVENT_CONFIRM, + action() { + self.fireEvent(AllValueMultiTextValueCombo.EVENT_CONFIRM); + }, + } + ], + ref() { + self.combo = this; + }, + }; + } + + setValue(v) { + const value = this._digestValue(v); + this.combo.setValue(value); + } + + getValue() { + const obj = this.combo.getValue() || {}; + obj.value = obj.value || []; + if (obj.type === Selection.All) { + const values = []; + each(this.options.items, (idx, item) => { + !contains(obj.value, item.value) && values.push(item.value); + }); + + return values; + } + + return obj.value || []; + } + + populate(items) { + this.options.items = items; + this.combo.populate(...arguments); + } + + _digestValue(v) { + return { + type: Selection.Multi, + value: v || [], + }; + } +} diff --git a/packages/fineui/src/component/form/form.field.js b/packages/fineui/src/component/form/form.field.js new file mode 100644 index 000000000..8cc80eae6 --- /dev/null +++ b/packages/fineui/src/component/form/form.field.js @@ -0,0 +1,108 @@ +import { AbsoluteLayout, VerticalAdaptLayout, shortcut, Widget, extend, concat, isKey, VerticalAlign } from "@/core"; +import { Label } from "@/base"; + +@shortcut() +export class FormField extends Widget { + static xtype = "bi.form_field"; + + props = { + baseCls: "bi-form-field", + label: "", + el: {}, + headerCls: "", + labelAlign: "right", // 文字默认右对齐 + validate() { + return true; + }, // 默认返回true + }; + + render() { + const self = this, + o = this.options; + + const field = { + type: AbsoluteLayout.xtype, + items: [ + { + el: extend({}, o.el, { + ref(_ref) { + self.field = _ref; + o.el.ref && o.el.ref.call(this, _ref); + }, + height: o.el.height || 28, + listeners: concat(o.el.listeners, [ + { + eventName: "EVENT_CHANGE", + action() { + self.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_CONFIRM", + action() { + self.fireEvent("EVENT_CONFIRM"); + }, + } + ]), + }), + left: 0, + bottom: 0, + right: 0, + top: 0, + }, + { + el: { + type: Label.xtype, + cls: "error-tip bi-error", + ref(_ref) { + self.error = _ref; + }, + invisible: true, + }, + bottom: -20, + left: 0, + right: 0, + height: 20, + } + ], + }; + + return { + type: VerticalAdaptLayout.xtype, + columnSize: ["auto", "fill"], + verticalAlign: VerticalAlign.Stretch, + items: isKey(o.label) + ? [ + { + el: { + type: Label.xtype, + textAlign: o.labelAlign, + text: o.label, + width: o.labelWidth, + cls: o.headerCls, + rgap: 20, // 表单文字与右侧输入间距均为20px + }, + }, + field + ] + : [field], + }; + } + + getValue() { + return this.field.getValue(); + } + + validate() { + const isValid = this.validateWithNoTip(); + !isValid && this.error.setText(this.options.tip(this.field.getValue(), this.field)); + this.error.setVisible(!isValid); + this.field.element[isValid ? "removeClass" : "addClass"]("bi-error"); + + return isValid; + } + + validateWithNoTip() { + return this.options.validate(this.field.getValue(), this.field); + } +} diff --git a/packages/fineui/src/component/form/form.js b/packages/fineui/src/component/form/form.js new file mode 100644 index 000000000..514280808 --- /dev/null +++ b/packages/fineui/src/component/form/form.js @@ -0,0 +1,85 @@ +import { VerticalLayout, shortcut, Widget, map, some, each } from "@/core"; +import { FormField } from "./form.field"; +import { ButtonGroup } from "@/base"; + +@shortcut() +export class Form extends Widget { + static xtype = "bi.custom_form"; + + props = { + baseCls: "bi-form", + labelAlign: "right", + layout: { type: VerticalLayout.xtype, vgap: 20 }, + items: [{ label: "", el: {} }], + labelWidth: "", + headerCls: "", + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + const o = this.options; + + return { + type: ButtonGroup.xtype, + items: this._createItems(), + layouts: [o.layout], + ref: _ref => { + this.group = _ref; + }, + }; + } + + _createItems() { + const self = this; + const o = this.options; + + return map(o.items, (idx, item) => { + return { + type: FormField.xtype, + height: item.el.height || 28, + labelAlign: o.labelAlign, + labelWidth: o.labelWidth, + headerCls: o.headerCls, + el: item.el, + label: item.label, + tip: item.tip, + validate: item.validate, + listeners: [ + { + eventName: "EVENT_CHANGE", + action() { + self.fireEvent(Form.EVENT_CHANGE, this.validate()); + }, + } + ], + }; + }); + } + + isAllValid() { + return !some(this.validateWithNoTip(), (idx, v) => !v); + } + + validateWithNoTip() { + const validInfo = []; + each(this.group.getAllButtons(), (idx, button) => { + validInfo.push(button.validateWithNoTip()); + }); + + return validInfo; + } + + validate() { + const validInfo = []; + each(this.group.getAllButtons(), (idx, button) => { + validInfo.push(button.validate()); + }); + + return validInfo; + } + + getValue() { + return !this.isAllValid() ? null : map(this.group.getAllButtons(), (idx, button) => button.getValue()); + } +} diff --git a/packages/fineui/src/component/form/index.js b/packages/fineui/src/component/form/index.js new file mode 100644 index 000000000..c2ffb7651 --- /dev/null +++ b/packages/fineui/src/component/form/index.js @@ -0,0 +1,2 @@ +export { Form } from "./form"; +export { FormField } from "./form.field"; diff --git a/packages/fineui/src/component/index.js b/packages/fineui/src/component/index.js new file mode 100644 index 000000000..6ce49c20b --- /dev/null +++ b/packages/fineui/src/component/index.js @@ -0,0 +1,21 @@ +export * from "./allvaluechooser"; +export * from "./form"; +export * from "./valuechooser"; +export * from "./treevaluechooser"; +export { AllValueMultiTextValueCombo } from "./allvaluemultitextvaluecombo/allvalue.multitextvalue.combo"; + +// Object.assign(BI, { +// ...allvaluechooser, +// ...form, +// ...valueChooser, +// ......treeValueChooser, +// AllValueMultiTextValueCombo, +// }); + +// export * from "./allvaluechooser"; +// export * from "./form"; +// export * from "./valuechooser"; +// export * from "./treevaluechooser"; +// export { +// AllValueMultiTextValueCombo +// }; diff --git a/src/component/treevaluechooser/__test__/combo.listtreevaluechooser.test.js b/packages/fineui/src/component/treevaluechooser/__test__/combo.listtreevaluechooser.test.js similarity index 100% rename from src/component/treevaluechooser/__test__/combo.listtreevaluechooser.test.js rename to packages/fineui/src/component/treevaluechooser/__test__/combo.listtreevaluechooser.test.js diff --git a/src/component/treevaluechooser/__test__/combo.treevaluechooser.insert.test.js b/packages/fineui/src/component/treevaluechooser/__test__/combo.treevaluechooser.insert.test.js similarity index 100% rename from src/component/treevaluechooser/__test__/combo.treevaluechooser.insert.test.js rename to packages/fineui/src/component/treevaluechooser/__test__/combo.treevaluechooser.insert.test.js diff --git a/src/component/treevaluechooser/__test__/combo.treevaluechooser.test.js b/packages/fineui/src/component/treevaluechooser/__test__/combo.treevaluechooser.test.js similarity index 100% rename from src/component/treevaluechooser/__test__/combo.treevaluechooser.test.js rename to packages/fineui/src/component/treevaluechooser/__test__/combo.treevaluechooser.test.js diff --git a/src/component/treevaluechooser/__test__/pane.treevaluechooser.test.js b/packages/fineui/src/component/treevaluechooser/__test__/pane.treevaluechooser.test.js similarity index 100% rename from src/component/treevaluechooser/__test__/pane.treevaluechooser.test.js rename to packages/fineui/src/component/treevaluechooser/__test__/pane.treevaluechooser.test.js diff --git a/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.js b/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.js new file mode 100644 index 000000000..90bf612d4 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.js @@ -0,0 +1,996 @@ +import { + Widget, + extend, + emptyFn, + isNotNull, + some, + Tree, + isEmpty, + each, + clone, + isNull, + UUID, + size, + i18nText, + deepClone, + isNotEmptyArray, + last, + has, + nextTick, + concat, + filter, + Func, + any, + every, + map, + difference, + keys, + isPlainObject, + get, + set +} from "@/core"; +import { TreeView } from "@/case"; + +export class AbstractTreeValueChooser extends Widget { + _const = { perPage: 100 }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + items: null, + itemsCreator: emptyFn, + open: false, + }); + } + + _valueFormatter(v) { + let text = v; + if (this.options.valueFormatter) { + return this.options.valueFormatter(v); + } + if (isNotNull(this.items)) { + some(this.items, (i, item) => { + if (item.value === v || `${item.value}` === v) { + text = item.text; + + return true; + } + }); + } + + return text; + } + + _initData(items) { + this.items = items; + const nodes = Tree.treeFormat(items); + this.tree = new Tree(); + this.tree.initTree(nodes); + } + + _itemsCreator(options, callback) { + const call = () => { + switch (options.type) { + case TreeView.REQ_TYPE_INIT_DATA: + this._reqInitTreeNode(options, callback); + break; + case TreeView.REQ_TYPE_ADJUST_DATA: + this._reqAdjustTreeNode(options, callback); + break; + case TreeView.REQ_TYPE_SELECT_DATA: + this._reqSelectedTreeNode(options, callback); + break; + case TreeView.REQ_TYPE_GET_SELECTED_DATA: + this._reqDisplayTreeNode(options, callback); + break; + default: + this._reqTreeNode(options, callback); + break; + } + }; + const o = this.options; + if (!this.items) { + o.itemsCreator({}, items => { + this._initData(items); + call(); + }); + } else { + call(); + } + } + + _reqDisplayTreeNode(op, callback) { + const result = []; + const selectedValues = op.selectedValues; + + if (selectedValues == null || isEmpty(selectedValues)) { + callback({}); + + return; + } + + const getCount = (jo, parentValues) => { + if (jo == null) { + return 0; + } + if (isEmpty(jo)) { + return this._getChildCount(parentValues); + } + + return size(jo); + }; + + const doCheck = (parentValues, node, selected) => { + if (selected == null || isEmpty(selected)) { + each(node.getChildren(), (i, child) => { + const newParents = clone(parentValues); + newParents.push(child.value); + const llen = this._getChildCount(newParents); + createOneJson(child, node.id, llen); + doCheck(newParents, child, {}); + }); + + return; + } + each(selected, k => { + const node = this._getTreeNode(parentValues, k); + // 找不到就是新增值 + if (isNull(node)) { + createOneJson( + { + id: UUID(), + text: k, + value: k, + }, + UUID(), + 0 + ); + } else { + const newParents = clone(parentValues); + newParents.push(node.value); + createOneJson(node, node.parent && node.parent.id, getCount(selected[k], newParents)); + doCheck(newParents, node, selected[k]); + } + }); + }; + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: result, + }); + + function createOneJson(node, pId, llen) { + result.push({ + id: node.id, + pId, + text: + node.text + + (llen > 0 ? `(${i18nText("BI-Basic_Altogether")}${llen}${i18nText("BI-Basic_Count")})` : ""), + value: node.value, + open: true, + disabled: node.disabled, + }); + } + } + + _reqSelectedTreeNode(op, callback) { + const self = this; + const selectedValues = deepClone(op.selectedValues); + const notSelectedValue = op.notSelectedValue || {}; + const keyword = op.keyword || ""; + const parentValues = op.parentValues || []; + + if (selectedValues == null || isEmpty(selectedValues)) { + callback({}); + + return; + } + + dealWithSelectedValues(selectedValues); + callback(selectedValues); + + function dealWithSelectedValues(selectedValues) { + let p = parentValues.concat(notSelectedValue); + // 存储的值中存在这个值就把它删掉 + // 例如选中了中国-江苏-南京, 取消中国或江苏或南京 + // p长度不大于selectedValues的情况才可能找到,这样可以直接删除selectedValues的节点 + if (canFindKey(selectedValues, p)) { + // 如果搜索的值在父亲链中 + if (isSearchValueInParent(p)) { + // 例如选中了 中国-江苏, 搜索江苏, 取消江苏(干掉了江苏) + self._deleteNode(selectedValues, p); + } else { + const searched = []; + // 要找到所有以notSelectedValue为叶子节点的链路 + const find = search(parentValues, notSelectedValue, [], searched); + if (find && isNotEmptyArray(searched)) { + each(searched, (i, arr) => { + const node = self._getNode(selectedValues, arr); + if (node) { + // 例如选中了 中国-江苏, 搜索江苏, 取消中国(实际上只想删除中国-江苏,因为搜的是江苏) + // 例如选中了 中国-江苏-南京,搜索南京,取消中国(实际上只想删除中国-江苏-南京,因为搜的是南京) + self._deleteNode(selectedValues, arr); + } else { + // 例如选中了 中国-江苏,搜索南京,取消中国(实际上只想删除中国-江苏-南京,因为搜的是南京) + expandSelectedValue(selectedValues, arr, last(arr)); + } + }); + } + } + } + + // 存储的值中不存在这个值,但父亲节点是全选的情况 + // 例如选中了中国-江苏,取消南京 + // important 选中了中国-江苏,取消了江苏,但是搜索的是南京 + if (isChild(selectedValues, p)) { + const result = []; + let find = false; + // 如果parentValues中有匹配的值,说明搜索结果不在当前值下 + if (isSearchValueInParent(p)) { + find = true; + } else { + // 从当前值开始搜 + find = search(parentValues, notSelectedValue, result); + p = parentValues; + } + + if (find === true) { + // 去掉点击的节点之后的结果集 + expandSelectedValue(selectedValues, p, notSelectedValue); + // 添加去掉搜索的结果集 + if (result.length > 0) { + each(result, (i, strs) => { + self._buildTree(selectedValues, strs); + }); + } + } + } + }; + + function expandSelectedValue(selectedValues, parents, notSelectedValue) { + let next = selectedValues; + const childrenCount = []; + const path = []; + // 去掉点击的节点之后的结果集 + some(parents, (i, v) => { + const t = next[v]; + if (t == null) { + if (i === 0) { + return true; + } + if (isEmpty(next)) { + const split = parents.slice(0, i); + const expanded = self._getChildren(split); + path.push(split); + childrenCount.push(expanded.length); + // 如果只有一个值且取消的就是这个值 + if ( + i === parents.length - 1 && + expanded.length === 1 && + expanded[0].value === notSelectedValue + ) { + for (let j = childrenCount.length - 1; j >= 0; j--) { + if (childrenCount[j] === 1) { + self._deleteNode(selectedValues, path[j]); + } else { + break; + } + } + } else { + each(expanded, (m, child) => { + if (i === parents.length - 1 && child.value === notSelectedValue) { + return true; + } + next[child.value] = {}; + }); + } + next = next[v]; + } else { + return true; + // next = {}; + // next[v] = {}; + } + } else { + next = t; + } + }); + }; + + function search(parents, current, result, searched) { + const newParents = clone(parents); + newParents.push(current); + if (self._isMatch(parents, current, keyword)) { + searched && searched.push(newParents); + + return true; + } + + const children = self._getChildren(newParents); + + const notSearch = []; + let can = false; + + each(children, (i, child) => { + if (search(newParents, child.value, result, searched)) { + can = true; + } else { + notSearch.push(child.value); + } + }); + if (can === true) { + each(notSearch, (i, v) => { + const next = clone(newParents); + next.push(v); + result.push(next); + }); + } + + return can; + }; + + function isSearchValueInParent(parentValues) { + for (let i = 0, len = parentValues.length; i < len; i++) { + if (self._isMatch(parentValues.slice(0, i), parentValues[i], keyword)) { + return true; + } + } + + return false; + }; + + function canFindKey(selectedValues, parents) { + let t = selectedValues; + for (let i = 0; i < parents.length; i++) { + const v = parents[i]; + t = t[v]; + if (t == null) { + return false; + } + } + + return true; + } + + function isChild(selectedValues, parents) { + let t = selectedValues; + for (let i = 0; i < parents.length; i++) { + const v = parents[i]; + if (!has(t, v)) { + return false; + } + t = t[v]; + if (isEmpty(t)) { + return true; + } + } + + return false; + } + } + + _reqAdjustTreeNode(op, callback) { + const result = []; + const selectedValues = op.selectedValues; + if (selectedValues == null || isEmpty(selectedValues)) { + callback({}); + + return; + } + each(selectedValues, (k, v) => { + result.push([k]); + }); + + const isAllSelected = (selected, parents) => isEmpty(selected) || this._getChildCount(parents) === size(selected); + + function dealWithSelectedValues(selected, parents) { + if (selected == null || isEmpty(selected)) { + return true; + } + let can = true; + each(selected, (k, v) => { + const p = clone(parents); + p.push(k); + if (!dealWithSelectedValues(selected[k], p) || op.searcherPaneAutoShrink === false) { + each(selected[k], (nk, nv) => { + const t = clone(p); + t.push(nk); + result.push(t); + }); + can = false; + } + }); + + return can && isAllSelected(selected, parents); + } + + dealWithSelectedValues(selectedValues, []); + + const jo = {}; + each(result, (i, strs) => { + this._buildTree(jo, strs); + }); + callback(jo); + + + } + + _reqInitTreeNode(op, callback) { + let result = []; + const self = this; + const keyword = op.keyword || ""; + const selectedValues = op.selectedValues; + const lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + const output = search(); + nextTick(() => { + callback({ + hasNext: output.length > this._const.perPage, + items: result, + lastSearchValue: last(output), + }); + }); + + function search(){ + const children = self._getChildren([]); + let start = children.length; + if (lastSearchValue !== "") { + for (let j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + const output = []; + for (let i = start, len = children.length; i < len; i++) { + let find; + if (output.length < self._const.perPage) { + find = nodeSearch(1, [], children[i].value, false, result); + } else if (output.length === self._const.perPage) { + find = nodeSearch(1, [], children[i].value, false, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + const nodes = self._getAddedValueNode([], selectedValues); + result = concat( + filter(nodes, (idx, node) => { + const find = Func.getSearchResult([node.text || node.value], keyword); + + return find.find.length > 0 || find.match.length > 0; + }), + result + ); + } + + return output; + } + + function nodeSearch(deep, parentValues, current, isAllSelect, result) { + if (self._isMatch(parentValues, current, keyword)) { + const checked = isAllSelect || isSelected(parentValues, current); + createOneJson( + parentValues, + current, + false, + checked, + !isAllSelect && isHalf(parentValues, current), + true, + result + ); + + return [true, checked]; + } + const newParents = clone(parentValues); + newParents.push(current); + const children = self._getChildren(newParents); + + let can = false, + checked = false; + + const isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); + each(children, (i, child) => { + const state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + // 当前节点的子节点是否选中,并不确定全选还是半选 + if (state[1] === true) { + checked = true; + } + // 当前节点的子节点要不要加入到结果集中 + if (state[0] === true) { + can = true; + } + }); + // 子节点匹配, 补充父节点 + if (can === true) { + checked = isCurAllSelected || (isSelected(parentValues, current) && checked); + createOneJson(parentValues, current, true, checked, false, false, result); + } + + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { + const node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked, + halfCheck: half, + flag, + disabled: node.disabled, + }); + } + + function isHalf(parentValues, value) { + const find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + + return any(find, (v, ob) => { + if (v === value) { + if (ob != null && !isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + const find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + + return any(find, (v, ob) => { + if (v === value) { + if (ob != null && isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parentValues, value) { + const find = findSelectedObj(parentValues); + if (find == null) { + return false; + } + + return any(find, v => { + if (v === value) { + return true; + } + }); + } + + function findSelectedObj(parentValues) { + let find = selectedValues; + if (find == null) { + return null; + } + every(parentValues, (i, v) => { + find = find[v]; + if (find == null) { + return false; + } + + return true; + }); + + return find; + } + } + + _reqTreeNode(op, callback) { + const o = this.options; + let result = []; + const times = op.times; + const checkState = op.checkState || {}; + const parentValues = op.parentValues || []; + const selectedValues = op.selectedValues || {}; + const getCheckState = (current, parentValues, valueMap, checkState) => { + // 节点本身的checked和half优先级最高 + const checked = checkState.checked, + half = checkState.half; + let tempCheck = false, + halfCheck = false; + if (has(valueMap, current)) { + // 可能是半选 + if (valueMap[current][0] === 1) { + const values = clone(parentValues); + values.push(current); + const childCount = this._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { + halfCheck = true; + } + } else if (valueMap[current][0] === 2) { + tempCheck = true; + } + } + let check; + // 展开的节点checked为false 且没有明确得出当前子节点是半选或者全选, 则check状态取决于valueMap + if (!checked && !halfCheck && !tempCheck) { + check = has(valueMap, current); + } else { + // 不是上面那种情况就先看在节点没有带有明确半选的时候,通过节点自身的checked和valueMap的状态能都得到选中信息 + check = ((tempCheck || checked) && !half) || has(valueMap, current); + } + + return [check, halfCheck]; + }; + const getResult = (parentValues, checkState) => { + let valueMap = {}; + // if (judgeState(parentValues, selectedValues, checkState)) { + const isAllSelected = (selected, parents) => { + if (isEmpty(selected)) { + return true; + } + + if (this._getChildCount(parents) !== size(selected)) { + return false; + } + + return every(selected, value => isAllSelected(selected[value], concat(parents, value))); + }; + + function dealWithSelectedValue(parentValues, selectedValues) { + const valueMap = {}, + parents = (parentValues || []).slice(0); + each(parentValues, (i, v) => { + parents.push(v); + + selectedValues = selectedValues[v] || {}; + }); + each(selectedValues, (value, obj) => { + const currentParents = concat(parents, value); + + if (isNull(obj)) { + valueMap[value] = [0, 0]; + + return; + } + if (isEmpty(obj)) { + valueMap[value] = [2, 0]; + + return; + } + const nextNames = {}; + each(obj, (t, o) => { + if (isNull(o) || isEmpty(o)) { + nextNames[t] = true; + } else { + isAllSelected(o, concat(currentParents, [t])) && (nextNames[t] = true); + } + }); + // valueMap的数组第一个参数为不选: 0, 半选: 1, 全选:2, 第二个参数为改节点下选中的子节点个数(子节点全选或者不存在) + valueMap[value] = [1, size(nextNames)]; + }); + + return valueMap; + } + valueMap = dealWithSelectedValue(parentValues, selectedValues); + // } + const nodes = this._getChildren(parentValues); + for (let i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + const state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); + const openState = o.open || nodes[i].open; + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].isParent || nodes[i].getChildrenLength() > 0, + checked: state[0], + half: state[1], + halfCheck: openState ? false : state[1], + open: openState, + disabled: nodes[i].disabled, + title: nodes[i].title || nodes[i].text, + warningTitle: nodes[i].warningTitle, + }); + if (openState) { + getResult(parentValues.concat([nodes[i].value]), { checked: state[0], half: state[1] }); + } + } + }; + + getResult(parentValues, checkState); + + // 如果指定节点全部打开 + // if (o.open) { + // var allNodes = []; + // // 获取所有节点 + // each(nodes, function (idx, node) { + // allNodes = concat(allNodes, self._getAllChildren(parentValues.concat([node.value]))); + // }); + // var lastFind; + // each(allNodes, function (idx, node) { + // var valueMap = dealWithSelectedValue(node.parentValues, selectedValues); + // // REPORT-24409 fix: 设置节点全部展开,添加的节点没有给状态 + // var parentCheckState = {}; + // var find = find(result, function (idx, pNode) { + // return pNode.id === node.pId; + // }); + // if (find) { + // parentCheckState.checked = find.halfCheck ? false : find.checked; + // parentCheckState.half = find.halfCheck; + // // 默认展开也需要重置父节点的halfCheck + // if (isNotNull(lastFind) && (lastFind !== find || allNodes.length - 1 === idx)) { + // lastFind.half = lastFind.halfCheck; + // lastFind.halfCheck = false; + // } + // } + // lastFind = find; + // var state = getCheckState(node.value, node.parentValues, valueMap, parentCheckState); + // result.push({ + // id: node.id, + // pId: node.pId, + // value: node.value, + // text: node.text, + // times: 1, + // isParent: node.getChildrenLength() > 0, + // checked: state[0], + // halfCheck: state[1], + // open: true, + // disabled: node.disabled, + // title: node.title || node.text, + // warningTitle: node.warningTitle, + // }); + // }); + // } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = concat(this._getAddedValueNode(parentValues, selectedValues), result); + } + nextTick(() => { + callback({ + items: result, + hasNext: this._getChildren(parentValues).length > times * this._const.perPage, + }); + }); + + // function judgeState(parentValues, selected_value, checkState) { + // var checked = checkState.checked, half = checkState.half; + // if (parentValues.length > 0 && !checked) { + // return false; + // } + // return (parentValues.length === 0 || (checked && half) && !isEmpty(selected_value)); + // } + } + + _getAddedValueNode(parentValues, selectedValues) { + const nodes = this._getChildren(parentValues); + + return map(difference(keys(selectedValues), map(nodes, "value")), (idx, v) => { + return { + id: UUID(), + pId: nodes.length > 0 ? nodes[0].pId : UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false, + }; + }); + } + + _getNode(selectedValues, parentValues) { + let pNode = selectedValues; + for (let i = 0, len = parentValues.length; i < len; i++) { + if (pNode == null) { + return null; + } + pNode = pNode[parentValues[i]]; + } + + return pNode; + } + + _deleteNode(selectedValues, values) { + let name = values[values.length - 1]; + let p = values.slice(0, values.length - 1); + let pNode = this._getNode(selectedValues, p); + if (pNode != null && pNode[name]) { + delete pNode[name]; + // 递归删掉空父节点 + while (p.length > 0 && isEmpty(pNode)) { + name = p[p.length - 1]; + p = p.slice(0, p.length - 1); + pNode = this._getNode(selectedValues, p); + if (pNode != null) { + delete pNode[name]; + } + } + } + } + + _buildTree(jo, values) { + let t = jo; + each(values, (i, v) => { + if (!has(t, v)) { + t[v] = {}; + } + t = t[v]; + }); + } + + _isMatch(parentValues, value, keyword) { + const o = this.options; + const node = this._getTreeNode(parentValues, value); + if (!node) { + return false; + } + const find = Func.getSearchResult([node.text || node.value], keyword); + if (o.allowSearchValue && node.value) { + const valueFind = Func.getSearchResult([node.value], keyword); + + return ( + valueFind.find.length > 0 || valueFind.match.length > 0 || find.find.length > 0 || find.match.length > 0 + ); + } + + return find.find.length > 0 || find.match.length > 0; + } + + _getTreeNode(parentValues, v) { + let findParentNode; + let index = 0; + let currentParent = this.tree.getRoot(); + this.tree.traverse(node => { + if (this.tree.isRoot(node)) { + return; + } + if (index > parentValues.length) { + return false; + } + + /** + * 一个树结构。要找root_1_3的子节点 + * {root: { 1: {1: {}, 2: {}, 3: {}}, 3: {1: {}, 2: {}} } } + * 当遍历到root_1节点时,index++,而下一个节点root_3时,符合下面的if逻辑,这样找到的节点就是root_3节点了,需要加步判断是否是root_1的子节点 + */ + if (index === parentValues.length && node.value === v) { + if (node.getParent() !== currentParent) { + return; + } + + findParentNode = node; + + return false; + } + if (node.value === parentValues[index] && node.getParent() === currentParent) { + index++; + currentParent = node; + + return; + } + + return true; + }); + + return findParentNode; + } + + _getChildren(parentValues) { + let parent; + if (parentValues.length > 0) { + const value = last(parentValues); + parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); + } else { + parent = this.tree.getRoot(); + } + + return parent ? parent.getChildren() : []; + } + + _getAllChildren(parentValues) { + const children = this._getChildren(parentValues); + let nodes = [].concat(children); + each(nodes, (idx, node) => { + node.parentValues = parentValues; + }); + let queue = map(children, (idx, node) => { + return { + parentValues, + value: node.value, + }; + }); + while (isNotEmptyArray(queue)) { + const node = queue.shift(); + const pValues = node.parentValues.concat(node.value); + const childNodes = this._getChildren(pValues); + each(childNodes, (idx, node) => { + node.parentValues = pValues; + }); + queue = queue.concat(childNodes); + nodes = nodes.concat(childNodes); + } + + return nodes; + } + + _getChildCount(parentValues) { + return this._getChildren(parentValues).length; + } + + assertSelectedValue(selectedValues, items = []) { + if (isPlainObject(selectedValues)) { + return selectedValues; + } + + const tree = Tree.transformToTreeFormat(items); + const value2ParentMap = {}; + Tree.traversal(tree, (index, node, pNode) => { + value2ParentMap[node.value] = pNode; + }); + + const result = {}; + each(selectedValues, (index, value) => { + let curr = value; + const parentPath = []; + while (curr) { + parentPath.unshift(curr); + curr = value2ParentMap[curr]?.value; + } + each(parentPath, index => { + if (isNull(get(result, parentPath.slice(0, index + 1)))) { + set(result, parentPath.slice(0, index + 1), {}); + } + }); + // 执行完一条路径,check一下 + const lengths = size(get(result, parentPath.slice(0, -1))); + if (lengths === value2ParentMap[value]?.children?.length) { + set(result, parentPath.slice(0, -1), {}); + } + }); + + return result; + } + + buildCompleteTree(selectedValues) { + const result = {}; + + const fill = (parentValues, node, selected, r) => { + if (selected === null || isEmpty(selected)) { + each(node.getChildren(), (i, child) => { + const newParents = clone(parentValues); + newParents.push(child.value); + r[child.value] = {}; + fill(newParents, child, null, r[child.value]); + }); + + return; + } + each(selected, k => { + const node = this._getTreeNode(parentValues, k); + const newParents = clone(parentValues); + newParents.push(node.value); + r[k] = {}; + fill(newParents, node, selected[k], r[k]); + }); + } + + if (selectedValues !== null && !isEmpty(selectedValues)) { + fill([], this.tree.getRoot(), selectedValues, result); + } + + return result; + } +} diff --git a/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.list.js b/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.list.js new file mode 100644 index 000000000..d3afdae79 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/abstract.treevaluechooser.list.js @@ -0,0 +1,329 @@ +import { + isEmpty, + values, + each, + isNull, + UUID, + has, + nextTick, + last, + concat, + filter, + Func, + clone, + any, + isEqual, + every, + flatten, + map, + difference +} from "@/core"; +import { AbstractTreeValueChooser } from "./abstract.treevaluechooser"; + +export class AbstractListTreeValueChooser extends AbstractTreeValueChooser { + _reqDisplayTreeNode(op, callback) { + const result = {}; + const selectedValues = op.selectedValues; + + if (selectedValues == null || isEmpty(selectedValues)) { + callback({}); + + return; + } + + doCheck.call(this, [], this.tree.getRoot(), selectedValues); + + callback({ + items: values(result), + }); + + function doCheck(parentValues, node, selected) { + each(selected, (idx, path) => { + each(path, (id, value) => { + const nodeValue = value; + const node = this._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (isNull(node)) { + createOneJson( + { + id: UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true, + }, + UUID() + ); + } else { + if (!has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf !== true && (result[node.id].isLeaf = id === path.length - 1); + } + }); + }); + } + + function createOneJson(node, pId) { + result[node.id] = { + id: node.id, + pId, + text: node.text, + value: node.value, + open: true, + isLeaf: node.isLeaf, + }; + } + } + + _reqInitTreeNode(op, callback) { + let result = []; + const keyword = op.keyword || ""; + const selectedValues = op.selectedValues; + const lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + const output = search(); + nextTick(() => { + callback({ + hasNext: output.length > this._const.perPage, + items: result, + lastSearchValue: last(output), + }); + }); + + const search = () => { + const children = this._getChildren([]); + let start = children.length; + if (lastSearchValue !== "") { + for (let j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + const output = []; + let find; + for (let i = start, len = children.length; i < len; i++) { + if (output.length < this._const.perPage) { + find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === this._const.perPage) { + find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > this._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + const nodes = this._getAddedValueNode([], selectedValues); + result = concat( + filter(nodes, (idx, node) => { + const find = Func.getSearchResult([node.text || node.value], keyword); + + return find.find.length > 0 || find.match.length > 0; + }), + result + ); + } + + return output; + }; + + const createOneJson = (parentValues, value, isOpen, checked, flag, result) => { + const node = this._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked, + halfCheck: false, + flag, + disabled: node.disabled, + }); + }; + + const nodeSearch = (deep, parentValues, current, result) => { + let checked; + if (this._isMatch(parentValues, current, keyword)) { + checked = isSelected(parentValues, current); + createOneJson(parentValues, current, false, checked, true, result); + + return [true, checked]; + } + const newParents = clone(parentValues); + newParents.push(current); + const children = this._getChildren(newParents); + + let can = false; + checked = false; + + each(children, (i, child) => { + const state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(parentValues, current); + createOneJson(parentValues, current, true, checked, false, result); + } + + return [can, checked]; + }; + + // eslint-disable-next-line no-unused-vars + function isHalf(parentValues, value) { + const find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + + return any(find, (v, ob) => { + if (v === value) { + if (ob != null && !isEmpty(ob)) { + return true; + } + } + }); + } + + // eslint-disable-next-line no-unused-vars + function isAllSelected(parentValues, value) { + const find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + + return any(find, (v, ob) => { + if (v === value) { + if (ob != null && isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parentValues, value) { + return any(selectedValues, (idx, array) => isEqual(parentValues, array.slice(0, parentValues.length)) && last(array) === value); + } + + function findSelectedObj(parentValues) { + let find = selectedValues; + if (find == null) { + return null; + } + every(parentValues, (i, v) => { + find = find[v]; + if (find == null) { + return false; + } + + return true; + }); + + return find; + } + } + + _reqTreeNode(op, callback) { + const o = this.options; + let result = []; + const times = op.times; + const parentValues = op.parentValues || []; + const selectedValues = op.selectedValues || []; + const valueMap = dealWithSelectedValue(parentValues, selectedValues); + const nodes = this._getChildren(parentValues); + for (let i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + const checked = has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked, + halfCheck: false, + open: o.open, + disabled: nodes[i].disabled, + }); + } + // 如果指定节点全部打开 + if (o.open) { + let allNodes = []; + // 获取所有节点 + each(nodes, (idx, node) => { + allNodes = concat(allNodes, this._getAllChildren(parentValues.concat([node.value]))); + }); + each(allNodes, (idx, node) => { + const valueMap = dealWithSelectedValue(node.parentValues, selectedValues); + const checked = has(valueMap, node.value); + result.push({ + id: node.id, + pId: node.pId, + value: node.value, + text: node.text, + times: 1, + isParent: node.getChildrenLength() > 0, + checked, + halfCheck: false, + open: o.open, + disabled: node.disabled, + }); + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = concat(this._getAddedValueNode(parentValues, selectedValues), result); + } + nextTick(() => { + callback({ + items: result, + hasNext: nodes.length > times * this._const.perPage, + }); + }); + + function dealWithSelectedValue(parentValues, selectedValues) { + const valueMap = {}; + each(selectedValues, (idx, v) => { + if (isEqual(parentValues, v.slice(0, parentValues.length))) { + valueMap[last(v)] = [2, 0]; + } + }); + + return valueMap; + } + } + + _getAddedValueNode(parentValues, selectedValues) { + const nodes = this._getChildren(parentValues); + const values = flatten( + filter(selectedValues, (idx, array) => array.length === 1) + ); + + return map(difference(values, map(nodes, "value")), (idx, v) => { + return { + id: UUID(), + pId: nodes.length > 0 ? nodes[0].pId : UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false, + }; + }); + } +} diff --git a/packages/fineui/src/component/treevaluechooser/combo.listtreevaluechooser.js b/packages/fineui/src/component/treevaluechooser/combo.listtreevaluechooser.js new file mode 100644 index 000000000..847280947 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/combo.listtreevaluechooser.js @@ -0,0 +1,135 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind } from "@/core"; +import { AbstractListTreeValueChooser } from "./abstract.treevaluechooser.list"; +import { MultiTreeListCombo, MultiTreeCombo } from "@/widget"; +import { TreeValueChooserInsertCombo } from "./combo.treevaluechooser.insert"; + +@shortcut() +export class ListTreeValueChooserInsertCombo extends AbstractListTreeValueChooser { + static xtype = "bi.list_tree_value_chooser_insert_combo"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + isNeedAdjustWidth: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = createWidget({ + type: MultiTreeListCombo.xtype, + simple: o.simple, + isNeedAdjustWidth: o.isNeedAdjustWidth, + element: this, + text: o.text, + defaultText: o.defaultText, + value: o.value, + watermark: o.watermark, + allowInsertValue: o.allowInsertValue, + allowEdit: o.allowEdit, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + listeners: [ + { + eventName: MultiTreeListCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiTreeListCombo.EVENT_BLUR, + action: () => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiTreeListCombo.EVENT_STOP, + action: () => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_STOP); + }, + }, + { + eventName: MultiTreeListCombo.EVENT_CLICK_ITEM, + action: v => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_CLICK_ITEM, v); + }, + }, + { + eventName: MultiTreeListCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiTreeListCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }, + }, + { + eventName: MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + getSearcher() { + return this.combo.getSearcher(); + } + + setValue(v) { + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + populate(items) { + if (isNotNull(items)) { + this._initData(items); + } + this.combo.populate(); + } + + focus() { + this.combo.focus(); + } + + blur() { + this.combo.blur(); + } + + setWaterMark(v) { + this.combo.setWaterMark(v); + } +} diff --git a/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.insert.js b/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.insert.js new file mode 100644 index 000000000..1eba57884 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.insert.js @@ -0,0 +1,134 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind } from "@/core"; +import { AbstractTreeValueChooser } from "./abstract.treevaluechooser"; +import { MultiTreeInsertCombo, MultiTreeCombo } from "@/widget"; +import { TreeValueChooserCombo } from "./combo.treevaluechooser"; + +@shortcut() +export class TreeValueChooserInsertCombo extends AbstractTreeValueChooser { + static xtype = "bi.tree_value_chooser_insert_combo"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + isNeedAdjustWidth: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = createWidget({ + type: MultiTreeInsertCombo.xtype, + simple: o.simple, + isNeedAdjustWidth: o.isNeedAdjustWidth, + allowEdit: o.allowEdit, + text: o.text, + defaultText: o.defaultText, + value: o.value, + watermark: o.watermark, + element: this, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + listeners: [ + { + eventName: MultiTreeInsertCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiTreeInsertCombo.EVENT_BLUR, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiTreeInsertCombo.EVENT_STOP, + action: () => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_STOP); + }, + }, + { + eventName: MultiTreeInsertCombo.EVENT_CLICK_ITEM, + action: v => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_CLICK_ITEM, v); + }, + }, + { + eventName: MultiTreeInsertCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiTreeInsertCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_CONFIRM); + }, + }, + { + eventName: MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(TreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + getSearcher() { + return this.combo.getSearcher(); + } + + setValue(v) { + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + populate(items) { + if (isNotNull(items)) { + this._initData(items); + } + this.combo.populate(); + } + + focus() { + this.combo.focus(); + } + + blur() { + this.combo.blur(); + } + + setWaterMark(v) { + this.combo.setWaterMark(v); + } +} diff --git a/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.js b/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.js new file mode 100644 index 000000000..51ee25614 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/combo.treevaluechooser.js @@ -0,0 +1,145 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind } from "@/core"; +import { AbstractTreeValueChooser } from "./abstract.treevaluechooser"; +import { MultiTreeCombo } from "@/widget"; + +@shortcut() +export class TreeValueChooserCombo extends AbstractTreeValueChooser { + // TODO:该组件有问题,未报错,但不显示pane,该问题看起来是其他组件es6化导致 + static xtype = "bi.tree_value_chooser_combo"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-tree-value-chooser-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + isNeedAdjustWidth: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = createWidget({ + type: MultiTreeCombo.xtype, + simple: o.simple, + text: o.text, + defaultText: o.defaultText, + allowEdit: o.allowEdit, + value: this.assertSelectedValue(o.value, o.items), + watermark: o.watermark, + element: this, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + isNeedAdjustWidth: o.isNeedAdjustWidth, + listeners: [ + { + eventName: MultiTreeCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiTreeCombo.EVENT_BLUR, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiTreeCombo.EVENT_STOP, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_STOP); + }, + }, + { + eventName: MultiTreeCombo.EVENT_CLICK_ITEM, + action: v => { + this.fireEvent(TreeValueChooserCombo.EVENT_CLICK_ITEM, v); + }, + }, + { + eventName: MultiTreeCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiTreeCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_CONFIRM); + }, + }, + { + eventName: MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_BEFORE_POPUPVIEW); + }, + }, + { + eventName: MultiTreeCombo.EVENT_AFTER_HIDEVIEW, + action: () => { + this.fireEvent(TreeValueChooserCombo.EVENT_AFTER_HIDEVIEW); + }, + } + ], + }); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + getSearcher() { + return this.combo.getSearcher(); + } + + setValue(v) { + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + getAllValue() { + return this.buildCompleteTree(this.combo.getValue()); + } + + populate(items) { + if (isNotNull(items)) { + this._initData(items); + } + this.combo.populate(); + } + + focus() { + this.combo.focus(); + } + + blur() { + this.combo.blur(); + } + + setWaterMark(v) { + this.combo.setWaterMark(v); + } +} diff --git a/packages/fineui/src/component/treevaluechooser/index.js b/packages/fineui/src/component/treevaluechooser/index.js new file mode 100644 index 000000000..6b439bb08 --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/index.js @@ -0,0 +1,6 @@ +export { AbstractTreeValueChooser } from "./abstract.treevaluechooser"; +export { AbstractListTreeValueChooser } from "./abstract.treevaluechooser.list"; +export { ListTreeValueChooserInsertCombo } from "./combo.listtreevaluechooser"; +export { TreeValueChooserInsertCombo } from "./combo.treevaluechooser.insert"; +export { TreeValueChooserCombo } from "./combo.treevaluechooser"; +export { TreeValueChooserPane } from "./pane.treevaluechooser"; diff --git a/packages/fineui/src/component/treevaluechooser/pane.treevaluechooser.js b/packages/fineui/src/component/treevaluechooser/pane.treevaluechooser.js new file mode 100644 index 000000000..ff5aad90f --- /dev/null +++ b/packages/fineui/src/component/treevaluechooser/pane.treevaluechooser.js @@ -0,0 +1,73 @@ +import { shortcut, extend, emptyFn, createWidget, bind, isNotNull } from "@/core"; +import { AbstractTreeValueChooser } from "./abstract.treevaluechooser"; +import { MultiSelectTree } from "@/widget/multiselecttree/multiselecttree"; +import { MultiSelectTreePopup } from "@/widget/multiselecttree/multiselecttree.popup"; + +@shortcut() +export class TreeValueChooserPane extends AbstractTreeValueChooser { + static xtype = "bi.tree_value_chooser_pane"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-tree-value-chooser-pane", + items: null, + itemsCreator: emptyFn, + showLine: true, + //searcherPaneAutoShrink和searcherPaneIsSelectedAny同时为false时,返回值和非搜索状态下的树逻辑一致 + searcherPaneAutoShrink: true,//其搜索树是否会判别子结点全选则取父结点的值 + searcherPaneIsSelectedAny: true, //其搜索树是否返回所有被checked的结点(包括被checked的结点的子结点) + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.pane = createWidget({ + type: o.hideSearch ? MultiSelectTreePopup.xtype : MultiSelectTree.xtype, + element: this, + showLine: o.showLine, + searcherPaneIsSelectedAny: o.hideSearch || o.searcherPaneIsSelectedAny, + itemsCreator: (options, callback) => { + options.searcherPaneAutoShrink = o.hideSearch || o.searcherPaneAutoShrink; + this._itemsCreator.call(this, options, callback); + }, + }); + + this.pane.on(MultiSelectTree.EVENT_CHANGE, () => { + this.fireEvent(TreeValueChooserPane.EVENT_CHANGE); + }); + if (isNotNull(o.value)) { + const selectedValues = this.assertSelectedValue(o.value, o.items); + this.pane.setSelectedValue(selectedValues); + } + if (isNotNull(o.items)) { + this._initData(o.items); + this.pane.populate(); + } + } + + setSelectedValue(v) { + this.pane.setSelectedValue(v); + } + + setValue(v) { + this.pane.setValue(v); + } + + getValue() { + return this.pane.getValue(); + } + + getAllValue() { + return this.buildCompleteTree(this.pane.getValue()); + } + + populate(items) { + if (isNotNull(items)) { + this._initData(items); + } + this.pane.populate(); + } +} diff --git a/src/component/valuechooser/__test__/combo.valuechooser.insert.test.js b/packages/fineui/src/component/valuechooser/__test__/combo.valuechooser.insert.test.js similarity index 100% rename from src/component/valuechooser/__test__/combo.valuechooser.insert.test.js rename to packages/fineui/src/component/valuechooser/__test__/combo.valuechooser.insert.test.js diff --git a/src/component/valuechooser/__test__/combo.valuechooser.test.js b/packages/fineui/src/component/valuechooser/__test__/combo.valuechooser.test.js similarity index 100% rename from src/component/valuechooser/__test__/combo.valuechooser.test.js rename to packages/fineui/src/component/valuechooser/__test__/combo.valuechooser.test.js diff --git a/src/component/valuechooser/__test__/pane.valuechooser.test.js b/packages/fineui/src/component/valuechooser/__test__/pane.valuechooser.test.js similarity index 100% rename from src/component/valuechooser/__test__/pane.valuechooser.test.js rename to packages/fineui/src/component/valuechooser/__test__/pane.valuechooser.test.js diff --git a/packages/fineui/src/component/valuechooser/abstract.valuechooser.js b/packages/fineui/src/component/valuechooser/abstract.valuechooser.js new file mode 100644 index 000000000..8cf66acc0 --- /dev/null +++ b/packages/fineui/src/component/valuechooser/abstract.valuechooser.js @@ -0,0 +1,122 @@ +import { + Widget, + extend, + emptyFn, + isNotNull, + some, + isNotEmptyArray, + each, + Func, + uniq, + makeObject, + filter, + Selection, + difference, + map +} from "@/core"; +import { MultiSelectCombo } from "@/widget"; + +export class AbstractValueChooser extends Widget { + _const = { perPage: 100 }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _valueFormatter(v) { + let text = v; + if (this.options.valueFormatter) { + return this.options.valueFormatter(v); + } + if (isNotNull(this.items)) { + some(this.items, (i, item) => { + // 把value都换成字符串 + if (item.value === v || `${item.value}` === v) { + text = item.text; + + return true; + } + }); + } + + return text; + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * this._const.perPage < items.length; + } + + _itemsCreator(options, callback) { + const call = items => { + const keywords = (options.keywords || []).slice(); + let resultItems = items; + if (isNotEmptyArray(keywords)) { + resultItems = []; + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + resultItems = resultItems.concat(search.match).concat(search.find); + }); + resultItems = uniq(resultItems); + } + if (options.selectedValues) { + // 过滤 + const filterFunc = makeObject(options.selectedValues, true); + resultItems = filter(resultItems, (i, ob) => !filterFunc[ob.value]); + } + if (options.type === MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: resultItems, + }); + + return; + } + if (options.type === MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: resultItems.length }); + + return; + } + callback({ + items: this._getItemsByTimes(resultItems, options.times), + hasNext: this._hasNextByTimes(resultItems, options.times), + }); + }; + const o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, items => { + this.items = items; + call(items); + }); + } else { + call(this.items); + } + } + + _assertValue(v) { + v = v || {}; + let value = v; + if (v.type === Selection.Multi && isNotNull(this.items)) { + const isAllSelect = difference(map(this.items, "value"), v.value).length === 0; + if (isAllSelect) { + value = { + type: Selection.All, + value: [], + }; + } + } + + return value; + } +} diff --git a/packages/fineui/src/component/valuechooser/combo.valuechooser.insert.js b/packages/fineui/src/component/valuechooser/combo.valuechooser.insert.js new file mode 100644 index 000000000..096aa5ac1 --- /dev/null +++ b/packages/fineui/src/component/valuechooser/combo.valuechooser.insert.js @@ -0,0 +1,114 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind, Selection, difference, map } from "@/core"; +import { AbstractValueChooser } from "./abstract.valuechooser"; +import { MultiSelectCombo, MultiSelectInsertCombo } from "@/widget"; + +@shortcut() +export class ValueChooserInsertCombo extends AbstractValueChooser { + static xtype = "bi.value_chooser_insert_combo"; + + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this.items = o.items; + } + this.combo = createWidget({ + type: MultiSelectInsertCombo.xtype, + simple: o.simple, + element: this, + allowEdit: o.allowEdit, + text: o.text, + value: this._assertValue(o.value), + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + listeners: [ + { + eventName: MultiSelectCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectCombo.EVENT_BLUR, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiSelectCombo.EVENT_STOP, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_STOP); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CLICK_ITEM, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(ValueChooserInsertCombo.EVENT_CONFIRM); + }, + } + ], + }); + } + + setValue(v) { + this.combo.setValue(this._assertValue(v)); + } + + getValue() { + const val = this.combo.getValue() || {}; + + return { + type: val.type, + value: val.value, + }; + } + + getAllValue() { + const val = this.combo.getValue() || {}; + if (val.type === Selection.Multi) { + return val.value || []; + } + + return difference(map(this.items, "value"), val.value || []); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.combo.populate(); + } +} diff --git a/packages/fineui/src/component/valuechooser/combo.valuechooser.js b/packages/fineui/src/component/valuechooser/combo.valuechooser.js new file mode 100644 index 000000000..b913f9a55 --- /dev/null +++ b/packages/fineui/src/component/valuechooser/combo.valuechooser.js @@ -0,0 +1,115 @@ +import { shortcut, extend, emptyFn, isNotNull, createWidget, bind, Selection, difference, map } from "@/core"; +import { AbstractValueChooser } from "./abstract.valuechooser"; +import { MultiSelectCombo } from "@/widget"; + +@shortcut() +export class ValueChooserCombo extends AbstractValueChooser { + static xtype = "bi.value_chooser_combo"; + + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-value-chooser-combo", + width: 200, + height: 24, + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + if (isNotNull(o.items)) { + this.items = o.items; + } + this.combo = createWidget({ + type: MultiSelectCombo.xtype, + simple: o.simple, + element: this, + allowEdit: o.allowEdit, + text: o.text, + defaultText: o.defaultText, + value: this._assertValue(o.value), + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + listeners: [ + { + eventName: MultiSelectCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectCombo.EVENT_BLUR, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiSelectCombo.EVENT_STOP, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_STOP); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CLICK_ITEM, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(ValueChooserCombo.EVENT_CONFIRM); + }, + } + ], + }); + } + + setValue(v) { + this.combo.setValue(this._assertValue(v)); + } + + getValue() { + const val = this.combo.getValue() || {}; + + return { + type: val.type, + value: val.value, + }; + } + + getAllValue() { + const val = this.combo.getValue() || {}; + if (val.type === Selection.Multi) { + return val.value || []; + } + + return difference(map(this.items, "value"), val.value || []); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.combo.populate(); + } +} diff --git a/packages/fineui/src/component/valuechooser/combo.valuechooser.nobar.js b/packages/fineui/src/component/valuechooser/combo.valuechooser.nobar.js new file mode 100644 index 000000000..502c61aaf --- /dev/null +++ b/packages/fineui/src/component/valuechooser/combo.valuechooser.nobar.js @@ -0,0 +1,98 @@ +import { shortcut, isNotNull, bind } from "@/core"; +import { AbstractValueChooser } from "./abstract.valuechooser"; +import { MultiSelectCombo, MultiSelectNoBarCombo } from "@/widget"; + +@shortcut() +export class ValueChooserNoBarCombo extends AbstractValueChooser { + static xtype = "bi.value_chooser_no_bar_combo"; + + props = { baseCls: "bi-value-chooser-combo", width: 200, height: 24, items: null, cache: true }; + + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + render() { + const o = this.options; + if (isNotNull(o.items)) { + this.items = o.items; + } + + return { + type: MultiSelectNoBarCombo.xtype, + simple: o.simple, + allowEdit: o.allowEdit, + text: o.text, + defaultText: o.defaultText, + value: this._assertValue(o.value), + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + width: o.width, + height: o.height, + ref: _ref => { + this.combo = _ref; + }, + listeners: [ + { + eventName: MultiSelectCombo.EVENT_FOCUS, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectCombo.EVENT_BLUR, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiSelectCombo.EVENT_STOP, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_STOP); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CLICK_ITEM, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectCombo.EVENT_SEARCHING, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiSelectCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(ValueChooserNoBarCombo.EVENT_CONFIRM); + }, + } + ], + }; + } + + setValue(v) { + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + getAllValue() { + return this.getValue(); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.combo.populate(); + } +} diff --git a/packages/fineui/src/component/valuechooser/index.js b/packages/fineui/src/component/valuechooser/index.js new file mode 100644 index 000000000..1b920d806 --- /dev/null +++ b/packages/fineui/src/component/valuechooser/index.js @@ -0,0 +1,5 @@ +export { ValueChooserInsertCombo } from "./combo.valuechooser.insert"; +export { ValueChooserCombo } from "./combo.valuechooser"; +export { ValueChooserNoBarCombo } from "./combo.valuechooser.nobar"; +export { AbstractValueChooser } from "./abstract.valuechooser"; +export { ValueChooserPane } from "./pane.valuechooser"; diff --git a/packages/fineui/src/component/valuechooser/pane.valuechooser.js b/packages/fineui/src/component/valuechooser/pane.valuechooser.js new file mode 100644 index 000000000..9936aeebd --- /dev/null +++ b/packages/fineui/src/component/valuechooser/pane.valuechooser.js @@ -0,0 +1,69 @@ +import { shortcut, extend, emptyFn, createWidget, bind, isNotNull, Selection, difference, map } from "@/core"; +import { AbstractValueChooser } from "./abstract.valuechooser"; +import { MultiSelectList } from "@/widget"; + +@shortcut() +export class ValueChooserPane extends AbstractValueChooser { + static xtype = "bi.value_chooser_pane"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-value-chooser-pane", + items: null, + itemsCreator: emptyFn, + cache: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.list = createWidget({ + type: MultiSelectList.xtype, + element: this, + value: o.value, + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: bind(this._valueFormatter, this), + }); + + this.list.on(MultiSelectList.EVENT_CHANGE, () => { + this.fireEvent(ValueChooserPane.EVENT_CHANGE); + }); + if (isNotNull(o.items)) { + this.items = o.items; + this.list.populate(); + } + } + + setValue(v) { + this.list.setValue(v); + } + + getValue() { + const val = this.list.getValue() || {}; + + return { + type: val.type, + value: val.value, + }; + } + + getAllValue() { + const val = this.combo.getValue() || {}; + if (val.type === Selection.Multi) { + return val.value || []; + } + + return difference(map(this.items, "value"), val.value || []); + } + + populate(items) { + // 直接用combo的populate不会作用到AbstractValueChooser上 + if (isNotNull(items)) { + this.items = items; + } + this.list.populate(); + } +} diff --git a/packages/fineui/src/core/0.foundation.js b/packages/fineui/src/core/0.foundation.js new file mode 100644 index 000000000..16c0d76a9 --- /dev/null +++ b/packages/fineui/src/core/0.foundation.js @@ -0,0 +1,24 @@ +/** + * Created by richie on 15/7/8. + */ +let _global = undefined; +if (typeof window !== "undefined") { + _global = window; +} else if (typeof global !== "undefined") { + _global = global; +} else if (typeof self !== "undefined") { + _global = self; +} else { + _global = this; +} + +if (_global) { + _global._global = _global; +} + +const prepares = []; + +export { + _global, + prepares +}; diff --git a/packages/fineui/src/core/1.lodash.js b/packages/fineui/src/core/1.lodash.js new file mode 100644 index 000000000..ca3a3ade0 --- /dev/null +++ b/packages/fineui/src/core/1.lodash.js @@ -0,0 +1,10361 @@ +/* eslint-disable */ +/** + * @license + * Lodash (Custom Build) + * Build: `lodash core plus="debounce,throttle,get,set,findIndex,findLastIndex,findKey,findLastKey,isArrayLike,invert,invertBy,uniq,uniqBy,omit,omitBy,zip,unzip,rest,range,random,reject,intersection,drop,countBy,union,zipObject,initial,cloneDeep,clamp,isPlainObject,take,takeRight,without,difference,defaultsDeep,trim,merge,groupBy,uniqBy,before,after,unescape,chunk,pick,pickBy,identity"` + * Copyright JS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +;(function () { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.17.5'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295; + + /** Used to associate wrap methods with their bit flags. */ + var wrapFlags = [ + ['ary', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] + ]; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, + reUnescapedHtml = /[&<>"']/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** Used to match wrap detail comments. */ + var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, + reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function () { + try { + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) { + } + }()); + + /* Node.js helper references. */ + var nodeIsDate = nodeUtil && nodeUtil.isDate, + nodeIsMap = nodeUtil && nodeUtil.isMap, + nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, + nodeIsSet = nodeUtil && nodeUtil.isSet, + nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /*--------------------------------------------------------------------------*/ + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: + return func.call(thisArg); + case 1: + return func.call(thisArg, args[0]); + case 2: + return func.call(thisArg, args[0], args[1]); + case 3: + return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + var asciiSize = baseProperty('length'); + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function (value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function (object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function (key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function (value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function (value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function (key) { + return object[key]; + }); + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) { + } + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) { + } + return index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + ++result; + } + } + return result; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + var escapeHtmlChar = basePropertyOf(htmlEscapes); + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function (value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function (arg) { + return func(transform(arg)); + }; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Gets the value at `key`, unless `key` is "__proto__". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + return key == '__proto__' + ? undefined + : object[key]; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function (value) { + result[++index] = value; + }); + return result; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /*--------------------------------------------------------------------------*/ + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function () { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, + symIterator = Symbol ? Symbol.iterator : undefined, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + var defineProperty = (function () { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) { + } + }()); + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeIsFinite = root.isFinite, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function () { + function object() { + } + + return function (proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + // Ensure wrappers are instances of `baseLodash`. + lodash.prototype = baseLodash.prototype; + lodash.prototype.constructor = lodash; + + LodashWrapper.prototype = baseCreate(baseLodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || (!isRight && arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + // Ensure `LazyWrapper` is an instance of `baseLodash`. + LazyWrapper.prototype = baseCreate(baseLodash.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function (value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function (subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + + return result; + } + + if (isMap(value)) { + value.forEach(function (subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + + return result; + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function (subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function () { + func.apply(undefined, args); + }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function (value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !isSymbol(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function (value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function (key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ + function baseGt(value, other) { + return value > other; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function (value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ + function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ + function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ + function baseLt(value, other) { + return value < other; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function (value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function (object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function (object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function (srcValue, key) { + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } else { + newValue = []; + } + } else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + newValue = initCloneObject(srcValue); + } + } else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(baseIteratee)); + + var result = baseMap(collection, function (value, key, collection) { + var criteria = arrayMap(iteratees, function (iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function (object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, paths) { + return basePickBy(object, paths, function (value, path) { + return hasIn(object, path); + }); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function (object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function (func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function (func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function (value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function (result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ + function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function (collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, baseIteratee(iteratee, 2), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function (object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function (collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function (object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + + return wrapper; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtor(Ctor) { + return function () { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: + return new Ctor; + case 1: + return new Ctor(args[0]); + case 2: + return new Ctor(args[0], args[1]); + case 3: + return new Ctor(args[0], args[1], args[2]); + case 4: + return new Ctor(args[0], args[1], args[2], args[3]); + case 5: + return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: + return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: + return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + + return wrapper; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function (collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = baseIteratee(predicate, 3); + collection = keys(collection); + predicate = function (key) { + return iteratee(iterable[key], key, iterable); + }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } + + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function (object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function (start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, argPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); + } + + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && (1 / setToArray(new Set([, -0]))[1]) == INFINITY) ? noop : function (values) { + return new Set(values); + }; + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ + function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; + } + + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ + function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function (othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function (func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) { + } + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function (object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function (symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols ? stubArray : function (object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function (value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag; + case mapCtorString: + return mapTag; + case promiseCtorString: + return promiseTag; + case setCtorString: + return setTag; + case weakMapCtorString: + return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': + start += size; + break; + case 'dropRight': + end -= size; + break; + case 'take': + end = nativeMin(end, start + size); + break; + case 'takeRight': + start = nativeMax(start, end - size); + break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ + function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: + case float64Tag: + case int8Tag: + case int16Tag: + case int32Tag: + case uint8Tag: + case uint8ClampedTag: + case uint16Tag: + case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ + function insertWrapDetails(source, details) { + var length = details.length; + if (!length) { + return source; + } + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); + } + + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ + function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function (object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function (key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = value; + } + // Use source `ary` if it's smaller. + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function () { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = shortOut(baseSetData); + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ + function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function () { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function (string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function (match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) { + } + try { + return (func + ''); + } catch (e) { + } + } + return ''; + } + + /** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ + function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function (pair) { + var value = '_.' + pair[0]; + if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); + } + + /** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ + var difference = baseRest(function (array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, baseIteratee(predicate, 3), index); + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, baseIteratee(predicate, 3), index, true); + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return (array && array.length) ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseIndexOf(array, value, index); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ + var intersection = baseRest(function (arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array == null ? array : nativeReverse.call(array); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ + var union = baseRest(function (arrays) { + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function (group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function (index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.pull`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.xor + * @example + * + * _.without([2, 1, 2, 3], 1, 2); + * // => [3] + */ + var without = baseRest(function (array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ + var zip = baseRest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @since 1.0.0 + * @category Seq + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + */ + var wrapperAt = flatRest(function (paths) { + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function (object) { + return baseAt(object, paths); + }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function (array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chain sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function (result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, baseIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, baseIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + var find = createFind(findIndex); + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, baseIteratee(iteratee, 3)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function (result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } + }); + + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, baseIteratee(iteratee, 3)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.filter + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, negate(baseIteratee(predicate, 3))); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, baseIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] + */ + var sortBy = baseRest(function (collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = function () { + return root.Date.now(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function () { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function () { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = baseRest(function (func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ + var defer = baseRest(function (func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ + var delay = baseRest(function (func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function () { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function () { + var args = arguments; + switch (args.length) { + case 0: + return !predicate.call(this); + case 1: + return !predicate.call(this, args[0]); + case 2: + return !predicate.call(this, args[0], args[1]); + case 3: + return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? start : toInteger(start); + return baseRest(func, start); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function () { + return arguments; + }()) ? baseIsArguments : function (value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function (object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function (object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function (args) { + args.push(undefined, customDefaultsMerge); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function (result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function (result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, baseIteratee); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function (object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function (object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function (object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function (path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(baseIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function (object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function (prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function (value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined; + } + while (++index < length) { + var value = object == null ? undefined : object[toKey(path[index])]; + if (value === undefined) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } else { + lower = toFinite(lower); + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } + + /** + * The inverse of `_.escape`; this method converts the HTML entities + * `&`, `<`, `>`, `"`, and `'` in `string` to + * their corresponding characters. + * + * **Note:** No other HTML entities are unescaped. To unescape additional + * HTML entities use a third-party library like [_he_](https://mths.be/he). + * + * @static + * @memberOf _ + * @since 0.6.0 + * @category String + * @param {string} [string=''] The string to unescape. + * @returns {string} Returns the unescaped string. + * @example + * + * _.unescape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function unescape(string) { + string = toString(string); + return (string && reHasEscapedHtml.test(string)) + ? string.replace(reEscapedHtml, unescapeHtmlChar) + : string; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant(value) { + return function () { + return value; + }; + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name, the created function returns the + * property value for a given element. If `func` is an array or object, the + * created function returns `true` for elements that contain the equivalent + * source properties, otherwise it returns `false`. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); + * // => [{ 'user': 'barney', 'age': 36, 'active': true }] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, _.iteratee(['user', 'fred'])); + * // => [{ 'user': 'fred', 'age': 40 }] + * + * // The `_.property` iteratee shorthand. + * _.map(users, _.iteratee('user')); + * // => ['barney', 'fred'] + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { + * return !_.isRegExp(func) ? iteratee(func) : function(string) { + * return func.test(string); + * }; + * }); + * + * _.filter(['abc', 'def'], /ef/); + * // => ['def'] + */ + function iteratee(func) { + return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG)); + } + + /** + * Creates a function that performs a partial deep comparison between a given + * object and `source`, returning `true` if the given object has equivalent + * property values, else `false`. + * + * **Note:** The created function is equivalent to `_.isMatch` with `source` + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Util + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + * @example + * + * var objects = [ + * { 'a': 1, 'b': 2, 'c': 3 }, + * { 'a': 4, 'b': 5, 'c': 6 } + * ]; + * + * _.filter(objects, _.matches({ 'a': 4, 'c': 6 })); + * // => [{ 'a': 4, 'b': 5, 'c': 6 }] + */ + function matches(source) { + return baseMatches(baseClone(source, CLONE_DEEP_FLAG)); + } + + /** + * Adds all own enumerable string keyed function properties of a source + * object to the destination object. If `object` is a function, then methods + * are added to its prototype as well. + * + * **Note:** Use `_.runInContext` to create a pristine `lodash` function to + * avoid conflicts caused by modifying the original. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {Function|Object} [object=lodash] The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.chain=true] Specify whether mixins are chainable. + * @returns {Function|Object} Returns `object`. + * @example + * + * function vowels(string) { + * return _.filter(string, function(v) { + * return /[aeiou]/i.test(v); + * }); + * } + * + * _.mixin({ 'vowels': vowels }); + * _.vowels('fred'); + * // => ['e'] + * + * _('fred').vowels().value(); + * // => ['e'] + * + * _.mixin({ 'vowels': vowels }, { 'chain': false }); + * _('fred').vowels(); + * // => ['e'] + */ + function mixin(object, source, options) { + var props = keys(source), + methodNames = baseFunctions(source, props); + + if (options == null && + !(isObject(source) && (methodNames.length || !props.length))) { + options = source; + source = object; + object = this; + methodNames = baseFunctions(source, keys(source)); + } + var chain = !(isObject(options) && 'chain' in options) || !!options.chain, + isFunc = isFunction(object); + + arrayEach(methodNames, function (methodName) { + var func = source[methodName]; + object[methodName] = func; + if (isFunc) { + object.prototype[methodName] = function () { + var chainAll = this.__chain__; + if (chain || chainAll) { + var result = object(this.__wrapped__), + actions = result.__actions__ = copyArray(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); + result.__chain__ = chainAll; + return result; + } + return func.apply(object, arrayPush([this.value()], arguments)); + }; + } + }); + + return object; + } + + /** + * Reverts the `_` variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + if (root._ === this) { + root._ = oldDash; + } + return this; + } + + /** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ + function noop() { + // No operation performed. + } + + /** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ + function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + var range = createRange(); + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return toString(prefix) + id; + } + + /*------------------------------------------------------------------------*/ + + /** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ + function max(array) { + return (array && array.length) + ? baseExtremum(array, identity, baseGt) + : undefined; + } + + /** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ + function min(array) { + return (array && array.length) + ? baseExtremum(array, identity, baseLt) + : undefined; + } + + /*------------------------------------------------------------------------*/ + + // Add methods that return wrapped values in chain sequences. + lodash.after = after; + lodash.assignIn = assignIn; + lodash.before = before; + lodash.bind = bind; + lodash.chain = chain; + lodash.chunk = chunk; + lodash.compact = compact; + lodash.concat = concat; + lodash.countBy = countBy; + lodash.create = create; + lodash.debounce = debounce; + lodash.defaults = defaults; + lodash.defaultsDeep = defaultsDeep; + lodash.defer = defer; + lodash.delay = delay; + lodash.difference = difference; + lodash.drop = drop; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.flattenDeep = flattenDeep; + lodash.groupBy = groupBy; + lodash.initial = initial; + lodash.intersection = intersection; + lodash.invert = invert; + lodash.invertBy = invertBy; + lodash.iteratee = iteratee; + lodash.keys = keys; + lodash.map = map; + lodash.matches = matches; + lodash.merge = merge; + lodash.mixin = mixin; + lodash.negate = negate; + lodash.omit = omit; + lodash.omitBy = omitBy; + lodash.once = once; + lodash.pick = pick; + lodash.pickBy = pickBy; + lodash.range = range; + lodash.reject = reject; + lodash.rest = rest; + lodash.set = set; + lodash.slice = slice; + lodash.sortBy = sortBy; + lodash.take = take; + lodash.takeRight = takeRight; + lodash.tap = tap; + lodash.throttle = throttle; + lodash.thru = thru; + lodash.toArray = toArray; + lodash.union = union; + lodash.uniq = uniq; + lodash.uniqBy = uniqBy; + lodash.unzip = unzip; + lodash.values = values; + lodash.without = without; + lodash.zip = zip; + lodash.zipObject = zipObject; + + // Add aliases. + lodash.extend = assignIn; + + // Add methods to `lodash.prototype`. + mixin(lodash, lodash); + + /*------------------------------------------------------------------------*/ + + // Add methods that return unwrapped values in chain sequences. + lodash.clamp = clamp; + lodash.clone = clone; + lodash.cloneDeep = cloneDeep; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.findIndex = findIndex; + lodash.findKey = findKey; + lodash.findLastIndex = findLastIndex; + lodash.findLastKey = findLastKey; + lodash.forEach = forEach; + lodash.get = get; + lodash.has = has; + lodash.head = head; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isArrayLike = isArrayLike; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isPlainObject = isPlainObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.last = last; + lodash.max = max; + lodash.min = min; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.random = random; + lodash.reduce = reduce; + lodash.result = result; + lodash.size = size; + lodash.some = some; + lodash.trim = trim; + lodash.unescape = unescape; + lodash.uniqueId = uniqueId; + + // Add aliases. + lodash.each = forEach; + lodash.first = head; + + mixin(lodash, (function () { + var source = {}; + baseForOwn(lodash, function (func, methodName) { + if (!hasOwnProperty.call(lodash.prototype, methodName)) { + source[methodName] = func; + } + }); + return source; + }()), { 'chain': false }); + + /*------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type {string} + */ + lodash.VERSION = VERSION; + + // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. + arrayEach(['drop', 'take'], function (methodName, index) { + LazyWrapper.prototype[methodName] = function (n) { + n = n === undefined ? 1 : nativeMax(toInteger(n), 0); + + var result = (this.__filtered__ && !index) + ? new LazyWrapper(this) + : this.clone(); + + if (result.__filtered__) { + result.__takeCount__ = nativeMin(n, result.__takeCount__); + } else { + result.__views__.push({ + 'size': nativeMin(n, MAX_ARRAY_LENGTH), + 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') + }); + } + return result; + }; + + LazyWrapper.prototype[methodName + 'Right'] = function (n) { + return this.reverse()[methodName](n).reverse(); + }; + }); + + // Add `LazyWrapper` methods that accept an `iteratee` value. + arrayEach(['filter', 'map', 'takeWhile'], function (methodName, index) { + var type = index + 1, + isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG; + + LazyWrapper.prototype[methodName] = function (iteratee) { + var result = this.clone(); + result.__iteratees__.push({ + 'iteratee': getIteratee(iteratee, 3), + 'type': type + }); + result.__filtered__ = result.__filtered__ || isFilter; + return result; + }; + }); + + // Add `LazyWrapper` methods for `_.head` and `_.last`. + arrayEach(['head', 'last'], function (methodName, index) { + var takeName = 'take' + (index ? 'Right' : ''); + + LazyWrapper.prototype[methodName] = function () { + return this[takeName](1).value()[0]; + }; + }); + + // Add `LazyWrapper` methods for `_.initial` and `_.tail`. + arrayEach(['initial', 'tail'], function (methodName, index) { + var dropName = 'drop' + (index ? '' : 'Right'); + + LazyWrapper.prototype[methodName] = function () { + return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); + }; + }); + + LazyWrapper.prototype.compact = function () { + return this.filter(identity); + }; + + LazyWrapper.prototype.find = function (predicate) { + return this.filter(predicate).head(); + }; + + LazyWrapper.prototype.findLast = function (predicate) { + return this.reverse().find(predicate); + }; + + LazyWrapper.prototype.invokeMap = baseRest(function (path, args) { + if (typeof path == 'function') { + return new LazyWrapper(this); + } + return this.map(function (value) { + return baseInvoke(value, path, args); + }); + }); + + LazyWrapper.prototype.reject = function (predicate) { + return this.filter(negate(getIteratee(predicate))); + }; + + LazyWrapper.prototype.slice = function (start, end) { + start = toInteger(start); + + var result = this; + if (result.__filtered__ && (start > 0 || end < 0)) { + return new LazyWrapper(result); + } + if (start < 0) { + result = result.takeRight(-start); + } else if (start) { + result = result.drop(start); + } + if (end !== undefined) { + end = toInteger(end); + result = end < 0 ? result.dropRight(-end) : result.take(end - start); + } + return result; + }; + + LazyWrapper.prototype.takeRightWhile = function (predicate) { + return this.reverse().takeWhile(predicate).reverse(); + }; + + LazyWrapper.prototype.toArray = function () { + return this.take(MAX_ARRAY_LENGTH); + }; + + // Add `LazyWrapper` methods to `lodash.prototype`. + baseForOwn(LazyWrapper.prototype, function (func, methodName) { + var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), + isTaker = /^(?:head|last)$/.test(methodName), + lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName], + retUnwrapped = isTaker || /^find/.test(methodName); + + if (!lodashFunc) { + return; + } + lodash.prototype[methodName] = function () { + var value = this.__wrapped__, + args = isTaker ? [1] : arguments, + isLazy = value instanceof LazyWrapper, + iteratee = args[0], + useLazy = isLazy || isArray(value); + + var interceptor = function (value) { + var result = lodashFunc.apply(lodash, arrayPush([value], args)); + return (isTaker && chainAll) ? result[0] : result; + }; + + if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { + // Avoid lazy use if the iteratee has a "length" value other than `1`. + isLazy = useLazy = false; + } + var chainAll = this.__chain__, + isHybrid = !!this.__actions__.length, + isUnwrapped = retUnwrapped && !chainAll, + onlyLazy = isLazy && !isHybrid; + + if (!retUnwrapped && useLazy) { + value = onlyLazy ? value : new LazyWrapper(this); + var result = func.apply(value, args); + result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(result, chainAll); + } + if (isUnwrapped && onlyLazy) { + return func.apply(this, args); + } + result = this.thru(interceptor); + return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result; + }; + }); + + // Add `Array` methods to `lodash.prototype`. + arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function (methodName) { + var func = arrayProto[methodName], + chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', + retUnwrapped = /^(?:pop|shift)$/.test(methodName); + + lodash.prototype[methodName] = function () { + var args = arguments; + if (retUnwrapped && !this.__chain__) { + var value = this.value(); + return func.apply(isArray(value) ? value : [], args); + } + return this[chainName](function (value) { + return func.apply(isArray(value) ? value : [], args); + }); + }; + }); + + // Map minified method names to their real names. + baseForOwn(LazyWrapper.prototype, function (func, methodName) { + var lodashFunc = lodash[methodName]; + if (lodashFunc) { + var key = (lodashFunc.name + ''), + names = realNames[key] || (realNames[key] = []); + + names.push({ 'name': methodName, 'func': lodashFunc }); + } + }); + + realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [ + { + 'name': 'wrapper', + 'func': undefined + } + ]; + + // Add methods to `LazyWrapper`. + LazyWrapper.prototype.clone = lazyClone; + LazyWrapper.prototype.reverse = lazyReverse; + LazyWrapper.prototype.value = lazyValue; + + // Add lazy aliases. + lodash.prototype.first = lodash.prototype.head; + + if (symIterator) { + lodash.prototype[symIterator] = wrapperToIterator; + } + + /*--------------------------------------------------------------------------*/ + + // Some AMD build optimizers, like r.js, check for condition patterns like: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose Lodash on the global object to prevent errors when Lodash is + // loaded by a script tag in the presence of an AMD loader. + // See http://requirejs.org/docs/errors.html#mismatch for more details. + // Use `_.noConflict` to remove Lodash from the global object. + root._ = lodash; + + // Define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module. + define(function () { + return lodash; + }); + } + // Check for `exports` after `define` in case a build optimizer adds it. + else if (freeModule) { + // Export for Node.js. + (freeModule.exports = lodash)._ = lodash; + // Export for CommonJS support. + freeExports._ = lodash; + } else { + // Export to the global object. + // BI._ = lodash; + } +}.call(this)); diff --git a/packages/fineui/src/core/2.base.js b/packages/fineui/src/core/2.base.js new file mode 100644 index 000000000..23fc68095 --- /dev/null +++ b/packages/fineui/src/core/2.base.js @@ -0,0 +1,1518 @@ +/** + * 基本函数 + * Create By GUY 2014\11\17 + * + */ +import _ from "./1.lodash"; +import { Widget } from "./4.widget"; +import { createWidget } from "./5.inject"; +import { prepares, _global } from "./0.foundation"; +import { CRYPT_TYPE, aesDecrypt, aesEncrypt } from "./structure/aes"; +import { Date as DateEnum, getMonthDays } from "./func/date"; + +const lodashFns = {}; + +function traverse(func, context) { + return function (value, key, obj) { + return func.call(context, key, value, obj); + }; +} +function _apply(name) { + return function () { + return _[name](...arguments); + }; +} +function _applyFunc(name) { + return function () { + const args = Array.prototype.slice.call(arguments, 0); + args[1] = _.isFunction(args[1]) ? traverse(args[1], args[2]) : args[1]; + + return _[name](...args); + }; +} + +export function assert(v, is) { + if (isFunction(is)) { + if (!is(v)) { + throw new Error(`${v} error`); + } else { + return true; + } + } + if (!isArray(is)) { + is = [is]; + } + if (!deepContains(is, v)) { + throw new Error(`${v} error`); + } + + return true; +} + +export function warn(message) { + console.warn(message); +} + +export function UUID() { + const f = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; + let str = ""; + for (let i = 0; i < 16; i++) { + const r = _global.parseInt(f.length * Math.random(), 10); + str += f[r]; + } + + return str; +} + +export function isWidget(widget) { + return widget instanceof Widget; +} + +export function createWidgets(items, options, context) { + if (!isArray(items)) { + throw new Error("items must be array", items); + } + if (isWidget(options)) { + context = options; + options = {}; + } else { + options || (options = {}); + } + + return map(flatten(items), (i, item) => createWidget(item, deepClone(options), context)); +} + +export function createItems(data, innerAttr, outerAttr) { + innerAttr = isArray(innerAttr) ? innerAttr : makeArray(flatten(data).length, innerAttr || {}); + outerAttr = isArray(outerAttr) ? outerAttr : makeArray(flatten(data).length, outerAttr || {}); + + return map(data, (i, item) => { + if (isArray(item)) { + return createItems(item, innerAttr, outerAttr); + } + if (item instanceof Widget) { + return extend({}, innerAttr.shift(), outerAttr.shift(), { + type: null, + el: item, + }); + } + if (innerAttr[0] instanceof Widget) { + outerAttr.shift(); + + return extend({}, item, { + el: innerAttr.shift(), + }); + } + if (item.el instanceof Widget) { + innerAttr.shift(); + + return extend({}, outerAttr.shift(), { type: null }, item); + } + if (item.el) { + return extend({}, outerAttr.shift(), item, { + el: extend({}, innerAttr.shift(), item.el), + }); + } + + return extend({}, outerAttr.shift(), { + el: extend({}, innerAttr.shift(), item), + }); + }); +} + +// 用容器包装items +export function packageItems(items, layouts) { + for (let i = layouts.length - 1; i >= 0; i--) { + items = map(items, (k, it) => + extend({}, layouts[i], { + items: [ + extend({}, layouts[i].el, { + el: it, + }), + ], + }) + ); + } + + return items; +} + +export function formatEL(obj) { + if (obj && !obj.type && obj.el) { + return obj; + } + + return { + el: obj, + }; +} + +// 剥开EL +export function stripEL(obj) { + return (obj.type && obj) || obj.el || obj; +} + +export function trans2Element(widgets) { + return map(widgets, (i, wi) => wi.element); +} + +// 集合相关方法 +_.each(["where", "findWhere", "invoke", "pluck", "shuffle", "sample", "toArray", "size"], name => { + lodashFns[name] = _apply(name); +}); +_.each( + [ + "get", + "set", + "each", + "map", + "reduce", + "reduceRight", + "find", + "filter", + "reject", + "every", + "all", + "some", + "any", + "max", + "min", + "sortBy", + "groupBy", + "indexBy", + "countBy", + "partition", + "clamp", + ], + name => { + if (name === "any") { + lodashFns[name] = _applyFunc("some"); + } else { + lodashFns[name] = _applyFunc(name); + } + } +); +export const where = lodashFns.where; +export const findWhere = lodashFns.findWhere; +export const invoke = lodashFns.invoke; +export const pluck = lodashFns.pluck; +export const shuffle = lodashFns.shuffle; +export const sample = lodashFns.sample; +export const toArray = lodashFns.toArray; +export const size = lodashFns.size; +export const get = lodashFns.get; +export const set = lodashFns.set; +export const each = lodashFns.each; +export const map = lodashFns.map; +export const reduce = lodashFns.reduce; +export const reduceRight = lodashFns.reduceRight; +export const find = lodashFns.find; +export const filter = lodashFns.filter; +export const reject = lodashFns.reject; +export const every = lodashFns.every; +export const all = lodashFns.all; +export const some = lodashFns.some; +export const any = lodashFns.any; +export const max = lodashFns.max; +export const min = lodashFns.min; +export const sortBy = lodashFns.sortBy; +export const groupBy = lodashFns.groupBy; +export const indexBy = lodashFns.indexBy; +export const countBy = lodashFns.countBy; +export const partition = lodashFns.partition; +export const clamp = lodashFns.clamp; + +// 数数 +export function count(from, to, predicate) { + let t; + if (predicate) { + for (t = from; t < to; t++) { + predicate(t); + } + } + + return to - from; +} + +// 倒数 +export function inverse(from, to, predicate) { + return count(to, from, predicate); +} + +export function firstKey(obj) { + let res = undefined; + any(obj, (key, value) => { + res = key; + + return true; + }); + + return res; +} + +export function lastKey(obj) { + let res = undefined; + each(obj, (key, value) => { + res = key; + + return true; + }); + + return res; +} + +export function firstObject(obj) { + let res = undefined; + any(obj, (key, value) => { + res = value; + + return true; + }); + + return res; +} + +export function lastObject(obj) { + let res = undefined; + each(obj, (key, value) => { + res = value; + + return true; + }); + + return res; +} + +export function concat(obj1, obj2) { + if (isKey(obj1)) { + return map([].slice.apply(arguments), (idx, v) => v).join(""); + } + if (isArray(obj1)) { + return _.concat.apply([], arguments); + } + if (isObject(obj1)) { + return extend.apply({}, arguments); + } +} + +export function backEach(obj, predicate, context) { + predicate = iteratee(predicate, context); + for (let index = obj.length - 1; index >= 0; index--) { + predicate(index, obj[index], obj); + } + + return false; +} + +export function backAny(obj, predicate, context) { + predicate = iteratee(predicate, context); + for (let index = obj.length - 1; index >= 0; index--) { + if (predicate(index, obj[index], obj)) { + return true; + } + } + + return false; +} + +export function backEvery(obj, predicate, context) { + predicate = iteratee(predicate, context); + for (let index = obj.length - 1; index >= 0; index--) { + if (!predicate(index, obj[index], obj)) { + return false; + } + } + + return true; +} + +export function backFindKey(obj, predicate, context) { + predicate = iteratee(predicate, context); + const objKeys = keys(obj); + let key; + for (let i = objKeys.length - 1; i >= 0; i--) { + key = objKeys[i]; + if (predicate(obj[key], key, obj)) { + return key; + } + } +} + +export function backFind(obj, predicate, context) { + let key; + if (isArray(obj)) { + key = findLastIndex(obj, predicate, context); + } else { + key = backFindKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) { + return obj[key]; + } +} + +export function remove(obj, target, context) { + const targetIsFunction = isFunction(target); + target = targetIsFunction || isArray(target) ? target : [target]; + let i; + if (isArray(obj)) { + for (i = 0; i < obj.length; i++) { + if ( + (targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || + (!targetIsFunction && contains(target, obj[i])) + ) { + obj.splice(i--, 1); + } + } + } else { + each(obj, (i, v) => { + if ( + (targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || + (!targetIsFunction && contains(target, obj[i])) + ) { + delete obj[i]; + } + }); + } +} + +export function removeAt(obj, index) { + index = isArray(index) ? index : [index]; + const objIsArray = isArray(obj); + let i; + for (i = 0; i < index.length; i++) { + if (objIsArray) { + obj[index[i]] = "$deleteIndex"; + } else { + delete obj[index[i]]; + } + } + if (objIsArray) { + remove(obj, "$deleteIndex"); + } +} + +export function string2Array(str) { + return str.split("&-&"); +} + +export function array2String(array) { + return array.join("&-&"); +} + +export function abc2Int(string) { + let idx = 0; + const start = "A", + str = string.toUpperCase(); + for (let i = 0, len = str.length; i < len; ++i) { + idx = str.charAt(i).charCodeAt(0) - start.charCodeAt(0) + 26 * idx + 1; + if (idx > (2147483646 - str.charAt(i).charCodeAt(0) + start.charCodeAt(0)) / 26) { + return 0; + } + } + + return idx; +} + +export function int2Abc(num) { + const DIGITS = [ + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + ]; + let idx = num, + str = ""; + if (num === 0) { + return ""; + } + while (idx !== 0) { + let t = idx % 26; + if (t === 0) { + t = 26; + } + str = DIGITS[t - 1] + str; + idx = (idx - t) / 26; + } + + return str; +} + +// 数组相关的方法 +_.each( + [ + "first", + "initial", + "last", + "rest", + "compact", + "flatten", + "without", + "union", + "intersection", + "difference", + "zip", + "unzip", + "object", + "indexOf", + "lastIndexOf", + "sortedIndex", + "range", + "take", + "takeRight", + "uniqBy", + ], + name => { + lodashFns[name] = _apply(name); + } +); +_.each(["findIndex", "findLastIndex"], name => { + lodashFns[name] = _applyFunc(name); +}); +export const first = lodashFns.first; +export const initial = lodashFns.initial; +export const last = lodashFns.last; +export const rest = lodashFns.rest; +export const compact = lodashFns.compact; +export const flatten = lodashFns.flatten; +export const without = lodashFns.without; +export const union = lodashFns.union; +export const intersection = lodashFns.intersection; +export const difference = lodashFns.difference; +export const zip = lodashFns.zip; +export const unzip = lodashFns.unzip; +export const object = lodashFns.object; +export const indexOf = lodashFns.indexOf; +export const lastIndexOf = lodashFns.lastIndexOf; +export const sortedIndex = lodashFns.sortedIndex; +export const range = lodashFns.range; +export const take = lodashFns.take; +export const takeRight = lodashFns.takeRight; +export const uniqBy = lodashFns.uniqBy; +export const findIndex = lodashFns.findIndex; +export const findLastIndex = lodashFns.findLastIndex; + +// 构建一个长度为length的数组 +export function makeArray(length, value) { + const res = []; + for (let i = 0; i < length; i++) { + if (isNull(value)) { + res.push(i); + } else { + res.push(deepClone(value)); + } + } + + return res; +} + +export function makeObject(array, value) { + const map = {}; + for (let i = 0; i < array.length; i++) { + if (isNull(value)) { + map[array[i]] = array[i]; + } else if (isFunction(value)) { + map[array[i]] = value(i, array[i]); + } else { + map[array[i]] = deepClone(value); + } + } + + return map; +} + +export function makeArrayByArray(array, value) { + const res = []; + if (!array) { + return res; + } + for (let i = 0, len = array.length; i < len; i++) { + if (isArray(array[i])) { + res.push(makeArrayByArray(array[i], value)); + } else { + res.push(deepClone(value)); + } + } + + return res; +} + +export function uniq(array, isSorted, iteratee, context) { + if (array === null) { + return []; + } + if (!isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + iteratee && (iteratee = traverse(iteratee, context)); + + return _.uniq.call(_, array, isSorted, iteratee, context); +} + +// 对象相关方法 +_.each( + [ + "keys", + "allKeys", + "values", + "pairs", + "invert", + "create", + "functions", + "extend", + "extendOwn", + "defaults", + "clone", + "property", + "propertyOf", + "matcher", + "isEqual", + "isMatch", + "isEmpty", + "isElement", + "isNumber", + "isString", + "isArray", + "isObject", + "isPlainObject", + "isArguments", + "isFunction", + "isFinite", + "isBoolean", + "isDate", + "isRegExp", + "isError", + "isNaN", + "isUndefined", + "zipObject", + "cloneDeep", + "pickBy", + ], + name => { + lodashFns[name] = _apply(name); + } +); +export const keys = lodashFns.keys; +export const allKeys = lodashFns.allKeys; +export const values = lodashFns.values; +export const pairs = lodashFns.pairs; +export const invert = lodashFns.invert; +export const create = lodashFns.create; +export const functions = lodashFns.functions; +export const extend = lodashFns.extend; +export const extendOwn = lodashFns.extendOwn; +export const defaults = lodashFns.defaults; +export const clone = lodashFns.clone; +export const property = lodashFns.property; +export const propertyOf = lodashFns.propertyOf; +export const matcher = lodashFns.matcher; +export const isEqual = lodashFns.isEqual; +export const isMatch = lodashFns.isMatch; +export const isEmpty = lodashFns.isEmpty; +export const isElement = lodashFns.isElement; +export const isNumber = lodashFns.isNumber; +export const isString = lodashFns.isString; +export const isArray = lodashFns.isArray; +export const isObject = lodashFns.isObject; +export const isPlainObject = lodashFns.isPlainObject; +export const isArguments = lodashFns.isArguments; +export const isFunction = lodashFns.isFunction; +export const isFinite = lodashFns.isFinite; +export const isBoolean = lodashFns.isBoolean; +export const isDate = lodashFns.isDate; +export const isRegExp = lodashFns.isRegExp; +export const isError = lodashFns.isError; +export const isNaN = lodashFns.isNaN; +export const isUndefined = lodashFns.isUndefined; +export const zipObject = lodashFns.zipObject; +export const cloneDeep = lodashFns.cloneDeep; +export const pickBy = lodashFns.pickBy; + +_.each(["mapObject", "findKey", "pick", "omit", "tap"], name => { + lodashFns[name] = _applyFunc(name); +}); +export const mapObject = lodashFns.mapObject; +export const findKey = lodashFns.findKey; +export const pick = lodashFns.pick; +export const omit = lodashFns.omit; +export const tap = lodashFns.tap; + +export function inherit(sp, overrides) { + function sb() { + return sp.apply(this, arguments); + } + function F() {} + const spp = sp.prototype; + F.prototype = spp; + sb.prototype = new F(); + sb.superclass = spp; + extend(sb.prototype, overrides, { + superclass: sp, + }); + + return sb; +} + +export function init() { + // 先把准备环境准备好 + while (prepares && prepares.length > 0) { + prepares.shift()(); + } + while (_global.___fineuiExposedFunction && _global.___fineuiExposedFunction.length > 0) { + _global.___fineuiExposedFunction.shift()(); + } + + if (_global.BI) { + _global.BI.initialized = true; + } +} + +export function has(obj, keys) { + if (isArray(keys)) { + if (keys.length === 0) { + return false; + } + + return every(keys, (i, key) => _.has(obj, key)); + } + + return _.has(...arguments); +} + +export function freeze(value) { + // 在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 TypeError + // 在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回 + if (Object.freeze && isObject(value)) { + return Object.freeze(value); + } + + return value; +} + +// 数字和字符串可以作为key +export function isKey(key) { + return isNumber(key) || (isString(key) && key.length > 0); +} + +// 忽略大小写的等于 +export function isCapitalEqual(a, b) { + a = isNull(a) ? a : `${a}`.toLowerCase(); + b = isNull(b) ? b : `${b}`.toLowerCase(); + + return isEqual(a, b); +} + +export function isWidthOrHeight(w) { + if (typeof w === "number") { + return w >= 0; + } else if (typeof w === "string") { + return /^\d{1,3}(\.\d)?%$/.test(w) || w === "auto" || /^\d+(\.\d+)?px$/.test(w) || /^calc/.test(w); + } +} + +export function isNotNull(obj) { + return !isNull(obj); +} + +export function isNull(obj) { + return typeof obj === "undefined" || obj === null; +} + +export function isEmptyArray(arr) { + return isArray(arr) && isEmpty(arr); +} + +export function isNotEmptyArray(arr) { + return isArray(arr) && !isEmpty(arr); +} + +export function isEmptyObject(obj) { + return isEqual(obj, {}); +} + +export function isNotEmptyObject(obj) { + return isPlainObject(obj) && !isEmptyObject(obj); +} + +export function isWindow(obj) { + return obj !== null && obj === obj.window; +} + +export function isPromise(obj) { + return !!obj && (isObject(obj) || isFunction(obj)) && isFunction(obj.then); +} + +export const deepClone = _.cloneDeep; +export const deepExtend = _.merge; + +export function isDeepMatch(object, attrs) { + const attrsKeys = keys(attrs), + length = attrsKeys.length; + if (object === null) { + return !length; + } + const obj = Object(object); + for (let i = 0; i < length; i++) { + const key = attrsKeys[i]; + if (!isEqual(attrs[key], obj[key]) || !(key in obj)) { + return false; + } + } + + return true; +} + +export function contains(obj, target, fromIndex) { + if (!_.isArrayLike(obj)) obj = values(obj); + + return indexOf(obj, target, typeof fromIndex === "number" && fromIndex) >= 0; +} + +export function deepContains(obj, copy) { + if (isObject(copy)) { + return any(obj, (i, v) => isEqual(v, copy)); + } + + return contains(obj, copy); +} + +export function deepIndexOf(obj, target) { + for (let i = 0; i < obj.length; i++) { + if (isEqual(target, obj[i])) { + return i; + } + } + + return -1; +} + +export function deepRemove(obj, target) { + let done = false; + let i; + if (isArray(obj)) { + for (i = 0; i < obj.length; i++) { + if (isEqual(target, obj[i])) { + obj.splice(i--, 1); + done = true; + } + } + } else { + each(obj, (i, v) => { + if (isEqual(target, obj[i])) { + delete obj[i]; + done = true; + } + }); + } + + return done; +} + +export function deepWithout(obj, target) { + if (isArray(obj)) { + const result = []; + for (let i = 0; i < obj.length; i++) { + if (!isEqual(target, obj[i])) { + result.push(obj[i]); + } + } + + return result; + } + const result = {}; + each(obj, (i, v) => { + if (!isEqual(target, obj[i])) { + result[i] = v; + } + }); + + return result; +} + +export function deepUnique(array) { + const result = []; + each(array, (i, item) => { + if (!deepContains(result, item)) { + result.push(item); + } + }); + + return result; +} + +// 比较两个对象得出不一样的key值 +export function deepDiff(object, other) { + object || (object = {}); + other || (other = {}); + const result = []; + const used = []; + for (const b in object) { + if (has(object, b)) { + if (!isEqual(object[b], other[b])) { + result.push(b); + } + used.push(b); + } + } + for (const b in other) { + if (has(other, b) && !contains(used, b)) { + result.push(b); + } + } + + return result; +} + +// 通用方法 +_.each(["uniqueId", "result", "chain", "iteratee", "unescape", "before", "after", "chunk"], name => { + lodashFns[name] = (...args) => _[name](...args); +}); +export const uniqueId = lodashFns.uniqueId; +export const result = lodashFns.result; +export const chain = lodashFns.chain; +export const iteratee = lodashFns.iteratee; +export const unescape = lodashFns.unescape; +export const before = lodashFns.before; +export const after = lodashFns.after; +export const chunk = lodashFns.chunk; + +// 事件相关方法 +_.each(["bind", "once", "partial", "debounce", "throttle", "delay", "defer", "wrap"], name => { + lodashFns[name] = (...args) => _[name](...args); +}); +export const bind = lodashFns.bind; +export const once = lodashFns.once; +export const partial = lodashFns.partial; +export const debounce = lodashFns.debounce; +export const throttle = lodashFns.throttle; +export const delay = lodashFns.delay; +export const defer = lodashFns.defer; +export const wrap = lodashFns.wrap; + +export const nextTick = (function () { + const callbacks = []; + let pending = false; + let timerFunc = void 0; + + function nextTickHandler() { + pending = false; + const copies = callbacks.slice(0); + callbacks.length = 0; + for (let i = 0; i < copies.length; i++) { + copies[i](); + } + } + + if (typeof Promise !== "undefined") { + const p = Promise.resolve(); + timerFunc = function timerFunc() { + p.then(nextTickHandler); + }; + } else if (typeof MutationObserver !== "undefined") { + let counter = 1; + const observer = new MutationObserver(nextTickHandler); + const textNode = document.createTextNode(String(counter)); + observer.observe(textNode, { + characterData: true, + }); + timerFunc = function timerFunc() { + counter = (counter + 1) % 2; + textNode.data = String(counter); + }; + } else if (typeof setImmediate !== "undefined") { + timerFunc = function timerFunc() { + setImmediate(nextTickHandler); + }; + } else { + // Fallback to setTimeout. + timerFunc = function timerFunc() { + setTimeout(nextTickHandler, 0); + }; + } + + return function queueNextTick(cb) { + let _resolve = void 0; + const args = [].slice.call(arguments, 1); + callbacks.push(() => { + if (cb) { + try { + cb(...args); + } catch (e) { + console.error(e); + } + } else if (_resolve) { + _resolve(...args); + } + }); + if (!pending) { + pending = true; + timerFunc(); + } + // $flow-disable-line + if (!cb && typeof Promise !== "undefined") { + return new Promise((resolve, reject) => { + _resolve = resolve; + }); + } + }; +})(); + +// 数字相关方法 +_.each(["random"], name => { + lodashFns[name] = _apply(name); +}); +export const random = lodashFns.random; + +export function parseInt(number) { + let radix = 10; + if (/^0x/g.test(number)) { + radix = 16; + } + try { + return _global.parseInt(number, radix); + } catch (e) { + throw new Error(`${number}parse int error`); + } +} + +export function parseSafeInt(value) { + const MAX_SAFE_INTEGER = 9007199254740991; + + return value ? clamp(parseInt(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; +} + +export function parseFloat(number) { + try { + return _global.parseFloat(number); + } catch (e) { + throw new Error(`${number}parse float error`); + } +} + +export function isNaturalNumber(number) { + return /^\d+$/.test(number); +} + +export function isPositiveInteger(number) { + return /^\+?[1-9][0-9]*$/.test(number); +} + +export function isNegativeInteger(number) { + return /^-[1-9][0-9]*$/.test(number); +} + +export function isInteger(number) { + return /^-?\d+$/.test(number); +} + +export function isNumeric(number) { + return !_global.isNaN(_global.parseFloat(number)) && _global.isFinite(number); +} + +export function isFloat(number) { + return /^([+-]?)\d*\.\d+$/.test(number); +} + +export function isOdd(number) { + if (!isInteger(number)) { + return false; + } + + return (number & 1) === 1; +} + +export function isEven(number) { + if (!isInteger(number)) { + return false; + } + + return (number & 1) === 0; +} + +export function sum(array, iteratee, context) { + let sum = 0; + each(array, (i, item) => { + if (iteratee) { + sum += Number(iteratee.apply(context, [i, item])); + } else { + sum += Number(item); + } + }); + + return sum; +} + +export function average(array, iteratee, context) { + const sumResult = sum(array, iteratee, context); + + return sumResult / array.length; +} + +export function trim(...args) { + return _.trim(...args); +} + +export function toUpperCase(string) { + return `${string}`.toLocaleUpperCase(); +} + +export function toLowerCase(string) { + return `${string}`.toLocaleLowerCase(); +} + +export function isEndWithBlank(string) { + return /(\s|\u00A0)$/.test(string); +} + +export function isLiteral(exp) { + return /^\s?(true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/.test(exp); +} + +export function stripQuotes(str) { + const a = str.charCodeAt(0); + const b = str.charCodeAt(str.length - 1); + + return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str; +} + +// background-color => backgroundColor +export function camelize(str) { + return str.replace(/-(.)/g, (_, character) => character.toUpperCase()); +} + +// backgroundColor => background-color +export function hyphenate(str) { + return str.replace(/([A-Z])/g, "-$1").toLowerCase(); +} + +export function isNotEmptyString(str) { + return isString(str) && !isEmpty(str); +} + +export function isEmptyString(str) { + return isString(str) && isEmpty(str); +} + +/** + * 通用解密方法 + * @param type 解密方式 + * @param text 文本 + * @param key 种子 + * @return {*} + */ +export function encrypt(type, text, key) { + switch (type) { + case CRYPT_TYPE.AES: + default: + return aesEncrypt(text, key); + } +} + +/** + * 通用解密方法 + * @param type 解密方式 + * @param text 文本 + * @param key 种子 + * @return {*} + */ +export function decrypt(type, text, key) { + switch (type) { + case CRYPT_TYPE.AES: + default: + return aesDecrypt(text, key); + } +} + +/** + * 对字符串中的'和\做编码处理 + * @static + * @param {String} string 要做编码处理的字符串 + * @return {String} 编码后的字符串 + */ +export function escape(string) { + return string.replace(/('|\\)/g, "\\$1"); +} + +/** + * 让字符串通过指定字符做补齐的函数 + * + * var s = BI.leftPad('123', 5, '0');//s的值为:'00123' + * + * @static + * @param {String} val 原始值 + * @param {Number} size 总共需要的位数 + * @param {String} ch 用于补齐的字符 + * @return {String} 补齐后的字符串 + */ +export function leftPad(val, size, ch) { + let result = String(val); + if (!ch) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + + return result.toString(); +} + +/** + * 对字符串做替换的函数 + * + * var cls = 'my-class', text = 'Some text'; + * var res = BI.format('
    {1}
    ', cls, text); + * //res的值为:'
    Some text
    '; + * + * @static + * @param {String} format 要做替换的字符串,替换字符串1,替换字符串2... + * @return {String} 做了替换后的字符串 + */ +export function format(format) { + const args = Array.prototype.slice.call(arguments, 1); + + return format.replace(/\{(\d+)\}/g, (m, i) => args[i]); +} + +/** + * 是否是闰年 + * @param year + * @returns {boolean} + */ +export function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; +} + +/** + * 检测是否在有效期 + * + * @param YY 年 + * @param MM 月 + * @param DD 日 + * @param minDate '1900-01-01' + * @param maxDate '2099-12-31' + * @returns {Array} 若无效返回无效状态,数组第一位为无效属性,第二位缺省为超下限,1为超上限 + */ +export function checkDateVoid(YY, MM, DD, minDate, maxDate) { + let back = []; + YY = YY | 0; + MM = MM | 0; + DD = DD | 0; + minDate = isString(minDate) ? minDate.match(/\d+/g) : minDate; + maxDate = isString(maxDate) ? maxDate.match(/\d+/g) : maxDate; + if (YY < minDate[0]) { + back = ["y"]; + } else if (YY > maxDate[0]) { + back = ["y", 1]; + } else if (YY >= minDate[0] && YY <= maxDate[0]) { + if (YY == minDate[0]) { + if (MM < minDate[1]) { + back = ["m"]; + } else if (MM == minDate[1]) { + if (DD < minDate[2]) { + back = ["d"]; + } + } + } + if (YY == maxDate[0]) { + if (MM > maxDate[1]) { + back = ["m", 1]; + } else if (MM == maxDate[1]) { + if (DD > maxDate[2]) { + back = ["d", 1]; + } + } + } + } + + return back; +} + +export function checkDateLegal(str) { + const ar = str.match(/\d+/g); + const YY = ar[0] | 0, + MM = ar[1] | 0, + DD = ar[2] | 0; + if (ar.length <= 1) { + return true; + } + if (ar.length <= 2) { + return MM >= 1 && MM <= 12; + } + const MD = DateEnum._MD.slice(0); + MD[1] = isLeapYear(YY) ? 29 : 28; + + return MM >= 1 && MM <= 12 && DD <= MD[MM - 1]; +} + +/** 解析日期时间字符串 + * + * @param str + * @param fmt + * @returns {Date|Date} + * 年月日缺省值为当前日期, 时分秒缺省值为0 + */ +export function parseDateTime(str, fmt) { + const today = getDate(); + let y; + let m; + let d; + // wei : 对于fmt为‘YYYYMM’或者‘YYYYMMdd’的格式,str的值为类似'201111'的形式,因为年月之间没有分隔符,所以正则表达式分割无效,导致bug7376。 + const a = str.split(/\W+/); + if (fmt.toLowerCase() === "%y%x" || fmt.toLowerCase() === "%y%x%d") { + const yearlength = 4; + const otherlength = 2; + a[0] = str.substring(0, yearlength); + a[1] = str.substring(yearlength, yearlength + otherlength); + a[2] = str.substring(yearlength + otherlength, yearlength + otherlength * 2); + } + const b = fmt.match(/%./g); + let i = 0, + j = 0; + let hr = 0; + let min = 0; + let sec = 0; + for (i = 0; i < a.length; ++i) { + switch (b[i]) { + case "%d": + case "%e": + d = _global.parseInt(a[i], 10); + break; + + case "%X": + m = _global.parseInt(a[i], 10) - 1; + break; + case "%x": + m = _global.parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = _global.parseInt(a[i], 10); + y < 100 && (y += y > 29 ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) { + m = j; + break; + } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = _global.parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) { + hr += 12; + } else if (/am/i.test(a[i]) && hr >= 12) { + hr -= 12; + } + break; + case "%Q": + case "%q": + m = (_global.parseInt(a[i], 10) - 1) * 3; + break; + case "%M": + min = _global.parseInt(a[i], 10); + break; + case "%S": + sec = _global.parseInt(a[i], 10); + break; + default: + } + } + // if (!a[i]) { + // continue; + // } + if (_global.isNaN(y)) { + y = today.getFullYear(); + } + if (_global.isNaN(m)) { + m = today.getMonth(); + } + if (_global.isNaN(d)) { + d = Math.min(getMonthDays(getDate(y, m)), today.getDate()); + } + if (_global.isNaN(hr)) { + hr = today.getHours(); + } + if (_global.isNaN(min)) { + min = today.getMinutes(); + } + if (_global.isNaN(sec)) { + sec = today.getSeconds(); + } + if (y !== 0) { + return getDate(y, m, d, hr, min, sec); + } + y = 0; + m = -1; + d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) !== -1) { + let t = -1; + for (j = 0; j < 12; ++j) { + if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) { + t = j; + break; + } + } + if (t !== -1) { + if (m !== -1) { + d = m + 1; + } + m = t; + } + } else if (_global.parseInt(a[i], 10) <= 12 && m === -1) { + m = a[i] - 1; + } else if (_global.parseInt(a[i], 10) > 31 && y === 0) { + y = _global.parseInt(a[i], 10); + y < 100 && (y += y > 29 ? 1900 : 2000); + } else if (d === 0) { + d = a[i]; + } + } + if (y === 0) { + y = today.getFullYear(); + } + if (m === -1) { + m = today.getMonth(); + } + if (m !== -1 && d !== 0) { + return getDate(y, m, d, hr, min, sec); + } + + return today; +} + +export function getDate(...args) { + const length = args.length; + let dt; + switch (length) { + // new Date() + case 0: + dt = new Date(); + break; + // new Date(long) + case 1: + dt = new Date(args[0]); + break; + // new Date(year, month) + case 2: + dt = new Date(args[0], args[1]); + break; + // new Date(year, month, day) + case 3: + dt = new Date(args[0], args[1], args[2]); + break; + // new Date(year, month, day, hour) + case 4: + dt = new Date(args[0], args[1], args[2], args[3]); + break; + // new Date(year, month, day, hour, minute) + case 5: + dt = new Date(args[0], args[1], args[2], args[3], args[4]); + break; + // new Date(year, month, day, hour, minute, second) + case 6: + dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); + break; + // new Date(year, month, day, hour, minute, second, millisecond) + case 7: + dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + break; + default: + dt = new Date(); + break; + } + if (isNotNull(BI.timeZone) && (arguments.length === 0 || (arguments.length === 1 && isNumber(arguments[0])))) { + const localTime = dt.getTime(); + // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 + const localOffset = dt.getTimezoneOffset() * 60000; // 获得当地时间偏移的毫秒数 + const utc = localTime + localOffset; // utc即GMT时间标准时区 + + return new Date(utc + BI.timeZone); // + Pool.timeZone.offset); + } + + return dt; +} + +export function getTime() { + const length = arguments.length; + const args = arguments; + let dt; + switch (length) { + // new Date() + case 0: + dt = new Date(); + break; + // new Date(long) + case 1: + dt = new Date(args[0]); + break; + // new Date(year, month) + case 2: + dt = new Date(args[0], args[1]); + break; + // new Date(year, month, day) + case 3: + dt = new Date(args[0], args[1], args[2]); + break; + // new Date(year, month, day, hour) + case 4: + dt = new Date(args[0], args[1], args[2], args[3]); + break; + // new Date(year, month, day, hour, minute) + case 5: + dt = new Date(args[0], args[1], args[2], args[3], args[4]); + break; + // new Date(year, month, day, hour, minute, second) + case 6: + dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); + break; + // new Date(year, month, day, hour, minute, second, millisecond) + case 7: + dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + break; + default: + dt = new Date(); + break; + } + if (isNotNull(BI.timeZone)) { + // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 + return dt.getTime() - BI.timeZone - new Date().getTimezoneOffset() * 60000; + } + + return dt.getTime(); +} diff --git a/packages/fineui/src/core/3.ob.js b/packages/fineui/src/core/3.ob.js new file mode 100644 index 000000000..1cf2d94ae --- /dev/null +++ b/packages/fineui/src/core/3.ob.js @@ -0,0 +1,216 @@ +import { isFunction, isArray, isObject, isArguments, reduce, bind, each } from "./2.base"; + +function obExtend() { + const target = arguments[0] || {}, length = arguments.length; + let i = 1, name, copy; + for (; i < length; i++) { + // Only deal with non-null/undefined values + const options = arguments[i]; + if (options !== null) { + // Extend the base object + for (name in options) { + copy = options[name]; + + // Prevent never-ending loop + if (target === copy) { + continue; + } + + + if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + return target; +} + +export class OB { + // props = {}; + + // init = null; + + // destroyed = null; + + constructor(config) { + this._constructor(config); + } + + _constructor(config) { + this._initProps(config); + this._init(); + this._initRef(); + } + + _defaultConfig(config) { + return {}; + } + + _initProps(config) { + let props = this.props; + if (isFunction(this.props)) { + props = this.props(config); + } + const defaultProps = obExtend(this._defaultConfig(config), props); + const modifiedDefaultProps = (config && config.type && OB.configFunctions[`${config.type}.props`]) ? reduce(OB.configFunctions[`${config.type}.props`], (value, conf, index) => obExtend(conf, value.fn(defaultProps, config, value.opt)), {}) : null; + this.options = obExtend(defaultProps, modifiedDefaultProps, config); + } + + _init() { + this._initListeners(); + this.init && this.init(); + } + + _initListeners() { + if (this.options.listeners !== null) { + each(this.options.listeners, (eventName, lis) => { + if (isFunction(lis)) { + this.on(eventName, lis); + + return; + } + if (isArray(lis)) { + lis.forEach(l => { + this.on(eventName, l); + }); + + return; + } + (lis.target ? lis.target : this)[lis.once ? "once" : "on"](lis.eventName, bind(lis.action, this)); + }); + delete this.options.listeners; + } + } + + // 获得一个当前对象的引用 + _initRef() { + const o = this.options; + if (o.__ref) { + isFunction(o.__ref) ? o.__ref.call(this, this) : o.__ref.current = this; + } + if (o.ref) { + isFunction(o.ref) ? o.ref.call(this, this) : o.ref.current = this; + } + } + + // 释放当前对象 + _purgeRef() { + const o = this.options; + if (o.__ref) { + isFunction(o.__ref) ? o.__ref.call(null, null) : o.__ref.current = null; + o.__ref = null; + } + if (o.ref) { + isFunction(o.ref) ? o.ref.call(null, null) : o.ref.current = null; + o.ref = null; + } + } + + _getEvents() { + if (!isObject(this.events)) { + this.events = {}; + } + + return this.events; + } + + /** + * 给观察者绑定一个事件 + * @param {String} eventName 事件的名字 + * @param {Function} fn 事件对应的执行函数 + */ + on(eventName, fn) { + eventName = eventName.toLowerCase(); + let fns = this._getEvents()[eventName]; + if (!isArray(fns)) { + fns = []; + this._getEvents()[eventName] = fns; + } + fns.push(fn); + + return () => this.un(eventName, fn); + } + + /** + * 给观察者绑定一个只执行一次的事件 + * @param {String} eventName 事件的名字 + * @param {Function} fn 事件对应的执行函数 + */ + once(eventName, fn) { + const proxy = () => { + fn.apply(this, arguments); + this.un(eventName, proxy); + }; + this.on(eventName, proxy); + } + + /** + * 解除观察者绑定的指定事件 + * @param {String} eventName 要解除绑定事件的名字 + * @param {Function} fn 事件对应的执行函数,该参数是可选的,没有该参数时,将解除绑定所有同名字的事件 + */ + un(eventName, fn) { + eventName = eventName.toLowerCase(); + + /* alex:如果fn是null,就是把eventName上面所有方法都un掉*/ + if (fn === null) { + delete this._getEvents()[eventName]; + } else { + const fns = this._getEvents()[eventName]; + if (isArray(fns)) { + const newFns = []; + fns.forEach(ifn => { + if (ifn !== fn) { + newFns.push(ifn); + } + }); + this._getEvents()[eventName] = newFns; + } + } + } + + /** + * 清除观察者的所有事件绑定 + */ + purgeListeners() { + /* alex:清空events*/ + this.events = {}; + } + + /** + * 触发绑定过的事件 + * + * @param {String} eventName 要触发的事件的名字 + * @returns {Boolean} 如果事件函数返回false,则返回false并中断其他同名事件的执行,否则执行所有的同名事件并返回true + */ + fireEvent() { + const eventName = arguments[0].toLowerCase(); + const fns = this._getEvents()[eventName]; + if (isArray(fns)) { + if (isArguments(arguments[1])) { + for (let i = 0; i < fns.length; i++) { + if (fns[i].apply(this, arguments[1]) === false) { + return false; + } + } + } else { + const args = Array.prototype.slice.call(arguments, 1); + for (let i = 0; i < fns.length; i++) { + if (fns[i].apply(this, args) === false) { + return false; + } + } + } + } + + return true; + } + + destroy() { + this.destroyed && this.destroyed(); + this._purgeRef(); + this.purgeListeners(); + } +} diff --git a/packages/fineui/src/core/4.widget.js b/packages/fineui/src/core/4.widget.js new file mode 100644 index 000000000..49dfef990 --- /dev/null +++ b/packages/fineui/src/core/4.widget.js @@ -0,0 +1,1200 @@ +/** + * Widget超类 + * @class Widget + * @extends OB + * + * @cfg {JSON} options 配置属性 + */ + +import $ from "jquery"; +import { + isFunction, + isArray, + each, + extend, + isPlainObject, + isNull, + uniqueId, + isWidget, + isWidthOrHeight, + isKey, + remove, + any, + isNotNull +} from "./2.base"; +import { OB } from "./3.ob"; +import { Providers, _lazyCreateWidget } from "./5.inject"; +import { DOM } from "./utils"; +import { Events, emptyFn, pixFormat } from "./constant"; +import { Plugin } from "./6.plugin"; +import { _global } from "./0.foundation"; +import { SystemProvider } from "./system"; + +const cancelAnimationFrame = + _global.cancelAnimationFrame || + _global.webkitCancelAnimationFrame || + _global.mozCancelAnimationFrame || + _global.oCancelAnimationFrame || + _global.msCancelAnimationFrame || + _global.clearTimeout; + +const requestAnimationFrame = + _global.requestAnimationFrame || + _global.webkitRequestAnimationFrame || + _global.mozRequestAnimationFrame || + _global.oRequestAnimationFrame || + _global.msRequestAnimationFrame || + _global.setTimeout; + +function callLifeHook(self, life) { + let hooks = [], + hook; + hook = self[life]; + if (hook) { + hooks = hooks.concat(isArray(hook) ? hook : [hook]); + } + hook = self.options[life]; + if (hook) { + hooks = hooks.concat(isArray(hook) ? hook : [hook]); + } + each(hooks, (i, hook) => { + hook.call(self); + }); +} + +let context = null, + current = null; +const contextStack = [], + currentStack = []; + + +export class Widget extends OB { + + static _renderEngine = { + createElement(widget) { + if (isWidget(widget)) { + const o = widget.options; + if (o.element) { + return $(o.element); + } + if (o.tagName) { + return $(document.createElement(o.tagName)); + } + + return $(document.createDocumentFragment()); + } + + return $(widget); + }, + createFragment() { + return document.createDocumentFragment(); + } + }; + + static registerRenderEngine(engine) { + Widget._renderEngine = engine; + } + + static pushContext(_context) { + if (context) contextStack.push(context); + Widget.context = context = _context; + } + + static popContext() { + Widget.context = context = contextStack.pop(); + } + + static execWithContext(context, execFunc) { + Widget.pushContext(context); + try { + execFunc(); + } catch (e) { + throw e; + } finally { + Widget.popContext(); + } + } + + _defaultConfig() { + return extend(super._defaultConfig(), { + root: false, + tagName: "div", + attributes: null, + data: null, + key: null, + + tag: null, + disabled: false, + invisible: false, + animation: "", + animationDuring: 0, + invalid: false, + baseCls: "", + extraCls: "", + cls: "", + css: null + + // vdom: false + }); + } + + _constructor() { + } + + // 覆盖父类的_constructor方法,widget不走ob的生命周期 + _constructed() { + if (this.setup) { + pushTarget(this); + const delegate = this.setup(this.options); + if (isPlainObject(delegate)) { + // 如果setup返回一个json,即对外暴露的方法 + extend(this, delegate); + } else { + this.render = delegate; + } + popTarget(); + } + } + + _lazyConstructor() { + if (!this.__constructed) { + this.__constructed = true; + this._init(); + this._initRef(); + } + } + + // // 生命周期函数 + // beforeInit = null; + + // beforeRender = null; + + // beforeCreate = null + + // created = null + + // render = null + + // beforeMount = null + + // mounted = null + // // 不想重写mounted时用 + // _mounted = null + + // shouldUpdate = null + + // update = null + + // beforeUpdate = null + + // updated = null + + // beforeDestroy = null + + // destroyed = null + // // 不想重写destroyed时用 + // _destroyed = null + + _init() { + super._init(...arguments); + this._initVisual(); + this._initState(); + this._initRender(); + } + + _initRender() { + let initCallbackCalled = false; + let renderCallbackCalled = false; + + const init = () => { + // 加个保险 + if (initCallbackCalled === true) { + _global.console && + console.error( + "widget: please check the beforeInit method. The callback can only be executed once" + ); + + return; + } + initCallbackCalled = true; + + const render = () => { + // 加个保险 + if (renderCallbackCalled === true) { + _global.console && + console.error( + "widget: please check the beforeRender method. The callback can only be executed once" + ); + + return; + } + renderCallbackCalled = true; + this._render(); + this.__afterRender(); + }; + + if (this.options.beforeRender || this.beforeRender) { + this.__async = true; + const beforeRenderResult = ( + this.options.beforeRender || this.beforeRender + ).call(this, render); + if (beforeRenderResult instanceof Promise) { + beforeRenderResult.then(render).catch((e) => { + _global.console && console.error(e); + render(); + }); + } + } else { + this._render(); + this.__afterRender(); + } + }; + + if (this.options.beforeInit || this.beforeInit) { + this.__asking = true; + const beforeInitResult = ( + this.options.beforeInit || this.beforeInit + ).call(this, init); + if (beforeInitResult instanceof Promise) { + beforeInitResult.then(init).catch((e) => { + _global.console && console.error(e); + init(); + }); + } + } else { + init(); + } + } + + __afterRender() { + pushTarget(this); + const async = this.__async; + this.__async = false; + if (async && this._isMounted) { + callLifeHook(this, "beforeMount"); + this._mount(); + callLifeHook(this, "mounted"); + this.fireEvent(Events.MOUNT); + } else { + this._mount(); + } + popTarget(); + } + + _render() { + this.__asking = false; + pushTarget(this); + callLifeHook(this, "beforeCreate"); + this._initElement(); + this._initEffects(); + callLifeHook(this, "created"); + popTarget(); + } + + _initCurrent() { + const o = this.options; + this._initElementWidth(); + this._initElementHeight(); + if (o._baseCls || o.baseCls || o.extraCls) { + this.element.addClass( + `${o._baseCls || ""} ${o.baseCls || ""} ${o.extraCls || ""}` + ); + } + if (o.cls) { + if (isFunction(o.cls)) { + let cls = this.__watch(o.cls, (context, newValue) => { + this.element.removeClass(cls).addClass((cls = newValue)); + }); + this.element.addClass(cls); + } else { + this.element.addClass(o.cls); + } + } + // if (o.key != null) { + // this.element.attr("key", o.key); + // } + if (o.attributes) { + this.element.attr(o.attributes); + } + if (o.data) { + this.element.data(o.data); + } + if (o.css) { + if (isFunction(o.css)) { + let css = this.__watch(o.css, (context, newValue) => { + for (const k in css) { + if (isNull(newValue[k])) { + newValue[k] = ""; + } + } + this.element.css((css = newValue)); + }); + this.element.css(css); + } else { + this.element.css(o.css); + } + } + } + + __watch(getter, handler, options) { + if (_global.Fix) { + this._watchers = this._watchers || []; + const watcher = new Fix.Watcher( + null, + () => getter.call(this, this), + (handler && + ((v) => { + handler.call(this, this, v); + })) || + emptyFn, + extend({ deep: true }, options) + ); + this._watchers.push(() => { + watcher.teardown(); + }); + + return watcher.value; + } else { + return getter(); + } + } + + /** + * 初始化根节点 + * @private + */ + _initRoot() { + const o = this.options; + this.widgetName = o.widgetName || uniqueId("widget"); + this._isRoot = o.root; + this._children = {}; + if (isWidget(o.element)) { + this.element = this.options.element.element; + this._parent = o.element; + this._parent._children && + this._parent.addWidget(this.widgetName, this); + } else if (o.element) { + this.element = Widget._renderEngine.createElement(this); + this._isRoot = true; + } else { + this.element = Widget._renderEngine.createElement(this); + } + this.element._isWidget = true; + // const widgets = this.element.data("__widgets") || []; + // widgets.push(this); + // this.element.data("__widgets", widgets); + this._initCurrent(); + } + + _initElementWidth() { + const o = this.options; + if (isWidthOrHeight(o.width)) { + this.element.css("width", pixFormat(o.width)); + } + } + + _initElementHeight() { + const o = this.options; + if (isWidthOrHeight(o.height)) { + this.element.css("height", pixFormat(o.height)); + } + } + + _initVisual() { + const o = this.options; + if (o.invisible) { + const invisible = (o.invisible = isFunction(o.invisible) + ? this.__watch(o.invisible, (context, newValue) => { + this.setVisible(!newValue); + }) + : o.invisible); + if (invisible) { + // 用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性 + this.__setElementVisible(false); + } + } + } + + _initEffects() { + const o = this.options; + if (o.disabled || o.invalid) { + if (this.options.disabled) { + const disabled = (o.disabled = isFunction(o.disabled) + ? this.__watch(o.disabled, (context, newValue) => { + this.setEnable(!newValue); + }) + : o.disabled); + if (disabled) { + this.setEnable(false); + } + } + if (this.options.invalid) { + const invalid = (o.invalid = isFunction(o.invalid) + ? this.__watch(o.invalid, (context, newValue) => { + this.setValid(!newValue); + }) + : o.invalid); + if (invalid) { + this.setValid(false); + } + } + } + if (o.effect) { + if (isArray(o.effect)) { + if (isArray(o.effect[0])) { + each(o.effect, (i, effect) => { + this.__watch(effect[0], effect[1]); + }); + } else { + this.__watch(o.effect[0], o.effect[1]); + } + } else { + this.__watch(o.effect); + } + } + } + + _initState() { + this._isMounted = false; + this._isDestroyed = false; + } + + __initWatch() { + // initWatch拦截的方法 + } + + _initElement() { + this.__isMounting = true; + // 当开启worker模式时,可以通过$render来实现另一种效果 + const workerMode = + Providers.getProvider(SystemProvider.xtype).getWorkerMode(); + const render = isFunction(this.options.render) + ? this.options.render + : workerMode + ? this.$render || this.render + : this.render; + let els = render && render.call(this); + els = this.options.configRender + ? this.options.configRender.call(this, els) + : els; + els = Plugin.getRender(this.options.type, els); + if (isPlainObject(els)) { + els = [els]; + } + this.__initWatch(); + if (isArray(els)) { + each(els, (i, el) => { + if (el) { + _lazyCreateWidget(el, { + element: this + }); + } + }); + } + } + + _setParent(parent) { + this._parent = parent; + } + + /** + * + * @param force 是否强制挂载子节点 + * @param deep 子节点是否也是按照当前force处理 + * @param lifeHook 生命周期钩子触不触发,默认触发 + * @param predicate 递归每个widget的回调 + * @param layer 组件层级 + * @returns {boolean} + * @private + */ + _mount(force, deep, lifeHook, predicate, layer) { + if ( + !force && + (this._isMounted || + !this.isVisible() || + this.__asking === true || + !( + this._isRoot === true || + (this._parent && this._parent._isMounted === true) + )) + ) { + return false; + } + layer = layer || 0; + lifeHook !== false && + !this.__async && + callLifeHook(this, "beforeMount"); + this._isMounted = true; + this.__isMounting = false; + for (const key in this._children) { + const child = this._children[key]; + child._mount && + child._mount( + deep ? force : false, + deep, + lifeHook, + predicate, + layer + 1 + ); + } + if (this._parent) { + if (!this._parent.isEnabled()) { + this._setEnable(false); + } + if (!this._parent.isValid()) { + this._setValid(false); + } + } + this._mountChildren && this._mountChildren(); + if (layer === 0) { + // mounted里面会执行scrollTo之类的方法,如果放宏任务里会闪 + // setTimeout(function () { + this.__afterMount(lifeHook, predicate); + // }, 0); + } + + return true; + } + + __afterMount(lifeHook, predicate) { + if (this._isMounted) { + for (const key in this._children) { + const child = this._children[key]; + child.__afterMount && child.__afterMount(lifeHook, predicate); + } + if (lifeHook !== false && !this.__async) { + callLifeHook(this, "_mounted"); + callLifeHook(this, "mounted"); + this.fireEvent(Events.MOUNT); + } + predicate && predicate(this); + } + } + + // _mountChildren = null; + + _update(nextProps, shouldUpdate) { + callLifeHook(this, "beforeUpdate"); + let res; + if (shouldUpdate) { + res = this.update && this.update(nextProps, shouldUpdate); + } + callLifeHook(this, "updated"); + + return res; + } + + isMounted() { + return this._isMounted; + } + + isDestroyed() { + return this._isDestroyed; + } + + setWidth(w) { + this.options.width = w; + this._initElementWidth(); + } + + setHeight(h) { + this.options.height = h; + this._initElementHeight(); + } + + _setEnable(enable) { + if (enable === true) { + this.options._disabled = false; + } else if (enable === false) { + this.options._disabled = true; + } + // 递归将所有子组件使能 + each(this._children, (i, child) => { + !child._manualSetEnable && + child._setEnable && + child._setEnable(enable); + }); + } + + _setValid(valid) { + if (valid === true) { + this.options._invalid = false; + } else if (valid === false) { + this.options._invalid = true; + } + // 递归将所有子组件使有效 + each(this._children, (i, child) => { + !child._manualSetValid && child._setValid && child._setValid(valid); + }); + } + + _setVisible(visible) { + if (visible === true) { + this.options.invisible = false; + } else if (visible === false) { + this.options.invisible = true; + } + } + + setEnable(enable) { + this._manualSetEnable = true; + this.options.disabled = !enable; + this._setEnable(enable); + if (enable === true) { + this.element.removeClass("base-disabled disabled"); + } else if (enable === false) { + this.element.addClass("base-disabled disabled"); + } + } + + __setElementVisible(visible) { + this.element.css("display", visible ? "" : "none"); + } + + _innerSetVisible(visible) { + const o = this.options; + const lastVisible = !o.invisible; + this._setVisible(visible); + if (visible === true) { + // 用this.element.show()会把display属性改成block + this.__setElementVisible(true); + this._mount(); + if (o.animation && !lastVisible) { + this.element + .removeClass(`${o.animation}-leave`) + .removeClass(`${o.animation}-leave-active`) + .addClass(`${o.animation}-enter`); + if (this._requestAnimationFrame) { + cancelAnimationFrame(this._requestAnimationFrame); + } + this._requestAnimationFrame = () => { + this.element.addClass(`${o.animation}-enter-active`); + }; + requestAnimationFrame(this._requestAnimationFrame); + if (this._animationDuring) { + clearTimeout(this._animationDuring); + } + this._animationDuring = setTimeout(() => { + this.element + .removeClass(`${o.animation}-enter`) + .removeClass(`${o.animation}-enter-active`); + }, o.animationDuring); + } + } else if (visible === false) { + if (o.animation && lastVisible) { + this.element + .removeClass(`${o.animation}-enter`) + .removeClass(`${o.animation}-enter-active`) + .addClass(`${o.animation}-leave`); + if (this._requestAnimationFrame) { + cancelAnimationFrame(this._requestAnimationFrame); + } + this._requestAnimationFrame = () => { + this.element.addClass(`${o.animation}-leave-active`); + }; + requestAnimationFrame(this._requestAnimationFrame); + if (this._animationDuring) { + clearTimeout(this._animationDuring); + } + this._animationDuring = setTimeout(() => { + this.element + .removeClass(`${o.animation}-leave`) + .removeClass(`${o.animation}-leave-active`); + this.__setElementVisible(false); + }, o.animationDuring); + } else { + this.__setElementVisible(false); + } + } + } + + setVisible(visible) { + this._innerSetVisible(visible); + this.fireEvent(Events.VIEW, visible); + } + + setValid(valid) { + this._manualSetValid = true; + this.options.invalid = !valid; + this._setValid(valid); + if (valid === true) { + this.element.removeClass("base-invalid invalid"); + } else if (valid === false) { + this.element.addClass("base-invalid invalid"); + } + } + + doBehavior() { + const args = arguments; + // 递归将所有子组件使有效 + each(this._children, (i, child) => { + child.doBehavior && child.doBehavior(...args); + }); + } + + getWidth() { + return this.options.width; + } + + getHeight() { + return this.options.height; + } + + addWidget(name, widget) { + const self = this; + if (name instanceof Widget) { + widget = name; + name = widget.getName(); + } + if (isKey(name)) { + name = `${name}`; + } + name = name || widget.getName() || uniqueId("widget"); + if (this._children[name]) { + throw new Error("widget: widget name already exists, cannot be added"); + } + widget._setParent && widget._setParent(this); + widget.on(Events.DESTROY, function() { + // TODO: self待删 + remove(self._children, this); + }); + + return (this._children[name] = widget); + } + + getWidgetByName(name) { + if (!isKey(name) || name === this.getName()) { + return this; + } + name = `${name}`; + let widget = void 0; + const other = {}; + any(this._children, (i, wi) => { + if (i === name) { + widget = wi; + + return true; + } + other[i] = wi; + }); + if (!widget) { + any(other, (i, wi) => (widget = wi.getWidgetByName(i))); + } + + return widget; + } + + removeWidget(nameOrWidget) { + if (isWidget(nameOrWidget)) { + remove(this._children, nameOrWidget); + } else { + delete this._children[nameOrWidget]; + } + } + + hasWidget(name) { + return isNotNull(this._children[name]); + } + + getName() { + return this.widgetName; + } + + setTag(tag) { + this.options.tag = tag; + } + + getTag() { + return this.options.tag; + } + + attr(key, value) { + if (isPlainObject(key)) { + each(key, (k, v) => this.attr(k, v)); + + return; + } + if (isNotNull(value)) { + this.options[key] = value; + } + + return this.options[key]; + } + + css(name, value) { + return this.element.css(name, value); + } + + getText() { + } + + setText(text) { + } + + getValue() { + } + + setValue(value) { + } + + isEnabled() { + return this.options.disabled === true ? false : !this.options._disabled; + } + + isValid() { + return this.options.invalid === true ? false : !this.options._invalid; + } + + isVisible() { + return !this.options.invisible; + } + + disable() { + this.setEnable(false); + } + + enable() { + this.setEnable(true); + } + + valid() { + this.setValid(true); + } + + invalid() { + this.setValid(false); + } + + invisible() { + this.setVisible(false); + } + + visible() { + this.setVisible(true); + } + + __d() { + each(this._children, (i, widget) => { + widget && widget._unMount && widget._unMount(); + }); + this._children = {}; + } + + // 主要是因为_destroy已经提供了protected方法 + __destroy() { + callLifeHook(this, "beforeDestroy"); + this.beforeDestroy = null; + this.__d(); + this._parent = null; + this._isMounted = false; + callLifeHook(this, "_destroyed"); + callLifeHook(this, "destroyed"); + this.destroyed = null; + this._isDestroyed = true; + // this._purgeRef(); // 清除ref的时机还是要仔细考虑一下 + } + + _unMount() { + this._assetMounted(); + this.__destroy(); + this.fireEvent(Events.UNMOUNT); + this.purgeListeners(); + } + + _assetMounted() { + if (!this.isVisible()) { + this._setVisible(true); + this._mount(false, false, false); + this._setVisible(false); + } + } + + _empty() { + this._assetMounted(); + each(this._children, (i, widget) => { + widget && widget._unMount && widget._unMount(); + }); + this._children = {}; + this.element.empty(); + } + + isolate() { + if (this._parent) { + this._parent.removeWidget(this); + } + DOM.hang([this]); + } + + empty() { + this._empty(); + } + + // 默认的reset方法就是干掉重来 + reset() { + // 还在异步状态的不需要执行reset + if (this.__async === true || this.__asking === true) { + return; + } + // if (this.options.vdom) { + // const vnode = this._renderVNode(); + // patchVNode(this.vnode, vnode); + // this.vnode = vnode; + // return; + // } + // this._isMounted = false; + // this.purgeListeners(); + + // 去掉组件绑定的watcher + each(this._watchers, (i, unwatches) => { + unwatches = isArray(unwatches) ? unwatches : [unwatches]; + each(unwatches, (j, unwatch) => { + unwatch(); + }); + }); + this._watchers && (this._watchers = []); + this._assetMounted(); + this.__d(); + this.element.empty(); + this.element.unbind(); + this._initCurrent(); + this._init(); + // this._initRef(); + } + + _destroy() { + this._assetMounted(); + this.__destroy(); + this.element.destroy(); + this.purgeListeners(); + } + + destroy() { + const o = this.options; + this._assetMounted(); + this.__destroy(); + if (o.animation) { + this._innerSetVisible(false); + setTimeout(() => this.element.destroy(), o.animationDuring); + } else { + this.element.destroy(); + } + this.fireEvent(Events.UNMOUNT); + this.fireEvent(Events.DESTROY); + this._purgeRef(); + this.purgeListeners(); + } +} + +function pushTarget(_current) { + if (current) currentStack.push(current); + Widget.current = current = _current; +} + +function popTarget() { + Widget.current = current = currentStack.pop(); +} + +export function useStore(_store) { + if (current && current.store) { + return current.store; + } + if (current && current.$storeDelegate) { + return current.$storeDelegate; + } + if (current) { + const currentStore = current._store; + const delegate = {}; + let origin; + if (_global.Proxy) { + const proxy = new Proxy(delegate, { + get(target, key) { + return Reflect.get(origin, key); + }, + set(target, key, value) { + return Reflect.set(origin, key, value); + } + }); + current._store = function() { + origin = (_store || currentStore).apply(this, arguments); + delegate.$delegate = origin; + + return origin; + }; + current.$storeDelegate = proxy; + + return current.$storeDelegate; + } + current._store = function() { + const st = (_store || currentStore).apply(this, arguments); + extend(delegate, st); + + return st; + }; + current.$storeDelegate = delegate; + + return current.$storeDelegate; + } +} + +export function useContext(inject) { + // 通过组件找最近的store + let vm = Widget.findStore(Widget.current || Widget.context); + if (vm) { + if (inject) { + if (vm.$$computed && inject in vm.$$computed) { + return vm; + } + if (vm.$$state && inject in vm.$$state) { + return vm; + } + if (vm.$$model && inject in vm.$$model) { + return vm; + } + while (vm) { + if (vm.$$context && inject in vm.$$context) { + return vm; + } + vm = vm._parent; + } + + return null; + } + } + + return vm; +} + +export function watch(vm, watch, handler) { + // 必须要保证组件当前环境存在 + if (Widget.current) { + if (vm instanceof BI.Model) { + const watchers = []; + if (isKey(watch)) { + const k = watch; + watch = {}; + watch[k] = handler; + } + for (const key in watch) { + const innerHandler = watch[key]; + if (isArray(handler)) { + for (let i = 0; i < handler.length; i++) { + watchers.push( + Fix.watch(vm.model, key, innerHandler, { + store: vm + }) + ); + } + } else { + watchers.push( + Fix.watch(vm.model, key, innerHandler, { + store: vm + }) + ); + } + } + // vm中一定有_widget + Widget.current._watchers || (Widget.current._watchers = []); + Widget.current._watchers = + Widget.current._watchers.concat(watchers); + + return; + } + handler = watch; + watch = vm; + Widget.current.$watchDelayCallbacks || + (Widget.current.$watchDelayCallbacks = []); + Widget.current.$watchDelayCallbacks.push([watch, handler]); + } +} + +export function onBeforeMount(beforeMount) { + if (current) { + if (current.__isMounting) { + beforeMount(); + + return; + } + if (!current.beforeMount) { + current.beforeMount = []; + } else if (!isArray(current.beforeMount)) { + current.beforeMount = [current.beforeMount]; + } + current.beforeMount.push(beforeMount); + } +} + +export function onMounted(mounted) { + if (current) { + if (current._isMounted && !this.__async) { + mounted(); + + return; + } + if (!current.mounted) { + current.mounted = []; + } else if (!isArray(current.mounted)) { + current.mounted = [current.mounted]; + } + current.mounted.push(mounted); + } +} + +export function onBeforeUnmount(beforeDestroy) { + if (current) { + if (!current.beforeDestroy) { + current.beforeDestroy = []; + } else if (!isArray(current.beforeDestroy)) { + current.beforeDestroy = [current.beforeDestroy]; + } + current.beforeDestroy.push(beforeDestroy); + } +} + +export function onUnmounted(destroyed) { + if (current) { + if (!current.destroyed) { + current.destroyed = []; + } else if (!isArray(current.destroyed)) { + current.destroyed = [current.destroyed]; + } + current.destroyed.push(destroyed); + } +} + +export function mount(widget, container, predicate, hydrate) { + if (hydrate === true) { + // 将widget的element元素都挂载好,并建立相互关系 + widget.element.data("__widgets", [widget]); + const res = widget._mount(true, false, false, function(w) { + each(w._children, (i, child) => { + let ws = child.element.data("__widgets"); + if (!ws) { + ws = []; + } + ws.push(child); + child.element.data("__widgets", ws); + }); + predicate && predicate.apply(this, arguments); + }); + // 将新的dom树属性(事件等)patch到已存在的dom上 + const c = Widget._renderEngine.createElement; + DOM.patchProps(widget.element, c(c(container).children()[0])); + + const triggerLifeHook = (w) => { + w.beforeMount && w.beforeMount(); + w.mounted && w.mounted(); + each(w._children, (i, child) => { + triggerLifeHook(child); + }); + }; + // 最后触发组件树生命周期函数 + triggerLifeHook(widget); + + return res; + } + if (container) { + Widget._renderEngine.createElement(container).append(widget.element); + } + + return widget._mount(true, false, false, predicate); +} diff --git a/packages/fineui/src/core/5.inject.js b/packages/fineui/src/core/5.inject.js new file mode 100644 index 000000000..0246f2497 --- /dev/null +++ b/packages/fineui/src/core/5.inject.js @@ -0,0 +1,603 @@ +import { + isFunction, + isNull, + isNotNull, + isArray, + each, + isWidget, + extend, + init, + isEmpty, + remove, + isString +} from "./2.base"; +import { OB } from "./3.ob"; +import { Widget } from "./4.widget"; +import { Plugin } from "./6.plugin"; +import { aspect } from "./structure"; +import { Events } from "./constant"; +import { _global } from "./0.foundation"; +import { SystemProvider } from "./system"; +import { loadResources } from "./platform"; + +const moduleInjection = {}, moduleInjectionMap = { + components: {}, + constants: {}, + stores: {}, + services: {}, + models: {}, + providers: {}, +}; + +export function module(xtype, cls) { + if (isNotNull(moduleInjection[xtype])) { + _global.console && console.error(`module: [${xtype}] already registered`); + } else { + if (isFunction(cls)) { + cls = cls(); + } + for (const k in moduleInjectionMap) { + if (cls[k]) { + for (const key in cls[k]) { + if (!moduleInjectionMap[k]) { + continue; + } + if (!moduleInjectionMap[k][key]) { + moduleInjectionMap[k][key] = []; + } + moduleInjectionMap[k][key].push({ + version: cls[k][key], + moduleId: xtype, + }); + } + } + } + moduleInjection[xtype] = cls; + } + + return () => Modules.getModule(xtype); +} + +const constantInjection = {}; + +export function constant(xtype, cls) { + if (isNotNull(constantInjection[xtype])) { + _global.console && console.error(`constant: [${xtype}]already registered`); + } else { + constantInjection[xtype] = cls; + } + + return () => Constants.getConstant(xtype); +} + +const modelInjection = {}; + +export function model(xtype, cls) { + if (isNotNull(modelInjection[xtype])) { + _global.console && console.error(`model: [${xtype}] already registered`); + } else { + modelInjection[xtype] = cls; + } + + return config => Models.getModel(xtype, config); +} + +const storeInjection = {}; + +export function store(xtype, cls) { + if (isNotNull(storeInjection[xtype])) { + _global.console && console.error(`store: [${xtype}] already registered`); + } else { + storeInjection[xtype] = cls; + } + + return config => Stores.getStore(xtype, config); +} + +const serviceInjection = {}; + +export function service(xtype, cls) { + if ((serviceInjection[xtype])) { + _global.console && console.error(`service: [${xtype}] already registered`); + } + + serviceInjection[xtype] = cls; + + return config => Services.getService(xtype, config); +} + +const providerInjection = {}; + +export function provider(xtype, cls) { + if ((providerInjection[xtype])) { + _global.console && console.error(`provider: [${xtype}] already registered`); + } else { + providerInjection[xtype] = cls; + } + + return config => Providers.getProvider(xtype, config); +} + +const configFunctions = OB.configFunctions = {}; +const runConfigFunction = (type, configFn) => { + if (!type || !configFunctions[type]) { + return false; + } + + let queue = []; + if (configFn) { + queue = configFunctions[type].filter(conf => conf.fn === configFn); + configFunctions[type] = configFunctions[type].filter(conf => conf.fn !== configFn); + } else { + queue = configFunctions[type]; + delete configFunctions[type]; + } + + const dependencies = Providers.getProvider(SystemProvider.xtype).getDependencies(); + const modules = moduleInjectionMap.components[type] + || moduleInjectionMap.constants[type] + || moduleInjectionMap.services[type] + || moduleInjectionMap.stores[type] + || moduleInjectionMap.models[type] + || moduleInjectionMap.providers[type]; + for (let i = 0; i < queue.length; i++) { + const conf = queue[i]; + const version = conf.opt.version; + const fn = conf.fn; + if (modules && version) { + let findVersion = false; + let module; + for (let j = 0; j < modules.length; j++) { + module = modules[j]; + if (module && dependencies[module.moduleId] && module.version === version) { + const minVersion = dependencies[module.moduleId].minVersion, + maxVersion = dependencies[module.moduleId].maxVersion; + if (minVersion && (moduleInjection[module.moduleId].version || version) < minVersion) { + findVersion = true; + break; + } + if (maxVersion && (moduleInjection[module.moduleId].version || version) > maxVersion) { + findVersion = true; + break; + } + } + } + if (findVersion === true) { + _global.console && console.error(`moduleId: [${module.moduleId}] interface: [${type}] version: [${version}] has expired. The version requirement is: `, dependencies[module.moduleId], "=>", moduleInjection[module.moduleId]); + continue; + } + } + if (constantInjection[type]) { + constantInjection[type] = fn(constantInjection[type]); + continue; + } + if (providerInjection[type]) { + if (!providers[type]) { + providers[type] = new providerInjection[type](); + } + if (providerInstance[type]) { + delete providerInstance[type]; + } + fn(providers[type]); + continue; + } + Plugin.configWidget(type, fn, conf.opt); + } +}; + +/** + * 配置组件依赖 + * @param deps + */ +function configWidgetDeps(deps) { + each(deps, (key, dep) => { + const deps = (isArray(dep) ? dep : [dep]).map(d => { + if (isString(d)) { + return { + src: d, + async: false + }; + } else { + return d; + } + }); + + config(key, props => { + + const asyncLoad = deps.some(dep => dep.async); + // 异步加载资源 + if (asyncLoad && !props._depsLoaded) { + return { + type: Widget, + beforeInit: () => { + return loadResources(deps); + }, + render: () => { + return { + ...props, + _depsLoaded: true + }; + }, + }; + } + + // 同步加载资源 + loadResources(deps); + + return props; + }); + }); +} + +export function config(type, configFn, opt) { + if (isFunction(type)) { + opt = configFn; + configFn = type; + type = SystemProvider.xtype; + } + opt = opt || {}; + + // 系统配置直接执行 + if (SystemProvider.xtype === type) { + if (!providers[type]) { + providers[type] = new providerInjection[type](); + } + // 如果config被重新配置的话,需要删除掉之前的实例 + if (providerInstance[type]) { + delete providerInstance[type]; + } + + return configFn(providers[type]); + } + + if (!configFunctions[type]) { + configFunctions[type] = []; + } + configFunctions[type].push({ + fn: configFn, + opt, + }); + + if (opt.deps) { + configWidgetDeps(opt.deps); + } + + if (opt.immediately) { + return runConfigFunction(type, configFn); + } +} + +export function getReference(type, fn) { + return Plugin.registerObject(type, fn); +} + +const actions = {}; +const globalAction = []; + +export function action(type, actionFn) { + if (isFunction(type)) { + globalAction.push(type); + + return () => { + remove(globalAction, idx => globalAction.indexOf(actionFn) === idx); + }; + } + if (!actions[type]) { + actions[type] = []; + } + actions[type].push(actionFn); + + return () => { + remove(actions[type], idx => actions[type].indexOf(actionFn) === idx); + if (actions[type].length === 0) { + delete actions[type]; + } + }; +} + +const points = {}; + +export function point(type, action, pointFn, after) { + if (!points[type]) { + points[type] = {}; + } + if (!points[type][action]) { + points[type][action] = {}; + } + if (!points[type][action][after ? "after" : "before"]) { + points[type][action][after ? "after" : "before"] = []; + } + points[type][action][after ? "after" : "before"].push(pointFn); +} + +export const Modules = { + getModule(type) { + if (!moduleInjection[type]) { + _global.console && console.error(`module: [${type}] undefined`); + } + + return moduleInjection[type]; + }, + getAllModules() { + return moduleInjection; + }, +}; + +export const Constants = { + getConstant(type) { + if (isNull(constantInjection[type])) { + _global.console && console.error(`constant: [${type}] undefined`); + } + runConfigFunction(type); + + return isFunction(constantInjection[type]) ? constantInjection[type]() : constantInjection[type]; + }, +}; + +function callPoint(inst, types) { + types = isArray(types) ? types : [types]; + each(types, (idx, type) => { + if (points[type]) { + for (const action in points[type]) { + const bfns = points[type][action].before; + if (bfns) { + aspect.before(inst, action, (function(bfns) { + return function() { + for (let i = 0, len = bfns.length; i < len; i++) { + try { + bfns[i].apply(inst, arguments); + } catch (e) { + _global.console && console.error(e); + } + } + }; + }(bfns))); + } + const afns = points[type][action].after; + if (afns) { + aspect.after(inst, action, (function(afns) { + return function() { + for (let i = 0, len = afns.length; i < len; i++) { + try { + afns[i].apply(inst, arguments); + } catch (e) { + _global.console && console.error(e); + } + } + }; + }(afns))); + } + } + } + }); +} + +export const Models = { + getModel(type, config) { + if (!modelInjection[type]) { + _global.console && console.error(`model: [${type}] undefined`); + } + runConfigFunction(type); + const inst = new modelInjection[type](config); + inst._constructor && inst._constructor(config); + inst.mixins && callPoint(inst, inst.mixins); + callPoint(inst, type); + + return inst; + }, +}; + +const stores = {}; +export const Stores = { + getStore(type, config) { + if (!storeInjection[type]) { + _global.console && console.error(`store: [${type}] undefined`); + } + if (stores[type]) { + return stores[type]; + } + const inst = stores[type] = new storeInjection[type](config); + inst._constructor && inst._constructor(config, () => { + delete stores[type]; + }); + callPoint(inst, type); + + return inst; + }, +}; + +const services = {}; +export const Services = { + getService: (type, config) => { + if (!serviceInjection[type]) { + _global.console && console.error(`service: [${type}] undefined`); + } + if (services[type]) { + return services[type]; + } + services[type] = new serviceInjection[type](config); + callPoint(services[type], type); + + return services[type]; + }, +}; + +const providers = {}, + providerInstance = {}; +export const Providers = { + getProvider: (type, config) => { + if (!providerInjection[type]) { + _global.console && console.error(`provider: [${type}] undefined`); + } + runConfigFunction(type); + if (!providers[type]) { + providers[type] = new providerInjection[type](); + } + if (!providerInstance[type] && providers[type].$get) { + providerInstance[type] = new (providers[type].$get())(config); + } + + return providerInstance[type]; + }, +}; + +export const Actions = { + runAction(type, event, config) { + each(actions[type], (i, act) => { + try { + act(event, config); + } catch (e) { + _global.console && console.error(e); + } + }); + }, + runGlobalAction() { + const args = [].slice.call(arguments); + each(globalAction, (i, act) => { + try { + act(...args); + } catch (e) { + _global.console && console.error(e); + } + }); + }, +}; + +const kv = {}; + +export function shortcut(xtype, cls) { + if (isNotNull(kv[xtype])) { + _global.console && console.error(`widget: [${xtype}] already registered`); + } + if (cls) { + cls.xtype = xtype; + } + + // 兼容性 + if (!cls.hasOwnProperty("superclass")) { + cls.superclass = Object.getPrototypeOf(cls.prototype); + } + + kv[xtype] = cls; +} + +export const component = shortcut; + +// 根据配置属性生成widget +const createRealWidget = (config, context, lazy) => { + const Cls = isFunction(config.type) ? config.type : kv[config.type]; + + if (!Cls) { + throw new Error(`widget: [${config.type}] undefined`); + } + let pushed = false; + const widget = new Cls(); + widget._context = Widget.context || context; + if (!Widget.context && context) { + pushed = true; + Widget.pushContext(context); + } + callPoint(widget, config.type); + widget._initProps(config); + widget._initRoot(); + widget._constructed(); + // if (!lazy || config.element || config.root) { + widget._lazyConstructor(); + // } + pushed && Widget.popContext(); + + return widget; +}; + +export function createWidget(item, options, context, lazy) { + item || (item = {}); + if (isWidget(options)) { + context = options; + options = {}; + } else { + options || (options = {}); + } + + let el, w; + if (item.type || options.type) { + el = extend({}, options, item); + } else if (item.el && (item.el.type || options.type)) { + el = extend({}, options, item.el); + } + let elType; + if (el) { + elType = (el.type && el.type.xtype) || el.type; + runConfigFunction(elType); + } + + // 先把准备环境准备好 + init(); + + if (isEmpty(item) && isEmpty(options)) { + return createWidget({ + type: "bi.layout", + }); + } + if (isWidget(item)) { + return item; + } + if (el) { + w = Plugin.getWidget(elType, el); + const wType = (w.type && w.type.xtype) || w.type; + if (wType === elType) { + if (Plugin.hasObject(elType)) { + if (!w.listeners || isArray(w.listeners)) { + w.listeners = (w.listeners || []).concat([{ + eventName: Events.MOUNT, + action: function() { + Plugin.getObject(elType, this); + }, + }]); + } else { + w.listeners[Events.MOUNT] = [ + function() { + Plugin.getObject(elType, this); + } + ].concat(w.listeners[Events.MOUNT] || []); + } + } + + return createRealWidget(w, context, lazy); + } + + return createWidget(w, options, context, lazy); + } + if (isWidget(item.el)) { + return item.el; + } + throw new Error("widget: Unable to create widget from item ", item); +} + +export function _lazyCreateWidget(item, options, context) { + return createWidget(item, options, context, true); +} + +export function createElement() { + const widget = createWidget.apply(this, arguments); + + return widget.element; +} + +export function getResource(type, config) { + if (isNotNull(constantInjection[type])) { + return Constants.getConstant(type); + } + if (modelInjection[type]) { + return Models.getModel(type, config); + } + if (storeInjection[type]) { + return Stores.getStore(type, config); + } + if (serviceInjection[type]) { + return Services.getService(type, config); + } + if (providerInjection[type]) { + return Providers.getProvider(type, config); + } + throw new Error("unknown type: [" + type + "] undefined"); +} diff --git a/packages/fineui/src/core/6.plugin.js b/packages/fineui/src/core/6.plugin.js new file mode 100644 index 000000000..70b3f95d0 --- /dev/null +++ b/packages/fineui/src/core/6.plugin.js @@ -0,0 +1,127 @@ +const _WidgetsPlugin = {}; +const _ObjectPlugin = {}; +const _ConfigPlugin = {}; +const _ConfigRenderPlugin = {}; +let _GlobalWidgetConfigFns = []; +let __GlobalObjectConfigFns = []; + +export const Plugin = { + getWidget (type, options) { + if (_GlobalWidgetConfigFns.length > 0) { + const fns = _GlobalWidgetConfigFns.slice(0); + for (let i = fns.length - 1; i >= 0; i--) { + fns[i](type, options); + } + } + + let res; + if (_ConfigPlugin[type]) { + for (let i = _ConfigPlugin[type].length - 1; i >= 0; i--) { + res = _ConfigPlugin[type][i](options); + if (res) { + options = res; + } + } + } + // Deprecated + if (_WidgetsPlugin[type]) { + for (let i = _WidgetsPlugin[type].length - 1; i >= 0; i--) { + res = _WidgetsPlugin[type][i](options); + if (res) { + return res; + } + } + } + + return options; + }, + + config (widgetConfigFn, objectConfigFn) { + _GlobalWidgetConfigFns = _GlobalWidgetConfigFns.concat(BI._.isArray(widgetConfigFn) ? widgetConfigFn : [widgetConfigFn]); + __GlobalObjectConfigFns = __GlobalObjectConfigFns.concat(BI._.isArray(objectConfigFn) ? objectConfigFn : [objectConfigFn]); + }, + + configWidget (type, fn, opt) { + // opt.single: true 最后一次注册有效 + if (!_ConfigPlugin[type] || (opt && opt.single)) { + _ConfigPlugin[type] = []; + } + _ConfigPlugin[type].push(fn); + }, + + getRender (type, rendered) { + let res; + if (_ConfigRenderPlugin[type]) { + for (let i = _ConfigRenderPlugin[type].length - 1; i >= 0; i--) { + res = _ConfigRenderPlugin[type][i](rendered); + if (res) { + rendered = res; + } + } + } + + return rendered; + }, + + configRender (type, fn) { + if (!_ConfigRenderPlugin[type]) { + _ConfigRenderPlugin[type] = []; + } + _ConfigRenderPlugin[type].push(fn); + }, + + // Deprecated + registerWidget (type, fn) { + if (!_WidgetsPlugin[type]) { + _WidgetsPlugin[type] = []; + } + if (_WidgetsPlugin[type].length > 0) { + console.log("widget already registered!"); + } + _WidgetsPlugin[type].push(fn); + }, + + // Deprecated + relieveWidget (type) { + delete _WidgetsPlugin[type]; + }, + + getObject (type, object) { + if (__GlobalObjectConfigFns.length > 0) { + const fns = __GlobalObjectConfigFns.slice(0); + for (let i = fns.length - 1; i >= 0; i--) { + fns[i](type, object); + } + } + + let res; + if (_ObjectPlugin[type]) { + for (let i = 0, len = _ObjectPlugin[type].length; i < len; i++) { + res = _ObjectPlugin[type][i](object); + if (res) { + object = res; + } + } + } + + return res || object; + }, + + hasObject (type) { + return __GlobalObjectConfigFns.length > 0 || !!_ObjectPlugin[type]; + }, + + registerObject (type, fn) { + if (!_ObjectPlugin[type]) { + _ObjectPlugin[type] = []; + } + if (_ObjectPlugin[type].length > 0) { + console.log("object already registered!"); + } + _ObjectPlugin[type].push(fn); + }, + + relieveObject (type) { + delete _ObjectPlugin[type]; + }, +}; diff --git a/src/core/__test__/alias.test.js b/packages/fineui/src/core/__test__/alias.test.js similarity index 100% rename from src/core/__test__/alias.test.js rename to packages/fineui/src/core/__test__/alias.test.js diff --git a/src/core/__test__/base.test.js b/packages/fineui/src/core/__test__/base.test.js similarity index 100% rename from src/core/__test__/base.test.js rename to packages/fineui/src/core/__test__/base.test.js diff --git a/src/core/__test__/context.test.js b/packages/fineui/src/core/__test__/context.test.js similarity index 100% rename from src/core/__test__/context.test.js rename to packages/fineui/src/core/__test__/context.test.js diff --git a/src/core/__test__/widget.test.js b/packages/fineui/src/core/__test__/widget.test.js similarity index 100% rename from src/core/__test__/widget.test.js rename to packages/fineui/src/core/__test__/widget.test.js diff --git a/packages/fineui/src/core/action/action.js b/packages/fineui/src/core/action/action.js new file mode 100644 index 000000000..f95569bfd --- /dev/null +++ b/packages/fineui/src/core/action/action.js @@ -0,0 +1,23 @@ +/** + * guy + * 由一个元素切换到另一个元素的行为 + * @class Action + * @extends OB + * @abstract + */ +import { OB } from "../3.ob"; + +export class Action extends OB { + props = { + src: null, + tar: null, + }; + + actionPerformed(src, tar, callback) { + + } + + actionBack(tar, src, callback) { + + } +} diff --git a/packages/fineui/src/core/action/action.show.js b/packages/fineui/src/core/action/action.show.js new file mode 100644 index 000000000..8ed0162f1 --- /dev/null +++ b/packages/fineui/src/core/action/action.show.js @@ -0,0 +1,33 @@ +/** + * guy + * 由一个元素切换到另一个元素的行为 + */ +import { Action } from "./action"; + +export class ShowAction extends Action { + actionPerformed(src, tar, callback) { + tar = tar || this.options.tar; + tar.setVisible(true); + callback && callback(); + } + + actionBack(tar, src, callback) { + tar = tar || this.options.tar; + tar.setVisible(false); + callback && callback(); + } +} + +export const ActionFactory = { + createAction (key, options) { + let Action; + switch (key) { + case "show": + Action = ShowAction; + break; + default: + } + + return new Action(options); + }, +}; diff --git a/packages/fineui/src/core/action/index.js b/packages/fineui/src/core/action/index.js new file mode 100644 index 000000000..c73457134 --- /dev/null +++ b/packages/fineui/src/core/action/index.js @@ -0,0 +1,2 @@ +export { Action } from "./action"; +export { ShowAction, ActionFactory } from "./action.show"; diff --git a/packages/fineui/src/core/behavior/0.behavior.js b/packages/fineui/src/core/behavior/0.behavior.js new file mode 100644 index 000000000..37dfb3375 --- /dev/null +++ b/packages/fineui/src/core/behavior/0.behavior.js @@ -0,0 +1,18 @@ +/** + * guy + * 行为控件 + */ +import { OB } from "../3.ob"; +import { extend } from "../2.base"; + +export class Behavior extends OB { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + rule: () => true, + }); + } + + doBehavior() { + + } +} diff --git a/packages/fineui/src/core/behavior/behavior.highlight.js b/packages/fineui/src/core/behavior/behavior.highlight.js new file mode 100644 index 000000000..2b10c012f --- /dev/null +++ b/packages/fineui/src/core/behavior/behavior.highlight.js @@ -0,0 +1,34 @@ +/** + * guy + */ +import { Behavior } from "./0.behavior"; +import { isFunction, each } from "../2.base"; +import { Single } from "@/base/single/0.single"; + +export class HighlightBehavior extends Behavior { + doBehavior(items) { + const args = Array.prototype.slice.call(arguments, 1), + { rule } = this.options; + each(items, (i, item) => { + if (item instanceof Single) { + const rules = rule(item.getValue(), item); + + function doBe (run) { + if (run === true) { + item.doHighLight && item.doHighLight(...args); + } else { + item.unHighLight && item.unHighLight(...args); + } + } + + if (isFunction(rules)) { + rules(doBe); + } else { + doBe(rules); + } + } else { + item.doBehavior && item.doBehavior(...args); + } + }); + } +} diff --git a/packages/fineui/src/core/behavior/behavior.redmark.js b/packages/fineui/src/core/behavior/behavior.redmark.js new file mode 100644 index 000000000..1158757a7 --- /dev/null +++ b/packages/fineui/src/core/behavior/behavior.redmark.js @@ -0,0 +1,25 @@ +/** + * guy + * 标红行为 + */ +import { Behavior } from "./0.behavior"; +import { each } from "../2.base"; +import { Single } from "@/base/single/0.single"; + +export class RedMarkBehavior extends Behavior { + doBehavior(items) { + const args = Array.prototype.slice.call(arguments, 1), + { rule } = this.options; + each(items, (i, item) => { + if (item instanceof Single) { + if (rule(item.getValue(), item)) { + item.doRedMark && item.doRedMark(...args); + } else { + item.doRedMark && item.unRedMark(...args); + } + } else { + item.doBehavior && item.doBehavior(...args); + } + }); + } +} diff --git a/packages/fineui/src/core/behavior/index.js b/packages/fineui/src/core/behavior/index.js new file mode 100644 index 000000000..52d5f6499 --- /dev/null +++ b/packages/fineui/src/core/behavior/index.js @@ -0,0 +1,26 @@ + +import { HighlightBehavior } from "./behavior.highlight"; +import { RedMarkBehavior } from "./behavior.redmark"; + +export const BehaviorFactory = { + createBehavior (key, options) { + let Behavior; + switch (key) { + case "highlight": + Behavior = HighlightBehavior; + break; + case "redmark": + Behavior = RedMarkBehavior; + break; + default: + } + + return new Behavior(options); + }, +}; + +export { Behavior } from "./0.behavior"; +export { + HighlightBehavior, + RedMarkBehavior +}; diff --git a/packages/fineui/src/core/constant/events.js b/packages/fineui/src/core/constant/events.js new file mode 100644 index 000000000..656f2e9ca --- /dev/null +++ b/packages/fineui/src/core/constant/events.js @@ -0,0 +1,441 @@ +/** + * 事件集合 + */ +export const Events = { + + /** + * @static + * @property keydown事件 + */ + KEYDOWN: "_KEYDOWN", + + /** + * @static + * @property 回撤事件 + */ + BACKSPACE: "_BACKSPACE", + + /** + * @static + * @property 空格事件 + */ + SPACE: "_SPACE", + + /** + * @static + * @property 回车事件 + */ + ENTER: "_ENTER", + + /** + * @static + * @property 确定事件 + */ + CONFIRM: "_CONFIRM", + + /** + * @static + * @property 错误事件 + */ + ERROR: "_ERROR", + + /** + * @static + * @property 暂停事件 + */ + PAUSE: "_PAUSE", + + /** + * @static + * @property destroy事件 + */ + DESTROY: "_DESTROY", + + /** + * @static + * @property 挂载事件 + */ + MOUNT: "_MOUNT", + + /** + * @static + * @property 取消挂载事件 + */ + UNMOUNT: "_UNMOUNT", + + /** + * @static + * @property 清除选择 + */ + CLEAR: "_CLEAR", + + /** + * @static + * @property 添加数据 + */ + ADD: "_ADD", + + /** + * @static + * @property 正在编辑状态事件 + */ + EDITING: "_EDITING", + + /** + * @static + * @property 空状态事件 + */ + EMPTY: "_EMPTY", + + /** + * @static + * @property 显示隐藏事件 + */ + VIEW: "_VIEW", + + /** + * @static + * @property 窗体改变大小 + */ + RESIZE: "_RESIZE", + + /** + * @static + * @property 编辑前事件 + */ + BEFOREEDIT: "_BEFOREEDIT", + + /** + * @static + * @property 编辑后事件 + */ + AFTEREDIT: "_AFTEREDIT", + + /** + * @static + * @property 开始编辑事件 + */ + STARTEDIT: "_STARTEDIT", + + /** + * @static + * @property 停止编辑事件 + */ + STOPEDIT: "_STOPEDIT", + + /** + * @static + * @property 值改变事件 + */ + CHANGE: "_CHANGE", + + /** + * @static + * @property 下拉弹出菜单事件 + */ + EXPAND: "_EXPAND", + + /** + * @static + * @property 关闭下拉菜单事件 + */ + COLLAPSE: "_COLLAPSE", + + /** + * @static + * @property 下拉菜单切换展开收起事件 + */ + TOGGLE: "_TOGGLE", + + /** + * @static + * @property 回调事件 + */ + CALLBACK: "_CALLBACK", + + /** + * @static + * @property 点击事件 + */ + CLICK: "_CLICK", + + /** + * @static + * @property 状态改变事件,一般是用在复选按钮和单选按钮 + */ + STATECHANGE: "_STATECHANGE", + + /** + * @static + * @property 状态改变前事件 + */ + BEFORESTATECHANGE: "_BEFORESTATECHANGE", + + + /** + * @static + * @property 初始化事件 + */ + INIT: "_INIT", + + /** + * @static + * @property 初始化后事件 + */ + AFTERINIT: "_AFTERINIT", + + /** + * @static + * @property 滚动条滚动事件 + */ + SCROLL: "_SCROLL", + + + /** + * @static + * @property 开始加载事件 + */ + STARTLOAD: "_STARTLOAD", + + /** + * @static + * @property 加载后事件 + */ + AFTERLOAD: "_AFTERLOAD", + + + /** + * @static + * @property 提交前事件 + */ + BS: "beforesubmit", + + /** + * @static + * @property 提交后事件 + */ + AS: "aftersubmit", + + /** + * @static + * @property 提交完成事件 + */ + SC: "submitcomplete", + + /** + * @static + * @property 提交失败事件 + */ + SF: "submitfailure", + + /** + * @static + * @property 提交成功事件 + */ + SS: "submitsuccess", + + /** + * @static + * @property 校验提交前事件 + */ + BVW: "beforeverifywrite", + + /** + * @static + * @property 校验提交后事件 + */ + AVW: "afterverifywrite", + + /** + * @static + * @property 校验后事件 + */ + AV: "afterverify", + + /** + * @static + * @property 填报前事件 + */ + BW: "beforewrite", + + /** + * @static + * @property 填报后事件 + */ + AW: "afterwrite", + + /** + * @static + * @property 填报成功事件 + */ + WS: "writesuccess", + + /** + * @static + * @property 填报失败事件 + */ + WF: "writefailure", + + /** + * @static + * @property 添加行前事件 + */ + BA: "beforeappend", + + /** + * @static + * @property 添加行后事件 + */ + AA: "afterappend", + + /** + * @static + * @property 删除行前事件 + */ + BD: "beforedelete", + + /** + * @static + * @property 删除行后事件 + */ + AD: "beforedelete", + + /** + * @static + * @property 未提交离开事件 + */ + UC: "unloadcheck", + + + /** + * @static + * @property PDF导出前事件 + */ + BTOPDF: "beforetopdf", + + /** + * @static + * @property PDF导出后事件 + */ + ATOPDF: "aftertopdf", + + /** + * @static + * @property Excel导出前事件 + */ + BTOEXCEL: "beforetoexcel", + + /** + * @static + * @property Excel导出后事件 + */ + ATOEXCEL: "aftertoexcel", + + /** + * @static + * @property Word导出前事件 + */ + BTOWORD: "beforetoword", + + /** + * @static + * @property Word导出后事件 + */ + ATOWORD: "aftertoword", + + /** + * @static + * @property 图片导出前事件 + */ + BTOIMAGE: "beforetoimage", + + /** + * @static + * @property 图片导出后事件 + */ + ATOIMAGE: "aftertoimage", + + /** + * @static + * @property HTML导出前事件 + */ + BTOHTML: "beforetohtml", + + /** + * @static + * @property HTML导出后事件 + */ + ATOHTML: "aftertohtml", + + /** + * @static + * @property Excel导入前事件 + */ + BIMEXCEL: "beforeimportexcel", + + /** + * @static + * @property Excel导出后事件 + */ + AIMEXCEL: "afterimportexcel", + + /** + * @static + * @property PDF打印前事件 + */ + BPDFPRINT: "beforepdfprint", + + /** + * @static + * @property PDF打印后事件 + */ + APDFPRINT: "afterpdfprint", + + /** + * @static + * @property Flash打印前事件 + */ + BFLASHPRINT: "beforeflashprint", + + /** + * @static + * @property Flash打印后事件 + */ + AFLASHPRINT: "afterflashprint", + + /** + * @static + * @property Applet打印前事件 + */ + BAPPLETPRINT: "beforeappletprint", + + /** + * @static + * @property Applet打印后事件 + */ + AAPPLETPRINT: "afterappletprint", + + /** + * @static + * @property 服务器打印前事件 + */ + BSEVERPRINT: "beforeserverprint", + + /** + * @static + * @property 服务器打印后事件 + */ + ASERVERPRINT: "afterserverprint", + + /** + * @static + * @property 邮件发送前事件 + */ + BEMAIL: "beforeemail", + + /** + * @static + * @property 邮件发送后事件 + */ + AEMAIL: "afteremail", +}; diff --git a/packages/fineui/src/core/constant/index.js b/packages/fineui/src/core/constant/index.js new file mode 100644 index 000000000..34aa468c5 --- /dev/null +++ b/packages/fineui/src/core/constant/index.js @@ -0,0 +1,3 @@ +export { Events } from "./events"; +export * from "./var"; +export * from "./writable.var" diff --git a/packages/fineui/src/core/constant/var.js b/packages/fineui/src/core/constant/var.js new file mode 100644 index 000000000..bf1c68e10 --- /dev/null +++ b/packages/fineui/src/core/constant/var.js @@ -0,0 +1,132 @@ +/** + * 常量 + */ + +export const MAX = 0xfffffffffffffff; +export const MIN = -0xfffffffffffffff; +export const zIndex_layer = 1e5; +export const zIndex_popover = 1e6; +export const zIndex_popup = 1e7; +export const zIndex_masker = 1e8; +export const zIndex_tip = 1e9; +export const emptyStr = ""; +export const empty = null; +export const Key = { + 48: "0", + 49: "1", + 50: "2", + 51: "3", + 52: "4", + 53: "5", + 54: "6", + 55: "7", + 56: "8", + 57: "9", + 65: "a", + 66: "b", + 67: "c", + 68: "d", + 69: "e", + 70: "f", + 71: "g", + 72: "h", + 73: "i", + 74: "j", + 75: "k", + 76: "l", + 77: "m", + 78: "n", + 79: "o", + 80: "p", + 81: "q", + 82: "r", + 83: "s", + 84: "t", + 85: "u", + 86: "v", + 87: "w", + 88: "x", + 89: "y", + 90: "z", + 96: "0", + 97: "1", + 98: "2", + 99: "3", + 100: "4", + 101: "5", + 102: "6", + 103: "7", + 104: "8", + 105: "9", + 106: "*", + 107: "+", + 109: "-", + 110: ".", + 111: "/", +}; +export const KeyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38, +}; +export const Status = { + SUCCESS: 1, + WRONG: 2, + START: 3, + END: 4, + WAITING: 5, + READY: 6, + RUNNING: 7, + OUTOFBOUNDS: 8, + NULL: -1, +}; +export const Direction = { + Top: "top", + Bottom: "bottom", + Left: "left", + Right: "right", + Custom: "custom", +}; +export const Axis = { + Vertical: "vertical", + Horizontal: "horizontal", +}; +export const Selection = { + Default: -2, + None: -1, + Single: 0, + Multi: 1, + All: 2, +}; +export const HorizontalAlign = { + Left: "left", + Right: "right", + Center: "center", + Stretch: "stretch", +}; +export const VerticalAlign = { + Middle: "middle", + Top: "top", + Bottom: "bottom", + Stretch: "stretch", +}; +export function emptyFn() {} diff --git a/packages/fineui/src/core/constant/writable.var.js b/packages/fineui/src/core/constant/writable.var.js new file mode 100644 index 000000000..45e048502 --- /dev/null +++ b/packages/fineui/src/core/constant/writable.var.js @@ -0,0 +1,150 @@ +/** + * 可写的常量 + */ +import { isNumber } from "../2.base"; +import { _global } from "../0.foundation"; +import { Cache } from "../structure"; + +const PropertyDescriptors = {}; + +export let EVENT_RESPONSE_TIME = 200; +export const setEventResponseTime = v => { + EVENT_RESPONSE_TIME = v; +}; +PropertyDescriptors["EVENT_RESPONSE_TIME"] = { + enumerable: true, + configurable: true, + get: function() { + return EVENT_RESPONSE_TIME; + }, + set: setEventResponseTime, +}; + +export let pixUnit = "px"; +export const setPixUnit = v => { + pixUnit = v; +}; +PropertyDescriptors["pixUnit"] = { + enumerable: true, + configurable: true, + get: function() { + return pixUnit; + }, + set: setPixUnit, +}; + +export let pixRatio = 1; +export const setPixRatio = v => { + pixRatio = v; +}; +PropertyDescriptors["pixRatio"] = { + enumerable: true, + configurable: true, + get: function() { + return pixRatio; + }, + set: setPixRatio, +}; + +export let StartOfWeek = 1; +export const setStartOfWeek = v => { + if (![0, 1].includes(v)) { + console.error("setStartOfWeek must be 0 or 1"); + return; + } + StartOfWeek = v; +}; +PropertyDescriptors["StartOfWeek"] = { + enumerable: true, + configurable: true, + get: function() { + return StartOfWeek; + }, + set: setStartOfWeek, +}; + +export let BlankSplitChar = "\u200b \u200b"; +export const setBlankSplitChar = v => { + BlankSplitChar = v; +}; +PropertyDescriptors["BlankSplitChar"] = { + enumerable: true, + configurable: true, + get: function() { + return BlankSplitChar; + }, + set: setBlankSplitChar, +}; + +// 一定返回最终的单位 +export let pixFormat = (pix, border) => { + if (!isNumber(pix)) { + return pix; + } + if (pixUnit === "px") { + return pix / pixRatio - (border || 0) + pixUnit; + } + const length = pix / pixRatio + pixUnit; + if (border > 0) { + return `calc(${length} - ${`${border}px`})`; + } + + return length; +}; +export const setPixFormat = v => { + pixFormat = v; +}; +PropertyDescriptors["pixFormat"] = { + enumerable: true, + configurable: true, + get: function() { + return pixFormat; + }, + set: setPixFormat, +}; + +export let toPix = (pix, border) => { + if (!isNumber(pix)) { + return pix; + } + if (pixUnit === "px") { + return pix - (border || 0) * pixRatio; + } + if (border > 0) { + return `calc(${pix / pixRatio + pixUnit} - ${`${border}px`})`; + } + + return pix; +}; +export let setToPix = v => { + toPix = v; +}; +PropertyDescriptors["toPix"] = { + enumerable: true, + configurable: true, + get: function() { + return toPix; + }, + set: setToPix, +}; + +const getCacheItem = key => { + Cache.getItem(key, { typeConversion: true, defaultValue: true }); +}; +export let EVENT_BLUR = _global.localStorage ? getCacheItem("event.blur") : true; +export const setEventBlur = v => { + EVENT_BLUR = v; + Cache.setItem("event.blur", v); +}; +PropertyDescriptors["EVENT_BLUR"] = { + enumerable: true, + configurable: true, + get: function() { + return EVENT_BLUR; + }, + set: setEventBlur, +}; + +export function _defineVarProperties(libName) { + Object.defineProperties(libName, PropertyDescriptors); +} diff --git a/packages/fineui/src/core/controller/0.controller.js b/packages/fineui/src/core/controller/0.controller.js new file mode 100644 index 000000000..7cda6a2a5 --- /dev/null +++ b/packages/fineui/src/core/controller/0.controller.js @@ -0,0 +1,10 @@ +/** + * guy + * 控制器 + * Controller层超类 + */ +import { OB } from "../3.ob"; + +export class Controller extends OB { + static EVENT_CHANGE = "__EVENT_CHANGE__"; +} diff --git a/packages/fineui/src/core/controller/controller.broadcast.js b/packages/fineui/src/core/controller/controller.broadcast.js new file mode 100644 index 000000000..3f1eb3035 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.broadcast.js @@ -0,0 +1,40 @@ +/** + * 广播 + * + * Created by GUY on 2015/12/23. + */ +import { Controller } from "./0.controller"; +import { each, remove } from "../2.base"; + +export class BroadcastController extends Controller { + init() { + this._broadcasts = {}; + } + + on(name, fn) { + if (!this._broadcasts[name]) { + this._broadcasts[name] = []; + } + this._broadcasts[name].push(fn); + + return () => this.remove(name, fn); + } + + send(name) { + const args = [].slice.call(arguments, 1); + each(this._broadcasts[name], (i, fn) => fn(...args)); + } + + remove(name, fn) { + if (fn) { + remove(this._broadcasts[name], (index, cb) => fn === cb); + if (this._broadcasts[name].length === 0) { + delete this._broadcasts[name]; + } + } else { + delete this._broadcasts[name]; + } + + return this; + } +} diff --git a/packages/fineui/src/core/controller/controller.bubbles.js b/packages/fineui/src/core/controller/controller.bubbles.js new file mode 100644 index 000000000..e92613312 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.bubbles.js @@ -0,0 +1,114 @@ +/** + * 气泡图控制器 + * 控制气泡图的显示方向 + * + * Created by GUY on 2015/8/21. + */ +import { Controller } from "./0.controller"; +import { isNotNull, each } from "../2.base"; +import { createWidget } from "../5.inject"; +import { createPopper } from "@popperjs/core"; + +export class BubblesController extends Controller { + init() { + this.storeBubbles = {}; + this.storePoppers = {}; + } + + /** + * + * @param name + * @param text + * @param context + * @param offsetStyle center, left, right三种类型, 默认left + * @returns {BubblesController} + */ + show(name, text, context, opt) { + opt || (opt = {}); + const container = opt.container || context; + const offsetStyle = opt.offsetStyle || "left"; + const level = opt.level || "error"; + const adjustYOffset = opt.adjustYOffset || 0; + const adjustXOffset = opt.adjustXOffset || 0; + // const fixed = opt.fixed !== false; + + if (!this.storeBubbles[name]) { + this.storeBubbles[name] = createWidget({ + type: "bi.text", + cls: `bi-bubble bubble-${level}`, + text, + hgap: 5, + height: 18, + }); + } + const bubble = this.storeBubbles[name]; + if (bubble.getText() !== text) { + bubble.setText(text); + } + + createWidget({ + type: "bi.default", + element: container, + items: [ + { + el: bubble, + } + ], + }); + if (this.storePoppers[name]) { + this.storePoppers[name].destroy(); + } + this.storePoppers[name] = createPopper(context.element[0], bubble.element[0], { + placement: ({ + left: "top-start", + center: "top", + right: "top-end", + })[offsetStyle], + strategy: "fixed", + modifiers: [ + { + name: "offset", + options: { + offset: [adjustXOffset, adjustYOffset], + }, + }, + { + name: "preventOverflow", + enabled: false, + } + ], + }); + + return this; + } + + hide(name) { + this.remove(name); + + return this; + } + + has(name) { + return isNotNull(this.storeBubbles[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + this.storeBubbles[name].destroy(); + this.storePoppers[name] && this.storePoppers[name].destroy(); + delete this.storeBubbles[name]; + + return this; + } + + removeAll() { + each(this.storeBubbles, (name, bubble) => bubble.destroy()); + each(this.storePoppers, (name, popper) => popper.destroy()); + this.storeBubbles = {}; + this.storePoppers = {}; + + return this; + } +} diff --git a/packages/fineui/src/core/controller/controller.drawer.js b/packages/fineui/src/core/controller/controller.drawer.js new file mode 100644 index 000000000..806d8c67b --- /dev/null +++ b/packages/fineui/src/core/controller/controller.drawer.js @@ -0,0 +1,164 @@ +/** + * guy + * popover弹出层控制器, z-index在100w层级 + */ +import { Controller } from "./0.controller"; +import { each, isNotNull } from "../2.base"; +import { createWidget } from "../5.inject"; + +export class DrawerController extends Controller { + constructor() { + super(); + this._constructor(); + this.modal = this.options.modal; + } + props = { + modal: true, // 模态窗口 + render: "body", + } + + init() { + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindexMap = {}; + } + + create(name, options, context) { + if (this.has(name)) { + return this; + } + const popover = createWidget(options || {}, { + type: "bi.drawer", + }, context); + this.add(name, popover, options, context); + + return this; + } + + open(name) { + if (!this.has(name)) { + return this; + } + if (!this.floatOpened[name]) { + this.floatOpened[name] = true; + const container = this.floatContainer[name]; + const zIndex = BI.Popovers._getZIndex(); + container.element.css("zIndex", zIndex); + this.modal && container.element.__hasZIndexMask__(this.zindexMap[name]) && container.element.__releaseZIndexMask__(this.zindexMap[name]); + this.zindexMap[name] = zIndex; + if (this.modal) { + const mask = container.element.__buildZIndexMask__(BI.Popovers._getZIndex()); + mask.click(() => { + mask.destroy(); + this.get(name).close(); + }); + } + this.get(name).setZindex(BI.Popovers._getZIndex()); + this.floatContainer[name].visible(); + const popover = this.get(name); + popover.show && popover.show(); + } + + return this; + } + + close(name) { + if (!this.has(name)) { + return this; + } + if (this.floatOpened[name]) { + delete this.floatOpened[name]; + this.floatContainer[name].invisible(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + } + + return this; + } + + show(name) { + return this.open(name); + } + + hide(name) { + return this.close(name); + } + + isVisible(name) { + return this.has(name) && this.floatOpened[name] === true; + } + + add(name, popover, options, context) { + options || (options = {}); + if (this.has(name)) { + return this; + } + this.floatContainer[name] = createWidget({ + type: "bi.absolute", + cls: "bi-popup-view", + items: [{ + el: (this.floatLayer[name] = createWidget({ + type: "bi.absolute", + items: [popover], + }, context)), + left: 0, + right: 0, + top: 0, + bottom: 0, + }], + }); + this.floatManager[name] = popover; + popover.on(BI.Drawer.EVENT_CLOSE, () => this.close(name)); + createWidget({ + type: "bi.absolute", + element: options.container || this.options.render, + items: [{ + el: this.floatContainer[name], + left: 0, + right: 0, + top: 0, + bottom: 0, + }], + }); + + return this; + } + + get(name) { + return this.floatManager[name]; + } + + has(name) { + return isNotNull(this.floatManager[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + this.floatContainer[name].destroy(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + delete this.floatManager[name]; + delete this.floatLayer[name]; + delete this.zindexMap[name]; + delete this.floatContainer[name]; + delete this.floatOpened[name]; + + return this; + } + + removeAll() { + each(this.floatContainer, (name, container) => { + container.destroy(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + }); + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindexMap = {}; + + return this; + } +} diff --git a/packages/fineui/src/core/controller/controller.layer.js b/packages/fineui/src/core/controller/controller.layer.js new file mode 100644 index 000000000..7b3196ef2 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.layer.js @@ -0,0 +1,201 @@ +/** + * 弹出层面板控制器, z-index在10w层级 + * + * Created by GUY on 2015/6/24. + */ +import { Controller } from "./0.controller"; +import { isNull, isNotNull, each, keys, isWidget, isNotEmptyString, extend, bind, uniqueId } from "../2.base"; +import { Widget } from "../4.widget"; +import { createWidget } from "../5.inject"; +import { zIndex_layer } from "../constant"; +import { DOM } from "../utils"; + +export class LayerController extends Controller { + constructor(Resizers) { + super(); + this._constructor(); + this.Resizers = Resizers; + } + + props = { + render: "body", + }; + + init() { + this.layerManager = {}; + this.layouts = {}; + this.zindex = zIndex_layer; + } + + _initResizer() { + this.resizer = this.Resizers.add(`layerController${uniqueId()}`, bind(this._resize, this)); + } + + _resize() { + each(this.layouts, (i, layer) => { + if (layer.element.is(":visible")) { + layer.element.trigger("__resize__"); + } + }); + } + + make(name, container, op, context) { + if (isWidget(container)) { + op = op || {}; + op.container = container; + } else { + context = op; + op = container; + } + + return this.create(name, null, op, context); + } + + create(name, from, op, context) { + isNull(this.resizer) && this._initResizer(); + if (this.has(name)) { + return this.get(name); + } + op || (op = {}); + const offset = op.offset || {}; + let w = from; + if (isWidget(from)) { + w = from.element; + } + if (isNotEmptyString(w)) { + w = Widget._renderEngine.createElement(w); + } + if (this.has(name)) { + return this.get(name); + } + const widget = createWidget((op.render || {}), extend({ + type: "bi.layout", + }, op), context); + const layout = createWidget({ + type: "bi.absolute", + invisible: true, + items: [ + { + el: widget, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }, context); + createWidget({ + type: "bi.absolute", + element: op.container || this.options.render, + items: [ + { + el: layout, + left: offset.left || 0, + right: offset.right || 0, + top: offset.top || 0, + bottom: offset.bottom || 0, + } + ], + }); + if (w) { + layout.element.addClass("bi-popup-view"); + + function getComputedPosition() { + const css = { + left: w.offset().left + (offset.left || 0), + top: w.offset().top + (offset.top || 0), + width: offset.width || (w.outerWidth() - (offset.left || 0) - (offset.right || 0)) || "", + height: offset.height || (w.outerHeight() - (offset.top || 0) - (offset.bottom || 0)) || "", + }; + + const { top, left, scaleY, scaleX } = DOM.getPositionRelativeContainingBlockRect(layout.element[0]); + + css.top = (css.top - top) / scaleY; + css.left = (css.left - left) / scaleX; + + return css; + } + + + layout.element.css(getComputedPosition()); + layout.element.on("__resize__", () => { + w.is(":visible") && + layout.element.css(getComputedPosition()); + }); + } + this.add(name, widget, layout); + + return widget; + } + + show(name, callback) { + if (!this.has(name)) { + return this; + } + this._getLayout(name).visible(); + this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); + + return this; + } + + hide(name, callback) { + if (!this.has(name)) { + return this; + } + this._getLayout(name).invisible(); + this._getLayout(name).element.hide(0, callback); + + return this; + } + + isVisible(name) { + return this.has(name) && this._getLayout(name).isVisible(); + } + + add(name, layer, layout) { + if (this.has(name)) { + throw new Error("can not create Layers with the same name"); + } + layout.setVisible(false); + this.layerManager[name] = layer; + this.layouts[name] = layout; + layout.element.css("z-index", this.zindex++); + + return this; + } + + _getLayout(name) { + return this.layouts[name]; + } + + get(name) { + return this.layerManager[name]; + } + + has(name) { + return isNotNull(this.layerManager[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + this.layerManager[name].destroy(); + this.layouts[name].destroy(); + delete this.layerManager[name]; + delete this.layouts[name]; + + return this; + } + + removeAll() { + each(keys(this.layerManager), (index, name) => { + this.layerManager[name].destroy(); + this.layouts[name].destroy(); + }); + this.layerManager = {}; + this.layouts = {}; + + return this; + } +} diff --git a/packages/fineui/src/core/controller/controller.masker.js b/packages/fineui/src/core/controller/controller.masker.js new file mode 100644 index 000000000..cd8f4cc05 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.masker.js @@ -0,0 +1,18 @@ +/** + * 遮罩面板, z-index在1亿层级 + * + * Created by GUY on 2015/6/24. + */ +import { LayerController } from "./controller.layer"; +import { zIndex_masker } from "../constant"; + +export class MaskersController extends LayerController { + constructor (Resizers) { + super(Resizers); + } + + init() { + super.init(...arguments); + this.zindex = zIndex_masker; + } +} diff --git a/packages/fineui/src/core/controller/controller.popover.js b/packages/fineui/src/core/controller/controller.popover.js new file mode 100644 index 000000000..b3fa2bbc5 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.popover.js @@ -0,0 +1,180 @@ +/** + * guy + * popover弹出层控制器, z-index在100w层级 + */ +import { Controller } from "./0.controller"; +import { isNotNull, each } from "../2.base"; +import { Widget } from "../4.widget"; +import { createWidget } from "../5.inject"; +import { zIndex_popover } from "../constant"; + +export class PopoverController extends Controller { + constructor() { + super(); + this._constructor(); + this.modal = this.options.modal; + } + + props = { + modal: true, // 模态窗口 + render: "body", + } + + init() { + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindex = zIndex_popover; + this.zindexMap = {}; + } + + create(name, options, context) { + if (this.has(name)) { + return this; + } + const popover = createWidget(options || {}, { + type: "bi.popover", + }, context); + this.add(name, popover, options, context); + + return this; + } + + open(name) { + if (!this.has(name)) { + return this; + } + if (!this.floatOpened[name]) { + this.floatOpened[name] = true; + const container = this.floatContainer[name]; + container.element.css("zIndex", this.zindex++); + this.modal && container.element.__hasZIndexMask__(this.zindexMap[name]) && container.element.__releaseZIndexMask__(this.zindexMap[name]); + this.zindexMap[name] = this.zindex; + this.modal && container.element.__buildZIndexMask__(this.zindex++); + this.get(name).setZindex(this.zindex++); + this.floatContainer[name].visible(); + const popover = this.get(name); + popover.show && popover.show(); + const W = Widget._renderEngine.createElement(this.options.render).width(), + H = Widget._renderEngine.createElement(this.options.render).height(); + const w = popover.element.width(), h = popover.element.height(); + let left = (W - w) / 2, top = (H - h) / 2; + if (left < 0) { + left = 0; + } + if (top < 0) { + top = 0; + } + popover.element.css({ + // 这里直接用px就可以 + left: `${left}px`, + top: `${top}px`, + }); + } + + return this; + } + + close(name) { + if (!this.has(name)) { + return this; + } + if (this.floatOpened[name]) { + delete this.floatOpened[name]; + this.floatContainer[name].invisible(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + } + + return this; + } + + show(name) { + return this.open(name); + } + + hide(name) { + return this.close(name); + } + + isVisible(name) { + return this.has(name) && this.floatOpened[name] === true; + } + + add(name, popover, options, context) { + options || (options = {}); + if (this.has(name)) { + return this; + } + this.floatContainer[name] = createWidget({ + type: "bi.absolute", + cls: "bi-popup-view", + items: [{ + el: (this.floatLayer[name] = createWidget({ + type: "bi.absolute", + items: [popover], + }, context)), + left: 0, + right: 0, + top: 0, + bottom: 0, + }], + }); + this.floatManager[name] = popover; + popover.on(BI.Popover.EVENT_CLOSE, () => this.close(name)); + createWidget({ + type: "bi.absolute", + element: options.container || this.options.render, + items: [{ + el: this.floatContainer[name], + left: 0, + right: 0, + top: 0, + bottom: 0, + }], + }); + + return this; + } + + get(name) { + return this.floatManager[name]; + } + + has(name) { + return isNotNull(this.floatManager[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + this.floatContainer[name].destroy(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + delete this.floatManager[name]; + delete this.floatLayer[name]; + delete this.zindexMap[name]; + delete this.floatContainer[name]; + delete this.floatOpened[name]; + + return this; + } + + removeAll() { + each(this.floatContainer, (name, container) => { + container.destroy(); + this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); + }); + this.floatManager = {}; + this.floatLayer = {}; + this.floatContainer = {}; + this.floatOpened = {}; + this.zindexMap = {}; + + return this; + } + + _getZIndex() { + return this.zindex++; + } +} diff --git a/packages/fineui/src/core/controller/controller.resizer.js b/packages/fineui/src/core/controller/controller.resizer.js new file mode 100644 index 000000000..421f06c6d --- /dev/null +++ b/packages/fineui/src/core/controller/controller.resizer.js @@ -0,0 +1,74 @@ +/** + * window.resize 控制器 + * + * Created by GUY on 2015/6/24. + */ +import { Controller } from "./0.controller"; +import { isNull, each, debounce, isNotNull, isFunction } from "../2.base"; +import { Widget } from "../4.widget"; +import { _global } from "../0.foundation"; +import { Layout } from "../wrapper/layout"; +import $ from "jquery"; + +export class ResizeController extends Controller { + init() { + this.resizerManger = {}; + } + + _initResizeListener() { + this.resizeHandler = debounce(ev => this._resize(ev), 30); + if ("onorientationchange" in _global) { + _global.onorientationchange = this.resizeHandler; + } else { + Widget._renderEngine.createElement(_global).resize(this.resizeHandler); + } + } + + _resize(ev) { + each(this.resizerManger, (key, resizer) => { + if (resizer instanceof $) { + if (resizer.is(":visible")) { + resizer.trigger("__resize__"); + } + + return; + } + if (resizer instanceof Layout) { + resizer.resize(); + + return; + } + if (isFunction(resizer)) { + resizer(ev); + } + }); + } + + add(name, resizer) { + isNull(this.resizeHandler) && this._initResizeListener(); + + if (this.has(name)) { + return this; + } + this.resizerManger[name] = resizer; + + return () => this.remove(name); + } + + get(name) { + return this.resizerManger[name]; + } + + has(name) { + return isNotNull(this.resizerManger[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + delete this.resizerManger[name]; + + return this; + } +} diff --git a/packages/fineui/src/core/controller/controller.tooltips.js b/packages/fineui/src/core/controller/controller.tooltips.js new file mode 100644 index 000000000..da571a504 --- /dev/null +++ b/packages/fineui/src/core/controller/controller.tooltips.js @@ -0,0 +1,156 @@ +/** + * tooltip控制器 + * 控制tooltip的显示, 且页面中只有一个tooltip显示 + * + * Created by GUY on 2015/9/8. + */ +import { Controller } from "./0.controller"; +import { each, isNotNull } from "../2.base"; +import { Widget } from "../4.widget"; +import { createWidget } from "../5.inject"; + +export class TooltipsController extends Controller { + init() { + this.tooltipsManager = {}; + this.showingTips = {};// 存储正在显示的tooltip + } + + /** + * + * @param opt + * @param opt.text {String} 文本 + * @param opt.level {String} 级别, success或warning + * @param opt.textAlign {String} 文本对齐方式, left, center, right + * @returns {*} + * @private + */ + _createTooltip(opt) { + return createWidget({ + type: "bi.tooltip", + ...opt, + stopEvent: true, + }); + } + + // opt: {container: '', belowMouse: false} + show(e, name, tooltipOpt, context, opt) { + opt || (opt = {}); + each(this.showingTips, (i, tip) => this.hide(i)); + this.showingTips = {}; + if (!this.has(name)) { + this.create(name, tooltipOpt, document.fullscreenElement ? context : (opt.container || "body")); + } + const offset = context.element.offset(); + let top; + + if (!opt.belowMouse) { + const bounds = context.element.bounds(); + if (bounds.height === 0 || bounds.width === 0) { + return; + } + top = offset.top + bounds.height + 5; + } + const tooltip = this.get(name); + tooltip.element.css({ + left: "0px", + top: "0px", + }); + tooltip.visible(); + tooltip.element.height(tooltip.element[0].scrollHeight); + this.showingTips[name] = true; + // scale影响要计算在内 + // const scale = context.element.offset().left / context.element.get(0).getBoundingClientRect().left; + // const x = (e.pageX || e.clientX) * scale + 15, y = (e.pageY || e.clientY) * scale + 15; + let x = (e.pageX || e.clientX) + 15, y = (e.pageY || e.clientY) + 15; + if (x + tooltip.element.outerWidth() > Widget._renderEngine.createElement("body").outerWidth()) { + x -= tooltip.element.outerWidth() + 15; + } + const bodyHeight = Widget._renderEngine.createElement("body").outerHeight(); + if (y + tooltip.element.outerHeight() > bodyHeight || top + tooltip.element.outerHeight() > bodyHeight) { + y -= tooltip.element.outerHeight() + 15; + !opt.belowMouse && (y = Math.min(y, offset.top - tooltip.element.outerHeight() - 5)); + } else { + !opt.belowMouse && (y = Math.max(y, top)); + } + tooltip.element.css({ + // 这里直接用px就可以 + left: x < 0 ? 0 : `${x}px`, + top: y < 0 ? 0 : `${y}px`, + }); + tooltip.element.hover(() => { + this.remove(name); + context.element.trigger(`mouseleave.title${context.getName()}`); + }); + + return this; + } + + hide(name, callback) { + if (!this.has(name)) { + return this; + } + delete this.showingTips[name]; + this.get(name).element.hide(0, callback); + this.get(name).invisible(); + + return this; + } + + create(name, tooltipOpt, context) { + if (!this.has(name)) { + const tooltip = this._createTooltip(tooltipOpt); + this.add(name, tooltip); + createWidget({ + type: "bi.absolute", + element: context || "body", + items: [{ + el: tooltip, + }], + }); + tooltip.invisible(); + } + + return this.get(name); + } + + add(name, bubble) { + if (this.has(name)) { + return this; + } + this.set(name, bubble); + + return this; + } + + get(name) { + return this.tooltipsManager[name]; + } + + set(name, bubble) { + this.tooltipsManager[name] = bubble; + } + + has(name) { + return isNotNull(this.tooltipsManager[name]); + } + + remove(name) { + if (!this.has(name)) { + return this; + } + this.tooltipsManager[name].destroy(); + delete this.tooltipsManager[name]; + + return this; + } + + removeAll() { + each(this.tooltipsManager, (name, tooltip) => { + tooltip.destroy(); + }); + this.tooltipsManager = {}; + this.showingTips = {}; + + return this; + } +} diff --git a/packages/fineui/src/core/controller/index.js b/packages/fineui/src/core/controller/index.js new file mode 100644 index 000000000..c025e0daa --- /dev/null +++ b/packages/fineui/src/core/controller/index.js @@ -0,0 +1,9 @@ +export { Controller } from "./0.controller"; +export { BroadcastController } from "./controller.broadcast"; +export { BubblesController } from "./controller.bubbles"; +export { DrawerController } from "./controller.drawer"; +export { LayerController } from "./controller.layer"; +export { MaskersController } from "./controller.masker"; +export { PopoverController } from "./controller.popover"; +export { ResizeController } from "./controller.resizer"; +export { TooltipsController } from "./controller.tooltips"; diff --git a/packages/fineui/src/core/decorator.js b/packages/fineui/src/core/decorator.js new file mode 100644 index 000000000..589a67367 --- /dev/null +++ b/packages/fineui/src/core/decorator.js @@ -0,0 +1,70 @@ +import * as inject from "./5.inject"; + +const transFunc2Decorator = targetFunc => { + return function () { + return function decorator(Target) { + targetFunc(Target.xtype, Target); + }; + }; +}; + +export const shortcut = transFunc2Decorator(inject.shortcut); +export const service = transFunc2Decorator(inject.service); +export const provider = transFunc2Decorator(inject.provider); +export const model = transFunc2Decorator(inject.model); + +/** + * 类注册_store属性 + * @param Model model类 + * @param opts 额外条件 + */ +export function store(Model, opts = {}) { + return function classDecorator(constructor) { + return class extends constructor { + _store() { + const props = opts.props ? opts.props.apply(this) : undefined; + + return inject.Models.getModel(Model.xtype, props); + } + }; + }; +} + +/** + * 注册mixin + * ie8下不能使用 + */ +export function mixin() { + return function decorator(Target) { + const mixin = {}; + + Object.getOwnPropertyNames(Target.prototype).forEach(name => { + if (name === "constructor") { + return; + } + + mixin[name] = Target.prototype[name]; + }); + + Fix.mixin(Target.xtype, mixin); + }; +} + +/** + * 类注册mixins属性 + * ie8下不能使用 + * @param Mixins + */ +export function mixins(...Mixins) { + return function classDecorator(constructor) { + const mixins = []; + + Mixins.forEach(mixin => { + mixin.xtype && mixins.push(mixin.xtype); + }); + + return class extends constructor { + mixins = mixins; + }; + }; +} diff --git a/packages/fineui/src/core/element/element.js b/packages/fineui/src/core/element/element.js new file mode 100644 index 000000000..9b08c0762 --- /dev/null +++ b/packages/fineui/src/core/element/element.js @@ -0,0 +1,76 @@ +import { registFunction } from "./plugins"; +import { isWidget, isString } from "../2.base"; + +export function Element(widget, attribs) { + this.l = this.r = this.t = this.b = 0; // 边框 + this.marginLeft = this.marginRight = this.marginTop = this.marginBottom = 0; // 间距 + this.position = {}; + this.classMap = {}; + this.classList = []; + this.children = []; + this.attribs = attribs || {}; + this.styles = {}; + // 兼容处理 + this["0"] = this; + this.style = {}; + if (!widget) { + this.nodeName = "body"; + this.position.x = 0; + this.position.y = 0; + this.attribs.id = "body"; + } else if (isWidget(widget)) { + this.widget = widget; + this.nodeName = widget.options.tagName; + this.textBaseLine = widget.options.textBaseLine; + } else if (isString(widget)) { + this.nodeName = widget; + } +} + +initElement(Element); +registFunction(Element); + +function initElement(element) { + element.prototype = { + appendChild(child) { + child.parent = this; + if (this.children.push(child) !== 1) { + const sibling = this.children[this.children.length - 2]; + sibling.next = child; + child.prev = sibling; + child.next = null; + } + }, + append(child) { + child.parent = this; + if (this.children.push(child) !== 1) { + const sibling = this.children[this.children.length - 2]; + sibling.next = child; + child.prev = sibling; + child.next = null; + } + }, + getParent() { + return this.parent; + }, + getSiblings() { + const parent = this.getParent(); + + return parent ? parent.getChildren() : [this]; + }, + getChildren() { + return this.children; + }, + + getBounds() { + return {}; + }, + + width() { + + }, + height() { + + }, + }; +} diff --git a/packages/fineui/src/core/element/index.js b/packages/fineui/src/core/element/index.js new file mode 100644 index 000000000..da27b0719 --- /dev/null +++ b/packages/fineui/src/core/element/index.js @@ -0,0 +1,33 @@ +import { Element } from "./element"; +import { isString, isWidget } from "../2.base"; + +Element.renderEngine = { + createElement: widget => { + if (isWidget(widget)) { + const o = widget.options; + if (o.element instanceof Element) { + return o.element; + } + if (typeof o.element === "string" && o.element !== "body") { + o.root = false; + + return new Element(widget); + } + + if (o.root === true) { + return new Element(); + } + } + if (isString(widget)) { + return new Element(widget); + } + + return new Element(widget); + }, + + createFragment() { + return new Element(); + }, +}; + +export { Element }; diff --git a/packages/fineui/src/core/element/plugins/attr.js b/packages/fineui/src/core/element/plugins/attr.js new file mode 100644 index 000000000..a680955c7 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/attr.js @@ -0,0 +1,25 @@ +import { isObject, each, isNull, isNotNull } from "../../2.base"; + +export const registAttrFun = Element => { + Element.registerFunction("attr", function (key, value) { + if (isObject(key)) { + each(key, (k, v) => { + this.attr(k, v); + }); + + return this; + } + if (isNull(value)) { + return this.attribs[key]; + } + this.attribs[key] = value; + + return this; + }); + Element.registerFunction("hasAttrib", function (key) { + return isNotNull(this.attribs[key]); + }); + Element.registerFunction("removeAttr", function (key) { + delete this.attribs[key]; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/class.js b/packages/fineui/src/core/element/plugins/class.js new file mode 100644 index 000000000..ac6e26890 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/class.js @@ -0,0 +1,25 @@ +import { each } from "../../2.base"; + +export const registClassFun = Element => { + Element.registerFunction("addClass", function (classList) { + each(classList.split(" "), (i, cls) => { + if (cls && !this.classMap[cls]) { + this.classList.push(cls); + } + cls && (this.classMap[cls] = true); + }); + + return this; + }); + + Element.registerFunction("removeClass", function (classList) { + each(classList.split(" "), (i, cls) => { + if (cls && this.classMap[cls]) { + delete this.classMap[cls]; + this.classList.splice(this.classList.indexOf(cls), 1); + } + }); + + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/css.js b/packages/fineui/src/core/element/plugins/css.js new file mode 100644 index 000000000..f5372da0e --- /dev/null +++ b/packages/fineui/src/core/element/plugins/css.js @@ -0,0 +1,26 @@ +import { isNull, isObject, each, trim, camelize } from "../../2.base"; + +export const registCssFun = Element => { + Element.registerFunction("css", function (key, value) { + if (isObject(key)) { + each(key, (k, v) => { + this.css(k, v); + }); + + return this; + } + key = trim(camelize(key)); + + return css(this, key, value); + }); +}; + +const css = (elem, key, value) => { + key = trim(camelize(key)); + if (isNull(value)) { + return elem.styles[key]; + } + elem.styles[key] = value; + + return elem; +}; diff --git a/packages/fineui/src/core/element/plugins/data.js b/packages/fineui/src/core/element/plugins/data.js new file mode 100644 index 000000000..0e7cbb2d5 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/data.js @@ -0,0 +1,15 @@ +import { isNull } from "../../2.base"; + +export const registDataFun = Element => { + Element.registerFunction("data", function (key, value) { + if (!this._data) { + this._data = {}; + } + if (isNull(value)) { + return this._data[key]; + } + this._data[key] = value; + + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/empty.js b/packages/fineui/src/core/element/plugins/empty.js new file mode 100644 index 000000000..3cfe0177c --- /dev/null +++ b/packages/fineui/src/core/element/plugins/empty.js @@ -0,0 +1,10 @@ +export const registEmptyFun = Element => { + Element.registerFunction("empty", function (text) { + this.children = []; + + return this; + }); + Element.registerFunction("destroy", function (text) { + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/event.js b/packages/fineui/src/core/element/plugins/event.js new file mode 100644 index 000000000..66d89de97 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/event.js @@ -0,0 +1,33 @@ +function returnThis () { + return this; +} + +export const registEventFun = Element => { + [ + "mousedown", + "mouseup", + "mousewheel", + "keydown", + "keyup", + "focus", + "focusin", + "focusout", + "click", + "on", + "off", + "bind", + "unbind", + "trigger", + "hover", + "scroll", + "scrollLeft", + "scrollTop", + "resize", + "show", + "hide", + "dblclick", + "blur" + ].forEach(event => { + Element.registerFunction(event, returnThis); + }); +}; diff --git a/packages/fineui/src/core/element/plugins/html.js b/packages/fineui/src/core/element/plugins/html.js new file mode 100644 index 000000000..18cf233d6 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/html.js @@ -0,0 +1,19 @@ +import { createWidget } from "../../5.inject"; +import { htmlDecode } from "../../func"; + +export const registHtmlFun = Element => { + Element.registerFunction("html", function (text) { + if (text && text.charAt(0) === "<") { + createWidget({ + type: "bi.html", + element: this.widget, + html: text, + }); + this.originalHtml = text; + } else { + this.text = htmlDecode(text); + } + + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/index.js b/packages/fineui/src/core/element/plugins/index.js new file mode 100644 index 000000000..79e2f692c --- /dev/null +++ b/packages/fineui/src/core/element/plugins/index.js @@ -0,0 +1,31 @@ +import { registAttrFun } from "./attr"; +import { registClassFun } from "./class"; +import { registCssFun } from "./css"; +import { registDataFun } from "./data"; +import { registEmptyFun } from "./empty"; +import { registEventFun } from "./event"; +import { registHtmlFun } from "./html"; +import { registKeywordMarkFun } from "./keywordMark"; +import { registRenderToHtmlFun } from "./renderToHtml"; +import { registRenderToStringFun } from "./renderToString"; +import { registTextFun } from "./text"; +import { registValFun } from "./val"; + +export const registFunction = Element => { + const functionMap = {}; + Element.registerFunction = (key, fn) => { + Element.prototype[key] = functionMap[key] = fn; + }; + registAttrFun(Element); + registClassFun(Element); + registCssFun(Element); + registDataFun(Element); + registEmptyFun(Element); + registEventFun(Element); + registHtmlFun(Element); + registKeywordMarkFun(Element); + registRenderToStringFun(Element); + registRenderToHtmlFun(Element); + registTextFun(Element); + registValFun(Element); +}; diff --git a/packages/fineui/src/core/element/plugins/keywordMark.js b/packages/fineui/src/core/element/plugins/keywordMark.js new file mode 100644 index 000000000..f0fcca96e --- /dev/null +++ b/packages/fineui/src/core/element/plugins/keywordMark.js @@ -0,0 +1,7 @@ +export const registKeywordMarkFun = Element => { + Element.registerFunction("__textKeywordMarked__", function (text) { + this[0].textContent = text; + + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/renderToHtml.js b/packages/fineui/src/core/element/plugins/renderToHtml.js new file mode 100644 index 000000000..a9db9f755 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/renderToHtml.js @@ -0,0 +1,69 @@ +import { each, isNull, hyphenate, isNumeric, isKey } from "../../2.base"; + +const skipArray = []; +const pxStyle = ["font-size", "width", "height"]; +function _renderToHtml(root) { + let str = ""; + if (isNull(root.originalHtml)) { + if (root.tag !== "body") { + str += `<${root.tag}`; + if (root.classList.length > 0) { + str += " class=\""; + each(root.classList, (i, cls) => { + str += ` ${cls}`; + }); + str += "\""; + } + str += " style=\""; + each(root.originalStyles, (key, stl) => { + if ( + skipArray.contains(key) || + (key === "height" && root.classList.contains("bi-design-components-data-data-table-cell")) + ) { + return; + } + key = hyphenate(key); + if (key === "font-family") { + stl = stl.replace(/"/g, ""); + } + if (pxStyle.contains(key) && isNumeric(stl)) { + stl += "px"; + } + if (isKey(stl)) { + str += ` ${key}:${stl};`; + } + }); + str += "\""; + each(root.attribs, (key, attr) => { + if (isKey(attr)) { + str += ` ${key}=${attr}`; + } + }); + if (root.textContent) { + str += ` title=${root.textContent}`; + } + str += ">"; + } + // 特殊处理,spread_table的行列元素是不取配置里的高度的,使用stretch拉伸的(leaves取了高度),但是功能代码里给单元格默认高度了,导致拉伸不了 + // 而spread_grid_table的行列元素是取配置里的高度的,拉不拉伸都一样 + each(root.children, (i, child) => { + str += _renderToHtml(child); + }); + } else { + str += root.originalHtml; + } + if (root.tag !== "body") { + if (root.textContent) { + str += root.textContent; + } + str += ``; + } + + return str; +} + +export const registRenderToHtmlFun = Element => { + Element.registerFunction("renderToHtml", function () { + return _renderToHtml(this); + }); +}; diff --git a/packages/fineui/src/core/element/plugins/renderToString.js b/packages/fineui/src/core/element/plugins/renderToString.js new file mode 100644 index 000000000..6ab9734dd --- /dev/null +++ b/packages/fineui/src/core/element/plugins/renderToString.js @@ -0,0 +1,54 @@ +import { each, hyphenate } from "../../2.base"; + +const skipArray = ["width", "height"]; +function _renderToString(root) { + let str = ""; + if (root.nodeName !== "body") { + str += `<${root.nodeName}`; + if (root.classList.length > 0) { + str += " class=\""; + each(root.classList, (i, cls) => { + str += ` ${cls}`; + }); + str += "\""; + } + str += " style=\""; + each(root.styles, (key, stl) => { + if (skipArray.includes(key)) { + return; + } + key = hyphenate(key); + str += ` ${key}:${stl};`; + }); + str += ` width:${root.width}px;`; + str += ` height:${root.height}px;`; + str += " position: fixed;"; + str += ` left: ${root.position.x}px;`; + str += ` top: ${root.position.y}px;`; + str += "\""; + each(root.attribs, (key, attr) => { + str += ` ${key}:${attr}`; + }); + str += ">"; + } + each(root.children, (i, child) => { + str += _renderToString(child); + }); + // if (root.htmlContent) { + // str += root.htmlContent; + // } + if (root.nodeName !== "body") { + if (root.text) { + str += root.text; + } + str += ``; + } + + return str; +} + +export const registRenderToStringFun = Element => { + Element.registerFunction("renderToString", function () { + return _renderToString(this); + }); +}; diff --git a/packages/fineui/src/core/element/plugins/text.js b/packages/fineui/src/core/element/plugins/text.js new file mode 100644 index 000000000..8e51fd178 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/text.js @@ -0,0 +1,12 @@ +export const registTextFun = Element => { + Element.registerFunction("setText", function (text) { + this.text = text; + + return this; + }); + Element.registerFunction("setValue", function (text) { + this.text = text; + + return this; + }); +}; diff --git a/packages/fineui/src/core/element/plugins/val.js b/packages/fineui/src/core/element/plugins/val.js new file mode 100644 index 000000000..4188cbd83 --- /dev/null +++ b/packages/fineui/src/core/element/plugins/val.js @@ -0,0 +1,13 @@ +import { isNotNull } from "../../2.base"; + +export const registValFun = Element => { + Element.registerFunction("val", function (value) { + if (isNotNull(value)) { + this.text = `${value}`; + + return this; + } + + return this.text; + }); +}; diff --git a/src/core/func/__test__/date.test.js b/packages/fineui/src/core/func/__test__/date.test.js similarity index 100% rename from src/core/func/__test__/date.test.js rename to packages/fineui/src/core/func/__test__/date.test.js diff --git a/packages/fineui/src/core/func/__test__/function.test.js b/packages/fineui/src/core/func/__test__/function.test.js new file mode 100644 index 000000000..db6901582 --- /dev/null +++ b/packages/fineui/src/core/func/__test__/function.test.js @@ -0,0 +1,24 @@ +/** + * @Author: lei.wang + * @Maintainers: lei.wang + * @Date: 2019-04-16 + */ +describe("core-function-test", function () { + /** + * test_author_lei.wang + */ + it("createDistinctName-支持字符串数组", function () { + const names = ["name", "name1"]; + expect(BI.Func.createDistinctName(names, "name")).to.equal("name2"); + expect(BI.Func.createDistinctName(names, "name2")).to.equal("name2"); + }); + + /** + * test_author_lei.wang + */ + it("createDistinctName-支持对象数组数组", function () { + const names = [{ name: "name" }, { name: "name1" }]; + expect(BI.Func.createDistinctName(names, "name")).to.equal("name2"); + expect(BI.Func.createDistinctName(names, "name2")).to.equal("name2"); + }); +}); diff --git a/src/core/func/__test__/string.test.js b/packages/fineui/src/core/func/__test__/string.test.js similarity index 100% rename from src/core/func/__test__/string.test.js rename to packages/fineui/src/core/func/__test__/string.test.js diff --git a/packages/fineui/src/core/func/alias.js b/packages/fineui/src/core/func/alias.js new file mode 100644 index 000000000..c2ddbb28f --- /dev/null +++ b/packages/fineui/src/core/func/alias.js @@ -0,0 +1,944 @@ +import { + each, + get, + isFunction, + isNull, + isObject, + isPlainObject, + keys, + leftPad, + parseDateTime, + values, + isArray +} from "../2.base"; +import { replaceAll } from "./string"; +import { getFullDayName, getMonthName, getTimezone } from "./date"; +import { _global } from "../0.foundation"; + +const getSpecialCharsMap = () => (get(_global, ["BI", "specialCharsMap"]) || {}); + +function isEmpty(value) { + // 判断是否为空值 + return value === "" || value === null || value === undefined; +} + +// 判断是否是无效的日期 +function isInvalidDate(date) { + return date === "Invalid Date" || date === "NaN"; +} + +/** + * CHART-1400 + * 使用数值计算的方式来获取任意数值的科学技术表示值。 + * 科学计数格式 + */ +function _eFormat(text, fmt) { + text = +text; + + return eFormat(text, fmt); + + /** + * 科学计数格式具体计算过程 + * @param num + * @param format {String}有两种形式, + * 1、"0.00E00"这样的字符串表示正常的科学计数表示,只不过规定了数值精确到百分位, + * 而数量级的绝对值如果是10以下的时候在前面补零。 + * 2、 "##0.0E0"这样的字符串则规定用科学计数法表示之后的数值的整数部分是三位,精确到十分位, + * 数量级没有规定,因为没见过实数里有用科学计数法表示之后E的后面会小于一位的情况(0无所谓)。 + * @returns {*} + */ + function eFormat(num, format) { + let neg = num < 0 ? (num *= -1, "-") : "", + magnitudeNeg = ""; + + const funcName = num > 0 && num < 1 ? "floor" : "ceil"; // -0.9999->-1 + // 数量级 + let magnitude = Math[funcName](Math.log(num) / Math.log(10)); + + if (!isFinite(magnitude)) { + return format.replace(/#/ig, "").replace(/\.e/ig, "E"); + } + + num = num / Math.pow(10, magnitude); + + // 让num转化成[1, 10)区间上的数 + if (num > 0 && num < 1) { + num *= 10; + magnitude -= 1; + } + + // 计算出format中需要显示的整数部分的位数,然后更新这个数值,也更新数量级 + const integerLen = getInteger(magnitude, format); + integerLen > 1 && (magnitude -= integerLen - 1, num *= Math.pow(10, integerLen - 1)); + + magnitude < 0 && (magnitudeNeg = "-", magnitude *= -1); + + // 获取科学计数法精确到的位数 + const precision = getPrecision(format); + // 判断num经过四舍五入之后是否有进位 + const isValueCarry = isValueCarried(num); + + num *= Math.pow(10, precision); + num = Math.round(num); + // 如果出现进位的情况,将num除以10 + isValueCarry && (num /= 10, magnitude += magnitudeNeg === "-" ? -1 : 1); + num /= Math.pow(10, precision); + + // 小数部分保留precision位 + num = num.toFixed(precision); + // 格式化指数的部分 + magnitude = formatExponential(format, magnitude, magnitudeNeg); + + return `${neg + num}E${magnitude}`; + } + + // 获取format格式规定的数量级的形式 + function formatExponential(format, num, magnitudeNeg) { + num += ""; + if (!/e/ig.test(format)) { + return num; + } + format = format.split(/e/ig)[1]; + + while (num.length < format.length) { + num = `0${num}`; + } + + // 如果magnitudeNeg是一个"-",而且num正好全是0,那么就别显示负号了 + let isAllZero = true; + for (let i = 0, len = num.length; i < len; i++) { + if (!isAllZero) { + continue; + } + isAllZero = num.charAt(i) === "0"; + } + magnitudeNeg = isAllZero ? "" : magnitudeNeg; + + return magnitudeNeg + num; + } + + // 获取format规定的科学计数法精确到的位数 + function getPrecision(format) { + if (!/e/ig.test(format)) { + return 0; + } + const arr = format.split(/e/ig)[0].split("."); + + return arr.length > 1 ? arr[1].length : 0; + } + + // 获取数值科学计数法表示之后整数的位数 + // 这边我们还需要考虑#和0的问题 + function getInteger(magnitude, format) { + if (!/e/ig.test(format)) { + return 0; + } + // return format.split(/e/ig)[0].split(".")[0].length; + + let formatLeft = format.split(/e/ig)[0].split(".")[0], i, f, len = formatLeft.length; + let valueLeftLen = 0; + + for (i = 0; i < len; i++) { + f = formatLeft.charAt(i); + // "#"所在的位置到末尾长度小于等于值的整数部分长度,那么这个#才可以占位 + if (f == 0 || (f == "#" && (len - i <= magnitude + 1))) { + valueLeftLen++; + } + } + + return valueLeftLen; + } + + // 判断num通过round函数之后是否有进位 + function isValueCarried(num) { + let roundNum = Math.round(num); + num = (`${num}`).split(".")[0]; + roundNum = (`${roundNum}`).split(".")[0]; + + return num.length !== roundNum.length; + } +} + +// '#.##'之类的格式处理 1.324e-18 这种的科学数字 +function _dealNumberPrecision(text, fright) { + if (/[eE]/.test(text)) { + let precision = 0, i = 0, ch; + + if (/[%‰]$/.test(fright)) { + precision = /[%]$/.test(fright) ? 2 : 3; + } + + for (let len = fright.length; i < len; i++) { + if ((ch = fright.charAt(i)) == "0" || ch == "#") { + precision++; + } + } + + return Number(text).toFixed(precision); + } + + return text; +} + +/** + * 数字格式 + */ +function _numberFormat(text, format) { + text = `${text}`; + + // 在调用数字格式的时候如果text里没有任何数字则不处理 + if (!(/[0-9]/.test(text)) || !format) { + return text; + } + + // 数字格式,区分正负数 + const numMod = format.indexOf(";"); + if (numMod > -1) { + if (text >= 0) { + return _numberFormat(`${text}`, format.substring(0, numMod)); + } + + return _numberFormat(`${-text}`, format.substring(numMod + 1)); + } else { + // 兼容格式处理负数的情况(copy:fr-jquery.format.js) + if (+text < 0 && format.charAt(0) !== "-") { + return _numberFormat(`${-text}`, `-${format}`); + } + } + + const fp = format.split("."), fleft = fp[0] || "", fright = fp[1] || ""; + text = _dealNumberPrecision(text, fright); + let tp = text.split("."), tleft = tp[0] || "", tright = tp[1] || ""; + + // 百分比,千分比的小数点移位处理 + if (/[%‰]$/.test(format)) { + const paddingZero = /[%]$/.test(format) ? "00" : "000"; + tright += paddingZero; + tleft += tright.substring(0, paddingZero.length); + tleft = tleft.replace(/^0+/gi, ""); + tright = tright.substring(paddingZero.length).replace(/0+$/gi, ""); + } + let right = _dealWithRight(tright, fright); + if (right.leftPlus) { + // 小数点后有进位 + tleft = `${parseInt(tleft) + 1}`; + + tleft = isNaN(tleft) ? "1" : tleft; + } + right = right.num; + let left = _dealWithLeft(tleft, fleft); + if (!(/[0-9]/.test(left))) { + left = `${left}0`; + } + if (!(/[0-9]/.test(right))) { + return left + right; + } else { + return `${left}.${right}`; + } +} + +/** + * 处理小数点右边小数部分 + * @param tright 右边内容 + * @param fright 右边格式 + * @returns {JSON} 返回处理结果和整数部分是否需要进位 + * @private + */ +function _dealWithRight(tright, fright) { + let right = "", j = 0, i = 0; + for (let len = fright.length; i < len; i++) { + const ch = fright.charAt(i); + let c = tright.charAt(j); + switch (ch) { + case "0": + if (isEmpty(c)) { + c = "0"; + } + right += c; + j++; + break; + case "#": + right += c; + j++; + break; + default : + right += ch; + break; + } + } + const rll = tright.substring(j); + const result = {}; + if (!isEmpty(rll) && rll.charAt(0) > 4) { + // 有多余字符,需要四舍五入 + result.leftPlus = true; + const numReg = right.match(/^[0-9]+/); + if (numReg) { + const num = numReg[0]; + const orilen = num.length; + let newnum = `${parseInt(num) + 1}`; + // 进位到整数部分 + if (newnum.length > orilen) { + newnum = newnum.substring(1); + } else { + newnum = leftPad(newnum, orilen, "0"); + result.leftPlus = false; + } + right = right.replace(/^[0-9]+/, newnum); + } + } + result.num = right; + + return result; +} + +/** + * 处理小数点左边整数部分 + * @param tleft 左边内容 + * @param fleft 左边格式 + * @returns {string} 返回处理结果 + * @private + */ +function _dealWithLeft(tleft, fleft) { + let newstr; + let left = ""; + let j = tleft.length - 1; + let combo = -1, last = -1; + let i = fleft.length - 1; + for (; i >= 0; i--) { + const ch = fleft.charAt(i); + let c = tleft.charAt(j); + switch (ch) { + case "0": + if (isEmpty(c)) { + c = "0"; + } + last = -1; + left = c + left; + j--; + break; + case "#": + last = i; + left = c + left; + j--; + break; + case ",": + if (!isEmpty(c)) { + // 计算一个,分隔区间的长度 + const com = fleft.match(/,[#0]+/); + if (com) { + combo = com[0].length - 1; + } + left = `,${left}`; + } + break; + default : + left = ch + left; + break; + } + } + if (last > -1) { + // 处理剩余字符 + const tll = tleft.substring(0, j + 1); + left = left.substring(0, last) + tll + left.substring(last); + } + if (combo > 0) { + // 处理,分隔区间 + let res = left.match(/[0-9]+,/); + if (res) { + res = res[0]; + newstr = ""; + let n = res.length - 1 - combo; + for (; n >= 0; n = n - combo) { + newstr = `${res.substring(n, n + combo)},${newstr}`; + } + const lres = res.substring(0, n + combo); + if (!isEmpty(lres)) { + newstr = `${lres},${newstr}`; + } + } + left = left.replace(/[0-9]+,/, newstr); + } + + return left; +} + +export const cjkEncode = function(text) { + // alex:如果非字符串,返回其本身(cjkEncode(234) 返回 ""是不对的) + if (typeof text !== "string") { + return text; + } + + let newText = ""; + for (let i = 0; i < text.length; i++) { + const code = text.charCodeAt(i); + if (code >= 128 || code === 91 || code === 93) {// 91 is "[", 93 is "]". + newText += `[${code.toString(16)}]`; + } else { + newText += text.charAt(i); + } + } + + return newText; +}; + +/** + * 将cjkEncode处理过的字符串转化为原始字符串 + * + * @static + * @param text 需要做解码的字符串 + * @return {String} 解码后的字符串 + */ +export const cjkDecode = function(text) { + if (text == null) { + return ""; + } + // 查找没有 "[", 直接返回. kunsnat:数字的时候, 不支持indexOf方法, 也是直接返回. + if (!isNaN(text) || text.indexOf("[") === -1) { + return text; + } + + let newText = ""; + for (let i = 0; i < text.length; i++) { + let ch = text.charAt(i); + if (ch === "[") { + const rightIdx = text.indexOf("]", i + 1); + if (rightIdx > i + 1) { + const subText = text.substring(i + 1, rightIdx); + // james:主要是考虑[CDATA[]]这样的值的出现 + if (subText.length > 0) { + ch = String.fromCharCode(eval(`0x${subText}`)); + } + + i = rightIdx; + } + } + + newText += ch; + } + + return newText; +}; + +// replace the html special tags +const SPECIAL_TAGS = { + "&": "&", + "\"": """, + "<": "<", + ">": ">", + "\x20": " ", + "\n": " ", +}; +export const htmlEncode = function(text) { + return isNull(text) ? "" : replaceAll(`${text}`, keys(SPECIAL_TAGS).join("|"), v => SPECIAL_TAGS[v] ? SPECIAL_TAGS[v] : v); +}; +// html decode +export const htmlDecode = function(text) { + return isNull(text) ? "" : replaceAll(`${text}`, values(SPECIAL_TAGS).join("|"), v => { + switch (v) { + case "&": + return "&"; + case """: + return "\""; + case "<": + return "<"; + case ">": + return ">"; + case " ": + return " "; + case " ": + return "\n"; + default: + return v; + } + }); +}; + +export const cjkEncodeDO = function(o) { + if (isPlainObject(o)) { + const result = {}; + each(o, (k, v) => { + if (!(typeof v === "string")) { + v = jsonEncode(v); + } + // wei:bug 43338,如果key是中文,cjkencode后o的长度就加了1,ie9以下版本死循环,所以新建对象result。 + k = cjkEncode(k); + result[k] = cjkEncode(v); + }); + + return result; + } + + return o; +}; + +export const jsonEncode = function(o) { + // james:这个Encode是抄的EXT的 + const useHasOwn = !!{}.hasOwnProperty; + + // crashes Safari in some instances + // var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/; + + const m = { + "\b": "\\b", + "\t": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "\"": "\\\"", + "\\": "\\\\", + }; + + const encodeString = function(s) { + if (/["\\\x00-\x1f]/.test(s)) { + return `"${s.replace(/([\x00-\x1f\\"])/g, (a, b) => { + let c = m[b]; + if (c) { + return c; + } + c = b.charCodeAt(); + + return `\\u00${ + Math.floor(c / 16).toString(16) + }${(c % 16).toString(16)}`; + })}"`; + } + + return `"${s}"`; + }; + + const encodeArray = function(o) { + let a = ["["], b, i, l = o.length, v; + for (i = 0; i < l; i += 1) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "function": + case "unknown": + break; + default: + if (b) { + a.push(","); + } + a.push(v === null ? "null" : jsonEncode(v)); + b = true; + } + } + a.push("]"); + + return a.join(""); + }; + + if (typeof o === "undefined" || o === null) { + return "null"; + } else if (isArray(o)) { + return encodeArray(o); + } else if (o instanceof Date) { + /* + * alex:原来只是把年月日时分秒简单地拼成一个String,无法decode + * 现在这么处理就可以decode了,但是JS.jsonDecode和Java.JSONObject也要跟着改一下 + */ + return jsonEncode({ + __time__: o.getTime(), + }); + } else if (typeof o === "string") { + return encodeString(o); + } else if (typeof o === "number") { + return isFinite(o) ? String(o) : "null"; + } else if (typeof o === "boolean") { + return String(o); + } else if (isFunction(o)) { + return String(o); + } + let a = ["{"], b, i, v; + for (i in o) { + if (!useHasOwn || o.hasOwnProperty(i)) { + v = o[i]; + switch (typeof v) { + case "undefined": + case "unknown": + break; + default: + if (b) { + a.push(","); + } + a.push(jsonEncode(i), ":", + v === null ? "null" : jsonEncode(v)); + b = true; + } + } + } + a.push("}"); + + return a.join(""); +}; + +export const jsonDecode = function(text) { + let jo; + try { + jo = JSON.parse(text); + if (jo == null) { + jo = {}; + } + } catch (e) { + /* + * richie:浏览器只支持标准的JSON字符串转换,而jQuery会默认调用浏览器的window.JSON.parse()函数进行解析 + * 比如:var str = "{'a':'b'}",这种形式的字符串转换为JSON就会抛异常 + */ + try { + jo = new Function(`return ${text}`)() || {}; + } catch (e) { + // do nothing + } + if (jo == null) { + jo = []; + } + } + if (!_hasDateInJson(text)) { + return jo; + } + + function _hasDateInJson(json) { + if (!json || typeof json !== "string") { + return false; + } + + return json.indexOf("__time__") !== -1; + } + + return (function parse(o) { + if (typeof o === "string") { + return o; + } + if (o && o.__time__ != null) { + return new Date(o.__time__); + } + for (const a in o) { + if (o[a] === o || typeof o[a] === "object" || isFunction(o[a])) { + break; + } + o[a] = parse(o[a]); + } + + return o; + }(jo)); +}; + +/** + * 获取编码后的url + * @param urlTemplate url模板 + * @param param 参数 + * @returns {*|String} + * @example + * BI.getEncodeURL("design/{tableName}/{fieldName}",{tableName: "A", fieldName: "a"}) // design/A/a + */ +export const getEncodeURL = function(urlTemplate, param) { + return replaceAll(urlTemplate, "\\{(.*?)\\}", (ori, str) => encodeURIComponent(isObject(param) ? param[str] : param)); +}; + +export const encodeURIComponent = function(url) { + const specialCharsMap = getSpecialCharsMap(); + url = url || ""; + url = replaceAll(`${url}`, keys(specialCharsMap || []).join("|"), str => { + switch (str) { + case "\\": + return specialCharsMap["\\\\"] || str; + default: + return specialCharsMap[str] || str; + } + }); + + return _global.encodeURIComponent(url); +}; + +export const decodeURIComponent = function(url) { + const specialCharsMap = getSpecialCharsMap(); + const reserveSpecialCharsMap = {}; + each(specialCharsMap, (initialChar, encodeChar) => { + reserveSpecialCharsMap[encodeChar] = initialChar === "\\\\" ? "\\" : initialChar; + }); + url = url || ""; + url = replaceAll(`${url}`, keys(reserveSpecialCharsMap || []).join("|"), str => reserveSpecialCharsMap[str] || str); + + return _global.decodeURIComponent(url); +}; + +export const contentFormat = function(cv, fmt) { + if (isEmpty(cv)) { + // 原值为空,返回空字符 + return ""; + } + let text = cv.toString(); + if (isEmpty(fmt)) { + // 格式为空,返回原字符 + return text; + } + if (fmt.match(/^T/)) { + // T - 文本格式 + return text; + } else if (fmt.match(/^D/)) { + // D - 日期(时间)格式 + if (!(cv instanceof Date)) { + if (typeof cv === "number") { + // 毫秒数类型 + cv = new Date(cv); + } else { + // 字符串类型转化为date类型 + cv = new Date(Date.parse((`${cv}`).replace(/-|\./g, "/"))); + } + } + if (!isInvalidDate(cv) && !isNull(cv)) { + const needTrim = fmt.match(/^DT/); + text = date2Str(cv, fmt.substring(needTrim ? 2 : 1)); + } + } else if (fmt.match(/E/)) { + // 科学计数格式 + text = _eFormat(text, fmt); + } else { + // 数字格式 + text = _numberFormat(text, fmt); + } + // ¤ - 货币格式 + text = text.replace(/¤/g, "¥"); + + return text; +}; + +/** + * 将Java提供的日期格式字符串装换为JS识别的日期格式字符串 + * @param fmt 日期格式 + * @returns {string} + */ +export const parseFmt = function(fmt) { + if (!fmt) { + return ""; + } + // 日期 + fmt = String(fmt) + // 年 + .replace(/y{4,}/g, "%Y")// yyyy的时候替换为Y + .replace(/y{2}/g, "%y")// yy的时候替换为y + // 月 + .replace(/M{4,}/g, "%b")// MMMM的时候替换为b,八 + .replace(/M{3}/g, "%B")// MMM的时候替换为M,八月 + .replace(/M{2}/g, "%X")// MM的时候替换为X,08 + .replace(/M{1}/g, "%x")// M的时候替换为x,8 + .replace(/a{1}/g, "%p"); + // 天 + if (new RegExp("d{2,}", "g").test(fmt)) { + fmt = fmt.replace(/d{2,}/g, "%d");// dd的时候替换为d + } else { + fmt = fmt.replace(/d{1}/g, "%e");// d的时候替换为j + } + // 时 + if (new RegExp("h{2,}", "g").test(fmt)) {// 12小时制 + fmt = fmt.replace(/h{2,}/g, "%I"); + } else { + fmt = fmt.replace(/h{1}/g, "%I"); + } + if (new RegExp("H{2,}", "g").test(fmt)) {// 24小时制 + fmt = fmt.replace(/H{2,}/g, "%H"); + } else { + fmt = fmt.replace(/H{1}/g, "%H"); + } + fmt = fmt.replace(/m{2,}/g, "%M")// 分 + // 秒 + .replace(/s{2,}/g, "%S"); + + return fmt; +}; + +/** + * 把字符串按照对应的格式转化成日期对象 + * + * @example + * var result = BI.str2Date('2013-12-12', 'yyyy-MM-dd');//Thu Dec 12 2013 00:00:00 GMT+0800 + * @param str 字符串 + * @param format 日期格式 + * @returns {Date} + */ +export const str2Date = function(str, format) { + if (typeof str != "string" || typeof format != "string") { + return null; + } + const fmt = parseFmt(format); + + return parseDateTime(str, fmt); +}; + +/** + * 把日期对象按照指定格式转化成字符串 + *@example + * var date = new Date('Thu Dec 12 2013 00:00:00 GMT+0800'); + * var result = BI.date2Str(date, 'yyyy-MM-dd');//2013-12-12 + * @param date + * @param format + * @returns {string} + */ +export const date2Str = function(date, format) { + if (!date) { + return ""; + } + // O(len(format)) + let len = format.length, result = ""; + if (len > 0) { + let flagch = format.charAt(0), start = 0, str = flagch; + for (let i = 1; i < len; i++) { + const ch = format.charAt(i); + if (flagch !== ch) { + result += compileJFmt({ + "char": flagch, + str, + len: i - start, + }, date); + flagch = ch; + start = i; + str = flagch; + } else { + str += ch; + } + } + result += compileJFmt({ + "char": flagch, + str, + len: len - start, + }, date); + } + + return result; + + function compileJFmt(jfmt, date) { + let str = jfmt.str, len = jfmt.len, ch = jfmt.char; + switch (ch) { + case "E": // 星期 + str = getFullDayName(date.getDay()); + break; + case "y": // 年 + if (len <= 3) { + str = (`${date.getFullYear()}`).slice(2, 4); + } else { + str = date.getFullYear(); + } + break; + case "M": // 月 + if (len > 2) { + str = getMonthName(date.getMonth()); + } else if (len < 2) { + str = date.getMonth() + 1; + } else { + str = leftPad(`${date.getMonth() + 1}`, 2, "0"); + } + break; + case "d": // 日 + if (len > 1) { + str = leftPad(`${date.getDate()}`, 2, "0"); + } else { + str = date.getDate(); + } + break; + case "h": // 时(12) + let hour = date.getHours() % 12; + if (hour === 0) { + hour = 12; + } + if (len > 1) { + str = leftPad(`${hour}`, 2, "0"); + } else { + str = hour; + } + break; + case "H": // 时(24) + if (len > 1) { + str = leftPad(`${date.getHours()}`, 2, "0"); + } else { + str = date.getHours(); + } + break; + case "m": + if (len > 1) { + str = leftPad(`${date.getMinutes()}`, 2, "0"); + } else { + str = date.getMinutes(); + } + break; + case "s": + if (len > 1) { + str = leftPad(`${date.getSeconds()}`, 2, "0"); + } else { + str = date.getSeconds(); + } + break; + case "a": + str = date.getHours() < 12 ? "am" : "pm"; + break; + case "z": + str = getTimezone(date); + break; + default: + str = jfmt.str; + break; + } + + return str; + } +}; + +export const object2Number = function(value) { + if (value == null) { + return 0; + } + if (typeof value === "number") { + return value; + } + const str = `${value}`; + if (str.indexOf(".") === -1) { + return parseInt(str); + } + + return parseFloat(str); +}; + +export const object2Date = function(obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } else if (typeof obj === "number") { + return new Date(obj); + } + let str = `${obj}`; + str = str.replace(/-/g, "/"); + const dt = new Date(str); + if (!isInvalidDate(dt)) { + return dt; + } + + return new Date(); +}; + +export const object2Time = function(obj) { + if (obj == null) { + return new Date(); + } + if (obj instanceof Date) { + return obj; + } + let str = `${obj}`; + str = str.replace(/-/g, "/"); + let dt = new Date(str); + if (!isInvalidDate(dt)) { + return dt; + } + if (str.indexOf("/") === -1 && str.indexOf(":") !== -1) { + dt = new Date(`1970/01/01 ${str}`); + if (!isInvalidDate(dt)) { + return dt; + } + } + dt = parseDateTime(str, "HH:mm:ss"); + if (!isInvalidDate(dt)) { + return dt; + } + + return new Date(); +}; diff --git a/packages/fineui/src/core/func/array.js b/packages/fineui/src/core/func/array.js new file mode 100644 index 000000000..76ce2a132 --- /dev/null +++ b/packages/fineui/src/core/func/array.js @@ -0,0 +1,19 @@ +/** + * 对数组对象的扩展 + * @class Array + */ +export function pushArray(sArray, array) { + sArray.push(...array); +} + +export function pushDistinct(sArray, obj) { + if (sArray.indexOf(obj) === -1) { + sArray.push(obj); + } +} + +export function pushDistinctArray(sArray, array) { + for (let i = 0, len = array.length; i < len; i++) { + pushDistinct(sArray, array[i]); + } +} diff --git a/packages/fineui/src/core/func/date.js b/packages/fineui/src/core/func/date.js new file mode 100644 index 000000000..b592ad7d7 --- /dev/null +++ b/packages/fineui/src/core/func/date.js @@ -0,0 +1,391 @@ +/** Constants used for time computations */ +import { getDate, getTime, parseInt } from "../2.base"; +import { i18nText } from "../utils"; +import { StartOfWeek } from "../constant"; +import { isKhtml } from "../platform/web"; +import { _global } from "../0.foundation"; + +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; +const WEEK = 7 * DAY; +const _FD = 1; +const _SMN = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 +]; +const _MD = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; +const _OFFSET = [0, -1, -2, -3, -4, -5, -6]; // 实际上无论周几作为一周的第一天,周初周末都是在-6-0间做偏移,用一个数组就可以 + +export const Date = { + SECOND, + MINUTE, + HOUR, + DAY, + WEEK, + _FD, + _SMN, + _MD, + _OFFSET, +}; + +/** + * 获取时区 + * @returns {String} + */ +export function getTimezone(date) { + return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, ""); +} + +/** + * Returns the number of days in the current month + */ +export function getMonthDays(date, month = date.getMonth()) { + const year = date.getFullYear(); + if (((0 === (year % 4)) && ((0 !== (year % 100)) || (0 === (year % 400)))) && month === 1) { + return 29; + } + + return _MD[month]; +} + +/** + * 获取每月的最后一天 + * @returns {Date} + */ +export function getLastDateOfMont(date) { + return getDate(date.getFullYear(), date.getMonth(), getMonthDays(date)); +} + +/** + * 获取每月的最后一天 + * @returns {Date} + */ +export function getLastDateOfMonth(date) { + return getDate(date.getFullYear(), date.getMonth(), getMonthDays(date)); +} + +/** + * Returns the number of day in the year. + * @param date + * @returns {number} + */ +export function getDayOfYear(date) { + const now = getDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + const then = getDate(date.getFullYear(), 0, 0, 0, 0, 0); + const time = now - then; + + return Math.floor(time / DAY); +} + + +/** + * Returns the number of the week in year, as defined in ISO 8601. + * @param date + * @returns {number} + */ +export function getWeekNumber(date) { + const d = getDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + const week = d.getDay(); + const startOfWeek = StartOfWeek % 7; + let middleDay = (startOfWeek + 3) % 7; + middleDay = middleDay || 7; + // 偏移到周周首之前需要多少天 + const offsetWeekStartCount = week < startOfWeek ? (7 + week - startOfWeek) : (week - startOfWeek); + const offsetWeekMiddleCount = middleDay < startOfWeek ? (7 + middleDay - startOfWeek) : (middleDay - startOfWeek); + d.setDate(d.getDate() - offsetWeekStartCount + offsetWeekMiddleCount); + const ms = d.valueOf(); + d.setMonth(0); + d.setDate(1); + + return Math.floor((ms - d.valueOf()) / (7 * 864e5)) + 1; +} + +export function getQuarter(date) { + return Math.floor(date.getMonth() / 3) + 1; +} + +/** + * 离当前时间多少天的时间 + * @param date + * @param offset + * @returns {Date} + */ +export function getOffsetDate(date, offset) { + return getDate(getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()) + offset * 864e5); +} + +export function getOffsetQuarter(date, n) { + const dt = getDate(getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); + let day = dt.getDate(); + const monthDay = getMonthDays(getDate(dt.getFullYear(), dt.getMonth() + parseInt(n, 10) * 3, 1)); + if (day > monthDay) { + day = monthDay; + } + dt.setDate(day); + dt.setMonth(dt.getMonth() + parseInt(n, 10) * 3); + + return dt; +} + +/** + * 得到本季度的起始月份 + * @param date + * @returns {number} + */ +export function getQuarterStartMonth(date) { + let quarterStartMonth = 0; + const nowMonth = date.getMonth(); + if (nowMonth < 3) { + quarterStartMonth = 0; + } + if (2 < nowMonth && nowMonth < 6) { + quarterStartMonth = 3; + } + if (5 < nowMonth && nowMonth < 9) { + quarterStartMonth = 6; + } + if (nowMonth > 8) { + quarterStartMonth = 9; + } + + return quarterStartMonth; +} + +/** + * 获得本季度的起始日期 + * @param date + * @returns {Date} + */ +export function getQuarterStartDate(date) { + return getDate(date.getFullYear(), getQuarterStartMonth(date), 1); +} + +/** + * 得到本季度的结束日期 + * @param date + * @returns {Date} + */ +export function getQuarterEndDate(date) { + const quarterEndMonth = getQuarterStartMonth(date) + 2; + + return getDate(date.getFullYear(), quarterEndMonth, getMonthDays(date)); +} + +/** + * 指定日期n个月之前或之后的日期 + * @param date + * @param n + * @returns {Date} + */ +export function getOffsetMonth(date, n) { + const dt = getDate(getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); + let day = dt.getDate(); + const monthDay = getMonthDays(getDate(dt.getFullYear(), dt.getMonth() + parseInt(n, 10), 1)); + if (day > monthDay) { + day = monthDay; + } + dt.setDate(day); + dt.setMonth(dt.getMonth() + parseInt(n, 10)); + + return dt; +} + +/** + * 获得本周的起始日期 + * @param date + * @returns {Date} + */ +export function getWeekStartDate(date) { + const w = date.getDay(); + const startOfWeek = StartOfWeek % 7; + + return getOffsetDate(date, _OFFSET[w < startOfWeek ? (7 + w - startOfWeek) : (w - startOfWeek)]); +} + +/** + * 得到本周的结束日期 + * @param date + * @returns {Date} + */ +export function getWeekEndDate(date) { + const w = date.getDay(); + const startOfWeek = StartOfWeek % 7; + + return getOffsetDate(date, _OFFSET[w < startOfWeek ? (7 + w - startOfWeek) : (w - startOfWeek)] + 6); +} + +export function getFullDayName(index) { + return [ + i18nText("BI-Basic_Sunday"), + i18nText("BI-Basic_Monday"), + i18nText("BI-Basic_Tuesday"), + i18nText("BI-Basic_Wednesday"), + i18nText("BI-Basic_Thursday"), + i18nText("BI-Basic_Friday"), + i18nText("BI-Basic_Saturday"), + i18nText("BI-Basic_Sunday") + ][index]; +} + +export function getShortDayName(index) { + return [ + i18nText("BI-Basic_Simple_Sunday"), + i18nText("BI-Basic_Simple_Monday"), + i18nText("BI-Basic_Simple_Tuesday"), + i18nText("BI-Basic_Simple_Wednesday"), + i18nText("BI-Basic_Simple_Thursday"), + i18nText("BI-Basic_Simple_Friday"), + i18nText("BI-Basic_Simple_Saturday"), + i18nText("BI-Basic_Simple_Sunday") + ][index]; +} + +export function getMonthName(index) { + return [ + i18nText("BI-Basic_January"), + i18nText("BI-Basic_February"), + i18nText("BI-Basic_March"), + i18nText("BI-Basic_April"), + i18nText("BI-Basic_May"), + i18nText("BI-Basic_June"), + i18nText("BI-Basic_July"), + i18nText("BI-Basic_August"), + i18nText("BI-Basic_September"), + i18nText("BI-Basic_October"), + i18nText("BI-Basic_November"), + i18nText("BI-Basic_December") + ][index]; +} + +export function getQuarterName(index) { + return [ + "", + i18nText("BI-Quarter_1"), + i18nText("BI-Quarter_2"), + i18nText("BI-Quarter_3"), + i18nText("BI-Quarter_4") + ][index]; +} + +/** + * 格式化打印日期 + * @param date + * @param str + * @returns {*} + */ +export function print(date, str) { + const m = date.getMonth(); + const d = date.getDate(); + const y = date.getFullYear(); + let yWith4number = `${y}`; + while (yWith4number.length < 4) { + yWith4number = `0${yWith4number}`; + } + const wn = getWeekNumber(date); + const qr = getQuarter(date); + const w = date.getDay(); + const s = {}; + const hr = date.getHours(); + const pm = (hr >= 12); + let ir = (pm) ? (hr - 12) : hr; + const dy = getDayOfYear(date); + if (ir === 0) { + ir = 12; + } + const min = date.getMinutes(); + const sec = date.getSeconds(); + s["%a"] = getShortDayName(w); // abbreviated weekday name [FIXME: I18N] + s["%A"] = getFullDayName(w); // full weekday name + s["%b"] = _SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = getMonthName(m); // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? (`0${d}`) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? (`0${hr}`) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? (`0${ir}`) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? (`00${dy}`) : (`0${dy}`)) : dy; // day of the year (range 001 to 366) + s["%k"] = `${hr}`; // hour, range 0 to 23 (24h format) + s["%l"] = `${ir}`; // hour, range 1 to 12 (12h format) + s["%X"] = (m < 9) ? (`0${1 + m}`) : (1 + m); // month, range 01 to 12 + s["%x"] = m + 1; // month, range 1 to 12 + s["%M"] = (min < 10) ? (`0${min}`) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(date.getTime() / 1000); + s["%S"] = (sec < 10) ? (`0${sec}`) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? (`0${wn}`) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = yWith4number.substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = yWith4number; // year with the century + s["%%"] = "%"; // a literal '%' character + s["%q"] = `0${qr}`; + s["%Q"] = qr; + + let re = /%./g; + const isNewKhtml = isKhtml || function () { + if (!_global.navigator) { + return false; + } + + return /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + }; + + // 包含年周的格式化,ISO8601标准周的计数会影响年 + if ((str.indexOf("%Y") !== -1 || str.indexOf("%y") !== -1) && (str.indexOf("%W") !== -1 || str.indexOf("%U") !== -1 || str.indexOf("%V") !== -1)) { + switch (wn) { + // 如果周数是1,但是当前却在12月,表示此周数为下一年的 + case 1: + if (m === 11) { + s["%y"] = parseInt(s["%y"]) + 1; + s["%Y"] = parseInt(s["%Y"]) + 1; + } + break; + // 如果周数是53,但是当前却在1月,表示此周数为上一年的 + case 53: + if (m === 0) { + s["%y"] = parseInt(s["%y"]) - 1; + s["%Y"] = parseInt(s["%Y"]) - 1; + } + break; + default: + break; + } + } + + if (!isNewKhtml()) { + return str.replace(re, par => s[par] || par); + } + const a = str.match(re); + for (let i = 0; i < a.length; i++) { + const tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], "g"); + str = str.replace(re, tmp); + } + } + + return str; +} diff --git a/packages/fineui/src/core/func/function.js b/packages/fineui/src/core/func/function.js new file mode 100644 index 000000000..0f13dabdd --- /dev/null +++ b/packages/fineui/src/core/func/function.js @@ -0,0 +1,185 @@ +/** + * 基本的函数 + * Created by GUY on 2015/6/24. + */ +import { every, isKey, isArray, toUpperCase, each, stripEL, isNotNull, isNull, isObject, flatten, isFunction } from "../2.base"; +import { makeFirstPY } from "../utils/chinesePY"; +import { CODE_INDEX } from "@/third/sort.gb2312"; +import { MAX } from "../constant"; + +/** + * 创建唯一的名字 + * @param array + * @param name + * @returns {*} + */ +export function createDistinctName(array, name) { + const src = name; + let idx = 1; + name = name || ""; + while (true) { + // eslint-disable-next-line no-loop-func + if (every(array, (i, item) => isKey(item) ? item !== name : item.name !== name)) { + break; + } + name = src + (idx++); + } + + return name; +} + +/** + * 获取字符宽度 + * @param str + * @return {number} + */ +export function getGBWidth(str) { + str = `${str}`; + str = str.replace(/[^\x00-\xff]/g, "xx"); + + return Math.ceil(str.length / 2); +} + +/** + * 获取搜索结果 + * @param items + * @param keyword + * @param param 搜索哪个属性 + */ +export function getSearchResult(items, keyword, param) { + const array = isArray(items); + items = array ? flatten(items) : items; + param || (param = "text"); + if (!isKey(keyword)) { + return { + find: items, + match: array ? [] : {}, + }; + } + let t, text, py; + keyword = toUpperCase(keyword); + const matched = array ? [] : {}, find = array ? [] : {}; + each(items, (i, item) => { + // 兼容item为null的处理 + if (isNull(item)) { + return; + } + t = stripEL(item); + text = [t[param], t.text, t.value, t.name, t].find(isNotNull); + + if (isNull(text) || isObject(text)) return; + + py = makeFirstPY(text, { + splitChar: "\u200b", + }); + text = toUpperCase(text); + py = toUpperCase(py); + let pidx; + if (text.indexOf(keyword) > -1) { + if (text === keyword) { + array ? matched.push(item) : (matched[i] = item); + } else { + array ? find.push(item) : (find[i] = item); + } + } else { // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 + pidx = py.indexOf(keyword); + if (pidx > -1) { + if (text === keyword || keyword.length === text.length) { + array ? matched.push(item) : (matched[i] = item); + } else { + array ? find.push(item) : (find[i] = item); + } + } + } + }); + + return { + match: matched, + find, + }; +} + +/** + * 获取按GB2312排序的结果 + * @param items + * @param key + * @return {any[]} + */ +export function getSortedResult(items, key = null) { + const getTextOfItem = isFunction(key) ? key : + function (item, key) { + if (isNotNull(key)) { + return item[key]; + } + if (isNotNull(item.text)) { + return item.text; + } + if (isNotNull(item.value)) { + return item.value; + } + + return item; + }; + + return items.sort((item1, item2) => { + const str1 = getTextOfItem(item1, key); + const str2 = getTextOfItem(item2, key); + if (isNull(str1) && isNull(str2)) { + return 0; + } + if (isNull(str1)) { + return -1; + } + if (isNull(str2)) { + return 1; + } + if (str1 === str2) { + return 0; + } + const len1 = str1.length, len2 = str2.length; + for (let i = 0; i < len1 && i < len2; i++) { + const char1 = str1[i]; + const char2 = str2[i]; + if (char1 !== char2) { + // 找不到的字符都往后面放 + return (isNull(CODE_INDEX[char1]) ? MAX : CODE_INDEX[char1]) - (isNull(CODE_INDEX[char2]) ? MAX : CODE_INDEX[char2]); + } + } + + return len1 - len2; + }); +} + +export function beforeFunc(sFunc, func) { + const __self = sFunc; + + return function () { + if (func.apply(sFunc, arguments) === false) { + return false; + } + + return __self.apply(sFunc, arguments); + }; +} + +export function afterFunc(sFunc, func) { + const __self = sFunc; + + return function () { + const ret = __self.apply(sFunc, arguments); + if (ret === false) { + return false; + } + func.apply(sFunc, arguments); + + return ret; + }; +} + + +export const Func = { + createDistinctName, + getGBWidth, + getSearchResult, + getSortedResult, +}; diff --git a/packages/fineui/src/core/func/index.js b/packages/fineui/src/core/func/index.js new file mode 100644 index 000000000..b04392bdc --- /dev/null +++ b/packages/fineui/src/core/func/index.js @@ -0,0 +1,6 @@ +export * from "./alias"; +export * from "./array"; +export * from "./date"; +export * from "./function"; +export * from "./number"; +export * from "./string"; diff --git a/packages/fineui/src/core/func/number.js b/packages/fineui/src/core/func/number.js new file mode 100644 index 000000000..d7a4f31f5 --- /dev/null +++ b/packages/fineui/src/core/func/number.js @@ -0,0 +1,154 @@ +// 给Number类型增加一个add方法,调用起来更加方便。 +export function add(num, arg) { + return accAdd(arg, num); + + /** + ** 加法函数,用来得到精确的加法结果 + ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 + ** 调用:accAdd(arg1,arg2) + ** 返回值:arg1加上arg2的精确结果 + **/ + function accAdd(arg1, arg2) { + let r1, r2, m, c; + try { + r1 = arg1.toString().split(".")[1].length; + } catch (e) { + r1 = 0; + } + try { + r2 = arg2.toString().split(".")[1].length; + } catch (e) { + r2 = 0; + } + c = Math.abs(r1 - r2); + m = Math.pow(10, Math.max(r1, r2)); + if (c > 0) { + const cm = Math.pow(10, c); + if (r1 > r2) { + arg1 = Number(arg1.toString().replace(".", "")); + arg2 = Number(arg2.toString().replace(".", "")) * cm; + } else { + arg1 = Number(arg1.toString().replace(".", "")) * cm; + arg2 = Number(arg2.toString().replace(".", "")); + } + } else { + arg1 = Number(arg1.toString().replace(".", "")); + arg2 = Number(arg2.toString().replace(".", "")); + } + return (arg1 + arg2) / m; + } +} + +// 给Number类型增加一个sub方法,调用起来更加方便。 +export function sub(num, arg) { + return accSub(num, arg); + + /** + ** 减法函数,用来得到精确的减法结果 + ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 + ** 调用:accSub(arg1,arg2) + ** 返回值:arg1加上arg2的精确结果 + **/ + function accSub(arg1, arg2) { + let r1, r2, m, n; + try { + r1 = arg1.toString().split(".")[1].length; + } catch (e) { + r1 = 0; + } + try { + r2 = arg2.toString().split(".")[1].length; + } catch (e) { + r2 = 0; + } + m = Math.pow(10, Math.max(r1, r2)); // last modify by deeka //动态控制精度长度 + n = (r1 >= r2) ? r1 : r2; + return ((arg1 * m - arg2 * m) / m).toFixed(n); + } +} + +// 给Number类型增加一个mul方法,调用起来更加方便。 +export function mul(num, arg) { + return accMul(arg, num); + + /** + ** 乘法函数,用来得到精确的乘法结果 + ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 + ** 调用:accMul(arg1,arg2) + ** 返回值:arg1乘以 arg2的精确结果 + **/ + function accMul(arg1, arg2) { + let m = 0, s1 = arg1.toString(), s2 = arg2.toString(); + try { + m += s1.split(".")[1].length; + } catch (e) { + } + try { + m += s2.split(".")[1].length; + } catch (e) { + } + return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); + } +} + +// 给Number类型增加一个div方法,调用起来更加方便。 +export function div(num, arg) { + return accDivide(num, arg); + + /** + * Return digits length of a number + * @param {*number} num Input number + */ + function digitLength(num) { + // Get digit length of e + const eSplit = num.toString().split(/[eE]/); + const len = (eSplit[0].split(".")[1] || "").length - (+(eSplit[1] || 0)); + return len > 0 ? len : 0; + } + + /** + * 把小数转成整数,支持科学计数法。如果是小数则放大成整数 + * @param {*number} num 输入数 + */ + function float2Fixed(num) { + if (num.toString().indexOf("e") === -1) { + return Number(num.toString().replace(".", "")); + } + const dLen = digitLength(num); + return dLen > 0 ? num * Math.pow(10, dLen) : num; + } + + /** + * 精确乘法 + */ + function times(num1, num2) { + const others = []; + for (let _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1))); + } + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + const baseNum = digitLength(num1) + digitLength(num2); + const leftValue = num1Changed * num2Changed; + return leftValue / Math.pow(10, baseNum); + } + + /** + * 精确除法 + */ + function accDivide(num1, num2) { + const others = []; + for (let _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return accDivide.apply(void 0, [accDivide(num1, num2), others[0]].concat(others.slice(1))); + } + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1))); + } +} diff --git a/packages/fineui/src/core/func/string.js b/packages/fineui/src/core/func/string.js new file mode 100644 index 000000000..f380b3581 --- /dev/null +++ b/packages/fineui/src/core/func/string.js @@ -0,0 +1,126 @@ +import { isString, each } from "../2.base"; + +/** + * 判断字符串是否已指定的字符串开始 + * @param str source字符串 + * @param {String} startTag 指定的开始字符串 + * @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false + */ +export function startWith(str, startTag) { + str = str || ""; + if (startTag == null || startTag == "" || str.length === 0 || startTag.length > str.length) { + return false; + } + + return str.substring(0, startTag.length) == startTag; +} + +/** + * 判断字符串是否以指定的字符串结束 + * @param str source字符串 + * @param {String} endTag 指定的字符串 + * @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false + */ +export function endWith(str, endTag) { + if (endTag == null || endTag == "" || str.length === 0 || endTag.length > str.length) { + return false; + } + + return str.substring(str.length - endTag.length) == endTag; +} + +/** + * 获取url中指定名字的参数 + * @param str source字符串 + * @param {String} name 参数的名字 + * @return {String} 参数的值 + */ +export function getQuery(str, name) { + const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`); + const r = str.substr(str.indexOf("?") + 1).match(reg); + if (r) { + return unescape(r[2]); + } + + return null; +} + +/** + * 给url加上给定的参数 + * @param str source字符串 + * @param {Object} paras 参数对象,是一个键值对对象 + * @return {String} 添加了给定参数的url + */ +export function appendQuery(str, paras) { + if (!paras) { + return str; + } + let src = str; + // 没有问号说明还没有参数 + if (src.indexOf("?") === -1) { + src += "?"; + } + // 如果以问号结尾,说明没有其他参数 + if (!src.endsWith("?")) { + src += "&"; + } + + each(paras, (name, value) => { + if (typeof (name) === "string") { + src += `${name}=${value}&`; + } + }); + src = src.substr(0, src.length - 1); + + return src; +} + +/** + * 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 + * @param str source字符串 + * @param {String} s1 要替换的字符串的正则表达式 + * @param {String} s2 替换的结果字符串 + * @returns {String} 替换后的字符串 + */ +export function replaceAll(str, s1, s2) { + return isString(str) ? str.replace(new RegExp(s1, "gm"), s2) : str; +} + +/** + * 总是让字符串以指定的字符开头 + * @param str source字符串 + * @param {String} start 指定的字符 + * @returns {String} 以指定字符开头的字符串 + */ +export function perfectStart(str, start) { + if (str.startsWith(start)) { + return str; + } + + return start + str; +} + +/** + * 获取字符串中某字符串的所有项位置数组 + * @param str source字符串 + * @param {String} sub 子字符串 + * @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 + */ +export function allIndexOf(str, sub) { + if (typeof sub !== "string") { + return []; + } + const location = []; + let offset = 0; + while (str.length > 0) { + const loc = str.indexOf(sub); + if (loc === -1) { + break; + } + location.push(offset + loc); + str = str.substring(loc + sub.length, str.length); + offset += loc + sub.length; + } + + return location; +} diff --git a/packages/fineui/src/core/h.js b/packages/fineui/src/core/h.js new file mode 100644 index 000000000..c413788c2 --- /dev/null +++ b/packages/fineui/src/core/h.js @@ -0,0 +1,59 @@ +import { isNotNull, isArray, isFunction, isKey, extend } from "./2.base"; + +export function Fragment () {} + +export function h (type, props, children) { + if (isNotNull(children)) { + if (!isArray(children)) { + children = [children]; + } + } else { + children = []; + } + if (arguments.length > 3) { + for (let i = 3; i < arguments.length; i++) { + if (isArray(arguments[i])) { + children = children.concat(arguments[i]); + } else { + children.push(arguments[i]); + } + } + } + if (type === Fragment) { + return children; + } + if (isFunction(type)) { + type = type.xtype || type; + } + if (type === "el") { + return extend({ + el: children[0], + }, props); + } + if (type === "left") { + return extend({ + left: children, + }, props); + } + if (type === "right") { + return extend({ + right: children, + }, props); + } + if (children.length === 1) { + if (isKey(children[0])) { + return extend({ + type, + }, { text: children[0] }, props); + } + if (isFunction(children[0])) { + return extend({ + type, + }, { items: children[0] }, props); + } + } + + return extend({ + type, + }, children.length > 0 ? { items: children } : {}, props); +} diff --git a/packages/fineui/src/core/index.js b/packages/fineui/src/core/index.js new file mode 100644 index 000000000..52e723217 --- /dev/null +++ b/packages/fineui/src/core/index.js @@ -0,0 +1,39 @@ +export * from "./0.foundation"; +export * from './system'; + +export { StyleLoaderManager } from './loader/loader.style'; +export { ShowListener } from './listener/listener.show'; +export { useInWorker } from './worker'; +export { Element } from './element'; + +export { Controller } from './controller/0.controller'; +export { BroadcastController } from './controller/controller.broadcast'; +export { BubblesController } from './controller/controller.bubbles'; +export { DrawerController } from './controller/controller.drawer'; +export { LayerController } from './controller/controller.layer'; +export { MaskersController } from './controller/controller.masker'; +export { PopoverController } from './controller/controller.popover'; +export { ResizeController } from './controller/controller.resizer'; +export { TooltipsController } from './controller/controller.tooltips'; + +export * as _ from './1.lodash'; +export * from './2.base'; +export * from './3.ob'; +export * from './4.widget'; +export * from './5.inject'; +export * from './6.plugin'; + +export * from './action'; +export * from './func'; +export * from './structure'; +export * from './h'; +export * from './constant'; +export * from './logic'; +export * from './wrapper'; +export * from './platform/web'; +export * from './utils'; + +export { shortcut, provider, store, model, mixin, mixins, service } from './decorator'; + + + diff --git a/packages/fineui/src/core/listener/listener.show.js b/packages/fineui/src/core/listener/listener.show.js new file mode 100644 index 000000000..e4bff5ffd --- /dev/null +++ b/packages/fineui/src/core/listener/listener.show.js @@ -0,0 +1,50 @@ +/** + * guy + * 检测某个Widget的EventChange事件然后去show某个card + */ +import { OB } from "../3.ob"; +import { isArray, isNull, nextTick } from "../2.base"; +import { createWidget } from "../5.inject"; +import { Controller } from "../controller/0.controller"; +import { Events, emptyFn } from "../constant"; + +export class ShowListener extends OB { + static EVENT_CHANGE = "EVENT_CHANGE"; + + props() { + return { + eventObj: createWidget(), + cardLayout: null, + cardNameCreator: v => v, + cardCreator: emptyFn, + afterCardCreated: emptyFn, + afterCardShow: emptyFn, + }; + } + + init() { + const { eventObj, cardLayout, afterCardCreated, cardNameCreator, cardCreator, afterCardShow } = this.options; + if (eventObj) { + eventObj.on(Controller.EVENT_CHANGE, (type, v, ob) => { + if (type === Events.CLICK) { + v = v || eventObj.getValue(); + v = isArray(v) ? (v.length > 1 ? v.toString() : v[0]) : v; + if (isNull(v)) { + throw new Error("canot be null"); + } + const cardName = cardNameCreator(v); + if (!cardLayout.isCardExisted(cardName)) { + const card = cardCreator(cardName); + cardLayout.addCardByName(cardName, card); + afterCardCreated(cardName); + } + cardLayout.showCardByName(cardName); + nextTick(() => { + afterCardShow(cardName); + this.fireEvent(ShowListener.EVENT_CHANGE, cardName); + }); + } + }); + } + } +} diff --git a/packages/fineui/src/core/loader/loader.style.js b/packages/fineui/src/core/loader/loader.style.js new file mode 100644 index 000000000..b8e4780ff --- /dev/null +++ b/packages/fineui/src/core/loader/loader.style.js @@ -0,0 +1,54 @@ +/** + * style加载管理器 + * + * Created by GUY on 2015/9/7. + */ +import { extend, isNotNull } from "../2.base"; +import { OB } from "../3.ob"; +import { _global } from "../0.foundation"; + +export class StyleLoaderManager extends OB { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), {}); + } + + _init() { + super._init(...arguments); + this.stylesManager = {}; + } + + loadStyle(name, styleString) { + if (!_global.document) { + return; + } + const d = document, styles = d.createElement("style"); + d.getElementsByTagName("head")[0].appendChild(styles); + styles.setAttribute("type", "text/css"); + if (styles.styleSheet) { + styles.styleSheet.cssText = styleString; + } else { + styles.appendChild(document.createTextNode(styleString)); + } + this.stylesManager[name] = styles; + + return this; + } + + get(name) { + return this.stylesManager[name]; + } + + has(name) { + return isNotNull(this.stylesManager[name]); + } + + removeStyle(name) { + if (!this.has(name)) { + return this; + } + this.stylesManager[name].parentNode.removeChild(this.stylesManager[name]); + delete this.stylesManager[name]; + + return this; + } +} diff --git a/packages/fineui/src/core/logic/index.js b/packages/fineui/src/core/logic/index.js new file mode 100644 index 000000000..224e2ed13 --- /dev/null +++ b/packages/fineui/src/core/logic/index.js @@ -0,0 +1,85 @@ +import { map, isWidget } from "../2.base"; +import { Direction } from "../constant"; +import { Logic } from "./logic"; +import { VerticalLayoutLogic, HorizontalLayoutLogic, TableLayoutLogic, HorizontalFillLayoutLogic } from "./logic.layout"; + +export const LogicFactory = { + Type: { + Vertical: "vertical", + Horizontal: "horizontal", + Table: "table", + HorizontalFill: "horizontal_fill", + }, + createLogic (key, options) { + let LogicCls; + switch (key) { + case LogicFactory.Type.Vertical: + LogicCls = VerticalLayoutLogic; + break; + case LogicFactory.Type.Horizontal: + LogicCls = HorizontalLayoutLogic; + break; + case LogicFactory.Type.Table: + LogicCls = TableLayoutLogic; + break; + case LogicFactory.Type.HorizontalFill: + LogicCls = HorizontalFillLayoutLogic; + break; + default: + LogicCls = Logic; + break; + } + + return new LogicCls(options).createLogic(); + }, + + createLogicTypeByDirection (direction) { + switch (direction) { + case Direction.Top: + case Direction.Bottom: + case Direction.Custom: + return LogicFactory.Type.Vertical; + case Direction.Left: + case Direction.Right: + return LogicFactory.Type.Horizontal; + default: + } + }, + + createLogicItemsByDirection (direction) { + let items = Array.prototype.slice.call(arguments, 1); + items = map(items, (i, item) => { + if (isWidget(item)) { + return { + el: item, + width: item.options.width, + height: item.options.height, + }; + } + + return item; + }); + switch (direction) { + case Direction.Bottom: + items.reverse(); + break; + case Direction.Right: + items.reverse(); + break; + case Direction.Custom: + items = items.slice(1); + break; + default: + } + + return items; + }, +}; + +export { + Logic, + VerticalLayoutLogic, + HorizontalLayoutLogic, + TableLayoutLogic, + HorizontalFillLayoutLogic +}; diff --git a/packages/fineui/src/core/logic/logic.js b/packages/fineui/src/core/logic/logic.js new file mode 100644 index 000000000..fd7223510 --- /dev/null +++ b/packages/fineui/src/core/logic/logic.js @@ -0,0 +1,8 @@ + +import { OB } from "../3.ob"; + +export class Logic extends OB { + createLogic() { + return this.options || {}; + } +} diff --git a/packages/fineui/src/core/logic/logic.layout.js b/packages/fineui/src/core/logic/logic.layout.js new file mode 100644 index 000000000..1251c6aee --- /dev/null +++ b/packages/fineui/src/core/logic/logic.layout.js @@ -0,0 +1,220 @@ +import { Logic } from "./logic"; +import { isNotNull, each, pickBy } from "../2.base"; + +/** + * guy + * 上下布局逻辑 + * 上下布局的时候要考虑到是动态布局还是静态布局 + */ +export class VerticalLayoutLogic extends Logic { + props() { + return { + dynamic: false, + scrollable: null, + scrolly: false, + scrollx: false, + items: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + innerVgap: 0, + innerHgap: 0, + }; + } + + createLogic() { + let layout; + const o = this.options; + if (o.dynamic) { + layout = "bi.vertical"; + } else { + layout = "bi.vtape"; + } + + return pickBy({ + type: layout, + scrollable: o.scrollable, + scrolly: o.scrolly, + scrollx: o.scrollx, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + }, isNotNull); + } +} + + +/** + * guy + * 左右布局逻辑 + * 左右布局的时候要考虑到是动态布局还是静态布局 + */ +export class HorizontalLayoutLogic extends Logic { + props() { + return { + dynamic: false, + scrollable: null, + scrolly: false, + scrollx: false, + items: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + innerVgap: 0, + innerHgap: 0, + }; + } + + createLogic() { + let layout; + const o = this.options; + if (o.dynamic) { + layout = "bi.vertical_adapt"; + } else { + layout = "bi.htape"; + } + + return pickBy({ + type: layout, + scrollable: o.scrollable, + scrolly: o.scrolly, + scrollx: o.scrollx, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + }, isNotNull); + } +} + +/** + * guy + * 表格布局逻辑 + * 表格布局的时候要考虑到是动态布局还是静态布局 + */ +export class TableLayoutLogic extends Logic { + props() { + return { + dynamic: false, + scrollable: null, + scrolly: false, + scrollx: false, + columns: 0, + rows: 0, + columnSize: [], + rowSize: [], + hgap: 0, + vgap: 0, + items: [], + }; + } + + createLogic() { + let layout; + const o = this.options; + if (o.dynamic) { + layout = "bi.table"; + } else { + layout = "bi.window"; + } + + return pickBy({ + type: layout, + scrollable: o.scrollable, + scrolly: o.scrolly, + scrollx: o.scrollx, + columns: o.columns, + rows: o.rows, + hgap: o.hgap, + vgap: o.vgap, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + }, isNotNull); + } +} + +/** + * guy + * 左右充满布局逻辑 + */ +export class HorizontalFillLayoutLogic extends Logic { + props() { + return { + dynamic: false, + scrollable: null, + scrolly: false, + scrollx: false, + items: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + innerVgap: 0, + innerHgap: 0, + }; + } + + createLogic() { + let layout; + const o = this.options; + const columnSize = []; + each(o.items, (i, item) => { + columnSize.push(item.width || 0); + }); + if (o.dynamic) { + layout = "bi.horizontal_fill"; + } else { + layout = "bi.htape"; + } + + return pickBy({ + type: layout, + scrollable: o.scrollable, + scrolly: o.scrolly, + scrollx: o.scrollx, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize, + rowSize: o.rowSize, + }, isNotNull); + } +} diff --git a/packages/fineui/src/core/platform/index.js b/packages/fineui/src/core/platform/index.js new file mode 100644 index 000000000..8ae69b05a --- /dev/null +++ b/packages/fineui/src/core/platform/index.js @@ -0,0 +1 @@ +export * from "./web"; \ No newline at end of file diff --git a/packages/fineui/src/core/platform/web/config.js b/packages/fineui/src/core/platform/web/config.js new file mode 100644 index 000000000..554af7a74 --- /dev/null +++ b/packages/fineui/src/core/platform/web/config.js @@ -0,0 +1,344 @@ +import { extend, map, each, isNull } from "../../2.base"; +import { Providers } from "../../5.inject"; +import { Plugin } from "../../6.plugin"; +import { isSupportCss3, isIE, getIEVersion } from "../../platform/web"; +import { HorizontalAlign, VerticalAlign } from "../../constant"; +import { + FlexCenterLayout, FlexHorizontalLayout, VerticalLayout, + FlexVerticalLayout, TdLayout, InlineLayout, + FloatHorizontalFillLayout, ResponsiveInlineLayout, + InlineCenterAdaptLayout, FlexVerticalCenterAdapt, + InlineVerticalAdaptLayout, HorizontalAutoLayout, + TableAdaptLayout, FlexHorizontalCenter, + InlineHorizontalAdaptLayout, TableLayout, + AutoVerticalTapeLayout, VTapeLayout, + HorizontalFillLayout, VerticalFillLayout, + FlexLeftRightVerticalAdaptLayout, ResponsiveFlexWrapperHorizontalLayout, + FlexWrapperHorizontalLayout, ResponsiveFlexHorizontalLayout, + FlexWrapperVerticalLayout +} from "@/core/wrapper"; +import { SystemProvider } from "@/core/system"; +import { ImageRadio, ImageCheckbox } from "@/base"; +import { HalfButton } from "@/case"; + +// 工程配置 +// 注册布局 +// adapt类布局优先级规则 +// 1、支持flex的浏览器下使用flex布局 +// 2、不支持flex的浏览器下使用inline布局 +// 3、当列宽既需要自动列宽又需要自适应列宽时,inline布局也处理不了了。当横向出滚动条时使用table布局,不出滚动条时使用float布局 +let _isSupportFlex, _isSupportGrid, _isSupportSticky; + +function isSupportFlex() { + if (!_isSupportFlex) { + _isSupportFlex = !!(isSupportCss3 && isSupportCss3("flex")); + } + + return _isSupportFlex; +} + +function isSupportGrid() { + if (!_isSupportGrid) { + _isSupportGrid = !!(isSupportCss3 && isSupportCss3("grid")); + } + + return _isSupportGrid; +} + +// 判断浏览器是否支持sticky 属性 +const innerSupportSticky = function() { + const vendorList = ["", "-webkit-", "-ms-", "-moz-", "-o-"], + vendorListLength = vendorList.length, + stickyElement = document.createElement("div"); + for (let i = 0; i < vendorListLength; i++) { + stickyElement.style.position = `${vendorList[i]}sticky`; + if (stickyElement.style.position !== "") { + return true; + } + } + + return false; +}; + +// 判断浏览器是否支持sticky 属性 +const isSupportSticky = function() { + if (_isSupportSticky == null) { + _isSupportSticky = innerSupportSticky(); + } + return _isSupportSticky; +}; + + +const configWidget = Plugin.configWidget; + +configWidget("bi.horizontal", ob => { + const supportFlex = isSupportFlex(); + // // 在横向自适应场景下我们需要使用table的自适应撑出滚动条的特性(flex处理不了这种情况) + // // 主要出现在center_adapt或者horizontal_adapt的场景,或者主动设置horizontalAlign的场景 + // if (ob.horizontalAlign === HorizontalAlign.Center || ob.horizontalAlign === HorizontalAlign.Stretch) { + // return extend({}, ob, {type: "bi.table_adapt"}); + // } + if (supportFlex) { + return extend({}, ob, { type: FlexHorizontalLayout.xtype }); + } + + return extend({ + scrollx: true + }, ob, { type: InlineLayout.xtype }); +}); +configWidget("bi.vertical", ob => { + if (ob.horizontalAlign === HorizontalAlign.Left || ob.horizontalAlign === HorizontalAlign.Right) { + if (isSupportFlex()) { + return extend({}, ob, { type: FlexVerticalLayout.xtype }); + } + + return extend({}, ob, { + horizontalAlign: HorizontalAlign.Stretch, + type: VerticalLayout.xtype, + items: map(ob.items, (i, item) => { + return { + type: InlineLayout.xtype, + horizontalAlign: ob.horizontalAlign, + items: [item] + }; + }) + }); + } + if (ob.verticalAlign === VerticalAlign.Stretch) { + if (isSupportFlex()) { + return extend({ + horizontalAlign: HorizontalAlign.Stretch + }, ob, { type: FlexVerticalLayout.xtype }); + } + } + + return ob; +}); +configWidget("bi.inline", ob => { + // 当列宽既需要自动列宽又需要自适应列宽时,inline布局也处理不了了,降级table处理吧 + let hasAutoAndFillColumnSize = false; + if (ob.columnSize && ob.columnSize.length > 0) { + if ((ob.columnSize.indexOf("") >= 0 || ob.columnSize.indexOf("auto") >= 0) && ob.columnSize.indexOf("fill") >= 0) { + hasAutoAndFillColumnSize = true; + } + } else { + let hasAuto = false, hasFill = false; + each(ob.items, (i, item) => { + if (item.width === "fill") { + hasFill = true; + } else if (isNull(item.width) || item.width === "" || item.width === "auto") { + hasAuto = true; + } + }); + hasAutoAndFillColumnSize = hasAuto && hasFill; + } + + if (hasAutoAndFillColumnSize) { + // 宽度是不是受限 + if ((ob.scrollable !== true && ob.scrollx !== true) || ob.horizontalAlign === HorizontalAlign.Stretch) { + return extend({ + verticalAlign: VerticalAlign.Top + }, ob, { type: FloatHorizontalFillLayout.xtype }); + } + + return extend({ + horizontalAlign: HorizontalAlign.Stretch + }, ob, { type: TableAdaptLayout.xtype }); + } + if (Providers.getProvider(SystemProvider.xtype).getResponsiveMode()) { + return extend({}, ob, { type: ResponsiveInlineLayout.xtype }); + } + + return ob; +}); +configWidget("bi.center_adapt", ob => { + const supportFlex = isSupportFlex(); + // var isAdapt = !ob.horizontalAlign || ob.horizontalAlign === HorizontalAlign.Center || ob.horizontalAlign === HorizontalAlign.Stretch; + // if (!isAdapt || justOneItem) { + if (supportFlex) { + return extend({}, ob, { type: FlexCenterLayout.xtype }); + } + + return extend({}, ob, { type: InlineCenterAdaptLayout.xtype }); + // } + // return ob; +}); +configWidget("bi.vertical_adapt", ob => { + const supportFlex = isSupportFlex(); + // var isAdapt = ob.horizontalAlign === HorizontalAlign.Center || ob.horizontalAlign === HorizontalAlign.Stretch; + // if (!isAdapt || justOneItem) { + if (supportFlex) { + return extend({}, ob, { type: FlexVerticalCenterAdapt.xtype }); + } + + return extend({}, ob, { type: InlineVerticalAdaptLayout.xtype }); + // } + // return ob; +}); + +configWidget("bi.horizontal_adapt", ob => { + const justOneItem = (ob.items && ob.items.length <= 1); + const isAdapt = !ob.horizontalAlign || ob.horizontalAlign === HorizontalAlign.Center || ob.horizontalAlign === HorizontalAlign.Stretch; + const verticalAlignTop = !ob.verticalAlign || ob.verticalAlign === VerticalAlign.TOP; + if (verticalAlignTop && justOneItem) { + return extend({}, ob, { type: HorizontalAutoLayout.xtype }); + } + const supportFlex = isSupportFlex(); + // 在横向自适应场景下我们需要使用table的自适应撑出滚动条的特性(flex处理不了这种情况) + // 主要出现在center_adapt或者horizontal_adapt的场景,或者主动设置horizontalAlign的场景 + if (isAdapt) { + return extend({ + horizontalAlign: HorizontalAlign.Center + }, ob, { type: TableAdaptLayout.xtype }); + } + if (supportFlex) { + return extend({ + horizontalAlign: HorizontalAlign.Center, + scrollx: false + }, ob, { type: FlexHorizontalLayout.xtype }); + } + + return extend({ + horizontalAlign: HorizontalAlign.Center + }, ob, { type: TableAdaptLayout.xtype }); +}); + +configWidget("bi.horizontal_float", ob => { + if (isSupportFlex()) { + return extend({}, ob, { type: FlexHorizontalCenter.xtype }); + } + if (ob.items && ob.items.length <= 1) { + return extend({}, ob, { type: InlineHorizontalAdaptLayout.xtype }); + } + + return ob; +}); + +configWidget("bi.horizontal_fill", ob => { + if (isSupportFlex()) { + return extend({ + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + scrollx: false + }, ob, { type: FlexHorizontalLayout.xtype }); + } + if ((ob.horizontalAlign && ob.horizontalAlign !== HorizontalAlign.Stretch) || (ob.scrollable === true || ob.scrollx === true)) { + // 宽度不受限,要用table布局 + return extend({ + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch + }, ob, { type: TableLayout.xtype }); + } + + return extend({}, ob, { type: FloatHorizontalFillLayout.xtype }); +}); +configWidget("bi.vertical_fill", ob => { + if (isSupportFlex()) { + return extend({ + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + scrolly: false + }, ob, { type: FlexVerticalLayout.xtype }); + } + if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { + // 有滚动条,降级到table布局处理 + return extend({}, ob, { + type: TdLayout.xtype, + items: map(ob.items, (i, item) => [item]) + }); + } + let hasAuto = false; + if (ob.rowSize && ob.rowSize.length > 0) { + if (ob.rowSize.indexOf("") >= 0 || ob.rowSize.indexOf("auto") >= 0) { + hasAuto = true; + } + } else { + each(ob.items, (i, item) => { + if (isNull(item.height) || item.height === "") { + hasAuto = true; + } + }); + } + if (hasAuto) { + // 有自动高的时候 + return extend({}, ob, { type: AutoVerticalTapeLayout.xtype }); + } + + return extend({}, ob, { type: VTapeLayout.xtype }); +}); +configWidget("bi.horizontal_sticky", ob => { + if (!isSupportSticky()) { + return extend({ scrollx: true }, ob, { type: HorizontalFillLayout.xtype }); + } +}); +configWidget("bi.vertical_sticky", ob => { + if (!isSupportSticky()) { + return extend({ scrolly: true }, ob, { type: VerticalFillLayout.xtype }); + } +}); + +configWidget("bi.left_right_vertical_adapt", ob => { + if (isSupportFlex()) { + // IE下其实也是可以使用flex布局的,只要排除掉出现滚动条的情况 + // if (!isIE() || (ob.scrollable !== true && ob.scrolly !== true)) { + return extend({}, ob, { type: FlexLeftRightVerticalAdaptLayout.xtype }); + // } + } + + return ob; +}); +configWidget("bi.flex_horizontal", ob => { + if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { + if (ob.hgap > 0 || ob.lgap > 0 || ob.rgap > 0) { + if (Providers.getProvider(SystemProvider.xtype).getResponsiveMode()) { + return extend({}, ob, { type: ResponsiveFlexWrapperHorizontalLayout.xtype }); + } + + return extend({}, ob, { type: FlexWrapperHorizontalLayout.xtype }); + } + } + if (Providers.getProvider(SystemProvider.xtype).getResponsiveMode()) { + return extend({}, ob, { type: ResponsiveFlexHorizontalLayout.xtype }); + } +}); +configWidget("bi.flex_vertical", ob => { + if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { + if (ob.hgap > 0 || ob.lgap > 0 || ob.rgap > 0) { + return extend({}, ob, { type: FlexWrapperVerticalLayout.xtype }); + } + } +}); + +configWidget("bi.table", ob => { + if (!isSupportGrid()) { + return extend({}, ob, { type: TdLayout.xtype }); + } + + return ob; +}); + +configWidget("bi.radio", ob => { + if (isIE() && getIEVersion() <= 9) { + return extend({}, ob, { type: ImageRadio.xtype }); + } + + return ob; +}); + +configWidget("bi.checkbox", ob => { + if (isIE() && getIEVersion() <= 9) { + return extend({}, ob, { type: ImageCheckbox.xtype }); + } + + return ob; +}); + +configWidget("bi.half_icon_button", ob => { + if (isIE() && getIEVersion() < 9) { + return ob; + } + + return extend({}, ob, { type: "bi.half_button" }); +}); + + diff --git a/packages/fineui/src/core/platform/web/detectElementResize.js b/packages/fineui/src/core/platform/web/detectElementResize.js new file mode 100644 index 000000000..3ae28a853 --- /dev/null +++ b/packages/fineui/src/core/platform/web/detectElementResize.js @@ -0,0 +1,55 @@ +import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer"; +import $ from "jquery"; + +const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill; + +function addResizeListener(element, fn) { + if (ResizeObserver) { + if (!element.__resizeObserver__) { + const resizeObserver = new ResizeObserver((() => { + element.__resizeListeners__.forEach(listener => { + $(element).is(":visible") && listener(); + }); + })); + resizeObserver.observe(element); + element.__resizeObserver__ = resizeObserver; + } + if (!element.__resizeListeners__) { + element.__resizeListeners__ = []; + } + element.__resizeListeners__.push(fn); + } +} + +function removeResizeListener(element, fn) { + if (ResizeObserver) { + if (BI.isNull(fn)) { + element.__resizeListeners__ = []; + element.__resizeObserver__ && element.__resizeObserver__.unobserve(element); + element.__resizeObserver__ = null; + + return; + } + const index = element.__resizeListeners__.indexOf(fn); + if (index >= 0) { + element.__resizeListeners__.splice(index, 1); + if (!element.__resizeListeners__.length) { + element.__resizeObserver__ && element.__resizeObserver__.unobserve(element); + element.__resizeObserver__ = null; + } + } + } +} + +export const ResizeDetector = { + addResizeListener(widget, fn) { + addResizeListener(widget.element[0], fn); + + return function () { + removeResizeListener(widget.element[0], fn); + }; + }, + removeResizeListener(widget, fn) { + removeResizeListener(widget.element[0], fn); + }, +}; diff --git a/packages/fineui/src/core/platform/web/function.js b/packages/fineui/src/core/platform/web/function.js new file mode 100644 index 000000000..5ab7fd47b --- /dev/null +++ b/packages/fineui/src/core/platform/web/function.js @@ -0,0 +1,171 @@ +// 浏览器相关方法 +import { isString } from "../../2.base"; +import { _global } from "../../0.foundation"; + +let __isIE; + +export function isIE() { + if (!_global.navigator) { + return false; + } + if (!__isIE) { + __isIE = /(msie|trident)/i.test(navigator.userAgent.toLowerCase()); + } + + return __isIE; +} + +let __IEVersion; + +export function getIEVersion() { + if (!_global.navigator) { + return 0; + } + if (__IEVersion) { + return __IEVersion; + } + let version = 0; + const agent = navigator.userAgent.toLowerCase(); + const v1 = agent.match(/(?:msie\s([\w.]+))/); + const v2 = agent.match(/(?:trident.*rv:([\w.]+))/); + if (v1 && v2 && v1[1] && v2[1]) { + version = Math.max(v1[1] * 1, v2[1] * 1); + } else if (v1 && v1[1]) { + version = v1[1] * 1; + } else if (v2 && v2[1]) { + version = v2[1] * 1; + } else { + version = 0; + } + __IEVersion = version; + + return __IEVersion; +} + +export function isIE9Below() { + if (!isIE()) { + return false; + } + + return getIEVersion() < 9; +} + +export function isEdge() { + if (!_global.navigator) { + return false; + } + + return /edg/i.test(navigator.userAgent.toLowerCase()); +} + +export function isChrome() { + if (!_global.navigator) { + return false; + } + + return /chrome/i.test(navigator.userAgent.toLowerCase()); +} + +export function isFireFox() { + if (!_global.navigator) { + return false; + } + + return /firefox/i.test(navigator.userAgent.toLowerCase()); +} + +export function isOpera() { + if (!_global.navigator) { + return false; + } + + return /opera/i.test(navigator.userAgent.toLowerCase()); +} + +export function isSafari() { + if (!_global.navigator) { + return false; + } + + return /safari/i.test(navigator.userAgent.toLowerCase()) && !/chrome/i.test(navigator.userAgent.toLowerCase()); +} + +export function isKhtml() { + if (!_global.navigator) { + return false; + } + + return /Konqueror|Safari|KHTML/i.test(navigator.userAgent); +} + +export function isMac() { + if (!_global.navigator) { + return false; + } + + return /macintosh|mac os x/i.test(navigator.userAgent); +} + +export function isWindows() { + if (!_global.navigator) { + return false; + } + + return /windows|win32/i.test(navigator.userAgent); +} + +export function isSupportCss3(style) { + if (!_global.document) { + return false; + } + const prefix = ["webkit", "Moz", "ms", "o"]; + const humpString = []; + const htmlStyle = document.documentElement.style; + let i; + let len; + + function _toHumb(string) { + if (!isString(string)) { + return ""; + } + + return string.replace(/-(\w)/g, ($0, $1) => $1.toUpperCase()); + }; + + for (i = 0; i < prefix.length; i++) { + humpString.push(_toHumb(`${prefix[i]}-${style}`)); + } + humpString.push(_toHumb(style)); + + for (i = 0, len = humpString.length; i < len; i++) { + if (humpString[i] in htmlStyle) { + return true; + } + } + + return false; +} + +export function getSafariVersion() { + if (!_global.navigator) { + return 0; + } + const agent = navigator.userAgent.toLowerCase(); + const version = agent.match(/version\/([\d.]+)/); + if (version && version[1]) { + return version[1] * 1; + } + + return 0; +} + +export function getMinimumFontSize() { + // not work for firefox + const el = document.createElement("div"); + el.style.fontSize = "1px"; + document.body.appendChild(el); + const size = getComputedStyle(el).fontSize; + el.remove(); + + return parseInt(size, 10); +} diff --git a/packages/fineui/src/core/platform/web/index.js b/packages/fineui/src/core/platform/web/index.js new file mode 100644 index 000000000..17213f37d --- /dev/null +++ b/packages/fineui/src/core/platform/web/index.js @@ -0,0 +1,6 @@ +export * from "./detectElementResize"; +export * from "./function"; +export * from "./load"; + + + diff --git a/src/core/platform/web/jquery/__test__/fn.test.js b/packages/fineui/src/core/platform/web/jquery/__test__/fn.test.js similarity index 100% rename from src/core/platform/web/jquery/__test__/fn.test.js rename to packages/fineui/src/core/platform/web/jquery/__test__/fn.test.js diff --git a/packages/fineui/src/core/platform/web/jquery/event.js b/packages/fineui/src/core/platform/web/jquery/event.js new file mode 100644 index 000000000..7dd61b2cf --- /dev/null +++ b/packages/fineui/src/core/platform/web/jquery/event.js @@ -0,0 +1,12 @@ +import $ from "jquery"; + +/* + * 给jQuery.Event对象添加的工具方法 + */ +$.extend($.Event.prototype, { + // event.stopEvent + stopEvent() { + this.stopPropagation(); + this.preventDefault(); + }, +}); diff --git a/packages/fineui/src/core/platform/web/jquery/fn.js b/packages/fineui/src/core/platform/web/jquery/fn.js new file mode 100644 index 000000000..2edb1545d --- /dev/null +++ b/packages/fineui/src/core/platform/web/jquery/fn.js @@ -0,0 +1,260 @@ +import { isIE, isIE9Below } from "../function"; +import { htmlEncode } from "../../../func"; +import { toUpperCase, remove, camelize, isKey, isNull, isNotEmptyString, map, hyphenate } from "../../../2.base"; +import { makeFirstPY } from "../../../utils"; +import { createWidget } from "../../../5.inject"; +import { _global } from "../../../0.foundation"; +import $ from "jquery"; + +$.fn.extend({ + + insets() { + const p = this.padding(), + b = this.border(); + + return { + top: p.top, + bottom: p.bottom + b.bottom + b.top, + left: p.left, + right: p.right + b.right + b.left, + }; + }, + + bounds(value) { + let tmp = { hasIgnoredBounds: true }; + + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + // tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + // tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + + return this; + } + + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + + return { + x: tmp.left, + y: tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + width: this.outerWidth(), + height: this.outerHeight(), + }; + }, + + destroy() { + this.remove(); + if (isIE() === true) { + this[0].outerHTML = ""; + } + }, + + /** + * 高亮显示 + * @param text 必需 + * @param keyword + * @param py + * @returns {*} + * @private + * 原理: + * 1、得到text的拼音py, 分别看是否匹配关键字keyword, 得到匹配索引tidx和pidx + * 2、比较tidx和pidx, 取大于-1且较小的索引,标红[索引,索引 + keyword.length - 1]的文本 + * 3、text和py各自取tidx/pidx + keyword.length索引开始的子串作为新的text和py, 重复1, 直到text和py有一个为"" + */ + __textKeywordMarked__(text, keyword, py) { + if (isNull(text)) { + text = ""; + } + if (!isKey(keyword) || (`${text}`).length > 100) { + if (isIE9Below()) { + return this.html(htmlEncode(text)); + } + // textContent性能更好,并且原生防xss + this[0].textContent = text; + + return this; + } + keyword = `${keyword}`; + keyword = toUpperCase(keyword); + let textLeft = `${text}`; + py = `${py || makeFirstPY(text, { + splitChar: "\u200b", + })}`; + py = toUpperCase(py); + this.empty(); + // BI-48487 性能: makeFirstPY出来的py中包含多音字是必要的,但虽然此方法中做了限制。但是对于一个长度为60,包含14个多音字的字符串 + // 获取的的py长度将达到1966080, 远超过text的长度,到后面都是在做"".substring的无用功,所以此循环应保证py和textLeft长度不为0 + while (py.length > 0 && textLeft.length > 0) { + const tidx = toUpperCase(textLeft).indexOf(keyword); + let pidx = py.indexOf(keyword); + if (pidx >= 0) { + pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length; + } + + // BI-56945 场景: 对'啊a'标红, a为keyword, 此时tidx为1, pidx为0, 此时使用tidx显然'啊'就无法标红了 + if (tidx >= 0 && (pidx > tidx || pidx === -1)) { + // 标红的text未encode + this.append(htmlEncode(textLeft.substr(0, tidx))); + this.append($("").addClass("bi-keyword-red-mark") + .html(htmlEncode(textLeft.substr(tidx, keyword.length)))); + + textLeft = textLeft.substr(tidx + keyword.length); + if (isNotEmptyString(py)) { + // 每一组拼音都应该前进,而不是只是当前的 + py = map(py.split("\u200b"), (idx, ps) => ps.slice(tidx + keyword.length)).join("\u200b"); + } + } else if (pidx >= 0) { + // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 + // 标红的text未encode + this.append(htmlEncode(textLeft.substr(0, pidx))); + this.append($("").addClass("bi-keyword-red-mark") + .html(htmlEncode(textLeft.substr(pidx, keyword.length)))); + if (isNotEmptyString(py)) { + // 每一组拼音都应该前进,而不是只是当前的 + py = map(py.split("\u200b"), (idx, ps) => ps.slice(pidx + keyword.length)).join("\u200b"); + } + textLeft = textLeft.substr(pidx + keyword.length); + } else { + // 标红的text未encode + this.append(htmlEncode(textLeft)); + break; + } + } + + return this; + }, + + getDomHeight(parent) { + const clone = $(this).clone(); + clone.appendTo($(parent || "body")); + const height = clone.height(); + clone.remove(); + + return height; + }, + + // 是否有竖直滚动条 + hasVerticalScroll() { + return this.height() > 0 && this[0].clientWidth < this[0].offsetWidth; + }, + + // 是否有水平滚动条 + hasHorizonScroll() { + return this.width() > 0 && this[0].clientHeight < this[0].offsetHeight; + }, + + // 获取计算后的样式 + getStyle(name) { + const node = this[0]; + let computedStyle = void 0; + + // W3C Standard + if (_global.getComputedStyle) { + // In certain cases such as within an iframe in FF3, this returns null. + computedStyle = _global.getComputedStyle(node, null); + if (computedStyle) { + return computedStyle.getPropertyValue(hyphenate(name)); + } + } + // Safari + if (document.defaultView && document.defaultView.getComputedStyle) { + computedStyle = document.defaultView.getComputedStyle(node, null); + // A Safari bug causes this to return null for `display: none` elements. + if (computedStyle) { + return computedStyle.getPropertyValue(hyphenate(name)); + } + if (name === "display") { + return "none"; + } + } + // Internet Explorer + if (node.currentStyle) { + if (name === "float") { + return node.currentStyle.cssFloat || node.currentStyle.styleFloat; + } + + return node.currentStyle[camelize(name)]; + } + + return node.style && node.style[camelize(name)]; + }, + + __isMouseInBounds__(e) { + const offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); + const width = offset2Body.width || this.outerWidth(); + const height = offset2Body.height || this.outerHeight(); + + // offset2Body.left的值可能会有小数,导致某点出现false + return !(e.pageX < Math.floor(offset2Body.left) || e.pageX > offset2Body.left + width + || e.pageY < Math.floor(offset2Body.top) || e.pageY > offset2Body.top + height); + }, + + __hasZIndexMask__(zindex) { + return zindex && this.zIndexMask[zindex] != null; + }, + + __buildZIndexMask__(zindex, domArray) { + this.zIndexMask = this.zIndexMask || {};// 存储z-index的mask + this.indexMask = this.indexMask || [];// 存储mask + const mask = createWidget({ + type: "bi.center_adapt", + cls: "bi-z-index-mask", + items: domArray, + }); + + mask.element.css({ "z-index": zindex }); + createWidget({ + type: "bi.absolute", + element: this, + items: [ + { + el: mask, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + this.indexMask.push(mask); + zindex && (this.zIndexMask[zindex] = mask); + + return mask.element; + }, + + __releaseZIndexMask__(zindex) { + if (zindex && this.zIndexMask[zindex]) { + remove(this.indexMask, this.zIndexMask[zindex]); + this.zIndexMask[zindex].destroy(); + + return; + } + this.indexMask = this.indexMask || []; + const indexMask = this.indexMask.pop(); + indexMask && indexMask.destroy(); + }, +}); + + +$.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), (function(e, t) { + $.fn[t] = function(e, i) { + return arguments.length > 0 ? this.on(t, null, e, i) : this.trigger(t) + } +})) \ No newline at end of file diff --git a/packages/fineui/src/core/platform/web/jquery/index.js b/packages/fineui/src/core/platform/web/jquery/index.js new file mode 100644 index 000000000..adc0e96a7 --- /dev/null +++ b/packages/fineui/src/core/platform/web/jquery/index.js @@ -0,0 +1,3 @@ +import "./event"; +import "./fn"; +import "./jquery.mousewheel"; diff --git a/packages/fineui/src/core/platform/web/jquery/jquery.mousewheel.js b/packages/fineui/src/core/platform/web/jquery/jquery.mousewheel.js new file mode 100644 index 000000000..7930f1b24 --- /dev/null +++ b/packages/fineui/src/core/platform/web/jquery/jquery.mousewheel.js @@ -0,0 +1,222 @@ +import { _global } from "../../../0.foundation"; +import $ from "jquery"; + +/* eslint-disable */ +/* ! + * jQuery Mousewheel 3.1.13 + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + */ + +(function (factory) { + // Browser globals + factory($); + // if ( typeof define === "function" && define.amd ) { + // // AMD. Register as an anonymous module. + // define(["../core/jquery"], factory); + // } else if (typeof exports === "object") { + // // Node/CommonJS style for Browserify + // module.exports = factory; + // } else { + // // Browser globals + // factory(BI.jQuery); + // } +}(function ($) { + + var toFix = ["wheel", "mousewheel", "DOMMouseScroll", "MozMousePixelScroll"], + toBind = ("onwheel" in document || document.documentMode >= 9) ? + ["wheel"] : ["mousewheel", "DomMouseScroll", "MozMousePixelScroll"], + slice = Array.prototype.slice, + nullLowestDeltaTimeout, lowestDelta; + + if ($.event.fixHooks) { + for (var i = toFix.length; i;) { + $.event.fixHooks[toFix[--i]] = $.event.mouseHooks; + } + } + + var special = $.event.special.mousewheel = { + version: "3.1.12", + + setup: function () { + if (this.addEventListener) { + for (var i = toBind.length; i;) { + this.addEventListener(toBind[--i], handler, false); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function () { + if (this.removeEventListener) { + for (var i = toBind.length; i;) { + this.removeEventListener(toBind[--i], handler, false); + } + } else { + this.onmousewheel = null; + } + }, + + settings: { + adjustOldDeltas: true, // see shouldAdjustOldDeltas() below + normalizeOffset: true // calls getBoundingClientRect for each event + } + }; + + $.fn.extend({ + mousewheel: function (fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function (fn) { + return this.unbind("mousewheel", fn); + } + }); + + + function handler(event) { + var orgEvent = event || _global.event, + args = slice.call(arguments, 1), + delta = 0, + deltaX = 0, + deltaY = 0, + absDelta = 0, + offsetX = 0, + offsetY = 0; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ("detail" in orgEvent) { + deltaY = orgEvent.detail * -1; + } + if ("wheelDelta" in orgEvent) { + deltaY = orgEvent.wheelDelta; + } + if ("wheelDeltaY" in orgEvent) { + deltaY = orgEvent.wheelDeltaY; + } + if ("wheelDeltaX" in orgEvent) { + deltaX = orgEvent.wheelDeltaX * -1; + } + + // Firefox < 17 horizontal scrolling related to DOMMouseScroll event + if ("axis" in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { + deltaX = deltaY * -1; + deltaY = 0; + } + + // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy + delta = deltaY === 0 ? deltaX : deltaY; + + // New school wheel delta (wheel event) + if ("deltaY" in orgEvent) { + deltaY = orgEvent.deltaY * -1; + delta = deltaY; + } + if ("deltaX" in orgEvent) { + deltaX = orgEvent.deltaX; + if (deltaY === 0) { + delta = deltaX * -1; + } + } + + // No change actually happened, no reason to go any further + if (deltaY === 0 && deltaX === 0) { + return; + } + + // Need to convert lines and pages to pixels if we aren't already in pixels + // There are three delta modes: + // * deltaMode 0 is by pixels, nothing to do + // * deltaMode 1 is by lines + // * deltaMode 2 is by pages + if (orgEvent.deltaMode === 1) { + var lineHeight = 40; + delta *= lineHeight; + deltaY *= lineHeight; + deltaX *= lineHeight; + } else if (orgEvent.deltaMode === 2) { + var pageHeight = 800; + delta *= pageHeight; + deltaY *= pageHeight; + deltaX *= pageHeight; + } + + // Store lowest absolute delta to normalize the delta values + absDelta = Math.max(Math.abs(deltaY), Math.abs(deltaX)); + + if (!lowestDelta || absDelta < lowestDelta) { + lowestDelta = absDelta; + + // Adjust older deltas if necessary + if (shouldAdjustOldDeltas(orgEvent, absDelta)) { + lowestDelta /= 40; + } + } + + // Adjust older deltas if necessary + if (shouldAdjustOldDeltas(orgEvent, absDelta)) { + // Divide all the things by 40! + delta /= 40; + deltaX /= 40; + deltaY /= 40; + } + + // Get a whole, normalized value for the deltas + delta = Math[delta >= 1 ? "floor" : "ceil"](delta / lowestDelta); + deltaX = Math[deltaX >= 1 ? "floor" : "ceil"](deltaX / lowestDelta); + deltaY = Math[deltaY >= 1 ? "floor" : "ceil"](deltaY / lowestDelta); + + // Normalise offsetX and offsetY properties + if (special.settings.normalizeOffset && this.getBoundingClientRect) { + var boundingRect = this.getBoundingClientRect(); + offsetX = event.clientX - boundingRect.left; + offsetY = event.clientY - boundingRect.top; + } + + // Add information to the event object + event.deltaX = deltaX; + event.deltaY = deltaY; + event.deltaFactor = lowestDelta; + event.offsetX = offsetX; + event.offsetY = offsetY; + // Go ahead and set deltaMode to 0 since we converted to pixels + // Although this is a little odd since we overwrite the deltaX/Y + // properties with normalized deltas. + event.deltaMode = 0; + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + // Clearout lowestDelta after sometime to better + // handle multiple device types that give different + // a different lowestDelta + // Ex: trackpad = 3 and mouse wheel = 120 + if (nullLowestDeltaTimeout) { + clearTimeout(nullLowestDeltaTimeout); + } + nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); + + return ($.event.dispatch || $.event.handle).apply(this, args); + } + + function nullLowestDelta() { + lowestDelta = null; + } + + function shouldAdjustOldDeltas(orgEvent, absDelta) { + // If this is an older event and the delta is divisable by 120, + // then we are assuming that the browser is treating this as an + // older mouse wheel event and that we should divide the deltas + // by 40 to try and get a more usable deltaFactor. + // Side note, this actually impacts the reported scroll distance + // in older browsers and can cause scrolling to be slower than native. + // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. + return special.settings.adjustOldDeltas && orgEvent.type === "mousewheel" && absDelta % 120 === 0; + } + +})); diff --git a/packages/fineui/src/core/platform/web/jquery/jquery.polyfill.js b/packages/fineui/src/core/platform/web/jquery/jquery.polyfill.js new file mode 100644 index 000000000..d7fb59e75 --- /dev/null +++ b/packages/fineui/src/core/platform/web/jquery/jquery.polyfill.js @@ -0,0 +1,96 @@ +/** + * 用于 jquery 在 worker 环境或者 V8 引擎的 polyfill + */ +// import { _global } from "@/core/0.foundation"; + +const _global = globalThis; + +const document = {}; +const fakeElement = Object.create(document); + +Object.assign(document, { + parentNode: null, + nodeType: 9, + head: fakeElement, + body: fakeElement, + ownerDocument: document, + documentElement: document, + toString() { + return "FakeDocument"; + }, + appendChild(child) { + return child; + }, + implementation: { + createHTMLDocument() { + return { + body: { + childNodes: [], + }, + }; + }, + createDocumentFragment() { + return this; + }, + }, + getElementById() { + return fakeElement; + }, + createElement() { + return fakeElement; + }, + createDocumentFragment() { + return this; + }, + cloneNode() { + return this; + }, + getElementsByTagName() { + return [fakeElement]; + }, + getElementsByClassName() { + return [fakeElement]; + }, + setAttribute() { + return null; + }, + getAttribute() { + return null; + }, + removeChild() { + return null; + }, + addEventListener() { + return null; + }, + removeEventListener() { + return null; + }, +}); + +Object.assign(fakeElement, { + nodeType: 1, + style: {}, + ownerDocument: document, + parentNod: fakeElement, + firstChild: fakeElement, + lastChild: fakeElement, + toString() { + return "FakeElement"; + }, +}); + +function polyfillProps(key, obj) { + _global[key] = _global[key] || obj; + if (typeof obj === "object") { + try { + Object.assign(_global[key], obj); + } catch(err) { + // _global[key] 可能只有 get 方法 + } + } +} + +_global.window = _global; +polyfillProps("XMLHttpRequest", function () {}); +polyfillProps("document", document); diff --git a/packages/fineui/src/core/platform/web/load.js b/packages/fineui/src/core/platform/web/load.js new file mode 100644 index 000000000..6dd203ea1 --- /dev/null +++ b/packages/fineui/src/core/platform/web/load.js @@ -0,0 +1,155 @@ +import $ from "jquery"; + +const _LOADED = {}; // alex:保存加载过的 + +function loadReady(src, must) { + const $scripts = $("head script, body script"); + $.each($scripts, (i, item) => { + if (item.src.indexOf(src) !== -1) { + _LOADED[src] = true; + } + }); + const $links = $("head link"); + $.each($links, (i, item) => { + if (item.href.indexOf(src) !== -1 && must) { + _LOADED[src] = false; + $(item).remove(); + } + }); +} + +/** + * + * @param src + * @param ext + * @param must 强行加载 + */ +export function $import(src, ext, must) { + loadReady(src, must); + // alex:如果已经加载过了的,直接return + if (_LOADED[src] === true) { + return; + } + if (ext === "css") { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.type = "text/css"; + link.href = src; + const head = document.getElementsByTagName("head")[0]; + head.appendChild(link); + _LOADED[src] = true; + } else { + // alex:这里用同步调用的方式,必须等待ajax完成 + $.ajax({ + url: src, + dataType: "script", // alex:指定dataType为script,jquery会帮忙做globalEval的事情 + async: false, + cache: true, + complete(res, status) { + /* + * alex:发现jquery会很智能地判断一下返回的数据类型是不是script,然后做一个globalEval + * 所以当status为success时就不需要再把其中的内容加到script里面去了 + */ + if (status === "success") { + _LOADED[src] = true; + } + }, + }); + } +} + +/** + * 同步加载javascript + * @param uri + * @returns {boolean} + */ +export function syncLoadScript(uri) { + if (_LOADED[uri]) { + return true; + } + const xhr = new XMLHttpRequest(); + xhr.open("GET", uri, false); + xhr.send(null); + if (xhr.status === 200) { + const script = document.createElement("script"); + script.type = "text/javascript"; + script.text = xhr.responseText; + document.head.appendChild(script); + _LOADED[uri] = true; + return true; + } + return false; +} + +/** + * 默认的异步加载javascript方法 + * @param uri + * @returns {Promise|Promise} + */ +export function loadScript(uri) { + if (_LOADED[uri]) { + return Promise.resolve(true); + } + return new Promise(resolve => { + const script = document.createElement("script"); + script.type = "application/javascript"; + script.src = uri; + script.onload = function() { + resolve(true); + }; + document.head.appendChild(script); + _LOADED[uri] = true; + }); +} + +/** + * 加载css方法,这没同步异步之分,都是同步的 + * @param uri + * @returns {boolean} + */ +export function loadStyleSheet(uri) { + if (_LOADED[uri]) { + return true; + } + const link = document.createElement("link"); + link.type = "text/css"; + link.ref = "stylesheet"; + link.href = uri; + document.head.appendChild(link); + _LOADED[uri] = true; + + return true; +} + + +export function loadResource(opt) { + const { src, async = false } = opt; + let extension = opt.extension; + if (!extension) { + const match = src.match(/\.[^.]+$/g); + if (match && match.length > 0) { + extension = match[0]; + } + } + if (extension === ".css") { + return loadStyleSheet(src); + } + if (async) { + return loadScript(src); + } + + return syncLoadScript(src); +} + + +export function loadResources(resources) { + const asyncLoad = resources.some(resource => resource.async); + + if (asyncLoad) { + return Promise.all(resources.map(resource => loadResource(resource))); + } + + return resources.forEach(resource => { + loadResource(resource); + }); +} diff --git a/packages/fineui/src/core/structure/aes.js b/packages/fineui/src/core/structure/aes.js new file mode 100644 index 000000000..f2e650d89 --- /dev/null +++ b/packages/fineui/src/core/structure/aes.js @@ -0,0 +1,2343 @@ +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/** + * CryptoJS core components. + */ + + +export const CRYPT_TYPE = { AES: "aes" }; + +const CryptoJS = (function (Math, undefined) { + /** + * CryptoJS namespace. + */ + const C = {}; + + /** + * Library namespace. + */ + const C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + const Base = C_lib.Base = (function () { + function F() { + } + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + F.prototype = this; + const subtype = new F(); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty("init")) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + const instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (const propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty("toString")) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + }, + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + const thisWords = this.words; + const thatWords = wordArray.words; + const thisSigBytes = this.sigBytes; + const thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + const thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else if (thatWords.length > 0xffff) { + // Copy one word at a time + for (var i = 0; i < thatSigBytes; i += 4) { + thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; + } + } else { + // Copy all words at once + thisWords.push.apply(thisWords, thatWords); + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + const words = this.words; + const sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + const clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + const words = []; + for (let i = 0; i < nBytes; i += 4) { + words.push((Math.random() * 0x100000000) | 0); + } + + return new WordArray.init(words, nBytes); + }, + }); + + /** + * Encoder namespace. + */ + const C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + const words = wordArray.words; + const sigBytes = wordArray.sigBytes; + + // Convert + const hexChars = []; + for (let i = 0; i < sigBytes; i++) { + const bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(""); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + const hexStrLength = hexStr.length; + + // Convert + const words = []; + for (let i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + }, + }; + + /** + * Latin1 encoding strategy. + */ + const Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + const words = wordArray.words; + const sigBytes = wordArray.sigBytes; + + // Convert + const latin1Chars = []; + for (let i = 0; i < sigBytes; i++) { + const bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(""); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + const latin1StrLength = latin1Str.length; + + // Convert + const words = []; + for (let i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + }, + }; + + /** + * UTF-8 encoding strategy. + */ + const Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error("Malformed UTF-8 data"); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + }, + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + const BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == "string") { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + // Shortcuts + const data = this._data; + const dataWords = data.words; + const dataSigBytes = data.sigBytes; + const blockSize = this.blockSize; + const blockSizeBytes = blockSize * 4; + + // Count blocks ready + let nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + const nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + const nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (let offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + var processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + const clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0, + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + const Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + const hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512 / 32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + }, + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; +}(Math)); + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +(function () { + // Shortcuts + const C = CryptoJS; + const C_lib = C.lib; + const WordArray = C_lib.WordArray; + const C_enc = C.enc; + + /** + * Base64 encoding strategy. + */ + const Base64 = C_enc.Base64 = { + /** + * Converts a word array to a Base64 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Base64 string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + const words = wordArray.words; + const sigBytes = wordArray.sigBytes; + const map = this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + const base64Chars = []; + for (let i = 0; i < sigBytes; i += 3) { + const byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + const byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + const byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + const triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (let j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + const paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(""); + }, + + /** + * Converts a Base64 string to a word array. + * + * @param {string} base64Str The Base64 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64.parse(base64String); + */ + parse: function (base64Str) { + // Shortcuts + let base64StrLength = base64Str.length; + const map = this._map; + + // Ignore padding + const paddingChar = map.charAt(64); + if (paddingChar) { + const paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex != -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + const words = []; + let nBytes = 0; + for (let i = 0; i < base64StrLength; i++) { + if (i % 4) { + const bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2); + const bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2); + words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + + return WordArray.create(words, nBytes); + }, + + _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + }; +}()); + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +(function (Math) { + // Shortcuts + const C = CryptoJS; + const C_lib = C.lib; + const WordArray = C_lib.WordArray; + const Hasher = C_lib.Hasher; + const C_algo = C.algo; + + // Constants table + const T = []; + + // Compute constants + (function () { + for (let i = 0; i < 64; i++) { + T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; + } + }()); + + /** + * MD5 hash algorithm. + */ + const MD5 = C_algo.MD5 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Swap endian + for (let i = 0; i < 16; i++) { + // Shortcuts + const offset_i = offset + i; + const M_offset_i = M[offset_i]; + + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Shortcuts + const H = this._hash.words; + + const M_offset_0 = M[offset + 0]; + const M_offset_1 = M[offset + 1]; + const M_offset_2 = M[offset + 2]; + const M_offset_3 = M[offset + 3]; + const M_offset_4 = M[offset + 4]; + const M_offset_5 = M[offset + 5]; + const M_offset_6 = M[offset + 6]; + const M_offset_7 = M[offset + 7]; + const M_offset_8 = M[offset + 8]; + const M_offset_9 = M[offset + 9]; + const M_offset_10 = M[offset + 10]; + const M_offset_11 = M[offset + 11]; + const M_offset_12 = M[offset + 12]; + const M_offset_13 = M[offset + 13]; + const M_offset_14 = M[offset + 14]; + const M_offset_15 = M[offset + 15]; + + // Working varialbes + let a = H[0]; + let b = H[1]; + let c = H[2]; + let d = H[3]; + + // Computation + a = FF(a, b, c, d, M_offset_0, 7, T[0]); + d = FF(d, a, b, c, M_offset_1, 12, T[1]); + c = FF(c, d, a, b, M_offset_2, 17, T[2]); + b = FF(b, c, d, a, M_offset_3, 22, T[3]); + a = FF(a, b, c, d, M_offset_4, 7, T[4]); + d = FF(d, a, b, c, M_offset_5, 12, T[5]); + c = FF(c, d, a, b, M_offset_6, 17, T[6]); + b = FF(b, c, d, a, M_offset_7, 22, T[7]); + a = FF(a, b, c, d, M_offset_8, 7, T[8]); + d = FF(d, a, b, c, M_offset_9, 12, T[9]); + c = FF(c, d, a, b, M_offset_10, 17, T[10]); + b = FF(b, c, d, a, M_offset_11, 22, T[11]); + a = FF(a, b, c, d, M_offset_12, 7, T[12]); + d = FF(d, a, b, c, M_offset_13, 12, T[13]); + c = FF(c, d, a, b, M_offset_14, 17, T[14]); + b = FF(b, c, d, a, M_offset_15, 22, T[15]); + + a = GG(a, b, c, d, M_offset_1, 5, T[16]); + d = GG(d, a, b, c, M_offset_6, 9, T[17]); + c = GG(c, d, a, b, M_offset_11, 14, T[18]); + b = GG(b, c, d, a, M_offset_0, 20, T[19]); + a = GG(a, b, c, d, M_offset_5, 5, T[20]); + d = GG(d, a, b, c, M_offset_10, 9, T[21]); + c = GG(c, d, a, b, M_offset_15, 14, T[22]); + b = GG(b, c, d, a, M_offset_4, 20, T[23]); + a = GG(a, b, c, d, M_offset_9, 5, T[24]); + d = GG(d, a, b, c, M_offset_14, 9, T[25]); + c = GG(c, d, a, b, M_offset_3, 14, T[26]); + b = GG(b, c, d, a, M_offset_8, 20, T[27]); + a = GG(a, b, c, d, M_offset_13, 5, T[28]); + d = GG(d, a, b, c, M_offset_2, 9, T[29]); + c = GG(c, d, a, b, M_offset_7, 14, T[30]); + b = GG(b, c, d, a, M_offset_12, 20, T[31]); + + a = HH(a, b, c, d, M_offset_5, 4, T[32]); + d = HH(d, a, b, c, M_offset_8, 11, T[33]); + c = HH(c, d, a, b, M_offset_11, 16, T[34]); + b = HH(b, c, d, a, M_offset_14, 23, T[35]); + a = HH(a, b, c, d, M_offset_1, 4, T[36]); + d = HH(d, a, b, c, M_offset_4, 11, T[37]); + c = HH(c, d, a, b, M_offset_7, 16, T[38]); + b = HH(b, c, d, a, M_offset_10, 23, T[39]); + a = HH(a, b, c, d, M_offset_13, 4, T[40]); + d = HH(d, a, b, c, M_offset_0, 11, T[41]); + c = HH(c, d, a, b, M_offset_3, 16, T[42]); + b = HH(b, c, d, a, M_offset_6, 23, T[43]); + a = HH(a, b, c, d, M_offset_9, 4, T[44]); + d = HH(d, a, b, c, M_offset_12, 11, T[45]); + c = HH(c, d, a, b, M_offset_15, 16, T[46]); + b = HH(b, c, d, a, M_offset_2, 23, T[47]); + + a = II(a, b, c, d, M_offset_0, 6, T[48]); + d = II(d, a, b, c, M_offset_7, 10, T[49]); + c = II(c, d, a, b, M_offset_14, 15, T[50]); + b = II(b, c, d, a, M_offset_5, 21, T[51]); + a = II(a, b, c, d, M_offset_12, 6, T[52]); + d = II(d, a, b, c, M_offset_3, 10, T[53]); + c = II(c, d, a, b, M_offset_10, 15, T[54]); + b = II(b, c, d, a, M_offset_1, 21, T[55]); + a = II(a, b, c, d, M_offset_8, 6, T[56]); + d = II(d, a, b, c, M_offset_15, 10, T[57]); + c = II(c, d, a, b, M_offset_6, 15, T[58]); + b = II(b, c, d, a, M_offset_13, 21, T[59]); + a = II(a, b, c, d, M_offset_4, 6, T[60]); + d = II(d, a, b, c, M_offset_11, 10, T[61]); + c = II(c, d, a, b, M_offset_2, 15, T[62]); + b = II(b, c, d, a, M_offset_9, 21, T[63]); + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + }, + + _doFinalize: function () { + // Shortcuts + const data = this._data; + const dataWords = data.words; + + const nBitsTotal = this._nDataBytes * 8; + const nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + + const nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); + const nBitsTotalL = nBitsTotal; + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( + (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | + (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) + ); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | + (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) + ); + + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + const hash = this._hash; + const H = hash.words; + + // Swap endian + for (let i = 0; i < 4; i++) { + // Shortcut + const H_i = H[i]; + + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + const clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + }, + }); + + function FF(a, b, c, d, x, s, t) { + const n = a + ((b & c) | (~b & d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function GG(a, b, c, d, x, s, t) { + const n = a + ((b & d) | (c & ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function HH(a, b, c, d, x, s, t) { + const n = a + (b ^ c ^ d) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function II(a, b, c, d, x, s, t) { + const n = a + (c ^ (b | ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.MD5('message'); + * var hash = CryptoJS.MD5(wordArray); + */ + C.MD5 = Hasher._createHelper(MD5); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacMD5(message, key); + */ + C.HmacMD5 = Hasher._createHmacHelper(MD5); +}(Math)); + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +(function () { + // Shortcuts + const C = CryptoJS; + const C_lib = C.lib; + const Base = C_lib.Base; + const WordArray = C_lib.WordArray; + const C_algo = C.algo; + const MD5 = C_algo.MD5; + + /** + * This key derivation function is meant to conform with EVP_BytesToKey. + * www.openssl.org/docs/crypto/EVP_BytesToKey.html + */ + const EvpKDF = C_algo.EvpKDF = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hash algorithm to use. Default: MD5 + * @property {number} iterations The number of iterations to perform. Default: 1 + */ + cfg: Base.extend({ + keySize: 128 / 32, + hasher: MD5, + iterations: 1, + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.EvpKDF.create(); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + // Shortcut + const cfg = this.cfg; + + // Init hasher + const hasher = cfg.hasher.create(); + + // Initial values + const derivedKey = WordArray.create(); + + // Shortcuts + const derivedKeyWords = derivedKey.words; + const keySize = cfg.keySize; + const iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + if (block) { + hasher.update(block); + } + var block = hasher.update(password).finalize(salt); + hasher.reset(); + + // Iterations + for (let i = 1; i < iterations; i++) { + block = hasher.finalize(block); + hasher.reset(); + } + + derivedKey.concat(block); + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + }, + }); + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.EvpKDF(password, salt); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.EvpKDF = function (password, salt, cfg) { + return EvpKDF.create(cfg).compute(password, salt); + }; +}()); + + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/** + * Cipher core components. + */ +CryptoJS.lib.Cipher || (function (undefined) { + // Shortcuts + const C = CryptoJS; + const C_lib = C.lib; + const Base = C_lib.Base; + const WordArray = C_lib.WordArray; + const BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; + const C_enc = C.enc; + const Utf8 = C_enc.Utf8; + const Base64 = C_enc.Base64; + const C_algo = C.algo; + const EvpKDF = C_algo.EvpKDF; + + /** + * Abstract base cipher template. + * + * @property {number} keySize This cipher's key size. Default: 4 (128 bits) + * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) + * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. + * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. + */ + const Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + * + * @property {WordArray} iv The IV to use for this operation. + */ + cfg: Base.extend(), + + /** + * Creates this cipher in encryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); + */ + createEncryptor: function (key, cfg) { + return this.create(this._ENC_XFORM_MODE, key, cfg); + }, + + /** + * Creates this cipher in decryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); + */ + createDecryptor: function (key, cfg) { + return this.create(this._DEC_XFORM_MODE, key, cfg); + }, + + /** + * Initializes a newly created cipher. + * + * @param {number} xformMode Either the encryption or decryption transormation mode constant. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @example + * + * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); + */ + init: function (xformMode, key, cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Store transform mode and key + this._xformMode = xformMode; + this._key = key; + + // Set initial values + this.reset(); + }, + + /** + * Resets this cipher to its initial state. + * + * @example + * + * cipher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-cipher logic + this._doReset(); + }, + + /** + * Adds data to be encrypted or decrypted. + * + * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. + * + * @return {WordArray} The data after processing. + * + * @example + * + * var encrypted = cipher.process('data'); + * var encrypted = cipher.process(wordArray); + */ + process: function (dataUpdate) { + // Append + this._append(dataUpdate); + + // Process available blocks + return this._process(); + }, + + /** + * Finalizes the encryption or decryption process. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. + * + * @return {WordArray} The data after final processing. + * + * @example + * + * var encrypted = cipher.finalize(); + * var encrypted = cipher.finalize('data'); + * var encrypted = cipher.finalize(wordArray); + */ + finalize: function (dataUpdate) { + // Final data update + if (dataUpdate) { + this._append(dataUpdate); + } + + // Perform concrete-cipher logic + const finalProcessedData = this._doFinalize(); + + return finalProcessedData; + }, + + keySize: 128 / 32, + + ivSize: 128 / 32, + + _ENC_XFORM_MODE: 1, + + _DEC_XFORM_MODE: 2, + + /** + * Creates shortcut functions to a cipher's object interface. + * + * @param {Cipher} cipher The cipher to create a helper for. + * + * @return {Object} An object with encrypt and decrypt shortcut functions. + * + * @static + * + * @example + * + * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); + */ + _createHelper: (function () { + function selectCipherStrategy(key) { + if (typeof key == "string") { + return PasswordBasedCipher; + } else { + return SerializableCipher; + } + } + + return function (cipher) { + return { + encrypt: function (message, key, cfg) { + return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); + }, + + decrypt: function (ciphertext, key, cfg) { + return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); + }, + }; + }; + }()), + }); + + /** + * Abstract base stream cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) + */ + const StreamCipher = C_lib.StreamCipher = Cipher.extend({ + _doFinalize: function () { + // Process partial blocks + const finalProcessedBlocks = this._process(!!"flush"); + + return finalProcessedBlocks; + }, + + blockSize: 1, + }); + + /** + * Mode namespace. + */ + const C_mode = C.mode = {}; + + /** + * Abstract base block cipher mode template. + */ + const BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ + /** + * Creates this mode for encryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); + */ + createEncryptor: function (cipher, iv) { + return this.Encryptor.create(cipher, iv); + }, + + /** + * Creates this mode for decryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); + */ + createDecryptor: function (cipher, iv) { + return this.Decryptor.create(cipher, iv); + }, + + /** + * Initializes a newly created mode. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @example + * + * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); + */ + init: function (cipher, iv) { + this._cipher = cipher; + this._iv = iv; + }, + }); + + /** + * Cipher Block Chaining mode. + */ + const CBC = C_mode.CBC = (function () { + /** + * Abstract base CBC mode. + */ + const CBC = BlockCipherMode.extend(); + + /** + * CBC encryptor. + */ + CBC.Encryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + const cipher = this._cipher; + const blockSize = cipher.blockSize; + + // XOR and encrypt + xorBlock.call(this, words, offset, blockSize); + cipher.encryptBlock(words, offset); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + }, + }); + + /** + * CBC decryptor. + */ + CBC.Decryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + const cipher = this._cipher; + const blockSize = cipher.blockSize; + + // Remember this block to use with next block + const thisBlock = words.slice(offset, offset + blockSize); + + // Decrypt and XOR + cipher.decryptBlock(words, offset); + xorBlock.call(this, words, offset, blockSize); + + // This block becomes the previous block + this._prevBlock = thisBlock; + }, + }); + + function xorBlock(words, offset, blockSize) { + // Shortcut + const iv = this._iv; + + // Choose mixing block + if (iv) { + var block = iv; + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + var block = this._prevBlock; + } + + // XOR blocks + for (let i = 0; i < blockSize; i++) { + words[offset + i] ^= block[i]; + } + } + + return CBC; + }()); + + /** + * Padding namespace. + */ + const C_pad = C.pad = {}; + + /** + * PKCS #5/7 padding strategy. + */ + const Pkcs7 = C_pad.Pkcs7 = { + /** + * Pads data using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to pad. + * @param {number} blockSize The multiple that the data should be padded to. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.pad(wordArray, 4); + */ + pad: function (data, blockSize) { + // Shortcut + const blockSizeBytes = blockSize * 4; + + // Count padding bytes + const nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Create padding word + const paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; + + // Create padding + const paddingWords = []; + for (let i = 0; i < nPaddingBytes; i += 4) { + paddingWords.push(paddingWord); + } + const padding = WordArray.create(paddingWords, nPaddingBytes); + + // Add padding + data.concat(padding); + }, + + /** + * Unpads data that had been padded using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to unpad. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.unpad(wordArray); + */ + unpad: function (data) { + // Get number of padding bytes from last byte + const nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + }, + }; + + /** + * Abstract base block cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) + */ + const BlockCipher = C_lib.BlockCipher = Cipher.extend({ + /** + * Configuration options. + * + * @property {Mode} mode The block mode to use. Default: CBC + * @property {Padding} padding The padding strategy to use. Default: Pkcs7 + */ + cfg: Cipher.cfg.extend({ + mode: CBC, + padding: Pkcs7, + }), + + reset: function () { + // Reset cipher + Cipher.reset.call(this); + + // Shortcuts + const cfg = this.cfg; + const iv = cfg.iv; + const mode = cfg.mode; + + // Reset block mode + if (this._xformMode == this._ENC_XFORM_MODE) { + var modeCreator = mode.createEncryptor; + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + var modeCreator = mode.createDecryptor; + + // Keep at least one block in the buffer for unpadding + this._minBufferSize = 1; + } + this._mode = modeCreator.call(mode, this, iv && iv.words); + }, + + _doProcessBlock: function (words, offset) { + this._mode.processBlock(words, offset); + }, + + _doFinalize: function () { + // Shortcut + const padding = this.cfg.padding; + + // Finalize + if (this._xformMode == this._ENC_XFORM_MODE) { + // Pad data + padding.pad(this._data, this.blockSize); + + // Process final blocks + var finalProcessedBlocks = this._process(!!"flush"); + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + // Process final blocks + var finalProcessedBlocks = this._process(!!"flush"); + + // Unpad data + padding.unpad(finalProcessedBlocks); + } + + return finalProcessedBlocks; + }, + + blockSize: 128 / 32, + }); + + /** + * A collection of cipher parameters. + * + * @property {WordArray} ciphertext The raw ciphertext. + * @property {WordArray} key The key to this ciphertext. + * @property {WordArray} iv The IV used in the ciphering operation. + * @property {WordArray} salt The salt used with a key derivation function. + * @property {Cipher} algorithm The cipher algorithm. + * @property {Mode} mode The block mode used in the ciphering operation. + * @property {Padding} padding The padding scheme used in the ciphering operation. + * @property {number} blockSize The block size of the cipher. + * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. + */ + const CipherParams = C_lib.CipherParams = Base.extend({ + /** + * Initializes a newly created cipher params object. + * + * @param {Object} cipherParams An object with any of the possible cipher parameters. + * + * @example + * + * var cipherParams = CryptoJS.lib.CipherParams.create({ + * ciphertext: ciphertextWordArray, + * key: keyWordArray, + * iv: ivWordArray, + * salt: saltWordArray, + * algorithm: CryptoJS.algo.AES, + * mode: CryptoJS.mode.CBC, + * padding: CryptoJS.pad.PKCS7, + * blockSize: 4, + * formatter: CryptoJS.format.OpenSSL + * }); + */ + init: function (cipherParams) { + this.mixIn(cipherParams); + }, + + /** + * Converts this cipher params object to a string. + * + * @param {Format} formatter (Optional) The formatting strategy to use. + * + * @return {string} The stringified cipher params. + * + * @throws Error If neither the formatter nor the default formatter is set. + * + * @example + * + * var string = cipherParams + ''; + * var string = cipherParams.toString(); + * var string = cipherParams.toString(CryptoJS.format.OpenSSL); + */ + toString: function (formatter) { + return (formatter || this.formatter).stringify(this); + }, + }); + + /** + * Format namespace. + */ + const C_format = C.format = {}; + + /** + * OpenSSL formatting strategy. + */ + const OpenSSLFormatter = C_format.OpenSSL = { + /** + * Converts a cipher params object to an OpenSSL-compatible string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The OpenSSL-compatible string. + * + * @static + * + * @example + * + * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); + */ + stringify: function (cipherParams) { + // Shortcuts + const ciphertext = cipherParams.ciphertext; + const salt = cipherParams.salt; + + // Format + if (salt) { + var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); + } else { + var wordArray = ciphertext; + } + + return wordArray.toString(Base64); + }, + + /** + * Converts an OpenSSL-compatible string to a cipher params object. + * + * @param {string} openSSLStr The OpenSSL-compatible string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); + */ + parse: function (openSSLStr) { + // Parse base64 + const ciphertext = Base64.parse(openSSLStr); + + // Shortcut + const ciphertextWords = ciphertext.words; + + // Test for salt + if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { + // Extract salt + var salt = WordArray.create(ciphertextWords.slice(2, 4)); + + // Remove salt from ciphertext + ciphertextWords.splice(0, 4); + ciphertext.sigBytes -= 16; + } + + return CipherParams.create({ ciphertext: ciphertext, salt: salt }); + }, + }; + + /** + * A cipher wrapper that returns ciphertext as a serializable cipher params object. + */ + var SerializableCipher = C_lib.SerializableCipher = Base.extend({ + /** + * Configuration options. + * + * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL + */ + cfg: Base.extend({ + format: OpenSSLFormatter, + }), + + /** + * Encrypts a message. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Encrypt + const encryptor = cipher.createEncryptor(key, cfg); + const ciphertext = encryptor.finalize(message); + + // Shortcut + const cipherCfg = encryptor.cfg; + + // Create and return serializable cipher params + return CipherParams.create({ + ciphertext: ciphertext, + key: key, + iv: cipherCfg.iv, + algorithm: cipher, + mode: cipherCfg.mode, + padding: cipherCfg.padding, + blockSize: cipher.blockSize, + formatter: cfg.format, + }); + }, + + /** + * Decrypts serialized ciphertext. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Decrypt + const plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); + + return plaintext; + }, + + /** + * Converts serialized ciphertext to CipherParams, + * else assumed CipherParams already and returns ciphertext unchanged. + * + * @param {CipherParams|string} ciphertext The ciphertext. + * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. + * + * @return {CipherParams} The unserialized ciphertext. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); + */ + _parse: function (ciphertext, format) { + if (typeof ciphertext == "string") { + return format.parse(ciphertext, this); + } else { + return ciphertext; + } + }, + }); + + /** + * Key derivation function namespace. + */ + const C_kdf = C.kdf = {}; + + /** + * OpenSSL key derivation function. + */ + const OpenSSLKdf = C_kdf.OpenSSL = { + /** + * Derives a key and IV from a password. + * + * @param {string} password The password to derive from. + * @param {number} keySize The size in words of the key to generate. + * @param {number} ivSize The size in words of the IV to generate. + * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. + * + * @return {CipherParams} A cipher params object with the key, IV, and salt. + * + * @static + * + * @example + * + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); + */ + execute: function (password, keySize, ivSize, salt) { + // Generate random salt + if (!salt) { + salt = WordArray.random(64 / 8); + } + + // Derive key and IV + const key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); + + // Separate key and IV + const iv = WordArray.create(key.words.slice(keySize), ivSize * 4); + key.sigBytes = keySize * 4; + + // Return params + return CipherParams.create({ key: key, iv: iv, salt: salt }); + }, + }; + + /** + * A serializable cipher wrapper that derives the key from a password, + * and returns ciphertext as a serializable cipher params object. + */ + var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ + /** + * Configuration options. + * + * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL + */ + cfg: SerializableCipher.cfg.extend({ + kdf: OpenSSLKdf, + }), + + /** + * Encrypts a message using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Derive key and other params + const derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Encrypt + const ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); + + // Mix in derived params + ciphertext.mixIn(derivedParams); + + return ciphertext; + }, + + /** + * Decrypts serialized ciphertext using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Derive key and other params + const derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Decrypt + const plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); + + return plaintext; + }, + }); +}()); + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/** + * Electronic Codebook block mode. + */ +CryptoJS.mode.ECB = (function () { + const ECB = CryptoJS.lib.BlockCipherMode.extend(); + + ECB.Encryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.encryptBlock(words, offset); + }, + }); + + ECB.Decryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.decryptBlock(words, offset); + }, + }); + + return ECB; +}()); + + +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +(function () { + // Shortcuts + const C = CryptoJS; + const C_lib = C.lib; + const BlockCipher = C_lib.BlockCipher; + const C_algo = C.algo; + + // Lookup tables + const SBOX = []; + const INV_SBOX = []; + const SUB_MIX_0 = []; + const SUB_MIX_1 = []; + const SUB_MIX_2 = []; + const SUB_MIX_3 = []; + const INV_SUB_MIX_0 = []; + const INV_SUB_MIX_1 = []; + const INV_SUB_MIX_2 = []; + const INV_SUB_MIX_3 = []; + + // Compute lookup tables + (function () { + // Compute double table + const d = []; + for (var i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } else { + d[i] = (i << 1) ^ 0x11b; + } + } + + // Walk GF(2^8) + let x = 0; + let xi = 0; + for (var i = 0; i < 256; i++) { + // Compute sbox + let sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; + SBOX[x] = sx; + INV_SBOX[sx] = x; + + // Compute multiplication + const x2 = d[x]; + const x4 = d[x2]; + const x8 = d[x4]; + + // Compute sub bytes, mix columns tables + var t = (d[sx] * 0x101) ^ (sx * 0x1010100); + SUB_MIX_0[x] = (t << 24) | (t >>> 8); + SUB_MIX_1[x] = (t << 16) | (t >>> 16); + SUB_MIX_2[x] = (t << 8) | (t >>> 24); + SUB_MIX_3[x] = t; + + // Compute inv sub bytes, inv mix columns tables + var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); + INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); + INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); + INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); + INV_SUB_MIX_3[sx] = t; + + // Compute next counter + if (!x) { + x = xi = 1; + } else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + }()); + + // Precomputed Rcon lookup + const RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + /** + * AES block cipher algorithm. + */ + const AES = C_algo.AES = BlockCipher.extend({ + _doReset: function () { + // Shortcuts + const key = this._key; + const keyWords = key.words; + const keySize = key.sigBytes / 4; + + // Compute number of rounds + const nRounds = this._nRounds = keySize + 6; + + // Compute number of key schedule rows + const ksRows = (nRounds + 1) * 4; + + // Compute key schedule + const keySchedule = this._keySchedule = []; + for (var ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + keySchedule[ksRow] = keyWords[ksRow]; + } else { + var t = keySchedule[ksRow - 1]; + + if (!(ksRow % keySize)) { + // Rot word + t = (t << 8) | (t >>> 24); + + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + + // Mix Rcon + t ^= RCON[(ksRow / keySize) | 0] << 24; + } else if (keySize > 6 && ksRow % keySize == 4) { + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + } + + keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; + } + } + + // Compute inv key schedule + const invKeySchedule = this._invKeySchedule = []; + for (let invKsRow = 0; invKsRow < ksRows; invKsRow++) { + var ksRow = ksRows - invKsRow; + + if (invKsRow % 4) { + var t = keySchedule[ksRow]; + } else { + var t = keySchedule[ksRow - 4]; + } + + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } else { + invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ + INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; + } + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); + }, + + decryptBlock: function (M, offset) { + // Swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + + this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); + + // Inv swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + }, + + _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { + // Shortcut + const nRounds = this._nRounds; + + // Get input, add round key + let s0 = M[offset] ^ keySchedule[0]; + let s1 = M[offset + 1] ^ keySchedule[1]; + let s2 = M[offset + 2] ^ keySchedule[2]; + let s3 = M[offset + 3] ^ keySchedule[3]; + + // Key schedule row counter + let ksRow = 4; + + // Rounds + for (let round = 1; round < nRounds; round++) { + // Shift rows, sub bytes, mix columns, add round key + var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; + var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; + var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; + var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; + + // Update state + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + // Shift rows, sub bytes, add round key + var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; + var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; + var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; + var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; + + // Set output + M[offset] = t0; + M[offset + 1] = t1; + M[offset + 2] = t2; + M[offset + 3] = t3; + }, + + keySize: 256 / 32, + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); + */ + C.AES = BlockCipher._createHelper(AES); +}()); + + +/** + * aes加密方法 + * aes-128-ecb + * + * @example + * + * var ciphertext = BI.aesEncrypt(text, key); + */ +export function aesEncrypt(text, key) { + key = CryptoJS.enc.Utf8.parse(key); + const cipher = CryptoJS.AES.encrypt(text, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + + return cipher.ciphertext.toString(CryptoJS.enc.Base64); +} + +/** + * aes解密方法 + * @param {String} text + * @param {String} key + */ +export function aesDecrypt(text, key) { + key = CryptoJS.enc.Utf8.parse(key); + const decipher = CryptoJS.AES.decrypt(text, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + + return CryptoJS.enc.Utf8.stringify(decipher); +} + diff --git a/packages/fineui/src/core/structure/aspect.js b/packages/fineui/src/core/structure/aspect.js new file mode 100644 index 000000000..ad47d42ae --- /dev/null +++ b/packages/fineui/src/core/structure/aspect.js @@ -0,0 +1,58 @@ +function _aspect(type) { + return function (target, methodName, advice) { + let exist = target[methodName], + dispatcher; + + if (!exist || exist.target != target) { + dispatcher = target[methodName] = function () { + // before methods + let beforeArr = dispatcher.before; + let args = arguments, next; + for (let l = beforeArr.length; l--;) { + next = beforeArr[l].advice.apply(this, args); + if (next === false) { + return false; + } + args = next || args; + } + // target method + let rs = dispatcher.method.apply(this, args); + // after methods + let afterArr = dispatcher.after; + for (let i = 0, ii = afterArr.length; i < ii; i++) { + next = afterArr[i].advice.call(this, rs, args); + if (rs === false) { + return false; + } + args = next || args; + } + return rs; + }; + + dispatcher.before = []; + dispatcher.after = []; + + if (exist) { + dispatcher.method = exist; + } + dispatcher.target = target; + } + + let aspectArr = (dispatcher || exist)[type]; + let obj = { + advice: advice, + _index: aspectArr.length, + remove: function () { + aspectArr.splice(this._index, 1); + }, + }; + aspectArr.push(obj); + + return obj; + }; +} + +export const aspect = { + before: _aspect("before"), + after: _aspect("after"), +}; diff --git a/packages/fineui/src/core/structure/base64.js b/packages/fineui/src/core/structure/base64.js new file mode 100644 index 000000000..9d3f0f217 --- /dev/null +++ b/packages/fineui/src/core/structure/base64.js @@ -0,0 +1,132 @@ +const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + +// private method for UTF-8 encoding +const _utf8_encode = function (string) { + string = string.replace(/\r\n/g, "\n"); + let utftext = ""; + + for (let n = 0; n < string.length; n++) { + + const c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; +}; + +// private method for UTF-8 decoding +const _utf8_decode = function (utftext) { + let string = ""; + let i = 0; + let c = 0, c3 = 0, c2 = 0; + + while (i < utftext.length) { + + c = utftext.charCodeAt(i); + + if (c < 128) { + string += String.fromCharCode(c); + i++; + } else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + + } + return string; +}; + +/** + * base64 encode + * @param input + * @returns {string} + */ +export function encode(input) { + let output = ""; + let chr1, chr2, chr3, enc1, enc2, enc3, enc4; + let i = 0; + + input = _utf8_encode(input); + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + + } + + return output; +} + +/** + * base64 decode + * @param input + * @returns {string} + */ +export function decode(input) { + let output = ""; + let chr1, chr2, chr3; + let enc1, enc2, enc3, enc4; + let i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + output = _utf8_decode(output); + + return output; + +} diff --git a/packages/fineui/src/core/structure/cache.js b/packages/fineui/src/core/structure/cache.js new file mode 100644 index 000000000..e0ebe4607 --- /dev/null +++ b/packages/fineui/src/core/structure/cache.js @@ -0,0 +1,92 @@ +export const Cache = { + _prefix: "bi", + setUsername: function (username) { + localStorage.setItem(Cache._prefix + ".username", (username + "" || "").toUpperCase()); + }, + getUsername: function () { + return localStorage.getItem(Cache._prefix + ".username") || ""; + }, + _getKeyPrefix: function () { + return Cache.getUsername() + "." + Cache._prefix + "."; + }, + _generateKey: function (key) { + return Cache._getKeyPrefix() + (key || ""); + }, + getItem: function (key, opt = {}) { + const { defaultValue, typeConversion } = opt; + const storageKey = Cache._generateKey(key); + let value = localStorage.getItem(storageKey); + + if (value !== null && typeConversion) { + if (value === "true") { + value = true; + } else if (value === "false") { + value = false; + } else if (Number.isNaN(Number(value))) { + value = Number(value); + } + } + + return value !== null ? value : defaultValue; + }, + setItem: function (key, value) { + localStorage.setItem(Cache._generateKey(key), value); + }, + removeItem: function (key) { + localStorage.removeItem(Cache._generateKey(key)); + }, + clear: function () { + for (let i = localStorage.length; i >= 0; i--) { + const key = localStorage.key(i); + if (key) { + if (key.indexOf(Cache._getKeyPrefix()) === 0) { + localStorage.removeItem(key); + } + } + } + }, + keys: function () { + const result = []; + for (let i = localStorage.length; i >= 0; i--) { + const key = localStorage.key(i); + if (key) { + const prefix = Cache._getKeyPrefix(); + if (key.indexOf(prefix) === 0) { + result[result.length] = key.substring(prefix.length); + } + } + } + return result; + }, + + addCookie: function (name, value, path, expiresHours) { + let cookieString = name + "=" + encodeURI(value); + // 判断是否设置过期时间 + if (expiresHours && expiresHours > 0) { + const date = new Date(); + // expires是标准GMT格式时间,应该使用时间戳作为起始时间 + date.setTime(date.getTime() + expiresHours * 3600 * 1000); + cookieString = cookieString + "; expires=" + date.toUTCString(); + } + if (path) { + cookieString = cookieString + "; path=" + path; + } + document.cookie = cookieString; + }, + getCookie: function (name) { + let arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); + if (arr = document.cookie.match(reg)) { + return decodeURI(arr[2]); + } + return null; + }, + deleteCookie: function (name, path) { + const date = new Date(); + date.setTime(date.getTime() - 10000); + let cookieString = name + "=v; expires=" + date.toUTCString(); + if (path) { + cookieString = cookieString + "; path=" + path; + } + document.cookie = cookieString; + }, +}; diff --git a/packages/fineui/src/core/structure/cellSizeAndPositionManager.js b/packages/fineui/src/core/structure/cellSizeAndPositionManager.js new file mode 100644 index 000000000..0adc4e22c --- /dev/null +++ b/packages/fineui/src/core/structure/cellSizeAndPositionManager.js @@ -0,0 +1,269 @@ +export class CellSizeAndPositionManager { + + constructor(cellCount, cellSizeGetter, estimatedCellSize) { + this._cellSizeGetter = cellSizeGetter; + this._cellCount = cellCount; + this._estimatedCellSize = estimatedCellSize; + this._cellSizeAndPositionData = {}; + this._lastMeasuredIndex = -1; + } + + configure(cellCount, estimatedCellSize) { + this._cellCount = cellCount; + this._estimatedCellSize = estimatedCellSize; + } + + getCellCount() { + return this._cellCount; + } + + getEstimatedCellSize() { + return this._estimatedCellSize; + } + + getLastMeasuredIndex() { + return this._lastMeasuredIndex; + } + + getSizeAndPositionOfCell(index) { + if (index < 0 || index >= this._cellCount) { + return; + } + if (index > this._lastMeasuredIndex) { + const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); + let offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; + + for (let i = this._lastMeasuredIndex + 1; i <= index; i++) { + const size = this._cellSizeGetter(i); + + if (size == null || isNaN(size)) { + continue; + } + + this._cellSizeAndPositionData[i] = { + offset: offset, + size: size, + }; + + offset += size; + } + + this._lastMeasuredIndex = index; + } + return this._cellSizeAndPositionData[index]; + } + + getSizeAndPositionOfLastMeasuredCell() { + return this._lastMeasuredIndex >= 0 + ? this._cellSizeAndPositionData[this._lastMeasuredIndex] + : { + offset: 0, + size: 0, + }; + } + + getTotalSize() { + const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); + return lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size + (this._cellCount - this._lastMeasuredIndex - 1) * this._estimatedCellSize; + } + + getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex) { + const datum = this.getSizeAndPositionOfCell(targetIndex); + const maxOffset = datum.offset; + const minOffset = maxOffset - containerSize + datum.size; + + let idealOffset; + + switch (align) { + case "start": + idealOffset = maxOffset; + break; + case "end": + idealOffset = minOffset; + break; + case "center": + idealOffset = maxOffset - ((containerSize - datum.size) / 2); + break; + default: + idealOffset = Math.max(minOffset, Math.min(maxOffset, currentOffset)); + break; + } + + const totalSize = this.getTotalSize(); + + return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); + } + + getVisibleCellRange(containerSize, offset) { + const totalSize = this.getTotalSize(); + + if (totalSize === 0) { + return {}; + } + + const maxOffset = offset + containerSize; + const start = this._findNearestCell(offset); + + const datum = this.getSizeAndPositionOfCell(start); + offset = datum.offset + datum.size; + + let stop = start; + + while (offset < maxOffset && stop < this._cellCount - 1) { + stop++; + offset += this.getSizeAndPositionOfCell(stop).size; + } + + return { + start: start, + stop: stop, + }; + } + + resetCell(index) { + this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); + } + + _binarySearch(high, low, offset) { + let middle; + let currentOffset; + + while (low <= high) { + middle = low + Math.floor((high - low) / 2); + currentOffset = this.getSizeAndPositionOfCell(middle).offset; + + if (currentOffset === offset) { + return middle; + } else if (currentOffset < offset) { + low = middle + 1; + } else if (currentOffset > offset) { + high = middle - 1; + } + } + + if (low > 0) { + return low - 1; + } + } + + _exponentialSearch(index, offset) { + let interval = 1; + + while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) { + index += interval; + interval *= 2; + } + + return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); + } + + _findNearestCell(offset) { + if (isNaN(offset)) { + return; + } + + offset = Math.max(0, offset); + + const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); + const lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); + + if (lastMeasuredCellSizeAndPosition.offset >= offset) { + return this._binarySearch(lastMeasuredIndex, 0, offset); + } + return this._exponentialSearch(lastMeasuredIndex, offset); + + } +} + +export class ScalingCellSizeAndPositionManager { + constructor(cellCount, cellSizeGetter, estimatedCellSize, maxScrollSize) { + this._cellSizeAndPositionManager = new CellSizeAndPositionManager(cellCount, cellSizeGetter, estimatedCellSize); + this._maxScrollSize = maxScrollSize || 10000000; + } + + configure() { + this._cellSizeAndPositionManager.configure.apply(this._cellSizeAndPositionManager, arguments); + } + + getCellCount() { + return this._cellSizeAndPositionManager.getCellCount(); + } + + getEstimatedCellSize() { + return this._cellSizeAndPositionManager.getEstimatedCellSize(); + } + + getLastMeasuredIndex() { + return this._cellSizeAndPositionManager.getLastMeasuredIndex(); + } + + getOffsetAdjustment(containerSize, offset) { + const totalSize = this._cellSizeAndPositionManager.getTotalSize(); + const safeTotalSize = this.getTotalSize(); + const offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); + + return Math.round(offsetPercentage * (safeTotalSize - totalSize)); + } + + getSizeAndPositionOfCell(index) { + return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); + } + + getSizeAndPositionOfLastMeasuredCell() { + return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); + } + + getTotalSize() { + return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); + } + + getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex) { + currentOffset = this._safeOffsetToOffset(containerSize, currentOffset); + + const offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex); + + return this._offsetToSafeOffset(containerSize, offset); + } + + getVisibleCellRange(containerSize, offset) { + offset = this._safeOffsetToOffset(containerSize, offset); + + return this._cellSizeAndPositionManager.getVisibleCellRange(containerSize, offset); + } + + resetCell(index) { + this._cellSizeAndPositionManager.resetCell(index); + } + + _getOffsetPercentage(containerSize, offset, totalSize) { + return totalSize <= containerSize + ? 0 + : offset / (totalSize - containerSize); + } + + _offsetToSafeOffset(containerSize, offset) { + const totalSize = this._cellSizeAndPositionManager.getTotalSize(); + const safeTotalSize = this.getTotalSize(); + + if (totalSize === safeTotalSize) { + return offset; + } + const offsetPercentage = this._getOffsetPercentage(containerSize, offset, totalSize); + + return Math.round(offsetPercentage * (safeTotalSize - containerSize)); + + } + + _safeOffsetToOffset(containerSize, offset) { + const totalSize = this._cellSizeAndPositionManager.getTotalSize(); + const safeTotalSize = this.getTotalSize(); + + if (totalSize === safeTotalSize) { + return offset; + } + const offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); + + return Math.round(offsetPercentage * (totalSize - containerSize)); + + } +} diff --git a/packages/fineui/src/core/structure/heap.js b/packages/fineui/src/core/structure/heap.js new file mode 100644 index 000000000..ae0aed9c1 --- /dev/null +++ b/packages/fineui/src/core/structure/heap.js @@ -0,0 +1,111 @@ +function defaultComparator(a, b) { + return a < b; +} + +export class Heap { + constructor(items, comparator) { + this._items = items || []; + this._size = this._items.length; + this._comparator = comparator || defaultComparator; + this._heapify(); + } + + empty() { + return this._size === 0; + } + + pop() { + if (this._size === 0) { + return; + } + + const elt = this._items[0]; + + const lastElt = this._items.pop(); + this._size--; + + if (this._size > 0) { + this._items[0] = lastElt; + this._sinkDown(0); + } + + return elt; + } + + push(item) { + this._items[this._size++] = item; + this._bubbleUp(this._size - 1); + } + + size() { + return this._size; + } + + peek() { + if (this._size === 0) { + return; + } + + return this._items[0]; + } + + _heapify() { + for (let index = Math.floor((this._size + 1) / 2); index >= 0; index--) { + this._sinkDown(index); + } + } + + _bubbleUp(index) { + const elt = this._items[index]; + while (index > 0) { + const parentIndex = Math.floor((index + 1) / 2) - 1; + const parentElt = this._items[parentIndex]; + + // if parentElt < elt, stop + if (this._comparator(parentElt, elt)) { + return; + } + + // swap + this._items[parentIndex] = elt; + this._items[index] = parentElt; + index = parentIndex; + } + } + + _sinkDown(index) { + const elt = this._items[index]; + + while (true) { + const leftChildIndex = 2 * (index + 1) - 1; + const rightChildIndex = 2 * (index + 1); + let swapIndex = -1; + + if (leftChildIndex < this._size) { + const leftChild = this._items[leftChildIndex]; + if (this._comparator(leftChild, elt)) { + swapIndex = leftChildIndex; + } + } + + if (rightChildIndex < this._size) { + const rightChild = this._items[rightChildIndex]; + if (this._comparator(rightChild, elt)) { + if (swapIndex === -1 || + this._comparator(rightChild, this._items[swapIndex])) { + swapIndex = rightChildIndex; + } + } + } + + // if we don't have a swap, stop + if (swapIndex === -1) { + return; + } + + this._items[index] = this._items[swapIndex]; + this._items[swapIndex] = elt; + index = swapIndex; + } + } +} diff --git a/packages/fineui/src/core/structure/index.js b/packages/fineui/src/core/structure/index.js new file mode 100644 index 000000000..263e41942 --- /dev/null +++ b/packages/fineui/src/core/structure/index.js @@ -0,0 +1,13 @@ +export * from "./aes"; +export * from "./aspect"; +export * from "./base64"; +export * from "./cache"; +export * from "./cellSizeAndPositionManager"; +export * from "./heap"; +export * from "./linkedHashMap"; +export * from "./lru"; +export * from "./prefixIntervalTree"; +export * from "./queue"; +export * from "./sectionManager"; +export * from "./tree"; +export * from "./vector"; diff --git a/packages/fineui/src/core/structure/linkedHashMap.js b/packages/fineui/src/core/structure/linkedHashMap.js new file mode 100644 index 000000000..d4a54eafd --- /dev/null +++ b/packages/fineui/src/core/structure/linkedHashMap.js @@ -0,0 +1,66 @@ +export class LinkHashMap { + constructor() { + this.array = []; + this.map = {}; + } + + has(key) { + return key in this.map; + } + + add(key, value) { + if (typeof key === "undefined") { + return; + } + if (key in this.map) { + this.map[key] = value; + } else { + this.array.push(key); + this.map[key] = value; + } + } + + remove(key) { + if (key in this.map) { + delete this.map[key]; + for (let i = 0; i < this.array.length; i++) { + if (this.array[i] == key) { + this.array.splice(i, 1); + break; + } + } + } + } + + size() { + return this.array.length; + } + + each(fn, scope) { + scope = scope || window; + fn = fn || null; + if (fn == null || typeof (fn) !== "function") { + return; + } + for (let i = 0; i < this.array.length; i++) { + const key = this.array[i]; + const value = this.map[key]; + const re = fn.call(scope, key, value, i, this.array, this.map); + if (re == false) { + break; + } + } + } + + get(key) { + return this.map[key]; + } + + toArray() { + const array = []; + this.each(function (key, value) { + array.push(value); + }); + return array; + } +} diff --git a/packages/fineui/src/core/structure/lru.js b/packages/fineui/src/core/structure/lru.js new file mode 100644 index 000000000..1d1ce30f6 --- /dev/null +++ b/packages/fineui/src/core/structure/lru.js @@ -0,0 +1,82 @@ +export class LRU { + constructor(limit) { + this.size = 0; + this.limit = limit; + this.head = this.tail = undefined; + this._keymap = {}; + } + + put(key, value) { + let removed; + if (this.size === this.limit) { + removed = this.shift(); + } + + let entry = this.get(key, true); + if (!entry) { + entry = { + key: key, + }; + this._keymap[key] = entry; + if (this.tail) { + this.tail.newer = entry; + entry.older = this.tail; + } else { + this.head = entry; + } + this.tail = entry; + this.size++; + } + entry.value = value; + + return removed; + } + + shift() { + const entry = this.head; + if (entry) { + this.head = this.head.newer; + this.head.older = undefined; + entry.newer = entry.older = undefined; + this._keymap[entry.key] = undefined; + this.size--; + } + return entry; + } + + get(key, returnEntry) { + const entry = this._keymap[key]; + if (entry === undefined) return; + if (entry === this.tail) { + return returnEntry + ? entry + : entry.value; + } + // HEAD--------------TAIL + // <.older .newer> + // <--- add direction -- + // A B C E + if (entry.newer) { + if (entry === this.head) { + this.head = entry.newer; + } + entry.newer.older = entry.older; // C <-- E. + } + if (entry.older) { + entry.older.newer = entry.newer; // C. --> E + } + entry.newer = undefined; // D --x + entry.older = this.tail; // D. --> E + if (this.tail) { + this.tail.newer = entry; // E. <-- D + } + this.tail = entry; + return returnEntry + ? entry + : entry.value; + } + + has(key) { + return this._keymap[key] != null; + } +} diff --git a/packages/fineui/src/core/structure/prefixIntervalTree.js b/packages/fineui/src/core/structure/prefixIntervalTree.js new file mode 100644 index 000000000..f4e58cbc4 --- /dev/null +++ b/packages/fineui/src/core/structure/prefixIntervalTree.js @@ -0,0 +1,179 @@ +import { _global } from "../0.foundation"; + +// 线段树 +const parent = function (node) { + return Math.floor(node / 2); +}; + +const Int32Array = _global.Int32Array || function (size) { + const xs = []; + for (let i = size - 1; i >= 0; --i) { + xs[i] = 0; + } + return xs; +}; + +const ceilLog2 = function (x) { + let y = 1; + while (y < x) { + y *= 2; + } + return y; +}; + +export class PrefixIntervalTree { + constructor(xs) { + this._size = xs.length; + this._half = ceilLog2(this._size); + // _heap是一个_size两倍以上的堆 + this._heap = new Int32Array(2 * this._half); + + let i; + // 初始化 >= _size 的堆空间, 即叶子节点 + for (i = 0; i < this._size; ++i) { + this._heap[this._half + i] = xs[i]; + } + // 初始化 < _size 的堆空间, 即非叶子节点,根节点包含整个区间 + for (i = this._half - 1; i > 0; --i) { + this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1]; + } + } + + static uniform(size, initialValue) { + const xs = []; + for (let i = size - 1; i >= 0; --i) { + xs[i] = initialValue; + } + + return new PrefixIntervalTree(xs); + } + + static empty(size) { + return PrefixIntervalTree.uniform(size, 0); + } + + set(index, value) { + let node = this._half + index; + this._heap[node] = value; + + node = parent(node); + for (; node !== 0; node = parent(node)) { + this._heap[node] = + this._heap[2 * node] + this._heap[2 * node + 1]; + } + } + + get(index) { + const node = this._half + index; + return this._heap[node]; + } + + getSize() { + return this._size; + } + + /** + * get(0) + get(1) + ... + get(end - 1). + */ + sumUntil(end) { + if (end === 0) { + return 0; + } + + let node = this._half + end - 1; + let sum = this._heap[node]; + for (; node !== 1; node = parent(node)) { + if (node % 2 === 1) { + sum += this._heap[node - 1]; + } + } + + return sum; + } + + /** + * get(0) + get(1) + ... + get(inclusiveEnd). + */ + sumTo(inclusiveEnd) { + return this.sumUntil(inclusiveEnd + 1); + } + + /** + * sum get(begin) + get(begin + 1) + ... + get(end - 1). + */ + sum(begin, end) { + return this.sumUntil(end) - this.sumUntil(begin); + } + + /** + * Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or + * -1 if no such i exists. + */ + greatestLowerBound(t) { + if (t < 0) { + return -1; + } + + let node = 1; + if (this._heap[node] <= t) { + return this._size; + } + + while (node < this._half) { + const leftSum = this._heap[2 * node]; + if (t < leftSum) { + node = 2 * node; + } else { + node = 2 * node + 1; + t -= leftSum; + } + } + + return node - this._half; + } + + /** + * Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or + * -1 if no such i exists. + */ + greatestStrictLowerBound(t) { + if (t <= 0) { + return -1; + } + + let node = 1; + if (this._heap[node] < t) { + return this._size; + } + + while (node < this._half) { + const leftSum = this._heap[2 * node]; + if (t <= leftSum) { + node = 2 * node; + } else { + node = 2 * node + 1; + t -= leftSum; + } + } + + return node - this._half; + } + + /** + * Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or + * size + 1 if no such i exists. + */ + leastUpperBound(t) { + return this.greatestStrictLowerBound(t) + 1; + } + + /** + * Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or + * size + 1 if no such i exists. + */ + leastStrictUpperBound(t) { + return this.greatestLowerBound(t) + 1; + } + + +} diff --git a/packages/fineui/src/core/structure/queue.js b/packages/fineui/src/core/structure/queue.js new file mode 100644 index 000000000..ed1d55f69 --- /dev/null +++ b/packages/fineui/src/core/structure/queue.js @@ -0,0 +1,86 @@ +import { contains, remove } from "../2.base"; + +export class Queue { + constructor(capacity) { + this.capacity = capacity; + this.array = []; + } + + contains(v) { + return contains(this.array, v); + } + + indexOf(v) { + return contains(this.array, v); + } + + getElementByIndex(index) { + return this.array[index]; + } + + push(v) { + this.array.push(v); + if (this.capacity && this.array.length > this.capacity) { + this.array.shift(); + } + } + + pop() { + this.array.pop(); + } + + shift() { + this.array.shift(); + } + + unshift(v) { + this.array.unshift(v); + if (this.capacity && this.array.length > this.capacity) { + this.array.pop(); + } + } + + remove(v) { + remove(this.array, v); + } + + splice() { + this.array.splice.apply(this.array, arguments); + } + + slice() { + this.array.slice.apply(this.array, arguments); + } + + size() { + return this.array.length; + } + + each(fn, scope) { + scope = scope || window; + fn = fn || null; + if (fn == null || typeof (fn) !== "function") { + return; + } + for (let i = 0; i < this.array.length; i++) { + const re = fn.call(scope, i, this.array[i], this.array); + if (re === false) { + break; + } + } + } + + toArray() { + return this.array; + } + + fromArray(array) { + array.forEach(v => this.push(v)); + } + + clear() { + this.array.length = 0; + } +} + + diff --git a/packages/fineui/src/core/structure/sectionManager.js b/packages/fineui/src/core/structure/sectionManager.js new file mode 100644 index 000000000..8eb348253 --- /dev/null +++ b/packages/fineui/src/core/structure/sectionManager.js @@ -0,0 +1,87 @@ +import {each, keys, map, size} from "../2.base"; + +class Section { + constructor(height, width, x, y) { + this.height = height; + this.width = width; + this.x = x; + this.y = y; + + this._indexMap = {}; + this._indices = []; + } + + addCellIndex(index) { + if (!this._indexMap[index]) { + this._indexMap[index] = true; + this._indices.push(index); + } + } + + getCellIndices() { + return this._indices; + } +} + +const SECTION_SIZE = 100; + +export class SectionManager { + constructor(sectionSize = SECTION_SIZE) { + this._sectionSize = sectionSize; + this._cellMetadata = []; + this._sections = {}; + } + + getCellIndices(height, width, x, y) { + const indices = {}; + + each(this.getSections(height, width, x, y), function (i, section) { + each(section.getCellIndices(), function (j, index) { + indices[index] = index; + }); + }); + + return map(keys(indices), function (i, index) { + return indices[index]; + }); + } + + getCellMetadata(index) { + return this._cellMetadata[index]; + } + + getSections(height, width, x, y) { + const sectionXStart = Math.floor(x / this._sectionSize); + const sectionXStop = Math.floor((x + width - 1) / this._sectionSize); + const sectionYStart = Math.floor(y / this._sectionSize); + const sectionYStop = Math.floor((y + height - 1) / this._sectionSize); + + const sections = []; + + for (let sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) { + for (let sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) { + const key = sectionX + "." + sectionY; + + if (!this._sections[key]) { + this._sections[key] = new Section(this._sectionSize, this._sectionSize, sectionX * this._sectionSize, sectionY * this._sectionSize); + } + + sections.push(this._sections[key]); + } + } + + return sections; + } + + getTotalSectionCount() { + return size(this._sections); + } + + registerCell(cellMetadatum, index) { + this._cellMetadata[index] = cellMetadatum; + + each(this.getSections(cellMetadatum.height, cellMetadatum.width, cellMetadatum.x, cellMetadatum.y), function (i, section) { + section.addCellIndex(index); + }); + } +} diff --git a/packages/fineui/src/core/structure/tree.js b/packages/fineui/src/core/structure/tree.js new file mode 100644 index 000000000..ec8db84c9 --- /dev/null +++ b/packages/fineui/src/core/structure/tree.js @@ -0,0 +1,521 @@ +import { + isObject, + UUID, + extend, + isEmpty, + isArray, + first, + last, + findIndex, + isUndefined, + isNull, + each, + deepClone, + isEqual, some, every, clone +} from "../2.base"; + +export class Node { + constructor(id) { + if (isObject(id)) { + extend(this, id); + } else { + this.id = id; + } + this.clear(); + } + + set(key, value) { + if (isObject(key)) { + extend(this, key); + return; + } + this[key] = value; + } + + get(key) { + return this[key]; + } + + isLeaf() { + return isEmpty(this.children); + } + + getChildren() { + return this.children; + } + + getChildrenLength() { + return this.children.length; + } + + getFirstChild() { + return first(this.children); + } + + getLastChild() { + return last(this.children); + } + + setLeft(left) { + this.left = left; + } + + getLeft() { + return this.left; + } + + setRight(right) { + this.right = right; + } + + getRight() { + return this.right; + } + + setParent(parent) { + this.parent = parent; + } + + getParent() { + return this.parent; + } + + getChild(index) { + return this.children[index]; + } + + getChildIndex(id) { + return findIndex(this.children, function (i, ch) { + return ch.get("id") === id; + }); + } + + removeChild(id) { + this.removeChildByIndex(this.getChildIndex(id)); + } + + removeChildByIndex(index) { + const before = this.getChild(index - 1); + const behind = this.getChild(index + 1); + if (before != null) { + before.setRight(behind || null); + } + if (behind != null) { + behind.setLeft(before || null); + } + this.children.splice(index, 1); + } + + removeAllChilds() { + this.children = []; + } + + addChild(child, index) { + let cur = null; + if (isUndefined(index)) { + cur = this.children.length - 1; + } else { + cur = index - 1; + } + child.setParent(this); + if (cur >= 0) { + this.getChild(cur) && this.getChild(cur).setRight(child); + child.setLeft(this.getChild(cur)); + } + if (isUndefined(index)) { + this.children.push(child); + } else { + this.children.splice(index, 0, child); + } + } + + equals(obj) { + return this === obj || this.id === obj.id; + } + + clear() { + this.parent = null; + this.left = null; + this.right = null; + this.children = []; + } +} + +export class Tree { + constructor() { + this.root = new Node(UUID()); + } + + addNode(node, newNode, index) { + if (isNull(newNode)) { + this.root.addChild(node, index); + } else if (isNull(node)) { + this.root.addChild(newNode, index); + } else { + node.addChild(newNode, index); + } + } + + isRoot(node) { + return node === this.root; + } + + getRoot() { + return this.root; + } + + clear() { + this.root.clear(); + } + + initTree(nodes) { + this.clear(); + const queue = new Set(); + each(nodes, (i, node) => { + const n = new Node(node); + n.set("data", node); + this.addNode(n); + queue.add(n); + }); + queue.forEach(parent => { + queue.delete(parent); + const node = parent.get("data"); + each(node.children, (i, child) => { + const n = new Node(child); + n.set("data", child); + queue.add(n); + this.addNode(parent, n); + }); + }) + } + + _toJSON(node) { + const children = []; + each(node.getChildren(), (i, child) => { + children.push(this._toJSON(child)); + }); + return extend({ + id: node.id, + }, deepClone(node.get("data")), (children.length > 0 ? { + children: children, + } : {})); + } + + toJSON(node) { + const result = []; + each((node || this.root).getChildren(), (i, child) => { + result.push(this._toJSON(child)); + }); + return result; + } + + _toJSONWithNode(node) { + const children = []; + each(node.getChildren(), (i, child) => { + children.push(this._toJSONWithNode(child)); + }); + return extend({ + id: node.id, + }, deepClone(node.get("data")), { + node: node, + }, (children.length > 0 ? { + children: children, + } : {})); + } + + toJSONWithNode(node) { + const result = []; + each((node || this.root).getChildren(), (i, child) => { + result.push(this._toJSONWithNode(child)); + }); + return result; + } + + search(root, target, param) { + if (!(root instanceof Node)) { + return this.search(this.root, root, target); + } + let next = null; + + if (isNull(target)) { + return null; + } + if (isEqual(root[param || "id"], target)) { + return root; + } + some(root.getChildren(), (i, child) => { + next = this.search(child, target, param); + if (null !== next) { + return true; + } + }); + return next; + } + + _traverse(node, callback) { + let queue = []; + queue.push(node); + while (!isEmpty(queue)) { + const temp = queue.shift(); + const b = callback && callback(temp); + if (b === false) { + break; + } + if (b === true) { + continue; + } + if (temp != null) { + queue.push(...temp.getChildren()); + } + } + } + + traverse(callback) { + this._traverse(this.root, callback); + } + + _recursion(node, route, callback) { + return every(node.getChildren(), (i, child) => { + const next = clone(route); + next.push(child.id); + const b = callback && callback(child, next); + if (b === false) { + return false; + } + if (b === true) { + return true; + } + return this._recursion(child, next, callback); + }); + } + + recursion(callback) { + this._recursion(this.root, [], callback); + } + + inOrderTraverse(callback) { + this._inOrderTraverse(this.root, callback); + } + + // 中序遍历(递归) + _inOrderTraverse(node, callback) { + if (node != null) { + this._inOrderTraverse(node.getLeft()); + callback && callback(node); + this._inOrderTraverse(node.getRight()); + } + } + + // 中序遍历(非递归) + nrInOrderTraverse(callback) { + + const stack = []; + let node = this.root; + while (node != null || !isEmpty(stack)) { + while (node != null) { + stack.push(node); + node = node.getLeft(); + } + node = stack.pop(); + callback && callback(node); + node = node.getRight(); + } + } + + preOrderTraverse(callback) { + this._preOrderTraverse(this.root, callback); + } + + // 先序遍历(递归) + _preOrderTraverse(node, callback) { + if (node != null) { + callback && callback(node); + this._preOrderTraverse(node.getLeft()); + this._preOrderTraverse(node.getRight()); + } + } + + // 先序遍历(非递归) + nrPreOrderTraverse(callback) { + + const stack = []; + let node = this.root; + + while (node != null || !isEmpty(stack)) { + + while (node != null) { + callback && callback(node); + stack.push(node); + node = node.getLeft(); + } + node = stack.pop(); + node = node.getRight(); + } + } + + postOrderTraverse(callback) { + this._postOrderTraverse(this.root, callback); + } + + // 后序遍历(递归) + _postOrderTraverse(node, callback) { + if (node != null) { + this._postOrderTraverse(node.getLeft()); + this._postOrderTraverse(node.getRight()); + callback && callback(node); + } + } + + // 后续遍历(非递归) + nrPostOrderTraverse(callback) { + + const stack = []; + let node = this.root; + let preNode = null;// 表示最近一次访问的节点 + + while (node != null || !isEmpty(stack)) { + + while (node != null) { + stack.push(node); + node = node.getLeft(); + } + + node = last(stack); + + if (node.getRight() == null || node.getRight() === preNode) { + callback && callback(node); + node = stack.pop(); + preNode = node; + node = null; + } else { + node = node.getRight(); + } + } + } + + static transformToArrayFormat(nodes, pId, childKey) { + if (!nodes) return []; + let r = []; + childKey = childKey || "children"; + if (isArray(nodes)) { + for (let i = 0, l = nodes.length; i < l; i++) { + const node = clone(nodes[i]); + node.pId = node.pId == null ? pId : node.pId; + delete node.children; + r.push(node); + if (nodes[i][childKey]) { + r = r.concat(Tree.transformToArrayFormat(nodes[i][childKey], node.id)); + } + } + } else { + const newNodes = clone(nodes); + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; + delete newNodes.children; + r.push(newNodes); + if (nodes[childKey]) { + r = r.concat(Tree.transformToArrayFormat(nodes[childKey], newNodes.id)); + } + } + return r; + } + + static arrayFormat(nodes, pId) { + if (!nodes) { + return []; + } + let r = []; + if (isArray(nodes)) { + for (let i = 0, l = nodes.length; i < l; i++) { + const node = nodes[i]; + node.pId = node.pId == null ? pId : node.pId; + r.push(node); + if (nodes[i]["children"]) { + r = r.concat(Tree.arrayFormat(nodes[i]["children"], node.id)); + } + } + } else { + const newNodes = nodes; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; + r.push(newNodes); + if (nodes["children"]) { + r = r.concat(Tree.arrayFormat(nodes["children"], newNodes.id)); + } + } + return r; + } + + static transformToTreeFormat(sNodes) { + let i, l; + if (!sNodes) { + return []; + } + + if (isArray(sNodes)) { + const r = []; + const tmpMap = {}; + for (i = 0, l = sNodes.length; i < l; i++) { + if (isNull(sNodes[i].id)) { + return sNodes; + } + tmpMap[sNodes[i].id] = clone(sNodes[i]); + } + for (i = 0, l = sNodes.length; i < l; i++) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { + if (!tmpMap[sNodes[i].pId].children) { + tmpMap[sNodes[i].pId].children = []; + } + tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); + } else { + r.push(tmpMap[sNodes[i].id]); + } + delete tmpMap[sNodes[i].id].pId; + } + return r; + } + return [sNodes]; + + } + + static treeFormat(sNodes) { + let i, l; + if (!sNodes) { + return []; + } + + if (isArray(sNodes)) { + const r = []; + const tmpMap = {}; + for (i = 0, l = sNodes.length; i < l; i++) { + if (isNull(sNodes[i].id)) { + return sNodes; + } + tmpMap[sNodes[i].id] = sNodes[i]; + } + for (i = 0, l = sNodes.length; i < l; i++) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { + if (!tmpMap[sNodes[i].pId].children) { + tmpMap[sNodes[i].pId].children = []; + } + tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); + } else { + r.push(tmpMap[sNodes[i].id]); + } + } + return r; + } + return [sNodes]; + + } + + static traversal(array, callback, pNode) { + if (isNull(array)) { + return; + } + some(array, (i, item) => { + if (callback(i, item, pNode) === false) { + return true; + } + this.traversal(item.children, callback, item); + }); + } +} diff --git a/packages/fineui/src/core/structure/vector.js b/packages/fineui/src/core/structure/vector.js new file mode 100644 index 000000000..cd52754fd --- /dev/null +++ b/packages/fineui/src/core/structure/vector.js @@ -0,0 +1,68 @@ +// 向量操作 +export class Vector { + constructor(x, y) { + this.x = x; + this.y = y; + } + + cross(v) { + return (this.x * v.y - this.y * v.x); + } + + length(v) { + return (Math.sqrt(this.x * v.x + this.y * v.y)); + } +} + +export class Region { + constructor(x, y, w, h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + // 判断两个区域是否相交,若相交,则要么顶点互相包含,要么矩形边界(或对角线)相交 + isIntersects(obj) { + if (this.isPointInside(obj.x, obj.y) || + this.isPointInside(obj.x + obj.w, obj.y) || + this.isPointInside(obj.x, obj.y + obj.h) || + this.isPointInside(obj.x + obj.w, obj.y + obj.h)) { + return true; + } else if (obj.isPointInside(this.x, this.y) || + obj.isPointInside(this.x + this.w, this.y) || + obj.isPointInside(this.x, this.y + this.h) || + obj.isPointInside(this.x + this.w, this.y + this.h)) { + return true; + } else if (obj.x != null && obj.y != null)// 判断矩形对角线相交 |v1 X v2||v1 X v3| < 0 + { + const vector1 = new Vector(this.w, this.h);// 矩形对角线向量 + const vector2 = new Vector(obj.x - this.x, obj.y - this.y); + const vector3 = new Vector(vector2.x + obj.w, vector2.y + obj.h); + if ((vector1.cross(vector2) * vector1.cross(vector3)) < 0) { + return true; + } + } + return false; + } + + // 判断一个点是否在这个区域内部 + isPointInside(x, y) { + if (this.x == null || this.y == null) { + return false; + } + if (x >= this.x && x <= this.x + this.w && y >= this.y && y <= this.y + this.h) { + return true; + } + return false; + } + + // 返回区域的重心,因为是矩形所以返回中点 + getPosition() { + const pos = []; + pos.push(this.x + this.w / 2); + pos.push(this.y + this.h / 2); + return pos; + } +} + diff --git a/packages/fineui/src/core/system.js b/packages/fineui/src/core/system.js new file mode 100644 index 000000000..e4c316633 --- /dev/null +++ b/packages/fineui/src/core/system.js @@ -0,0 +1,154 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2021/6/30 + */ +import { prepares } from "./0.foundation"; +import { deepExtend, extend } from "./2.base"; +import { OB } from "./3.ob"; +import { Providers } from "./5.inject"; +import { provider } from "./decorator"; +import { isIE as checkIE } from "./platform/web"; + +// 系统参数常量 +const system = { + dependencies: {}, + layoutOptimize: false, + responsiveMode: false, + workerMode: false, + size: { + // 尺寸 + // 通用尺寸 + TOOL_BAR_HEIGHT: 24, + LIST_ITEM_HEIGHT: 24, + TRIGGER_HEIGHT: 24, + TOAST_TOP: 10, + H_GAP_SIZE: "M", + V_GAP_SIZE: "S", + }, + loadingCreator(config) { + const loadingSize = (config ? config.loadingSize : "small") || "small"; + + const isIE = checkIE(); + + function getSize(v) { + return Math.ceil(v / (loadingSize === "small" ? 2 : 1)); + } + + return { + type: "bi.horizontal", + cls: `bi-loading-widget${isIE ? " wave-loading hack" : ""}`, + height: getSize(60), + width: getSize(60), + hgap: getSize(10), + vgap: 2.5, + items: isIE ? [] : [{ + type: "bi.layout", + cls: "animate-rect rect1", + height: getSize(50), + width: getSize(5), + }, { + type: "bi.layout", + cls: "animate-rect rect2", + height: getSize(50), + width: getSize(5), + }, { + type: "bi.layout", + cls: "animate-rect rect3", + height: getSize(50), + width: getSize(5), + }], + }; + }, +}; + +// 具体尺寸还没定,先写着 +const sizeMap = { + S: 10, + M: 20, + L: 24, +}; + +class SystemProviderOB extends OB { + getSize () { + const size = system.size; + const H_GAP_SIZE = sizeMap[size.H_GAP_SIZE]; + const V_GAP_SIZE = sizeMap[size.V_GAP_SIZE]; + + return extend({}, size, { + H_GAP_SIZE, + V_GAP_SIZE, + }); + } + + getResponsiveMode () { + return system.responsiveMode; + } + + getWorkerMode () { + return system.workerMode; + } + + getLayoutOptimize () { + return system.layoutOptimize; + } + + getDependencies () { + return system.dependencies; + } + + getLoading(config) { + return system.loadingCreator(config); + } +} + +@provider() +export class SystemProvider { + static xtype = "bi.provider.system"; + + SYSTEM = system; + + setSize(opt) { + deepExtend(system, { size: opt }); + } + + setResponsiveMode(mode) { + system.responsiveMode = !!mode; + } + + setWorkerMode(mode) { + system.workerMode = !!mode; + } + + setLayoutOptimize(layoutOptimize) { + system.layoutOptimize = layoutOptimize; + } + + addDependency(moduleId, minVersion, maxVersion) { + system.dependencies[moduleId] = { + min: minVersion, + max: maxVersion, + }; + } + + addDependencies(moduleConfig) { + extend(system.dependencies, moduleConfig); + } + + setLoadingCreator = function(creator) { + system.loadingCreator = creator; + }; + + $get() { + return SystemProviderOB; + } +} + +export const SIZE_CONSANTS = {}; +// 不再增加线型的配置了,之后不维护前置版本直接删掉,都用实线连接线 +export const STYLE_CONSTANTS = {}; + +prepares.push(() => { + extend(SIZE_CONSANTS, Providers.getProvider(SystemProvider.xtype).getSize()); + STYLE_CONSTANTS.LINK_LINE_TYPE = SIZE_CONSANTS.LIST_ITEM_HEIGHT === 24 ? "dashed" : "solid"; +}); diff --git a/src/core/utils/__test__/aes.test.js b/packages/fineui/src/core/utils/__test__/aes.test.js similarity index 100% rename from src/core/utils/__test__/aes.test.js rename to packages/fineui/src/core/utils/__test__/aes.test.js diff --git a/packages/fineui/src/core/utils/chinesePY.js b/packages/fineui/src/core/utils/chinesePY.js new file mode 100644 index 000000000..9f39354da --- /dev/null +++ b/packages/fineui/src/core/utils/chinesePY.js @@ -0,0 +1,448 @@ +import { isNull } from "../2.base"; + +/** + * 汉字拼音索引 + */ +const _ChineseFirstPY = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSCYYYNJQYXXGJHHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPCBZJJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZZXNBGNNXBXLZSZSBSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZXYALMELDCCXGZYRJXSDLTYZCQKCNNJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXPJBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQTGLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCSKDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMBDTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCSHZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZASYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNCLLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXHLGTGXBQJDZPYJSJYJCTMRNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJFFFFJCZFMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXKLQSCGJCLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZMLJLLJKYWXMKJLHSKJGBMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJGBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLLSDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJXXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYLJSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXPXJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYLYMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWGYJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPPBFYHZHTJYFDZWKGKZBLDNTSXHQEEGZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBMLSFBHHGYGYYGGBHSCYAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZYGPZSZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMCHKDSCRSWJPWXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCKZXSHMLQXXTTHXWZFKHCCZDYTCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHPYYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTXJCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGGTGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZWGPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWFZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDGCYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGAFFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTLFYQKASDNTCYHBLWDZHBBYDWJRYGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSLCMBJCSZZKYDCZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZSYMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZBYJTZBXHFDXKDASWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZEMMQBSQEHXFZMBMFLZZSRXYMJGSXWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNYNPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMCPJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYXYWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXYYRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZYJZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMTCJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYSXQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDHZGZDWYBSSCSKXSYHYTXXGCQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJYZWZXZDDXJSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWXLYDHLYQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAWHZMLJTWYGXLYQZLJEEYYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZSZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQYTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZQJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYWYWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSBDSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZGMDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQCFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMTYBBCLBJASKYTSSQYYMSZXFJEWLXLLSZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBSDZZTFDMXHCNJZYMQWSRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZXJTCZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHXNWXXKHKFHTSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHHCJYXGLHZXCSNHEKDTGZXQYPKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKTLXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWSZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSLFYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCPMMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQQPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQJSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZKKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQHHHEYTMHLFSBDJSYYSHFYSTCZQLPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBBZPNPPTYZZYBQNYDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJLJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNNWZXQXCDSLQGDSDPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAXYWQCJTLLCKJJTJHGDXDXYQYZZBYWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZKSSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQGYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJXLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJYEMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLLHYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGDXJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXMSZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYSPYMPQZMLPPLFFXJJNZZYLSJEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZSXYFYMNCWDABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYSPMJKHWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCTZQXKYQFPYYRPFFLKQUNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJSWLJMYMMZYHFBJDGYXCCPSHXNZCSBSJYJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLHPFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZBLCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZDQQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYGBDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPHZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZSKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPBYKXRYLYBHKJKSFXTZJMMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRTQZSSTKXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZMMNYTPZSXQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNYXHSZXCGJZYQPYLFHDJSBPCCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZLYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZCQQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXYGYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDESJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLBDJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMHQNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJMQPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXSRGJCWTJTZZQMGWJJTJHTQJBBHWZPXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMBZZLYGHGFMSHPZFZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQPWQLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYHDHRJZSFGXTSYCZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYKQSYSLZDQJMPXYYSSRHZJNYWTQDFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQQQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYSYXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYFJHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYPJYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJSXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWTYYDCHQLXKPZWBGQYBKFCMZWPZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYLMSTDJCYHBZLLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLTYXHQLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJCFPQRYQXCYYYQYGRPYWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXNSQYXMQYWRGYQLXBBZLJSYLPSYTJZYHYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXLYYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCRYLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDPBCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCDJJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZGMYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYSLBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYMCCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXXTXXNBHRMLYJSLTXMRHNLXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYXLSZQYXBEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXDRMJWRHXCJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZDJGTKHSSTCYJLPSWZLXZXRWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZBLZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNTYJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSDCHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLYCYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYMDJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGWHKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLLMQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZMDPJHGCLGMJJPGAEHHBWCQXAXHHHZCHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZQYXXDXXPFDMMSSYMPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPPMHNLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPMLKJXMHLMLQMXCTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNPPLPLPEPSZALLTYLKCKQZKGENQLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYDWQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDFXQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXLDDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZLLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQHZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHTXSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTCTSSYLLGZRZBBQZZKLPKLCZYSSUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYSJYCZTLQZYBBYBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJQJPDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRFKZTJDHCZKLBSDZCFJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXPZXHYZYCLWDXJJHXMFDZPFZHQHQMQGKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDLXBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZLSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHLXZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFLCJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZKJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFSZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZXZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJHZYJFJXRZSDLLLTQSQQZQWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXYWGSYJYZNBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJHZCXZBTYNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJKRDHHGXJLJJTGXJXXSTJTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFXGFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRLFSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLYZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFXPYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXDYLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQYCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDUTJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJFZYNAKRGYWYQPQXXFKJTSZZXSWZDDFBBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJKYHCPSTMCSQTZJYXTPCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJPXGLBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZZGJZZXTZJXYCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCYSCCLDXYCDDQLYJJWMQLLCSGLJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZMYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBGMYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCYXZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJYHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBXGLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJDQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQDSPDJZZGHGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXXNCWCXYPMAELYKKJMZZZBRXYYQJFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCXTLWDQZPCYCYKPPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXMBDZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLYXWJHSNLXYYXHBHAWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXXLYLLJDZBTYMHPFSTTQQWLHOKYBLZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHLJKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZKBXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHGZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFYWLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZWFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGCULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJLLQZYJSWXMZZMMYLMXCLMXCZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLLLPYPSYJYSXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZYPFDWFGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYDTZJYQGGKQTTFZXBDKTYYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJDSZBLPRZTSWSBXBCLLXXLZDJZSJPYLYXXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGYGMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCYZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZYXXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZLJJXLSBHPYXXPSXSHHEZTXFPTLQYZZXHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWDXZSXZDZXLEYJJZQBHZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJHOJYNXELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYDMPXMDSXYBSQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPGNYDMSXHMMMMAMYNBYJTMPXYYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXMJSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZBYZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQSQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQQJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZKZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMTJQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLCTZSXKJZQZPZLBZRBTJDCXFCZDBCCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYCZGJWYXDXFRSKSTQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZFYBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCPZBLLCYBBBBUBBCBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSSTPHNDJXXBYXQTZQDDTJTDYYTGWSCSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZAZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYYLLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJXGNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYMRBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMSLPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZXJCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXTQCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLFNDXQKCZFYWHGQMRDSXYCYTXNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZCZPTQFZMYFLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZTLMLWZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZJYJGMCTXLTGXSZLMLHBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQMSTPXLSKLZYNWRTSQLSZBPSPSGZWYHTLKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCLXXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQJZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKNXJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGYZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQGBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZLPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZNCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPCQDHLXZLYCBLCXZZJADJLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQKTWPXXHCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBBFJLLCXDLMJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPSSYYFNEJDXYZHLXLLLZQZSJNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYADTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDDWRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZPKJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSHCKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQHYWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHHJTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQBSHYLLPJJJTHYJKYPPTHYYKTYEZYENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFSYZYZBJTBCTSBSDHRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZNSDJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQPQJPZYPZJZNJPZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQCZLPTXCDYYZXSQZSLXLZMYCPCQBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJQQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZTDKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBRFERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDDNXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXCYZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSDDTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZSQYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZHLYQQJBEYFXXXWHSRXWQHWPSLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELGLXYDJYTLFBHBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYFLZBYFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJTJTPWJYBJJBXJJTJTEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHYYXWSHCTXRLJHQXHCCYYYJLTKTTYTMXGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYLBLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZGLHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJLJXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQQMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQDCYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTTSSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHWWKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWPYMLGKDLDLGKQQBGYCHJXY"; + +// 此处收录了375个多音字,数据来自于http://www.51windows.net/pages/pinyin.asp +const oMultiDiff = { + 19969: "DZ", + 19975: "WM", + 19988: "QJ", + 20048: "YL", + 20056: "SC", + 20060: "NM", + 20094: "QG", + 20127: "QJ", + 20167: "QC", + 20193: "YG", + 20250: "KH", + 20256: "ZC", + 20282: "SC", + 20285: "QJG", + 20291: "TD", + 20314: "YD", + 20315: "BF", + 20340: "NE", + 20375: "TD", + 20389: "YJ", + 20391: "CZ", + 20415: "PB", + 20446: "YS", + 20447: "SQ", + 20504: "TC", + 20608: "KG", + 20854: "QJ", + 20857: "ZC", + 20911: "PF", + 20985: "AW", + 21032: "PB", + 21048: "XQ", + 21049: "SC", + 21089: "YS", + 21119: "JC", + 21242: "SB", + 21273: "SC", + 21305: "YP", + 21306: "QO", + 21330: "ZC", + 21333: "SDC", + 21345: "QK", + 21378: "CA", + 21397: "SC", + 21414: "XS", + 21442: "SC", + 21477: "JG", + 21480: "TD", + 21484: "ZS", + 21494: "YX", + 21505: "YX", + 21512: "HG", + 21523: "XH", + 21537: "PB", + 21542: "PF", + 21549: "KH", + 21571: "E", + 21574: "DA", + 21588: "TD", + 21589: "O", + 21618: "ZC", + 21621: "KHA", + 21632: "ZJ", + 21654: "KG", + 21679: "LKG", + 21683: "KH", + 21710: "A", + 21719: "YH", + 21734: "WOE", + 21769: "A", + 21780: "WN", + 21804: "XH", + 21834: "A", + 21899: "ZD", + 21903: "RN", + 21908: "WO", + 21939: "ZC", + 21956: "SA", + 21964: "YA", + 21970: "TD", + 22003: "A", + 22031: "JG", + 22040: "XS", + 22060: "ZC", + 22066: "ZC", + 22079: "MH", + 22129: "XJ", + 22179: "XA", + 22237: "NJ", + 22244: "TD", + 22280: "JQ", + 22300: "YH", + 22313: "XW", + 22331: "YQ", + 22343: "YJ", + 22351: "PH", + 22395: "DC", + 22412: "TD", + 22484: "PB", + 22500: "PB", + 22534: "ZD", + 22549: "DH", + 22561: "PB", + 22612: "TD", + 22771: "KQ", + 22831: "HB", + 22841: "JG", + 22855: "QJ", + 22865: "XQ", + 23013: "ML", + 23081: "WM", + 23487: "SX", + 23558: "QJ", + 23561: "YW", + 23586: "YW", + 23614: "YW", + 23615: "SN", + 23631: "PB", + 23646: "ZS", + 23663: "ZT", + 23673: "YG", + 23762: "TD", + 23769: "ZS", + 23780: "QJ", + 23884: "QK", + 24055: "XH", + 24113: "DC", + 24162: "ZC", + 24191: "GA", + 24273: "QJ", + 24324: "NL", + 24377: "TD", + 24378: "QJ", + 24439: "PF", + 24554: "ZS", + 24683: "TD", + 24694: "WE", + 24733: "LK", + 24925: "TN", + 25094: "ZG", + 25100: "XQ", + 25103: "XH", + 25153: "PB", + 25170: "PB", + 25179: "KG", + 25203: "PB", + 25240: "ZS", + 25282: "FB", + 25303: "NA", + 25324: "KG", + 25341: "ZY", + 25373: "WZ", + 25375: "XJ", + 25384: "A", + 25457: "A", + 25528: "SD", + 25530: "SC", + 25552: "TD", + 25774: "ZC", + 25874: "ZC", + 26044: "YW", + 26080: "WM", + 26292: "PB", + 26333: "PB", + 26355: "ZY", + 26366: "CZ", + 26397: "ZC", + 26399: "QJ", + 26415: "ZS", + 26451: "SB", + 26526: "ZC", + 26552: "JG", + 26561: "TD", + 26588: "JG", + 26597: "CZ", + 26629: "ZS", + 26638: "YL", + 26646: "XQ", + 26653: "KG", + 26657: "XJ", + 26727: "HG", + 26894: "ZC", + 26937: "ZS", + 26946: "ZC", + 26999: "KJ", + 27099: "KJ", + 27449: "YQ", + 27481: "XS", + 27542: "ZS", + 27663: "ZS", + 27748: "TS", + 27784: "SC", + 27788: "ZD", + 27795: "TD", + 27812: "O", + 27850: "PB", + 27852: "MB", + 27895: "SL", + 27898: "PL", + 27973: "QJ", + 27981: "KH", + 27986: "HX", + 27994: "XJ", + 28044: "YC", + 28065: "WG", + 28177: "SM", + 28267: "QJ", + 28291: "KH", + 28337: "ZQ", + 28463: "TL", + 28548: "DC", + 28601: "TD", + 28689: "PB", + 28805: "JG", + 28820: "QG", + 28846: "PB", + 28952: "TD", + 28975: "ZC", + 29100: "A", + 29325: "QJ", + 29575: "SL", + 29602: "FB", + 30010: "TD", + 30044: "CX", + 30058: "PF", + 30091: "YSP", + 30111: "YN", + 30229: "XJ", + 30427: "SC", + 30465: "SX", + 30631: "YQ", + 30655: "QJ", + 30684: "QJG", + 30707: "SD", + 30729: "XH", + 30796: "LG", + 30917: "PB", + 31074: "NM", + 31085: "JZ", + 31109: "SC", + 31181: "ZC", + 31192: "MLB", + 31293: "JQ", + 31400: "YX", + 31584: "YJ", + 31896: "ZN", + 31909: "ZY", + 31995: "XJ", + 32321: "PF", + 32327: "ZY", + 32418: "HG", + 32420: "XQ", + 32421: "HG", + 32438: "LG", + 32473: "GJ", + 32488: "TD", + 32521: "QJ", + 32527: "PB", + 32562: "ZSQ", + 32564: "JZ", + 32735: "ZD", + 32793: "PB", + 33071: "PF", + 33098: "XL", + 33100: "YA", + 33152: "PB", + 33261: "CX", + 33324: "BP", + 33333: "TD", + 33406: "YA", + 33426: "WM", + 33432: "PB", + 33445: "JG", + 33486: "ZN", + 33493: "TS", + 33507: "QJ", + 33540: "QJ", + 33544: "ZC", + 33564: "XQ", + 33617: "YT", + 33632: "QJ", + 33636: "XH", + 33637: "YX", + 33694: "WG", + 33705: "PF", + 33728: "YW", + 33882: "SR", + 34067: "WM", + 34074: "YW", + 34121: "QJ", + 34255: "ZC", + 34259: "XL", + 34425: "JH", + 34430: "XH", + 34485: "KH", + 34503: "YS", + 34532: "HG", + 34552: "XS", + 34558: "YE", + 34593: "ZL", + 34660: "YQ", + 34892: "XH", + 34928: "SC", + 34999: "QJ", + 35048: "PB", + 35059: "SC", + 35098: "ZC", + 35203: "TQ", + 35265: "JX", + 35299: "JX", + 35782: "SZ", + 35828: "YS", + 35830: "E", + 35843: "TD", + 35895: "YG", + 35977: "MH", + 36158: "JG", + 36228: "QJ", + 36426: "XQ", + 36466: "DC", + 36710: "CJ", + 36711: "ZYG", + 36767: "PB", + 36866: "SK", + 36951: "YW", + 37034: "YX", + 37063: "XH", + 37218: "ZC", + 37325: "ZC", + 38063: "PB", + 38079: "TD", + 38085: "QY", + 38107: "DC", + 38116: "TD", + 38123: "YD", + 38224: "HG", + 38241: "XTC", + 38271: "ZC", + 38415: "YE", + 38426: "KH", + 38461: "YD", + 38463: "AE", + 38466: "PB", + 38477: "XJ", + 38518: "YT", + 38551: "WK", + 38585: "ZC", + 38704: "XS", + 38739: "LJ", + 38761: "GJ", + 38808: "SQ", + 39048: "JG", + 39049: "XJ", + 39052: "HG", + 39076: "CZ", + 39271: "XT", + 39534: "TD", + 39552: "TD", + 39584: "PB", + 39647: "SB", + 39730: "LG", + 39748: "TPB", + 40109: "ZQ", + 40479: "ND", + 40516: "HG", + 40536: "HG", + 40583: "QJ", + 40765: "YQ", + 40784: "QJ", + 40840: "YK", + 40863: "QJG", +}; + +function _checkPYCh(ch) { + const uni = ch.charCodeAt(0); + // 如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数 + if (uni > 40869 || uni < 19968) { + return ch; + } // dealWithOthers(ch); + + return (oMultiDiff[uni] ? oMultiDiff[uni] : (_ChineseFirstPY.charAt(uni - 19968))); +} + +function _mkPYRslt(arr, options) { + const ignoreMulti = options.ignoreMulti; + const splitChar = options.splitChar; + let arrRslt = [""], k, multiLen = 0; + for (let i = 0, len = arr.length; i < len; i++) { + const str = arr[i]; + const strlen = str.length; + // 多音字过多的情况下,指数增长会造成浏览器卡死,超过20完全卡死,18勉强能用,考虑到不同性能最好是16或者14 + // 超过14个多音字之后,后面的都用第一个拼音 + if (strlen === 1 || multiLen > 14 || ignoreMulti) { + const tmpStr = str.substring(0, 1); + for (k = 0; k < arrRslt.length; k++) { + arrRslt[k] += tmpStr; + } + } else { + const tmpArr = arrRslt.slice(0); + arrRslt = []; + multiLen++; + for (k = 0; k < strlen; k++) { + // 复制一个相同的arrRslt + const tmp = tmpArr.slice(0); + // 把当前字符str[k]添加到每个元素末尾 + for (let j = 0; j < tmp.length; j++) { + tmp[j] += str.charAt(k); + } + // 把复制并修改后的数组连接到arrRslt上 + arrRslt = arrRslt.concat(tmp); + } + } + } + + // BI-56386 这边直接将所有多音字组合拼接是有风险的,因为丢失了每一组的起始索引信息, 外部使用indexOf等方法会造成错位 + // 一旦错位就可能认为不符合条件, 但实际上还是有可能符合条件的,故此处以一个无法搜索的不可见字符作为连接 + return arrRslt.join(splitChar || "").toLowerCase(); +} + +export function makeFirstPY(str, options) { + options = options || {}; + // BI-119441 长字段搜索分叉后数量达百万级,这里控制下字段过长的话不进行多音字分叉 + if (str.length > 100 && isNull(options.ignoreMulti)) { + options.ignoreMulti = true; + } + if (typeof (str) !== "string") { + return `${str}`; + } + const arrResult = []; // 保存中间结果的数组 + for (let i = 0, len = str.length; i < len; i++) { + // 获得unicode码 + const ch = str.charAt(i); + // 检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理 + arrResult.push(_checkPYCh(ch)); + } + + // 处理arrResult,返回所有可能的拼音首字母串数组 + return _mkPYRslt(arrResult, options); +} diff --git a/packages/fineui/src/core/utils/color.js b/packages/fineui/src/core/utils/color.js new file mode 100644 index 000000000..718a9e74b --- /dev/null +++ b/packages/fineui/src/core/utils/color.js @@ -0,0 +1,206 @@ +import { parseInt, parseFloat, isNull, isKey } from "../2.base"; + +export function isColor(color) { + return color && (isRGBColor(color) || isHexColor(color)); +} + +export function isRGBColor(color) { + if (!color) { + return false; + } + + return color.substr(0, 3) === "rgb"; +} + +export function isHexColor(color) { + if (!color) { + return false; + } + + return color[0] === "#" && color.length === 7; +} + +export function isDarkColor(hex) { + if (!hex || !isHexColor(hex)) { + return false; + } + const rgb = rgb2json(hex2rgb(hex)); + const grayLevel = Math.round(rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114); + if (grayLevel < 192/** 网上给的是140**/) { + return true; + } + + return false; +} + +// 获取对比颜色 +export function getContrastColor(color) { + if (!color || !isColor(color)) { + return ""; + } + if (isDarkColor(color)) { + return "#FFFFFF"; + } + + return "#3D4D66"; +} + +export function rgb2hex(rgbColour) { + if (!rgbColour || rgbColour.substr(0, 3) !== "rgb") { + return ""; + } + const rgbValues = rgbColour.match(/\d+(\.\d+)?/g); + const red = parseInt(rgbValues[0]); + const green = parseInt(rgbValues[1]); + const blue = parseInt(rgbValues[2]); + + const hexColour = `#${int2hex(red)}${int2hex(green)}${int2hex(blue)}`; + + return hexColour; +} + +function _hue2rgb(m1, m2, h) { + h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); + if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; + if (h * 2 < 1) return m2; + if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; + + return m1; +} + +export function hsl2rgb(hsl) { + const h = hsl[0], s = hsl[1], l = hsl[2]; + const m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; + const m1 = l * 2 - m2; + + return [ + _hue2rgb(m1, m2, h + 0.33333), + _hue2rgb(m1, m2, h), + _hue2rgb(m1, m2, h - 0.33333) + ]; +} + +export function rgb2hsl(rgb) { + let h, s; + const r = rgb[0], g = rgb[1], b = rgb[2]; + const min = Math.min(r, Math.min(g, b)); + const max = Math.max(r, Math.max(g, b)); + const delta = max - min; + const l = (min + max) / 2; + s = 0; + if (l > 0 && l < 1) { + s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); + } + h = 0; + if (delta > 0) { + if (max === r && max !== g) h += (g - b) / delta; + if (max === g && max !== b) h += (2 + (b - r) / delta); + if (max === b && max !== r) h += (4 + (r - g) / delta); + h /= 6; + } + + return [h, s, l]; +} + +export function rgb2json(rgbColour) { + if (!rgbColour) { + return {}; + } + if (!isRGBColor(rgbColour)) { + return {}; + } + const rgbValues = rgbColour.match(/\d+(\.\d+)?/g); + + return { + r: parseInt(rgbValues[0]), + g: parseInt(rgbValues[1]), + b: parseInt(rgbValues[2]), + }; +} + +export function rgba2json(rgbColour) { + if (!rgbColour) { + return {}; + } + const rgbValues = rgbColour.match(/\d+(\.\d+)?/g); + + return { + r: parseInt(rgbValues[0]), + g: parseInt(rgbValues[1]), + b: parseInt(rgbValues[2]), + a: parseFloat(rgbValues[3]), + }; +} + +export function json2rgb(rgb) { + if (!isKey(rgb.r) || !isKey(rgb.g) || !isKey(rgb.b)) { + return ""; + } + + return `rgb(${rgb.r},${rgb.g},${rgb.b})`; +} + +export function json2rgba(rgba) { + if (!isKey(rgba.r) || !isKey(rgba.g) || !isKey(rgba.b)) { + return ""; + } + + return `rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a})`; +} + +export function int2hex(strNum) { + const hexdig = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; + + return `${hexdig[strNum >>> 4]}${hexdig[strNum & 15]}`; +} + +export function hex2rgb(color) { + if (!color) { + return ""; + } + if (!isHexColor(color)) { + return color; + } + let tempValue = "rgb(", colorArray; + + if (color.length === 7) { + colorArray = [ + parseInt(`0x${color.substring(1, 3)}`), + parseInt(`0x${color.substring(3, 5)}`), + parseInt(`0x${color.substring(5, 7)}`) + ]; + } else if (color.length === 4) { + colorArray = [ + parseInt(`0x${color.substring(1, 2)}`), + parseInt(`0x${color.substring(2, 3)}`), + parseInt(`0x${color.substring(3, 4)}`) + ]; + } + tempValue += `${colorArray[0]},`; + tempValue += `${colorArray[1]},`; + tempValue += `${colorArray[2]})`; + + return tempValue; +} + +export function rgba2rgb(rgbColor, bgColor) { + if (isNull(bgColor)) { + bgColor = 1; + } + if (rgbColor.substr(0, 4) !== "rgba") { + return ""; + } + const rgbValues = rgbColor.match(/\d+(\.\d+)?/g); + if (rgbValues.length < 4) { + return ""; + } + const R = parseFloat(rgbValues[0]); + const G = parseFloat(rgbValues[1]); + const B = parseFloat(rgbValues[2]); + const A = parseFloat(rgbValues[3]); + + return `rgb(${Math.floor(255 * (bgColor * (1 - A)) + R * A)},${ + Math.floor(255 * (bgColor * (1 - A)) + G * A)},${ + Math.floor(255 * (bgColor * (1 - A)) + B * A)})`; +} + diff --git a/packages/fineui/src/core/utils/dom.js b/packages/fineui/src/core/utils/dom.js new file mode 100644 index 000000000..552a60d44 --- /dev/null +++ b/packages/fineui/src/core/utils/dom.js @@ -0,0 +1,790 @@ +/** + * 对DOM操作的通用函数 + */ +import { Widget } from "../4.widget"; +import { each, isEmpty, isNull, isNotNull } from "../2.base"; +import $ from "jquery"; +import { isIE } from "./../platform"; + +export function ready(fn) { + Widget._renderEngine.createElement(document).ready(fn); +} + +export function patchProps(fromElement, toElement) { + const elemData = $._data(fromElement[0]); + const events = elemData.events; + each(events, (eventKey, event) => { + each(event, (i, handler) => { + toElement.on(eventKey + (handler.namespace ? (`.${handler.namespace}`) : ""), handler); + }); + }); + const fromChildren = fromElement.children(), toChildren = toElement.children(); + if (fromChildren.length !== toChildren.length) { + throw new Error("don't match"); + } + each(fromChildren, (i, child) => { + patchProps($(child), $(toChildren[i])); + }); + each(fromElement.data("__widgets"), (i, widget) => { + widget.element = toElement; + }); +} + +/** + * 把dom数组或元素悬挂起来,使其不对html产生影响 + * @param dom + */ +export function hang(doms) { + if (isEmpty(doms)) { + return; + } + const frag = Widget._renderEngine.createFragment(); + each(doms, (i, dom) => { + dom instanceof Widget && (dom = dom.element); + dom instanceof $ && dom[0] && frag.appendChild(dom[0]); + }); + + return frag; +} + +export function isExist(obj) { + return Widget._renderEngine.createElement("body").find(obj.element).length > 0; +} + +// 预加载图片 +export function preloadImages(srcArray, onload) { + let count = 0; + const images = []; + + function complete() { + count++; + if (count >= srcArray.length) { + onload(); + } + } + + each(srcArray, (i, src) => { + images[i] = new Image(); + images[i].src = src; + images[i].onload = function() { + complete(); + }; + images[i].onerror = function() { + complete(); + }; + }); +} + +export function getTextSizeWidth(text, fontSize = 12) { + const span = Widget._renderEngine.createElement("").addClass("text-width-span").appendTo("body"); + + fontSize = `${fontSize}px`; + + span.css("font-size", fontSize).text(text); + + const width = span.width(); + span.remove(); + + return width; +} + +export function getTextSizeHeight(text, fontSize = 12) { + const span = Widget._renderEngine.createElement("").addClass("text-width-span").appendTo("body"); + + fontSize = `${fontSize}px`; + + span.css("font-size", fontSize).text(text); + + const height = span.height(); + span.remove(); + + return height; +} + +// 获取滚动条的宽度,页面display: none时候获取到的为0 +let _scrollWidth = null; + +export function getScrollWidth(css) { + if (isNull(_scrollWidth) || isNotNull(css) || _scrollWidth === 0) { + const ul = Widget._renderEngine.createElement("
    ").width(50).height(50) + .css({ + position: "absolute", + top: "-9999px", + overflow: "scroll", + ...css + }) + .appendTo("body"); + _scrollWidth = ul[0].offsetWidth - ul[0].clientWidth; + ul.destroy(); + } + + return _scrollWidth; +} + +export function getImage(param, fillStyle, backgroundColor) { + const canvas = document.createElement("canvas"); + const ratio = 2; + Widget._renderEngine.createElement("body").append(canvas); + + const ctx = canvas.getContext("2d"); + ctx.font = "12px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif"; + const w = ctx.measureText(param).width + 4; + canvas.width = w * ratio; + canvas.height = 16 * ratio; + ctx.font = `${12 * ratio}px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif`; + ctx.fillStyle = fillStyle || "#3685f2"; + ctx.textBaseline = "middle"; + // ctx.fillStyle = "#EAF2FD"; + ctx.fillText(param, 2 * ratio, 9 * ratio); + Widget._renderEngine.createElement(canvas).destroy(); + const backColor = backgroundColor || "rgba(54, 133, 242, 0.1)"; + + // IE可以放大缩小所以要固定最大最小宽高 + return { + width: w, + height: 16, + src: canvas.toDataURL("image/png"), + style: `background-color: ${backColor};vertical-align: middle; margin: 0 1px; width:${w}px;height: 16px; max-width:${w}px;max-height: 16px; min-width:${w}px;min-height: 16px`, + param, + }; +} + +export function getLeftPosition(combo, popup, extraWidth, container) { + const el = combo.element; + const popupEl = popup.element; + const elRect = el[0].getBoundingClientRect(); + const popupElRect = popupEl[0].getBoundingClientRect(); + const containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + + return { + left: elRect.left - containerRect.left - popupElRect.width - (extraWidth || 0), + }; +} + +export function getInnerLeftPosition(combo, popup, extraWidth) { + return { + left: combo.element.offset().left + (extraWidth || 0), + }; +} + +export function getRightPosition(combo, popup, extraWidth, container) { + const el = combo.element; + const elRect = el[0].getBoundingClientRect(); + const containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + + return { + left: elRect.left + elRect.width - containerRect.left + (extraWidth || 0), + }; +} + +export function getInnerRightPosition(combo, popup, extraWidth) { + const el = combo.element, viewBounds = popup.element.bounds(); + + return { + left: el.offset().left + el.outerWidth() - viewBounds.width - (extraWidth || 0), + }; +} + +export function getTopPosition(combo, popup, extraHeight, container) { + const el = combo.element; + const popupEl = popup.element; + const elRect = el[0].getBoundingClientRect(); + const popupElRect = popupEl[0].getBoundingClientRect(); + const containerRect = container ? container.getBoundingClientRect() : { top: 0 }; + + return { + top: elRect.top - containerRect.top - popupElRect.height - (extraHeight || 0), + }; +} + +export function getBottomPosition(combo, popup, extraHeight, container) { + const el = combo.element; + const elRect = el[0].getBoundingClientRect(); + const containerRect = container ? container.getBoundingClientRect() : { top: 0 }; + + return { + top: elRect.top - containerRect.top + elRect.height + (extraHeight || 0), + }; +} + +export function isLeftSpaceEnough(combo, popup, extraWidth) { + return getLeftPosition(combo, popup, extraWidth).left >= 0; +} + +export function isInnerLeftSpaceEnough(combo, popup, extraWidth) { + const viewBounds = popup.element.bounds(), + windowBounds = Widget._renderEngine.createElement("body").bounds(); + + return getInnerLeftPosition(combo, popup, extraWidth).left + viewBounds.width <= windowBounds.width; +} + +export function isRightSpaceEnough(combo, popup, extraWidth) { + const viewBounds = popup.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + + return getRightPosition(combo, popup, extraWidth).left + viewBounds.width <= viewportBounds.width; +} + +export function isInnerRightSpaceEnough(combo, popup, extraWidth) { + return getInnerRightPosition(combo, popup, extraWidth).left >= 0; +} + +export function isTopSpaceEnough(combo, popup, extraHeight) { + return getTopPosition(combo, popup, extraHeight).top >= 0; +} + +export function isBottomSpaceEnough(combo, popup, extraHeight) { + const viewBounds = popup.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + + return getBottomPosition(combo, popup, extraHeight).top + viewBounds.height <= viewportBounds.height; +} + +export function isRightSpaceLarger(combo) { + const comboBounds = combo.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + + return viewportBounds.width - comboBounds.right >= comboBounds.left; +} + +export function isBottomSpaceLarger(combo) { + const comboBounds = combo.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + + return viewportBounds.height - comboBounds.bottom >= comboBounds.top; +} + +export function _getLeftAlignPosition(combo, popup, extraWidth, container) { + const comboRect = combo.element[0].getBoundingClientRect(), + popupRect = popup.element[0].getBoundingClientRect(), + viewportRect = document.documentElement.getBoundingClientRect(), + containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + let left = comboRect.left - containerRect.left + extraWidth; + + if (comboRect.left + popupRect.width > viewportRect.width) { + left = viewportRect.width - popupRect.width - containerRect.left; + } + + return left; +} + +export function getLeftAlignPosition(combo, popup, extraWidth, container) { + let left = _getLeftAlignPosition(combo, popup, extraWidth, container); + let dir = ""; + // 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0 + const containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + if (left + containerRect.left < 0) { + left = _getRightAlignPosition(combo, popup, extraWidth); + dir = "left"; + } + if (left + containerRect.left < 0) { + left = 0 - containerRect.left; + } + + return { + left, + dir: dir || "right", + }; +} + +export function getLeftAdaptPosition(combo, popup, extraWidth, container) { + if (isLeftSpaceEnough(combo, popup, extraWidth, container)) { + return getLeftPosition(combo, popup, extraWidth, container); + } + + return { + left: 0, + }; +} + +export function _getRightAlignPosition(combo, popup, extraWidth, container) { + const comboBounds = combo.element[0].getBoundingClientRect(), + viewBounds = popup.element[0].getBoundingClientRect(), + containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + + return comboBounds.left + comboBounds.width - viewBounds.width - extraWidth - containerRect.left; +} + +export function getRightAlignPosition(combo, popup, extraWidth, container) { + let left = _getRightAlignPosition(combo, popup, extraWidth, container); + let dir = ""; + // 如果放不下,优先使用LeftAlign, 如果LeftAlign也放不下, 再使用left=0 + if (left < 0) { + left = _getLeftAlignPosition(combo, popup, extraWidth, container); + dir = "right"; + } + if (left < 0) { + left = 0; + } + + return { + left, + dir: dir || "left", + }; +} + +export function getRightAdaptPosition(combo, popup, extraWidth, container) { + if (isRightSpaceEnough(combo, popup, extraWidth, container)) { + return getRightPosition(combo, popup, extraWidth, container); + } + + return { + left: document.documentElement.getBoundingClientRect().width - popup.element[0].getBoundingClientRect().width - container.getBoundingClientRect().left, + }; +} + +export function getTopAlignPosition(combo, popup, extraHeight, needAdaptHeight, container) { + const comboBounds = combo.element[0].getBoundingClientRect(), + popupBounds = popup.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(), + containerBounds = container ? container.getBoundingClientRect() : { top: 0 }; + let top, adaptHeight, dir; + if (isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { + top = comboBounds.top - containerBounds.top + extraHeight; + } else if (needAdaptHeight) { + top = comboBounds.top - containerBounds.top + extraHeight; + adaptHeight = viewportBounds.height - comboBounds.top; + } else if (isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { + // 下方空间不足且不允许调整高度的情况下,优先使用上对齐 + top = comboBounds.top + comboBounds.height - popupBounds.height - containerBounds.top - extraHeight; + dir = "top"; + } else { + top = viewportBounds.height - popupBounds.height; + if (top < extraHeight) { + adaptHeight = viewportBounds.height - extraHeight; + } + } + if (top < extraHeight) { + top = extraHeight; + } + + return adaptHeight ? { + top, + adaptHeight, + dir: dir || "bottom", + } : { + top, + dir: dir || "bottom", + }; +} + +export function getTopAdaptPosition(combo, popup, extraHeight, needAdaptHeight, positionRelativeElement) { + const comboBounds = combo.element[0].getBoundingClientRect(), + popupBounds = popup.element[0].getBoundingClientRect(), + positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + if (isTopSpaceEnough(combo, popup, extraHeight)) { + return getTopPosition(combo, popup, extraHeight); + } + if (needAdaptHeight) { + return { + top: 0 - positionRelativeElementRect.top, + adaptHeight: comboBounds.top - extraHeight, + }; + } + if (popupBounds.height + extraHeight > viewportBounds.height) { + return { + top: 0 - positionRelativeElementRect.top, + adaptHeight: viewportBounds.height - extraHeight, + }; + } + + return { + top: 0 - positionRelativeElementRect.top, + }; +} + +export function getBottomAlignPosition(combo, popup, extraHeight, needAdaptHeight, container) { + const comboBounds = combo.element[0].getBoundingClientRect(), + popupBounds = popup.element[0].getBoundingClientRect(), + windowBounds = Widget._renderEngine.createElement("body").bounds(), + containerBounds = container ? container.getBoundingClientRect() : { top: 0 }; + let top, adaptHeight, dir; + if (isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { + top = comboBounds.top + comboBounds.height - containerBounds.top - popupBounds.height; + } else if (needAdaptHeight) { + top = 0 - containerBounds.top; + adaptHeight = comboBounds.top + comboBounds.height - extraHeight; + } else if (isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { + // 上方空间不足且不允许调整高度的情况下,优先使用下对齐 + top = comboBounds.top - containerBounds.top + extraHeight; + dir = "bottom"; + } else { + top = 0; + if (popupBounds.height + extraHeight > windowBounds.height) { + adaptHeight = windowBounds.height - extraHeight; + } + } + if (top + containerBounds.top < 0) { + top = 0; + } + + return adaptHeight ? { + top, + adaptHeight, + dir: dir || "top", + } : { + top, + dir: dir || "top", + }; +} + +export function getBottomAdaptPosition(combo, popup, extraHeight, needAdaptHeight, positionRelativeElement) { + const comboBounds = combo.element[0].getBoundingClientRect(), + popupBounds = popup.element[0].getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(), + positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(); + if (isBottomSpaceEnough(combo, popup, extraHeight)) { + return getBottomPosition(combo, popup, extraHeight, positionRelativeElement); + } + if (needAdaptHeight) { + return { + top: comboBounds.top + comboBounds.height + extraHeight - positionRelativeElementRect.top, + adaptHeight: viewportBounds.height - comboBounds.top - comboBounds.height - extraHeight, + }; + } + if (popupBounds.height + extraHeight > viewportBounds.height) { + return { + top: extraHeight - positionRelativeElementRect.top, + adaptHeight: viewportBounds.height - extraHeight, + }; + } + + return { + top: viewportBounds.height - popupBounds.height - extraHeight - positionRelativeElementRect.top, + }; +} + +export function getCenterAdaptPosition(combo, popup, positionRelativeElement) { + const comboRect = combo.element[0].getBoundingClientRect(), + popupRect = popup.element[0].getBoundingClientRect(), + positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + let left; + if (comboRect.left + comboRect.width / 2 + popupRect.width / 2 > viewportBounds.width) { + left = viewportBounds.width - popupRect.width - positionRelativeElementRect.left; + } else { + left = comboRect.left + (comboRect.width - popupRect.width) / 2 - positionRelativeElementRect.left; + } + if (left + positionRelativeElementRect.left < 0) { + left = 0; + } + + return { + left, + }; +} + +export function getMiddleAdaptPosition(combo, popup, positionRelativeElement) { + const comboRect = combo.element[0].getBoundingClientRect(), + popupRect = popup.element[0].getBoundingClientRect(), + positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), + viewportBounds = document.documentElement.getBoundingClientRect(); + + let top; + if (comboRect.top + comboRect.height / 2 + popupRect.height / 2 > viewportBounds.height) { + top = viewportBounds.height - popupRect.height - positionRelativeElementRect.top; + } else { + top = comboRect.top + (comboRect.height - popupRect.height) / 2 - positionRelativeElementRect.top; + } + if (top + positionRelativeElementRect.top < 0) { + top = 0; + } + + return { + top, + }; +} + +export function getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, container) { + extraWidth || (extraWidth = 0); + extraHeight || (extraHeight = 0); + let i, direct; + const leftRight = [], topBottom = [], innerLeftRight = []; + let isNeedAdaptHeight = false, tbFirst = false, lrFirst = false; + let left, top, pos, firstDir = directions[0]; + for (i = 0; i < directions.length; i++) { + direct = directions[i]; + switch (direct) { + case "left": + leftRight.push(direct); + break; + case "right": + leftRight.push(direct); + break; + case "top": + topBottom.push(direct); + break; + case "bottom": + topBottom.push(direct); + break; + case "innerLeft": + innerLeftRight.push(direct); + break; + case "innerRight": + innerLeftRight.push(direct); + break; + default: + break; + } + } + for (i = 0; i < directions.length; i++) { + let tW, tH; + direct = directions[i]; + switch (direct) { + case "left": + if (!isNeedAdaptHeight) { + tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; + if (isLeftSpaceEnough(combo, popup, tW)) { + left = getLeftPosition(combo, popup, tW, container).left; + if (topBottom[0] === "bottom") { + pos = getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); + } else { + pos = getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); + } + pos.dir = `left,${pos.dir}`; + if (tbFirst) { + pos.change = "left"; + } + pos.left = left; + + return pos; + } + } + lrFirst = true; + break; + case "right": + if (!isNeedAdaptHeight) { + tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; + if (isRightSpaceEnough(combo, popup, tW)) { + left = getRightPosition(combo, popup, tW, container).left; + if (topBottom[0] === "bottom") { + pos = getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); + } else { + pos = getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); + } + pos.dir = `right,${pos.dir}`; + if (tbFirst) { + pos.change = "right"; + } + pos.left = left; + + return pos; + } + } + lrFirst = true; + break; + case "top": + tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; + if (isTopSpaceEnough(combo, popup, tH)) { + top = getTopPosition(combo, popup, tH, container).top; + if (leftRight[0] === "right") { + pos = getLeftAlignPosition(combo, popup, tW, container); + } else { + pos = getRightAlignPosition(combo, popup, tW, container); + } + pos.dir = `top,${pos.dir}`; + if (lrFirst) { + pos.change = "top"; + } + pos.top = top; + + return pos; + } + if (needAdaptHeight) { + isNeedAdaptHeight = true; + } + tbFirst = true; + break; + case "bottom": + tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; + if (isBottomSpaceEnough(combo, popup, tH)) { + top = getBottomPosition(combo, popup, tH, container).top; + if (leftRight[0] === "right") { + pos = getLeftAlignPosition(combo, popup, tW, container); + } else { + pos = getRightAlignPosition(combo, popup, tW, container); + } + pos.dir = `bottom,${pos.dir}`; + if (lrFirst) { + pos.change = "bottom"; + } + pos.top = top; + + return pos; + } + if (needAdaptHeight) { + isNeedAdaptHeight = true; + } + tbFirst = true; + break; + case "innerLeft": + if (!isNeedAdaptHeight) { + tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; + if (isInnerLeftSpaceEnough(combo, popup, tW)) { + left = getInnerLeftPosition(combo, popup, tW).left; + if (topBottom[0] === "bottom") { + pos = getTopAlignPosition(combo, popup, tH, needAdaptHeight); + } else { + pos = getBottomAlignPosition(combo, popup, tH, needAdaptHeight); + } + pos.dir = `innerLeft,${pos.dir}`; + if (tbFirst) { + pos.change = "innerLeft"; + } + pos.left = left; + + return pos; + } + } + lrFirst = true; + break; + case "innerRight": + if (!isNeedAdaptHeight) { + tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; + if (isInnerRightSpaceEnough(combo, popup, tW)) { + left = getInnerRightPosition(combo, popup, tW).left; + if (topBottom[0] === "bottom") { + pos = getTopAlignPosition(combo, popup, tH, needAdaptHeight); + } else { + pos = getBottomAlignPosition(combo, popup, tH, needAdaptHeight); + } + pos.dir = `innerLeft,${pos.dir}`; + if (tbFirst) { + pos.change = "innerRight"; + } + pos.left = left; + + return pos; + } + } + break; + default: + break; + } + } + + // 此处为四个方向放不下时挑空间最大的方向去放置, 也就是说我设置了弹出方向为"bottom,left", + // 最后发现实际弹出方向可能是"top,left",那么此时外界获取popup的方向应该是"top,left" + switch (directions[0]) { + case "left": + case "right": + if (isRightSpaceLarger(combo)) { + left = getRightAdaptPosition(combo, popup, extraWidth, container).left; + firstDir = "right"; + } else { + left = getLeftAdaptPosition(combo, popup, extraWidth, container).left; + firstDir = "left"; + } + if (topBottom[0] === "bottom") { + pos = getTopAlignPosition(combo, popup, extraHeight, needAdaptHeight); + pos.left = left; + pos.dir = `${firstDir},${pos.dir}`; + + return pos; + } + pos = getBottomAlignPosition(combo, popup, extraHeight, needAdaptHeight); + pos.left = left; + pos.dir = `${firstDir},${pos.dir}`; + + return pos; + default : + if (isBottomSpaceLarger(combo)) { + top = getBottomAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; + firstDir = "bottom"; + } else { + top = getTopAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; + firstDir = "top"; + } + if (leftRight[0] === "right") { + pos = getLeftAlignPosition(combo, popup, extraWidth, container); + pos.top = top; + pos.dir = `${firstDir},${pos.dir}`; + + return pos; + } + pos = getRightAlignPosition(combo, popup, extraWidth, container); + pos.top = top; + pos.dir = `${firstDir},${pos.dir}`; + + return pos; + } +} + + +export function getComboPosition(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, offsetStyle, positionRelativeElement) { + extraWidth || (extraWidth = 0); + extraHeight || (extraHeight = 0); + const viewportBounds = document.documentElement.getBoundingClientRect(); + const maxHeight = Math.min(popup.attr("maxHeight") || viewportBounds.height, viewportBounds.height); + popup.resetHeight && popup.resetHeight(maxHeight); + const position = getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions || ["bottom", "top", "right", "left"], positionRelativeElement); + switch (offsetStyle) { + case "center": + if (position.change) { + const p = getMiddleAdaptPosition(combo, popup, positionRelativeElement); + position.top = p.top; + } else { + const p = getCenterAdaptPosition(combo, popup, positionRelativeElement); + position.left = p.left; + } + break; + case "middle": + if (position.change) { + const p = getCenterAdaptPosition(combo, popup, positionRelativeElement); + position.left = p.left; + } else { + const p = getMiddleAdaptPosition(combo, popup, positionRelativeElement); + position.top = p.top; + } + break; + default: + break; + } + if (needAdaptHeight === true) { + popup.resetHeight && popup.resetHeight(Math.min(viewportBounds.height - position.top - (positionRelativeElement ? positionRelativeElement.getBoundingClientRect().top : 0), maxHeight)); + } + + return position; +} + +/** + * 获取position:fixed相对定位的元素 + */ +export function getPositionRelativeContainingBlock(element) { + if (isIE() || ["html", "body", "#document"].indexOf((element.nodeName || "").toLowerCase()) >= 0) { + // $FlowFixMe[incompatible-return]: assume body is always available + return element.ownerDocument.body; + } + + function isExcept(node) { + const _computedStyle = getComputedStyle(node); + const transform = _computedStyle.transform; + const perspective = _computedStyle.perspective; + const filter = _computedStyle.filter; + const willChange = _computedStyle["will-change"]; + + return [transform, perspective, filter].some(value => value !== "none") || (willChange === "transform"); + } + + if (isExcept(element)) { + return element; + } + + return getPositionRelativeContainingBlock(element.parentNode); +} + +/** + * 获取position:fixed相对定位的元素的clientRect + */ +export function getPositionRelativeContainingBlockRect(element) { + const positionRelativeElement = getPositionRelativeContainingBlock(element); + const rect = positionRelativeElement.getBoundingClientRect(); + const { top, right, bottom, left, width, height, x, y } = positionRelativeElement.getBoundingClientRect(); + + return { + top, right, bottom, left, width, height, x, y, + scaleX: rect.width / positionRelativeElement.offsetWidth, + scaleY: rect.height / positionRelativeElement.offsetHeight, + }; +} diff --git a/packages/fineui/src/core/utils/events/eventlistener.js b/packages/fineui/src/core/utils/events/eventlistener.js new file mode 100644 index 000000000..b8067c114 --- /dev/null +++ b/packages/fineui/src/core/utils/events/eventlistener.js @@ -0,0 +1,42 @@ +import { emptyFn } from "../../constant"; + +export const EventListener = { + listen: function listen (target, eventType, callback) { + if (target.addEventListener) { + target.addEventListener(eventType, callback, false); + + return { + remove: function remove () { + target.removeEventListener(eventType, callback, false); + }, + }; + } else if (target.attachEvent) { + target.attachEvent(`on${eventType}`, callback); + + return { + remove: function remove () { + target.detachEvent(`on${eventType}`, callback); + }, + }; + } + }, + + capture: function capture (target, eventType, callback) { + if (target.addEventListener) { + target.addEventListener(eventType, callback, true); + + return { + remove: function remove () { + target.removeEventListener(eventType, callback, true); + }, + }; + } + + return { + remove: emptyFn, + }; + }, + + registerDefault: function registerDefault () { + }, +}; diff --git a/packages/fineui/src/core/utils/events/index.js b/packages/fineui/src/core/utils/events/index.js new file mode 100644 index 000000000..9639166d4 --- /dev/null +++ b/packages/fineui/src/core/utils/events/index.js @@ -0,0 +1,3 @@ +export { EventListener } from "./eventlistener"; +export { MouseMoveTracker } from "./mousemovetracker"; +export { WheelHandler } from "./wheelhandler"; diff --git a/packages/fineui/src/core/utils/events/mousemovetracker.js b/packages/fineui/src/core/utils/events/mousemovetracker.js new file mode 100644 index 000000000..ea25782ae --- /dev/null +++ b/packages/fineui/src/core/utils/events/mousemovetracker.js @@ -0,0 +1,108 @@ +import { EventListener } from "./eventlistener"; +import { bind } from "../../2.base"; +import { _global } from "../../0.foundation"; + +const cancelAnimationFrame = + _global.cancelAnimationFrame || + _global.webkitCancelAnimationFrame || + _global.mozCancelAnimationFrame || + _global.oCancelAnimationFrame || + _global.msCancelAnimationFrame || + _global.clearTimeout; + +const requestAnimationFrame = _global.requestAnimationFrame || _global.webkitRequestAnimationFrame || _global.mozRequestAnimationFrame || _global.oRequestAnimationFrame || _global.msRequestAnimationFrame || _global.setTimeout; + +export class MouseMoveTracker { + constructor(onMove, onMoveEnd, domNode) { + this._isDragging = false; + this._animationFrameID = null; + this._domNode = domNode; + this._onMove = onMove; + this._onMoveEnd = onMoveEnd; + + this._onMouseMove = bind(this._onMouseMove, this); + this._onMouseUp = bind(this._onMouseUp, this); + this._didMouseMove = bind(this._didMouseMove, this); + } + + captureMouseMoves(event) { + if (!this._eventMoveToken && !this._eventUpToken) { + this._eventMoveToken = EventListener.listen( + this._domNode, + "mousemove", + this._onMouseMove + ); + this._eventUpToken = EventListener.listen( + this._domNode, + "mouseup", + this._onMouseUp + ); + } + + if (!this._isDragging) { + this._deltaX = 0; + this._deltaY = 0; + this._isDragging = true; + this._x = event.clientX; + this._y = event.clientY; + } + // event.preventDefault ? event.preventDefault() : (event.returnValue = false); + } + + releaseMouseMoves() { + if (this._eventMoveToken && this._eventUpToken) { + this._eventMoveToken.remove(); + this._eventMoveToken = null; + this._eventUpToken.remove(); + this._eventUpToken = null; + } + + if (this._animationFrameID !== null) { + cancelAnimationFrame(this._animationFrameID); + this._animationFrameID = null; + } + + if (this._isDragging) { + this._isDragging = false; + this._x = null; + this._y = null; + } + } + + isDragging() /* boolean*/ { + return this._isDragging; + } + + _onMouseMove(/* object*/ event) { + const x = event.clientX; + const y = event.clientY; + + this._deltaX += (x - this._x); + this._deltaY += (y - this._y); + + if (this._animationFrameID === null) { + // The mouse may move faster then the animation frame does. + // Use `requestAnimationFrame` to avoid over-updating. + this._animationFrameID = + requestAnimationFrame(() => this._didMouseMove(event)); + } + + this._x = x; + this._y = y; + event.preventDefault ? event.preventDefault() : (event.returnValue = false); + } + + _didMouseMove(event) { + this._animationFrameID = null; + this._onMove(this._deltaX, this._deltaY, event); + this._deltaX = 0; + this._deltaY = 0; + } + + _onMouseUp(event) { + if (this._animationFrameID) { + this._didMouseMove(event); + } + this._onMoveEnd(event); + } +} diff --git a/packages/fineui/src/core/utils/events/wheelhandler.js b/packages/fineui/src/core/utils/events/wheelhandler.js new file mode 100644 index 000000000..abae9a308 --- /dev/null +++ b/packages/fineui/src/core/utils/events/wheelhandler.js @@ -0,0 +1,132 @@ +import { bind } from "../../2.base"; +import { _global } from "../../0.foundation"; + +const PIXEL_STEP = 10; +const LINE_HEIGHT = 40; +const PAGE_HEIGHT = 800; +const requestAnimationFrame = _global.requestAnimationFrame || _global.webkitRequestAnimationFrame || _global.mozRequestAnimationFrame || _global.oRequestAnimationFrame || _global.msRequestAnimationFrame || _global.setTimeout; + +function normalizeWheel (/* object*/event) /* object*/ { + let sX = 0, + sY = 0, + // spinX, spinY + pX = 0, + pY = 0; // pixelX, pixelY + + // Legacy + if ("detail" in event) { + sY = event.detail; + } + if ("wheelDelta" in event) { + sY = -event.wheelDelta / 120; + } + if ("wheelDeltaY" in event) { + sY = -event.wheelDeltaY / 120; + } + if ("wheelDeltaX" in event) { + sX = -event.wheelDeltaX / 120; + } + + // side scrolling on FF with DOMMouseScroll + if ("axis" in event && event.axis === event.HORIZONTAL_AXIS) { + sX = sY; + sY = 0; + } + + pX = sX * PIXEL_STEP; + pY = sY * PIXEL_STEP; + + if ("deltaY" in event) { + pY = event.deltaY; + } + if ("deltaX" in event) { + pX = event.deltaX; + } + + if ((pX || pY) && event.deltaMode) { + if (event.deltaMode === 1) { + // delta in LINE units + pX *= LINE_HEIGHT; + pY *= LINE_HEIGHT; + } else { + // delta in PAGE units + pX *= PAGE_HEIGHT; + pY *= PAGE_HEIGHT; + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { + sX = pX < 1 ? -1 : 1; + } + if (pY && !sY) { + sY = pY < 1 ? -1 : 1; + } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY, + }; +} + +export class WheelHandler { + constructor(onWheel, handleScrollX, handleScrollY, stopPropagation) { + this._animationFrameID = null; + this._deltaX = 0; + this._deltaY = 0; + this._didWheel = bind(this._didWheel, this); + if (typeof handleScrollX !== "function") { + handleScrollX = handleScrollX ? () => true : () => false; + } + + if (typeof handleScrollY !== "function") { + handleScrollY = handleScrollY ? () => true : () => false; + } + + if (typeof stopPropagation !== "function") { + stopPropagation = stopPropagation ? () => true : () => false; + } + + this._handleScrollX = handleScrollX; + this._handleScrollY = handleScrollY; + this._stopPropagation = stopPropagation; + this._onWheelCallback = onWheel; + this.onWheel = bind(this.onWheel, this); + } + + onWheel(event) { + const normalizedEvent = normalizeWheel(event); + const deltaX = this._deltaX + normalizedEvent.pixelX; + const deltaY = this._deltaY + normalizedEvent.pixelY; + const handleScrollX = this._handleScrollX(deltaX, deltaY); + const handleScrollY = this._handleScrollY(deltaY, deltaX); + if (!handleScrollX && !handleScrollY) { + return; + } + + this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0; + this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0; + event.preventDefault ? event.preventDefault() : (event.returnValue = false); + + let changed; + if (this._deltaX !== 0 || this._deltaY !== 0) { + if (this._stopPropagation()) { + event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true); + } + changed = true; + } + + if (changed === true && this._animationFrameID === null) { + this._animationFrameID = requestAnimationFrame(this._didWheel); + } + } + + _didWheel() { + this._animationFrameID = null; + this._onWheelCallback(this._deltaX, this._deltaY); + this._deltaX = 0; + this._deltaY = 0; + } +} diff --git a/packages/fineui/src/core/utils/i18n.js b/packages/fineui/src/core/utils/i18n.js new file mode 100644 index 000000000..3f085f6fc --- /dev/null +++ b/packages/fineui/src/core/utils/i18n.js @@ -0,0 +1,51 @@ +import { extend } from "../2.base"; +import { replaceAll } from "../func"; + +let i18nStore = {}; +const i18nFormatters = {}; + +export function changeI18n(i18n) { + if (i18n) { + i18nStore = i18n; + } +} + +export function addI18n(i18n) { + extend(i18nStore, i18n); +} + +export function i18nText(key) { + const globalI18nStore = _global?.BI?.i18n || {}; + let localeText = i18nStore[key] || globalI18nStore[key] || ""; + if (!localeText) { + localeText = key; + } + const len = arguments.length; + if (len > 1) { + if (localeText.indexOf("{R1") > -1) { + for (let i = 1; i < len; i++) { + const reg = new RegExp(`{R${i},(.*?)}`, "g"); + + const result = reg.exec(localeText); + + if (result) { + const formatName = result[1]; + localeText = replaceAll(localeText, reg, i18nFormatters[formatName](key, arguments[i])); + } else { + localeText = replaceAll(localeText, `{R${i}}`, `${arguments[i]}`); + } + } + } else { + const args = Array.prototype.slice.call(arguments); + let count = 1; + + return replaceAll(localeText, "\\{\\s*\\}", () => `${args[count++]}`); + } + } + + return localeText; +} + +export function addI18nFormatter(formatName, fn) { + i18nFormatters[formatName] = fn; +} diff --git a/packages/fineui/src/core/utils/index.js b/packages/fineui/src/core/utils/index.js new file mode 100644 index 000000000..d01e65bbc --- /dev/null +++ b/packages/fineui/src/core/utils/index.js @@ -0,0 +1,12 @@ +export * from "./events"; +export * from "./i18n"; +export { makeFirstPY } from "./chinesePY"; + +import * as platformDom from "./dom"; +import * as colorDom from "./color"; + + +export const DOM = { + ...platformDom, + ...colorDom, +}; diff --git a/packages/fineui/src/core/version.js b/packages/fineui/src/core/version.js new file mode 100644 index 000000000..6900e8235 --- /dev/null +++ b/packages/fineui/src/core/version.js @@ -0,0 +1,2 @@ +// BI.version = "2.0"; +export const version = "2.0" \ No newline at end of file diff --git a/packages/fineui/src/core/worker.js b/packages/fineui/src/core/worker.js new file mode 100644 index 000000000..643e77e1a --- /dev/null +++ b/packages/fineui/src/core/worker.js @@ -0,0 +1,54 @@ +import { isPlainObject, extend, each, isArray } from "./2.base"; +import { Models } from "./5.inject"; + +export function useInWorker () { + function createWatcher (model, keyOrFn, cb, options) { + if (isPlainObject(cb)) { + options = cb; + cb = cb.handler; + } + options = options || {}; + + return Fix.watch(model, keyOrFn, cb, extend(options, { + store: model, + })); + } + + const models = {}, watches = {}; + addEventListener("message", e => { + const data = e.data; + let store; + switch (data.eventType) { + case "action": + models[data.name][data.action](...data.args); + break; + case "destroy": + each(watches[data.name], (i, unwatches) => { + unwatches = isArray(unwatches) ? unwatches : [unwatches]; + each(unwatches, (j, unwatch) => { + unwatch(); + }); + }); + delete models[data.name]; + delete watches[data.name]; + break; + case "create": + store = models[data.name] = Models.getModel(data.type, data.options); + watches[data.name] = []; + each(data.watches, (i, key) => { + watches[data.name].push(createWatcher(store.model, key, (newValue, oldValue) => { + postMessage(extend({}, data, { + eventType: "watch", + currentWatchType: key, + }, { args: [newValue, oldValue] })); + })); + }); + postMessage(extend({}, data, { + eventType: "create", + }, { msg: store.model })); + break; + default: + break; + } + }, false); +} diff --git a/packages/fineui/src/core/wrapper/index.js b/packages/fineui/src/core/wrapper/index.js new file mode 100644 index 000000000..0e7310cd2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/index.js @@ -0,0 +1,2 @@ +export { Layout } from "./layout.js"; +export * from "./layout/index"; diff --git a/packages/fineui/src/core/wrapper/layout.js b/packages/fineui/src/core/wrapper/layout.js new file mode 100644 index 000000000..288d586eb --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout.js @@ -0,0 +1,821 @@ +import { isNull, isFunction, each, stripEL, keys, isArray, contains, isKey, isOdd, isWidget, isNotNull, has } from "../2.base"; +import { Widget } from "../4.widget"; +import { _lazyCreateWidget, Providers } from "../5.inject"; +import { shortcut } from "../decorator"; +import { pixFormat, Events } from "../constant"; +import { SystemProvider } from "../system"; + +/** + * 布局容器类 + * + * @cfg {JSON} options 配置属性 + * @cfg {Boolean} [options.scrollable=false] 子组件超出容器边界之后是否会出现滚动条 + * @cfg {Boolean} [options.scrollx=false] 子组件超出容器边界之后是否会出现横向滚动条 + * @cfg {Boolean} [options.scrolly=false] 子组件超出容器边界之后是否会出现纵向滚动条 + */ +@shortcut() +export class Layout extends Widget { + static xtype = "bi.layout"; + + props() { + return { + scrollable: null, // true, false, null + scrollx: false, // true, false + scrolly: false, // true, false + items: [], + innerHgap: 0, + innerVgap: 0, + }; + } + + render() { + const o = this.options; + this._init4Margin(); + this._init4Scroll(); + if (isFunction(o.columnSize)) { + const columnSizeFn = o.columnSize; + o.columnSize = this.__watch(columnSizeFn, (context, newValue) => { + o.columnSize = newValue; + this.resize(); + }); + } + if (isFunction(o.rowSize)) { + const rowSizeFn = o.rowSize; + o.rowSize = this.__watch(rowSizeFn, (context, newValue) => { + o.rowSize = newValue; + this.resize(); + }); + } + } + + _init4Margin() { + if (this.options.top) { + this.element.css("top", pixFormat(this.options.top)); + } + if (this.options.left) { + this.element.css("left", pixFormat(this.options.left)); + } + if (this.options.bottom) { + this.element.css("bottom", pixFormat(this.options.bottom)); + } + if (this.options.right) { + this.element.css("right", pixFormat(this.options.right)); + } + } + + _init4Scroll() { + switch (this.options.scrollable) { + case true: + case "xy": + this.element.css("overflow", "auto"); + + return; + case false: + this.element.css("overflow", "hidden"); + + return; + case "x": + this.element.css({ + "overflow-x": "auto", + "overflow-y": "hidden", + }); + + return; + case "y": + this.element.css({ + "overflow-x": "hidden", + "overflow-y": "auto", + }); + + return; + default : + break; + } + if (this.options.scrollx) { + this.element.css({ + "overflow-x": "auto", + "overflow-y": "hidden", + }); + + return; + } + if (this.options.scrolly) { + this.element.css({ + "overflow-x": "hidden", + "overflow-y": "auto", + }); + } + } + + appendFragment(frag) { + this.element.append(frag); + } + + _mountChildren() { + const frag = Widget._renderEngine.createFragment(); + let hasChild = false; + for (const key in this._children) { + const child = this._children[key]; + if (child.element !== this.element) { + frag.appendChild(child.element[0]); + hasChild = true; + } + } + if (hasChild === true) { + this.appendFragment(frag); + } + } + + _getChildName(index) { + return `${index}`; + } + + _addElement(i, item, context, widget) { + let w; + if (widget) { + return widget; + } + if (!this.hasWidget(this._getChildName(i))) { + w = _lazyCreateWidget(item, context); + w.on(Events.DESTROY, () => { + each(this._children, (name, child) => { + if (child === w) { + delete this._children[name]; + this.removeItemAt(name | 0); + } + }); + }); + this.addWidget(this._getChildName(i), w); + } else { + w = this.getWidgetByName(this._getChildName(i)); + } + + return w; + } + + _newElement(i, item, context) { + const w = _lazyCreateWidget(item, context); + w.on(Events.DESTROY, () => { + each(this._children, (name, child) => { + if (child === w) { + delete this._children[name]; + this.removeItemAt(name | 0); + } + }); + }); + + return this._addElement(i, item, context, w); + } + + _getOptions(item) { + if (item instanceof Widget) { + item = item.options; + } + item = stripEL(item); + if (item instanceof Widget) { + item = item.options; + } + + return item; + } + + _compare(item1, item2) { + // 不比较函数 + const eq = (a, b, aStack, bStack) => { + if (a === b) { + return a !== 0 || 1 / a === 1 / b; + } + if (isNull(a) || isNull(b)) { + return a === b; + } + const className = Object.prototype.toString.call(a); + switch (className) { + case "[object RegExp]": + case "[object String]": + return `${a}` === `${b}`; + case "[object Number]": + if (+a !== +a) { + return +b !== +b; + } + + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case "[object Date]": + case "[object Boolean]": + return +a === +b; + default: + } + + const areArrays = className === "[object Array]"; + if (!areArrays) { + if (isFunction(a) && isFunction(b)) { + return true; + } + a = this._getOptions(a); + b = this._getOptions(b); + } + + aStack = aStack || []; + bStack = bStack || []; + let length = aStack.length; + while (length--) { + if (aStack[length] === a) { + return bStack[length] === b; + } + } + + aStack.push(a); + bStack.push(b); + + if (areArrays) { + length = a.length; + if (length !== b.length) { + return false; + } + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) { + return false; + } + } + } else { + const aKeys = keys(a); + let key; + length = aKeys.length; + if (keys(b).length !== length) { + return false; + } + while (length--) { + key = aKeys[length]; + if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) { + return false; + } + } + } + aStack.pop(); + bStack.pop(); + + return true; + }; + + return eq(item1, item2); + } + + _getWrapper() { + return this.element; + } + + // 不依赖于this.options.items进行更新 + _updateItemAt(oldIndex, newIndex, item) { + const del = this._children[this._getChildName(oldIndex)]; + const w = this._newElement(newIndex, item); + // 需要有个地方临时存一下新建的组件,否则如果直接使用newIndex的话,newIndex位置的元素可能会被用到 + this._children[`${this._getChildName(newIndex)}-temp`] = w; + const nextSibling = del.element.next(); + if (nextSibling.length > 0) { + Widget._renderEngine.createElement(nextSibling).before(w.element); + } else { + w.element.appendTo(this._getWrapper()); + } + del._destroy(); + w._mount(); + + return true; + } + + _addItemAt(index, item) { + for (let i = this.options.items.length; i > index; i--) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i - 1)]; + } + delete this._children[this._getChildName(index)]; + this.options.items.splice(index, 0, item); + } + + _removeItemAt(index) { + for (let i = index; i < this.options.items.length - 1; i++) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i + 1)]; + } + delete this._children[this._getChildName(this.options.items.length - 1)]; + this.options.items.splice(index, 1); + } + + _clearGap(w) { + w.element.css({ + "margin-top": "", + "margin-bottom": "", + "margin-left": "", + "margin-right": "", + }); + } + + _optimiseGap(gap) { + return (gap > 0 && gap < 1) ? `${(gap * 100).toFixed(1)}%` : pixFormat(gap); + } + + _optimiseItemLgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._lgap || 0) + (item.lgap || 0)) : item._lgap) || 0; + } + + return (item._lgap || 0) + (item.lgap || 0); + } + _optimiseItemRgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._rgap || 0) + (item.rgap || 0)) : item._rgap) || 0; + } + + return (item._rgap || 0) + (item.rgap || 0); + } + _optimiseItemTgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._tgap || 0) + (item.tgap || 0)) : item._tgap) || 0; + } + + return (item._tgap || 0) + (item.tgap || 0); + } + _optimiseItemBgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._bgap || 0) + (item.bgap || 0)) : item._bgap) || 0; + } + + return (item._bgap || 0) + (item.bgap || 0); + } + _optimiseItemHgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._hgap || 0) + (item.hgap || 0)) : item._hgap) || 0; + } + + return (item._hgap || 0) + (item.hgap || 0); + } + _optimiseItemVgap(item) { + if (Providers.getProvider(SystemProvider.xtype).getLayoutOptimize()) { + return ((!item.type && item.el) ? ((item._vgap || 0) + (item.vgap || 0)) : item._vgap) || 0; + } + + return (item._vgap || 0) + (item.vgap || 0); + } + + _handleGap(w, item, hIndex, vIndex) { + const o = this.options; + let innerLgap, innerRgap, innerTgap, innerBgap; + if (isNull(vIndex)) { + innerTgap = innerBgap = o.innerVgap; + innerLgap = hIndex === 0 ? o.innerHgap : 0; + innerRgap = hIndex === o.items.length - 1 ? o.innerHgap : 0; + } else { + innerLgap = innerRgap = o.innerHgap; + innerTgap = vIndex === 0 ? o.innerVgap : 0; + innerBgap = vIndex === o.items.length - 1 ? o.innerVgap : 0; + } + if (o.vgap + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + const top = ((isNull(vIndex) || vIndex === 0) ? o.vgap : 0) + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-top": this._optimiseGap(top), + }); + } + if (o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + const left = ((isNull(hIndex) || hIndex === 0) ? o.hgap : 0) + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-left": this._optimiseGap(left), + }); + } + if (o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + const right = o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-right": this._optimiseGap(right), + }); + } + if (o.vgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + const bottom = o.vgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-bottom": this._optimiseGap(bottom), + }); + } + } + + // 横向换纵向 + _handleReverseGap(w, item, index) { + const o = this.options; + const innerLgap = o.innerHgap; + const innerRgap = o.innerHgap; + const innerTgap = index === 0 ? o.innerVgap : 0; + const innerBgap = index === o.items.length - 1 ? o.innerVgap : 0; + if (o.vgap + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + const top = (index === 0 ? o.vgap : 0) + (index === 0 ? o.tgap : 0) + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-top": this._optimiseGap(top), + }); + } + if (o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + const left = o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-left": this._optimiseGap(left), + }); + } + if (o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + const right = o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-right": this._optimiseGap(right), + }); + } + // 这里的代码是关键 + if (o.vgap + o.hgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + const bottom = (index === o.items.length - 1 ? o.vgap : o.hgap) + (index === o.items.length - 1 ? o.bgap : 0) + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-bottom": this._optimiseGap(bottom), + }); + } + } + + /** + * 添加一个子组件到容器中 + * @param {JSON/Widget} item 子组件 + */ + addItem(item) { + return this.addItemAt(this.options.items.length, item); + } + + prependItem(item) { + return this.addItemAt(0, item); + } + + addItemAt(index, item) { + if (index < 0 || index > this.options.items.length) { + return; + } + this._addItemAt(index, item); + const w = this._addElement(index, item); + // addItemAt 还是用之前的找上个兄弟节点向后插入的方式 + if (index > 0) { + this._children[this._getChildName(index - 1)].element.after(w.element); + } else { + w.element.prependTo(this._getWrapper()); + } + w._mount(); + + return w; + } + + removeItemAt(indexes) { + indexes = isArray(indexes) ? indexes : [indexes]; + const deleted = []; + const newItems = [], newChildren = {}; + for (let i = 0, len = this.options.items.length; i < len; i++) { + const child = this._children[this._getChildName(i)]; + if (contains(indexes, i)) { + child && deleted.push(child); + } else { + newChildren[this._getChildName(newItems.length)] = child; + newItems.push(this.options.items[i]); + } + } + this.options.items = newItems; + this._children = newChildren; + each(deleted, (i, c) => { + c._destroy(); + }); + } + + shouldUpdateItem(index, item) { + const child = this._children[this._getChildName(index)]; + if (!child || !child.shouldUpdate) { + return null; + } + + return child.shouldUpdate(this._getOptions(item)); + } + + addItems(items, context) { + const o = this.options; + const fragment = Widget._renderEngine.createFragment(); + const added = []; + each(items, (i, item) => { + const w = this._addElement(o.items.length, item, context); + this._children[this._getChildName(o.items.length)] = w; + o.items.push(item); + added.push(w); + fragment.appendChild(w.element[0]); + }); + if (this._isMounted) { + this._getWrapper().append(fragment); + each(added, (i, w) => { + w._mount(); + }); + } + } + + prependItems(items, context) { + items = items || []; + const fragment = Widget._renderEngine.createFragment(); + const added = []; + for (let i = items.length - 1; i >= 0; i--) { + this._addItemAt(0, items[i]); + const w = this._addElement(0, items[i], context); + this._children[this._getChildName(0)] = w; + this.options.items.unshift(items[i]); + added.push(w); + fragment.appendChild(w.element[0]); + } + if (this._isMounted) { + this._getWrapper().prepend(fragment); + each(added, (i, w) => { + w._mount(); + }); + } + } + + getValue() { + let value = [], child; + each(this.options.items, i => { + child = this._children[this._getChildName(i)]; + if (child) { + let v = child.getValue(); + v = isArray(v) ? v : [v]; + value = value.concat(v); + } + }); + + return value; + } + + setValue(v) { + let child; + each(this.options.items, i => { + child = this._children[this._getChildName(i)]; + child && child.setValue(v); + }); + } + + setText(v) { + let child; + each(this.options.items, i => { + child = this._children[this._getChildName(i)]; + child && child.setText(v); + }); + } + + patchItem(oldVnode, vnode, oldIndex, newIndex) { + const shouldUpdate = this.shouldUpdateItem(oldIndex, vnode); + const child = this._children[this._getChildName(oldIndex)]; + if (shouldUpdate) { + this._children[`${this._getChildName(newIndex)}-temp`] = child; + + return child._update(this._getOptions(vnode), shouldUpdate); + } + if (shouldUpdate === null && !this._compare(oldVnode, vnode)) { + // if (child.update) { + // return child.update(this._getOptions(vnode)); + // } + return this._updateItemAt(oldIndex, newIndex, vnode); + } + } + + updateChildren(oldCh, newCh, context) { + let oldStartIdx = 0, newStartIdx = 0; + let oldEndIdx = oldCh.length - 1; + let oldStartVnode = oldCh[0]; + let oldEndVnode = oldCh[oldEndIdx]; + let newEndIdx = newCh.length - 1; + let newStartVnode = newCh[0]; + let newEndVnode = newCh[newEndIdx]; + let before; + let updated; + const children = {}; + + const sameVnode = (vnode1, vnode2, oldIndex, newIndex) => { + vnode1 = this._getOptions(vnode1); + vnode2 = this._getOptions(vnode2); + if (isKey(vnode1.key)) { + return vnode1.key === vnode2.key; + } + if (oldIndex >= 0) { + return oldIndex === newIndex; + } + }; + + const addNode = (vnode, index, context) => { + const opt = this._getOptions(vnode); + const key = isNull(opt.key) ? index : opt.key; + children[key] = this._newElement(index, vnode, context); + + return children[key]; + }; + + const addVnodes = (before, vnodes, startIdx, endIdx, context) => { + for (; startIdx <= endIdx; ++startIdx) { + const node = addNode(vnodes[startIdx], startIdx, context); + insertBefore(node, before, false, startIdx); + } + }; + + const removeVnodes = (vnodes, startIdx, endIdx) => { + for (; startIdx <= endIdx; ++startIdx) { + const ch = vnodes[startIdx]; + if (isNotNull(ch)) { + const node = this._getOptions(ch); + const key = isNull(node.key) ? startIdx : node.key; + children[key]._destroy(); + } + } + }; + + const insertBefore = (insert, before, isNext, index) => { + insert = this._getOptions(insert); + before = before && this._getOptions(before); + const insertKey = isKey(insert.key) ? insert.key : index; + if (before && children[before.key]) { + const beforeKey = isKey(before.key) ? before.key : index; + let next; + if (isNext) { + next = children[beforeKey].element.next(); + } else { + next = children[beforeKey].element; + } + if (next.length > 0) { + next.before(children[insertKey].element); + } else { + this._getWrapper().append(children[insertKey].element); + } + } else { + this._getWrapper().append(children[insertKey].element); + } + }; + + const findOldVnode = (vnodes, vNode, beginIdx, endIdx) => { + let i, found, findIndex; + for (i = beginIdx; i <= endIdx; ++i) { + if (vnodes[i] && sameVnode(vnodes[i], vNode)) { + found = vnodes[i]; + findIndex = i; + } + } + + return [found, findIndex]; + }; + + each(oldCh, (i, child) => { + child = this._getOptions(child); + const key = isNull(child.key) ? i : child.key; + if (isKey(key)) { + children[key] = this._children[this._getChildName(i)]; + } + }); + + while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { + if (isNull(oldStartVnode)) { + oldStartVnode = oldCh[++oldStartIdx]; + } else if (isNull(oldEndVnode)) { + oldEndVnode = oldCh[--oldEndIdx]; + } else if (sameVnode(oldStartVnode, newStartVnode, oldStartIdx, newStartIdx)) { + const willUpdate = this.patchItem(oldStartVnode, newStartVnode, oldStartIdx, newStartIdx); + updated = willUpdate || updated; + children[isNull(oldStartVnode.key) ? oldStartIdx : oldStartVnode.key] = willUpdate ? this._children[`${this._getChildName(newStartIdx)}-temp`] : this._children[this._getChildName(oldStartIdx)]; + oldStartVnode = oldCh[++oldStartIdx]; + newStartVnode = newCh[++newStartIdx]; + } else if (sameVnode(oldEndVnode, newEndVnode, oldEndIdx, newEndIdx)) { + const willUpdate = this.patchItem(oldEndVnode, newEndVnode, oldEndIdx, newEndIdx); + updated = willUpdate || updated; + children[isNull(oldEndVnode.key) ? oldEndIdx : oldEndVnode.key] = willUpdate ? this._children[`${this._getChildName(newEndIdx)}-temp`] : this._children[this._getChildName(oldEndIdx)]; + oldEndVnode = oldCh[--oldEndIdx]; + newEndVnode = newCh[--newEndIdx]; + } else if (sameVnode(oldStartVnode, newEndVnode)) { + const willUpdate = this.patchItem(oldStartVnode, newEndVnode, oldStartIdx, newStartIdx); + updated = willUpdate || updated; + children[isNull(oldStartVnode.key) ? oldStartIdx : oldStartVnode.key] = willUpdate ? this._children[`${this._getChildName(newStartIdx)}-temp`] : this._children[this._getChildName(oldStartIdx)]; + insertBefore(oldStartVnode, oldEndVnode, true); + oldStartVnode = oldCh[++oldStartIdx]; + newEndVnode = newCh[--newEndIdx]; + } else if (sameVnode(oldEndVnode, newStartVnode)) { + const willUpdate = this.patchItem(oldEndVnode, newStartVnode, oldEndIdx, newEndIdx); + updated = willUpdate || updated; + children[isNull(oldEndVnode) ? oldEndIdx : oldEndVnode.key] = willUpdate ? this._children[`${this._getChildName(newEndIdx)}-temp`] : this._children[this._getChildName(oldEndIdx)]; + insertBefore(oldEndVnode, oldStartVnode); + oldEndVnode = oldCh[--oldEndIdx]; + newStartVnode = newCh[++newStartIdx]; + } else { + const sameOldVnode = findOldVnode(oldCh, newStartVnode, oldStartIdx, oldEndIdx); + if (isNull(sameOldVnode[0])) { // 不存在就把新的放到左边 + const node = addNode(newStartVnode, newStartIdx, context); + insertBefore(node, oldStartVnode); + } else { // 如果新节点在旧节点区间中存在就复用一下 + const sameOldIndex = sameOldVnode[1]; + const willUpdate = this.patchItem(sameOldVnode[0], newStartVnode, sameOldIndex, newStartIdx); + updated = willUpdate || updated; + children[isNull(sameOldVnode[0].key) ? newStartIdx : sameOldVnode[0].key] = willUpdate ? this._children[`${this._getChildName(newStartIdx)}-temp`] : this._children[this._getChildName(sameOldIndex)]; + oldCh[sameOldIndex] = undefined; + insertBefore(sameOldVnode[0], oldStartVnode); + } + newStartVnode = newCh[++newStartIdx]; + } + } + if (oldStartIdx > oldEndIdx) { + before = isNull(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1]; + addVnodes(before, newCh, newStartIdx, newEndIdx, context); + } else if (newStartIdx > newEndIdx) { + removeVnodes(oldCh, oldStartIdx, oldEndIdx); + } + + this._children = {}; + each(newCh, (i, child) => { + const node = this._getOptions(child); + const key = isNull(node.key) ? i : node.key; + children[key]._setParent && children[key]._setParent(this); + children[key]._mount(); + this._children[this._getChildName(i)] = children[key]; + }); + + return updated; + } + + forceUpdate(opt) { + if (this._isMounted) { + each(this._children, (i, c) => { + c.destroy(); + }); + this._children = {}; + this._isMounted = false; + } + this.options.items = opt.items; + this.stroke(opt.items); + this._mount(); + } + + update(opt) { + const o = this.options; + const items = opt.items || []; + const context = opt.context; + const oldItems = o.items; + this.options.items = items; + + return this.updateChildren(oldItems, items, context); + } + + stroke(items, options) { + options = options || {}; + each(items, (i, item) => { + item && this._addElement(i, item, options.context); + }); + } + + getRowColumnCls(rowIndex, colIndex, lastRowIndex, lastColIndex) { + let cls = ""; + if (rowIndex === 0) { + cls += " first-row"; + } else if (rowIndex === lastRowIndex) { + cls += " last-row"; + } + if (colIndex === 0) { + cls += " first-col"; + } else if (colIndex === lastColIndex) { + cls += " last-col"; + } + isOdd(rowIndex + 1) ? (cls += " odd-row") : (cls += " even-row"); + isOdd(colIndex + 1) ? (cls += " odd-col") : (cls += " even-col"); + cls += " center-element"; + + return cls; + } + + removeWidget(nameOrWidget) { + let removeIndex; + if (isWidget(nameOrWidget)) { + each(this._children, (name, child) => { + if (child === nameOrWidget) { + removeIndex = name; + } + }); + } else { + removeIndex = nameOrWidget; + } + if (removeIndex) { + this._removeItemAt(removeIndex | 0); + } + } + + empty() { + super.empty(...arguments); + this.options.items = []; + } + + destroy() { + super.destroy(...arguments); + this.options.items = []; + } + + populate(items, options) { + items = items || []; + options = options || {}; + if (this._isMounted) { + this.update({ + items, + context: options.context, + }); + + return; + } + this.options.items = items; + this.stroke(items, options); + } + + resize() { + this.stroke(this.options.items); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/absolute.center.js b/packages/fineui/src/core/wrapper/layout/adapt/absolute.center.js new file mode 100644 index 000000000..126a9ec23 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/absolute.center.js @@ -0,0 +1,54 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend, isFunction } from "../../../2.base"; + +/** + * absolute实现的居中布局 + * @class AbsoluteCenterLayout + * @extends Layout + */ +@shortcut() +export class AbsoluteCenterLayout extends Layout { + static xtype ="bi.absolute_center_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-c-a", + hgap: 0, + lgap: 0, + rgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + w.element.css({ + position: "absolute", + left: this._optimiseGap(o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item)), + right: this._optimiseGap(o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item)), + top: this._optimiseGap(o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item)), + bottom: this._optimiseGap(o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item)), + margin: "auto", + }); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/absolute.horizontal.js b/packages/fineui/src/core/wrapper/layout/adapt/absolute.horizontal.js new file mode 100644 index 000000000..cedcfa334 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/absolute.horizontal.js @@ -0,0 +1,62 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { HorizontalAlign } from "../../../constant"; + +/** + * absolute实现的水平布局 + * @class AbsoluteHorizontalLayout + * @extends Layout + */ +@shortcut() +export class AbsoluteHorizontalLayout extends Layout { + static xtype = "bi.absolute_horizontal_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-h-a", + horizontalAlign: HorizontalAlign.Center, + rowSize: [], + hgap: 0, + lgap: 0, + rgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.vtape", + horizontalAlign: o.horizontalAlign, + rowSize: o.rowSize, + items: o.items, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + ref: _ref => { + this.layout = _ref; + }, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js b/packages/fineui/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js new file mode 100644 index 000000000..aec88d0ba --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js @@ -0,0 +1,175 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend, isArray, each, map, stripEL } from "../../../2.base"; +import { VerticalAlign } from "../../../constant"; + +@shortcut() +export class AbsoluteLeftRightVerticalAdaptLayout extends Layout { + static xtype = "bi.absolute_left_right_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-lr-v-a", + verticalAlign: VerticalAlign.Middle, + items: {}, + llgap: 0, + lrgap: 0, + lhgap: 0, + ltgap: 0, + lbgap: 0, + lvgap: 0, + rlgap: 0, + rrgap: 0, + rhgap: 0, + rtgap: 0, + rbgap: 0, + rvgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + items: this._formatItems(o.items), + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + _formatItems(items) { + const o = this.options; + let left, right; + if (isArray(items)) { + each(items, (i, item) => { + if (item.left) { + left = item.left; + } + if (item.right) { + right = item.right; + } + }); + } + let leftItems = left || items.left || []; + let rightItems = right || items.right || []; + leftItems = map(leftItems, (i, item) => { + const json = { + el: stripEL(item), + width: item.width, + }; + if (o.lvgap + o.ltgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + json.tgap = o.lvgap + o.ltgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + } + if (o.lhgap + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + } + if (o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + json.rgap = o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + } + if (o.lvgap + o.lbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + json.bgap = o.lvgap + o.lbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + } + + return json; + }); + rightItems = map(rightItems, (i, item) => { + const json = { + el: stripEL(item), + width: item.width, + }; + if (o.rvgap + o.rtgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + json.tgap = o.rvgap + o.rtgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + } + if (o.rhgap + o.rlgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + json.lgap = (i === 0 ? o.rhgap : 0) + o.rlgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + } + if (o.rhgap + o.rrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + json.rgap = o.rhgap + o.rrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + } + if (o.rvgap + o.rbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + json.bgap = o.rvgap + o.rbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + } + + return json; + }); + + return leftItems.concat({}, rightItems); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} + +@shortcut() +export class AbsoluteRightVerticalAdaptLayout extends Layout { + static xtype = "bi.absolute_right_vertical_adapt"; + + props () { + return extend(super.props(...arguments), { + baseCls: "bi-abs-r-v-a", + verticalAlign: VerticalAlign.Middle, + items: [], + lgap: 0, + rgap: 0, + hgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + }); + } + + render () { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + items: [{}].concat(o.items), + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + vgap: o.vgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + resize () { + this.layout.stroke([{}].concat(this.options.items)); + } + + addItem () { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate (items) { + this.layout.populate([{}].concat(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/absolute.vertical.js b/packages/fineui/src/core/wrapper/layout/adapt/absolute.vertical.js new file mode 100644 index 000000000..ea3f750a2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/absolute.vertical.js @@ -0,0 +1,62 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { VerticalAlign } from "../../../constant"; + +/** + * absolute实现的居中布局 + * @class AbsoluteVerticalLayout + * @extends Layout + */ +@shortcut() +export class AbsoluteVerticalLayout extends Layout { + static xtype = "bi.absolute_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-v-a", + verticalAlign: VerticalAlign.Middle, + columnSize: [], + hgap: 0, + lgap: 0, + rgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + items: o.items, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + ref: _ref => { + this.layout = _ref; + }, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/adapt.center.js b/packages/fineui/src/core/wrapper/layout/adapt/adapt.center.js new file mode 100644 index 000000000..446633caf --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/adapt.center.js @@ -0,0 +1,64 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 自适应水平和垂直方向都居中容器 + * @class CenterAdaptLayout + * @extends Layout + */ +@shortcut() +export class CenterAdaptLayout extends Layout { + static xtype = "bi.center_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-c-a", + horizontalAlign: HorizontalAlign.Center, + columnSize: [], + scrollx: false, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.horizontal", + verticalAlign: VerticalAlign.Middle, + horizontalAlign: o.horizontalAlign, + columnSize: o.columnSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + items: o.items, + ref: _ref => { + this.layout = _ref; + }, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/adapt.horizontal.js b/packages/fineui/src/core/wrapper/layout/adapt/adapt.horizontal.js new file mode 100644 index 000000000..4e44c6c19 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/adapt.horizontal.js @@ -0,0 +1,9 @@ +import { shortcut } from "../../../decorator"; + +/** + * 水平方向居中容器 + */ +@shortcut() +export class HorizontalAdaptLayout { + static xtype = "bi.horizontal_adapt"; +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js b/packages/fineui/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js new file mode 100644 index 000000000..0668c0aa2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js @@ -0,0 +1,243 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend, isArray, each } from "../../../2.base"; +import { HorizontalAlign } from "../../../constant"; + +/** + * 左右分离,垂直方向居中容器 + * items:{ + left: [{el:{type:"bi.button"}}], + right:[{el:{type:"bi.button"}}] + } + * @class LeftRightVerticalAdaptLayout + * @extends Layout + */ +@shortcut() +export class LeftRightVerticalAdaptLayout extends Layout { + static xtype = "bi.left_right_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-lr-v-a", + items: {}, + llgap: 0, + lrgap: 0, + lhgap: 0, + ltgap: 0, + lbgap: 0, + lvgap: 0, + rlgap: 0, + rrgap: 0, + rhgap: 0, + rtgap: 0, + rbgap: 0, + rvgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + const leftRight = this._getLeftRight(o.items); + const layoutArray = []; + if (leftRight.left || "left" in o.items) { + layoutArray.push({ + type: "bi.left", + lgap: o.innerHgap, + vgap: o.innerVgap, + items: [{ + el: { + type: "bi.vertical_adapt", + ref: _ref => { + this.left = _ref; + }, + height: "100%", + items: leftRight.left || o.items.left, + hgap: o.lhgap, + lgap: o.llgap, + rgap: o.lrgap, + tgap: o.ltgap, + bgap: o.lbgap, + vgap: o.lvgap, + }, + }], + }); + } + if (leftRight.right || "right" in o.items) { + layoutArray.push({ + type: "bi.right", + rgap: o.innerHgap, + vgap: o.innerVgap, + items: [{ + el: { + type: "bi.vertical_adapt", + ref: _ref => { + this.right = _ref; + }, + height: "100%", + items: leftRight.right || o.items.right, + hgap: o.rhgap, + lgap: o.rlgap, + rgap: o.rrgap, + tgap: o.rtgap, + bgap: o.rbgap, + vgap: o.rvgap, + }, + }], + }); + } + + return layoutArray; + } + + _getLeftRight(items) { + let left, right; + if (isArray(items)) { + each(items, (i, item) => { + if (item.left) { + left = item.left; + } + if (item.right) { + right = item.right; + } + }); + } + + return { + left, + right, + }; + } + + resize() { + const leftRight = this._getLeftRight(this.options.items); + this.left.stroke(leftRight.left || this.options.items.left); + this.right.stroke(leftRight.right || this.options.items.right); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + const leftRight = this._getLeftRight(items); + this.left.populate(leftRight.left || items.left); + this.right.populate(leftRight.right || items.right); + } +} + +@shortcut() +export class LeftVerticalAdaptLayout extends Layout { + static xtype = "bi.left_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-l-v-a", + items: [], + columnSize: [], + lgap: 0, + rgap: 0, + hgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.vertical_adapt", + ref: _ref => { + this.layout = _ref; + }, + items: o.items, + columnSize: o.columnSize, + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + vgap: o.vgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + resize() { + this.layout.resize(); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(...arguments); + } +} + +@shortcut() +export class RightVerticalAdaptLayout extends Layout { + static xtype = "bi.right_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-r-v-a", + items: [], + columnSize: [], + lgap: 0, + rgap: 0, + hgap: 0, + tgap: 0, + bgap: 0, + vgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.vertical_adapt", + ref: _ref => { + this.layout = _ref; + }, + horizontalAlign: HorizontalAlign.Right, + items: o.items, + columnSize: o.columnSize, + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + vgap: o.vgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + resize() { + this.layout.resize(); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/adapt.table.js b/packages/fineui/src/core/wrapper/layout/adapt/adapt.table.js new file mode 100644 index 000000000..4526edde6 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/adapt.table.js @@ -0,0 +1,123 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend, isFunction, some, isNull } from "../../../2.base"; +import { Widget } from "../../../4.widget"; +import { _lazyCreateWidget } from "../../../5.inject"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 使用display:table和display:table-cell实现的horizontal布局 + * @class TableAdaptLayout + * @extends Layout + */ +@shortcut() +export class TableAdaptLayout extends Layout { + static xtype = "bi.table_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-t-a", + columnSize: [], + verticalAlign: VerticalAlign.Top, + horizontalAlign: HorizontalAlign.Left, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.$table = Widget._renderEngine.createElement("
    ").css({ + position: "relative", + display: "table", + width: (o.horizontalAlign === HorizontalAlign.Center || o.horizontalAlign === HorizontalAlign.Stretch || this._hasFill()) ? "100%" : "auto", + height: (o.verticalAlign !== VerticalAlign.Top) ? "100%" : "auto", + "white-space": "nowrap", + }); + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _hasFill() { + const o = this.options; + if (o.columnSize.length > 0) { + return o.columnSize.indexOf("fill") >= 0; + } + + return some(o.items, (i, item) => { + if (item.width === "fill") { + return true; + } + }); + } + + _addElement(i, item) { + const o = this.options; + let td, width = ""; + let w; + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (columnSize > 0) { + width = this._optimiseGap(columnSize + (i === 0 ? o.hgap : 0) + o.hgap + o.lgap + o.rgap); + } + if ((isNull(columnSize) || columnSize === "") && this._hasFill()) { + width = 2; + } + if (!this.hasWidget(this._getChildName(i))) { + w = _lazyCreateWidget(item); + w.element.css({ position: "relative", top: "0", left: "0", margin: "0px auto" }); + td = _lazyCreateWidget({ + type: "bi.default", + width, + items: [w], + }); + this.addWidget(this._getChildName(i), td); + } else { + td = this.getWidgetByName(this._getChildName(i)); + td.element.width(width); + } + if (o.verticalAlign === VerticalAlign.Stretch) { + const top = o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item), + bottom = o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + w.element.css("height", `calc(100% - ${this._optimiseGap(top + bottom)})`); + } + // 对于表现为td的元素设置最大宽度,有几点需要注意 + // 1、由于直接对td设置最大宽度是在规范中未定义的, 所以要使用类似td:firstChild来迂回实现 + // 2、不能给多个td设置最大宽度,这样只会平分宽度 + // 3、多百分比宽度就算了 + if (columnSize > 0) { + td.element.css({ + "max-width": width, + "min-width": width, + }); + } + if (i === 0) { + td.element.addClass("first-element"); + } + td.element.css({ + position: "relative", + display: "table-cell", + "vertical-align": o.verticalAlign, + height: "100%", + }); + this._handleGap(w, item, i); + + return td; + } + + appendFragment(frag) { + this.$table.append(frag); + this.element.append(this.$table); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/adapt.vertical.js b/packages/fineui/src/core/wrapper/layout/adapt/adapt.vertical.js new file mode 100644 index 000000000..0a0f6c012 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/adapt.vertical.js @@ -0,0 +1,62 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 垂直方向居中容器 + * @class VerticalAdaptLayout + * @extends Layout + */ +@shortcut() +export class VerticalAdaptLayout extends Layout { + static xtype = "bi.vertical_adapt"; + + props = { + baseCls: "bi-v-a", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + scrollx: false, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.horizontal", + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + items: o.items, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + ref: _ref => { + this.layout = _ref; + }, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/auto.horizontal.js b/packages/fineui/src/core/wrapper/layout/adapt/auto.horizontal.js new file mode 100644 index 000000000..f55acaeea --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/auto.horizontal.js @@ -0,0 +1,50 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend, isFunction } from "../../../2.base"; + +/** + * 水平方向居中自适应容器 + * @class HorizontalAutoLayout + * @extends Layout + */ +@shortcut() +export class HorizontalAutoLayout extends Layout { + static xtype = "bi.horizontal_auto"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-h-o", + hgap: 0, + lgap: 0, + rgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const w = super._addElement(...arguments); + w.element.css({ + position: "relative", + margin: "0px auto", + }); + this._handleGap(w, item, null, i); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/index.js b/packages/fineui/src/core/wrapper/layout/adapt/index.js new file mode 100644 index 000000000..82505c49c --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/index.js @@ -0,0 +1,13 @@ +export { AbsoluteCenterLayout } from "./absolute.center"; +export { AbsoluteHorizontalLayout } from "./absolute.horizontal"; +export { AbsoluteLeftRightVerticalAdaptLayout, AbsoluteRightVerticalAdaptLayout } from "./absolute.leftrightvertical"; +export { AbsoluteVerticalLayout } from "./absolute.vertical"; +export { CenterAdaptLayout } from "./adapt.center"; +export { HorizontalAdaptLayout } from "./adapt.horizontal"; +export { LeftRightVerticalAdaptLayout, LeftVerticalAdaptLayout, RightVerticalAdaptLayout } from "./adapt.leftrightvertical"; +export { TableAdaptLayout } from "./adapt.table"; +export { VerticalAdaptLayout } from "./adapt.vertical"; +export { HorizontalAutoLayout } from "./auto.horizontal"; +export { InlineCenterAdaptLayout } from "./inline.center"; +export { InlineHorizontalAdaptLayout } from "./inline.horizontal"; +export { InlineVerticalAdaptLayout } from "./inline.vertical"; diff --git a/packages/fineui/src/core/wrapper/layout/adapt/inline.center.js b/packages/fineui/src/core/wrapper/layout/adapt/inline.center.js new file mode 100644 index 000000000..ede12b455 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/inline.center.js @@ -0,0 +1,64 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 内联布局 + * @class InlineCenterAdaptLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class InlineCenterAdaptLayout extends Layout { + static xtype = "bi.inline_center_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-i-c-a", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.inline", + ref: _ref => { + this.layout = _ref; + }, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/inline.horizontal.js b/packages/fineui/src/core/wrapper/layout/adapt/inline.horizontal.js new file mode 100644 index 000000000..5f7a6a3a2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/inline.horizontal.js @@ -0,0 +1,64 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 内联布局 + * @class InlineHorizontalAdaptLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class InlineHorizontalAdaptLayout extends Layout { + static xtype = "bi.inline_horizontal_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-i-h-a", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Top, + columnSize: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.inline", + ref: _ref => { + this.layout = _ref; + }, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/adapt/inline.vertical.js b/packages/fineui/src/core/wrapper/layout/adapt/inline.vertical.js new file mode 100644 index 000000000..748074c02 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/adapt/inline.vertical.js @@ -0,0 +1,64 @@ +import { shortcut } from "../../../decorator"; +import { Layout } from "../../layout"; +import { extend } from "../../../2.base"; +import { HorizontalAlign, VerticalAlign } from "../../../constant"; + +/** + * 内联布局 + * @class InlineVerticalAdaptLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class InlineVerticalAdaptLayout extends Layout { + static xtype = "bi.inline_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-i-v-a", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.inline", + ref: _ref => { + this.layout = _ref; + }, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/fill/auto.vtape.js b/packages/fineui/src/core/wrapper/layout/fill/auto.vtape.js new file mode 100644 index 000000000..aa6c2eb9b --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/fill/auto.vtape.js @@ -0,0 +1,133 @@ +import { shortcut } from "@/core/decorator"; +import { extend, any, isEmptyObject, isNull, backAny } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +@shortcut() +export class AutoVerticalTapeLayout extends Layout { + static xtype = "bi.vtape_auto"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-auto-htape", + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + rowSize: [], + items: [], + }); + } + + render() { + const o = this.options; + + return { + type: "bi.vtape", + ref: _ref => { + this.layout = _ref; + }, + items: o.items, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + rowSize: o.rowSize, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + _handleResize() { + const o = this.options; + const items = o.items; + const top = {}, bottom = {}; + top[0] = o.innerVgap; + bottom[items.length - 1] = o.innerVgap; + + any(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.layout.getWidgetByName(this._getChildName(i)); + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = item.height; + } + } + if (isNull(top[i])) { + let preRowSize = o.rowSize.length > 0 ? o.rowSize[i - 1] : items[i - 1].height; + if (preRowSize === "") { + preRowSize = this.layout.getWidgetByName(this._getChildName(i - 1)).element.height(); + } + top[i] = top[i - 1] + preRowSize + this._optimiseItemTgap(items[i - 1]) + this._optimiseItemBgap(items[i - 1]) + 2 * this._optimiseItemVgap(items[i - 1]) + o.vgap + o.tgap + o.bgap; + } + w.element.css({ + top: this._optimiseGap(top[i] + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) + o.vgap + o.tgap), + }); + + if (rowSize === "fill") { + return true; + } + }); + backAny(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.layout.getWidgetByName(this._getChildName(i)); + const rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (isNull(bottom[i])) { + let nextRowSize = o.rowSize.length > 0 ? o.rowSize[i + 1] : items[i + 1].height; + if (nextRowSize === "") { + nextRowSize = this.layout.getWidgetByName(this._getChildName(i + 1)).element.height(); + } + bottom[i] = bottom[i + 1] + nextRowSize + this._optimiseItemTgap(items[i + 1]) + this._optimiseItemBgap(items[i + 1]) + 2 * this._optimiseItemVgap(items[i + 1]) + o.vgap + o.tgap + o.bgap; + } + w.element.css({ + bottom: this._optimiseGap(bottom[i] + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) + o.vgap + o.bgap), + }); + + if (rowSize === "fill") { + return true; + } + }); + } + + mounted() { + if (window.ResizeObserver) { + this.resizeObserver = new window.ResizeObserver(this._handleResize.bind(this)); + this.resizeObserver.observe(this.element[0]); + } + if (window.MutationObserver) { + this.mutationObserver = new window.MutationObserver(this._handleResize.bind(this)); + this.mutationObserver.observe(this.element[0], { + attributes: true, + childList: true, + subtree: true, + }); + } + this._handleResize(); + } + + destroyed() { + this.resizeObserver && this.resizeObserver.unobserve(this.element[0]); + this.mutationObserver && this.mutationObserver.disconnect(); + } + + resize() { + this.layout.resize(); + } + + populate(...args) { + this.layout.populate(...args); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/fill/fill.horizontal.js b/packages/fineui/src/core/wrapper/layout/fill/fill.horizontal.js new file mode 100644 index 000000000..88cc76e7d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/fill/fill.horizontal.js @@ -0,0 +1,9 @@ +import { shortcut } from "@/core/decorator"; + +/** + * 横向填满布局 + */ +@shortcut() +export class HorizontalFillLayout { + static xtype = "bi.horizontal_fill"; +} diff --git a/packages/fineui/src/core/wrapper/layout/fill/fill.vertical.js b/packages/fineui/src/core/wrapper/layout/fill/fill.vertical.js new file mode 100644 index 000000000..66fbafa7d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/fill/fill.vertical.js @@ -0,0 +1,9 @@ +import { shortcut } from "@/core/decorator"; + +/** + * 纵向填满布局 + */ +@shortcut() +export class VerticalFillLayout { + static xtype = "bi.vertical_fill"; +} diff --git a/packages/fineui/src/core/wrapper/layout/fill/float.fill.horizontal.js b/packages/fineui/src/core/wrapper/layout/fill/float.fill.horizontal.js new file mode 100644 index 000000000..1d8f8beb0 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/fill/float.fill.horizontal.js @@ -0,0 +1,155 @@ +import { shortcut } from "@/core/decorator"; +import { extend, any, isEmptyObject, isNull, backAny, isFunction, compact, each } from "@/core/2.base"; +import { _lazyCreateWidget } from "@/core/5.inject"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +@shortcut() +export class FloatHorizontalFillLayout extends Layout { + static xtype = "bi.horizontal_float_fill"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-h-float-fill clearfix", + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + columnSize: [], + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + items = compact(items); + let rank = 0; + + const createWidget = (i, item, desc) => { + let w; + if (o.verticalAlign !== VerticalAlign.Stretch) { + w = _lazyCreateWidget({ + type: "bi.vertical_adapt", + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: o.verticalAlign, + columnSize: ["fill"], + items: [item], + }); + } else { + w = _lazyCreateWidget(item); + } + if (o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + w.element.css({ + "margin-top": this._optimiseGap(o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item)), + }); + } + if (desc) { + if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + w.element.css({ + "margin-right": this._optimiseGap((i === o.items.length - 1 ? o.hgap : 0) + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item)), + }); + } + if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + w.element.css({ + "margin-left": this._optimiseGap(o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item)), + }); + } + } else { + if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + w.element.css({ + "margin-left": this._optimiseGap((i === 0 ? o.hgap : 0) + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item)), + }); + } + if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + w.element.css({ + "margin-right": this._optimiseGap(o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item)), + }); + } + } + if (o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + w.element.css({ + "margin-bottom": this._optimiseGap(o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item)), + }); + } + const top = o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item), + bottom = o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + if (o.verticalAlign === VerticalAlign.Stretch && isNull(item.height)) { + w.element.css({ + height: `calc(100% - ${this._optimiseGap(top + bottom)})`, + }); + } + w.element.css({ + position: "relative", + }); + + return w; + }; + + any(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (columnSize === "fill") { + return true; + } + const w = createWidget(i, item); + this.addWidget(this._getChildName(rank++), w); + w.element.css({ + "float": "left", + }); + }); + backAny(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (columnSize === "fill") { + return true; + } + const w = createWidget(i, item, true); + this.addWidget(this._getChildName(rank++), w); + w.element.css({ + "float": "right", + }); + }); + each(items, (i, item) => { + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (columnSize === "fill") { + const w = createWidget(i, item); + this.addWidget(this._getChildName(rank++), w); + } + }); + } + + resize() { + // console.log("填充布局不需要resize"); + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/fill/index.js b/packages/fineui/src/core/wrapper/layout/fill/index.js new file mode 100644 index 000000000..aefc020d1 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/fill/index.js @@ -0,0 +1,4 @@ +export { AutoVerticalTapeLayout } from "./auto.vtape"; +export { HorizontalFillLayout } from "./fill.horizontal"; +export { VerticalFillLayout } from "./fill.vertical"; +export { FloatHorizontalFillLayout } from "./float.fill.horizontal"; diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.center.js b/packages/fineui/src/core/wrapper/layout/flex/flex.center.js new file mode 100644 index 000000000..caec5842e --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.center.js @@ -0,0 +1,63 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexCenterLayout + * @extends Layout + */ +@shortcut() +export class FlexCenterLayout extends Layout { + static xtype = "bi.flex_center_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-c", + verticalAlign: VerticalAlign.Middle, + horizontalAlign: HorizontalAlign.Center, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_horizontal", + ref: _ref => { + this.layout = _ref; + }, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + hgap: o.hgap, + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.center.js b/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.center.js new file mode 100644 index 000000000..ffc0d6aac --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.center.js @@ -0,0 +1,69 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + * Created by GUY on 2016/12/2. + * + * @class FlexHorizontalCenter + * @extends Layout + */ +@shortcut() +export class FlexHorizontalCenter extends Layout { + static xtype = "bi.flex_horizontal_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-h-c", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Top, + rowSize: [], + scrolly: false, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_vertical", + ref: _ref => { + this.layout = _ref; + }, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + hgap: o.hgap, + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} + +@shortcut() +export class FlexHorizontalCenterAdapt extends FlexHorizontalCenter { + static xtype = "bi.flex_horizontal_center_adapt"; +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.js b/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.js new file mode 100644 index 000000000..7489d30a7 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.horizontal.js @@ -0,0 +1,114 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isFunction, some } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexHorizontalLayout + * @extends Layout + */ +@shortcut() +export class FlexHorizontalLayout extends Layout { + static xtype = "bi.flex_horizontal"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-h", + verticalAlign: VerticalAlign.Top, + horizontalAlign: HorizontalAlign.Left, // 如果只有一个子元素且想让该子元素横向撑满,设置成Stretch + columnSize: [], + scrollx: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.element.addClass(`v-${o.verticalAlign}`).addClass(`h-${o.horizontalAlign}`); + if (o.scrollable === true || o.scrollx === true) { + this.element.addClass("f-scroll-x"); + } + if (o.scrollable === true || o.scrolly === true) { + this.element.addClass("f-scroll-y"); + } + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _hasFill() { + const o = this.options; + if (o.columnSize.length > 0) { + return o.columnSize.indexOf("fill") >= 0 || o.columnSize.indexOf("auto") >= 0; + } + + return some(o.items, (i, item) => { + if (item.width === "fill" || item.width === "auto") { + return true; + } + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = null; + } + } + w.element.css({ + position: "relative", + }); + if (columnSize !== "auto") { + if (columnSize === "fill" || columnSize === "") { + if (o.horizontalAlign !== HorizontalAlign.Stretch) { + if (o.scrollable === true || o.scrollx === true) { + w.element.addClass("f-s-n"); + } + } + // 当既有动态宽度和自适应宽度的时候只压缩自适应 + if (columnSize === "" && this._hasFill()) { + w.element.addClass("f-s-n"); + } + } else { + w.element.addClass("f-s-n"); + } + } + if (columnSize > 0) { + w.element.width(this._optimiseGap(columnSize)); + } + if (columnSize === "fill") { + w.element.addClass("f-f"); + } + if (columnSize === "" || columnSize === "auto") { + w.element.addClass("f-auto"); + } + w.element.addClass("c-e"); + if (i === 0) { + w.element.addClass("f-c"); + } + if (i === o.items.length - 1) { + w.element.addClass("l-c"); + } + this._handleGap(w, item, i); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js b/packages/fineui/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js new file mode 100644 index 000000000..4292347d3 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js @@ -0,0 +1,114 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isArray, each, map, stripEL } from "@/core/2.base"; +import { Layout } from "../../layout"; + +@shortcut() +export class FlexLeftRightVerticalAdaptLayout extends Layout { + static xtype = "bi.flex_left_right_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-lr-v-c", + columnSize: [], + items: {}, + llgap: 0, + lrgap: 0, + lhgap: 0, + ltgap: 0, + lbgap: 0, + lvgap: 0, + rlgap: 0, + rrgap: 0, + rhgap: 0, + rtgap: 0, + rbgap: 0, + rvgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + const items = this._formatItems(o.items); + + return { + type: "bi.flex_vertical_adapt", + ref: _ref => { + this.layout = _ref; + }, + columnSize: o.columnSize.slice(0, (o.items.left || []).length).concat((o.items.right || []).length > 0 ? [""] : []), + items, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + _formatItems(items) { + const o = this.options; + let left, right; + if (isArray(items)) { + each(items, (i, item) => { + if (item.left) { + left = item.left; + } + if (item.right) { + right = item.right; + } + }); + } + let leftItems = left || items.left || []; + const rightItems = right || items.right || []; + leftItems = map(leftItems, (i, item) => { + const json = { + el: stripEL(item), + }; + if (o.lvgap + o.ltgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + json.tgap = o.lvgap + o.ltgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + } + if (o.lhgap + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + } + if (o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + json.rgap = o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + } + if (o.lvgap + o.lbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + json.bgap = o.lvgap + o.lbgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + } + + return json; + }); + + return leftItems.concat({ + el: { + type: "bi.flex_vertical_adapt", + columnSize: o.columnSize.slice(leftItems.length), + css: { + "margin-left": "auto", + }, + hgap: o.rhgap, + vgap: o.rvgap, + lgap: o.rlgap, + rgap: o.rrgap, + tgap: o.rtgap, + bgap: o.rbgap, + items: rightItems, + }, + }); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.center.js b/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.center.js new file mode 100644 index 000000000..a4a830862 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.center.js @@ -0,0 +1,70 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexVerticalCenter + * @extends Layout + */ +@shortcut() +export class FlexVerticalCenter extends Layout { + static xtype = "bi.flex_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-v-c", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + scrollx: false, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_horizontal", + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + horizontalAlign: o.horizontalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + hgap: o.hgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} + +@shortcut() +export class FlexVerticalCenterAdapt extends FlexVerticalCenter { + static xtype = "bi.flex_vertical_center_adapt" +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.js b/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.js new file mode 100644 index 000000000..5ee654642 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/flex.vertical.js @@ -0,0 +1,112 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isFunction, some } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + * Created by GUY on 2016/12/2. + * + * @class FlexVerticalLayout + * @extends Layout + */ +@shortcut() +export class FlexVerticalLayout extends Layout { + static xtype = "bi.flex_vertical"; + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-v", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Top, + rowSize: [], + scrolly: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const self = this, o = this.options; + this.element.addClass(`h-${o.horizontalAlign}`).addClass(`v-${o.verticalAlign}`); + if (o.scrollable === true || o.scrollx === true) { + this.element.addClass("f-scroll-x"); + } + if (o.scrollable === true || o.scrolly === true) { + this.element.addClass("f-scroll-y"); + } + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + self.populate(newValue); + }) : o.items; + this.populate(items); + } + + _hasFill() { + const o = this.options; + if (o.rowSize.length > 0) { + return o.rowSize.indexOf("fill") >= 0 || o.rowSize.indexOf("auto") >= 0; + } + + return some(o.items, (i, item) => { + if (item.height === "fill" || item.height === "auto") { + return true; + } + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement.apply(this, arguments); + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = null; + } + } + w.element.css({ + position: "relative", + }); + if (rowSize !== "auto") { + if (rowSize === "fill" || rowSize === "") { + if (o.verticalAlign !== VerticalAlign.Stretch) { + if (o.scrollable === true || o.scrolly === true) { + w.element.addClass("f-s-n"); + } + } + // 当既有动态宽度和自适应宽度的时候只压缩自适应 + if (rowSize === "" && this._hasFill()) { + w.element.addClass("f-s-n"); + } + } else { + w.element.addClass("f-s-n"); + } + } + if (rowSize > 0) { + w.element.height(this._optimiseGap(rowSize)); + } + if (rowSize === "fill") { + w.element.addClass("f-f"); + } + if (rowSize === "" || rowSize === "auto") { + w.element.addClass("f-auto"); + } + w.element.addClass("c-e"); + if (i === 0) { + w.element.addClass("f-c"); + } + if (i === o.items.length - 1) { + w.element.addClass("l-c"); + } + this._handleGap(w, item, null, i); + + return w; + } + + populate(items) { + super.populate.apply(this, arguments); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/index.js b/packages/fineui/src/core/wrapper/layout/flex/index.js new file mode 100644 index 000000000..1625f8ad0 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/index.js @@ -0,0 +1,7 @@ +export { FlexCenterLayout } from "./flex.center"; +export { FlexHorizontalCenter, FlexHorizontalCenterAdapt } from "./flex.horizontal.center"; +export { FlexHorizontalLayout } from "./flex.horizontal"; +export { FlexLeftRightVerticalAdaptLayout } from "./flex.leftrightvertical.center"; +export { FlexVerticalCenter, FlexVerticalCenterAdapt } from "./flex.vertical.center"; +export { FlexVerticalLayout } from "./flex.vertical"; +export * from "./wrapper"; diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js new file mode 100644 index 000000000..347ab62a9 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js @@ -0,0 +1,64 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "@/core/wrapper/layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexWrapperCenterLayout + * @extends Layout + */ +@shortcut() +export class FlexWrapperCenterLayout extends Layout { + static xtype = "bi.flex_scrollable_center_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-s-c", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + scrollx: false, + scrollable: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_scrollable_horizontal", + ref: _ref => { + this.layout = _ref; + }, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js new file mode 100644 index 000000000..c15e28369 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js @@ -0,0 +1,69 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "@/core/wrapper/layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexVerticalCenter + * @extends Layout + */ +@shortcut() +export class FlexWrapperHorizontalCenter extends Layout { + static xtype = "bi.flex_scrollable_horizontal_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-s-v-c", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Top, + rowSize: [], + scrollable: true, + scrolly: false, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_scrollable_vertical", + ref: _ref => { + this.layout = _ref; + }, + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + hgap: o.hgap, + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} + +@shortcut() +export class FlexWrapperHorizontalCenterAdapt extends FlexWrapperHorizontalCenter { + static xtype = "bi.flex_scrollable_horizontal_center_adapt"; +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js new file mode 100644 index 000000000..4e3cee14a --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js @@ -0,0 +1,122 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isFunction, some } from "@/core/2.base"; +import { Widget } from "@/core/4.widget"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "@/core/wrapper/layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexHorizontalLayout + * @extends Layout + */ +@shortcut() +export class FlexWrapperHorizontalLayout extends Layout { + static xtype = "bi.flex_scrollable_horizontal"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-s-h", + verticalAlign: VerticalAlign.Top, + horizontalAlign: HorizontalAlign.Left, + columnSize: [], + scrollable: null, + scrollx: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.element.addClass(`v-${o.verticalAlign}`).addClass(`h-${o.horizontalAlign}`); + this.$wrapper = Widget._renderEngine.createElement("
    ").addClass(`f-s-h-w v-${o.verticalAlign}`).addClass(`h-${o.horizontalAlign}`); + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _hasFill() { + const o = this.options; + if (o.columnSize.length > 0) { + return o.columnSize.indexOf("fill") >= 0 || o.columnSize.indexOf("auto") >= 0; + } + + return some(o.items, (i, item) => { + if (item.width === "fill" || item.width === "auto") { + return true; + } + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = null; + } + } + w.element.css({ + position: "relative", + }); + if (columnSize !== "auto") { + if (columnSize === "fill" || columnSize === "") { + if (o.horizontalAlign !== HorizontalAlign.Stretch) { + if (o.scrollable === true || o.scrollx === true) { + w.element.addClass("f-s-n"); + } + } + // 当既有动态宽度和自适应宽度的时候只压缩自适应 + if (columnSize === "" && this._hasFill()) { + w.element.addClass("f-s-n"); + } + } else { + w.element.addClass("f-s-n"); + } + } + if (columnSize > 0) { + w.element.width(this._optimiseGap(columnSize)); + } + if (columnSize === "fill") { + w.element.addClass("f-f"); + this.element.addClass("f-f"); + } + if (columnSize === "" || columnSize === "auto") { + w.element.addClass("f-auto"); + this.element.addClass("f-auto"); + } + w.element.addClass("c-e"); + if (i === 0) { + w.element.addClass("f-c"); + } + if (i === o.items.length - 1) { + w.element.addClass("l-c"); + } + this._handleGap(w, item, i); + + return w; + } + + appendFragment(frag) { + this.$wrapper.append(frag); + this.element.append(this.$wrapper); + } + + _getWrapper() { + return this.$wrapper; + } + + populate(items) { + super.populate(...arguments); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js new file mode 100644 index 000000000..98c340452 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js @@ -0,0 +1,69 @@ +import { shortcut } from "@/core/decorator"; +import { extend } from "@/core/2.base"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "@/core/wrapper/layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexVerticalCenter + * @extends Layout + */ +@shortcut() +export class FlexWrapperVerticalCenter extends Layout { + static xtype = "bi.flex_scrollable_vertical_adapt"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-s-v-c", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Middle, + columnSize: [], + scrollx: false, + scrollable: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + + return { + type: "bi.flex_scrollable_horizontal", + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + horizontalAlign: o.horizontalAlign, + columnSize: o.columnSize, + rowSize: o.rowSize, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + items: o.items, + }; + } + + resize() { + this.layout.resize(); + } + + populate(items) { + this.layout.populate(items); + } +} + +@shortcut() +export class FlexWrapperVerticalCenterAdapt extends FlexWrapperVerticalCenter { + static xtype = "bi.flex_scrollable_vertical_center_adapt"; +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js new file mode 100644 index 000000000..f557ba543 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js @@ -0,0 +1,122 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isFunction, some } from "@/core/2.base"; +import { Widget } from "@/core/4.widget"; +import { HorizontalAlign, VerticalAlign } from "@/core/constant"; +import { Layout } from "@/core/wrapper/layout"; + +/** + *自适应水平和垂直方向都居中容器 + * Created by GUY on 2016/12/2. + * + * @class FlexWrapperVerticalLayout + * @extends Layout + */ +@shortcut() +export class FlexWrapperVerticalLayout extends Layout { + static xtype = "bi.flex_scrollable_vertical"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-f-s-v", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Top, + rowSize: [], + scrollable: null, + scrolly: true, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.element.addClass(`v-${o.verticalAlign}`).addClass(`h-${o.horizontalAlign}`); + this.$wrapper = Widget._renderEngine.createElement("
    ").addClass(`f-s-v-w h-${o.horizontalAlign}`).addClass(`v-${o.verticalAlign}`); + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _hasFill() { + const o = this.options; + if (o.rowSize.length > 0) { + return o.rowSize.indexOf("fill") >= 0 || o.rowSize.indexOf("auto") >= 0; + } + + return some(o.items, (i, item) => { + if (item.height === "fill" || item.height === "auto") { + return true; + } + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = null; + } + } + w.element.css({ + position: "relative", + }); + if (rowSize !== "auto") { + if (rowSize === "fill" || rowSize === "") { + if (o.verticalAlign !== VerticalAlign.Stretch) { + if (o.scrollable === true || o.scrolly === true) { + w.element.addClass("f-s-n"); + } + } + // 当既有动态宽度和自适应宽度的时候只压缩自适应 + if (rowSize === "" && this._hasFill()) { + w.element.addClass("f-s-n"); + } + } else { + w.element.addClass("f-s-n"); + } + } + if (rowSize > 0) { + w.element.height(this._optimiseGap(rowSize)); + } + if (rowSize === "fill") { + w.element.addClass("f-f"); + this.element.addClass("f-f"); + } + if (rowSize === "" || rowSize === "auto") { + w.element.addClass("f-auto"); + this.element.addClass("f-auto"); + } + w.element.addClass("c-e"); + if (i === 0) { + w.element.addClass("f-c"); + } + if (i === o.items.length - 1) { + w.element.addClass("l-c"); + } + this._handleGap(w, item, null, i); + + return w; + } + + appendFragment(frag) { + this.$wrapper.append(frag); + this.element.append(this.$wrapper); + } + + _getWrapper() { + return this.$wrapper; + } + + populate(items) { + super.populate(...arguments); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/flex/wrapper/index.js b/packages/fineui/src/core/wrapper/layout/flex/wrapper/index.js new file mode 100644 index 000000000..5257a1b70 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/flex/wrapper/index.js @@ -0,0 +1,5 @@ +export { FlexWrapperCenterLayout } from "./flex.wrapper.center"; +export { FlexWrapperHorizontalCenter, FlexWrapperHorizontalCenterAdapt } from "./flex.wrapper.horizontal.center"; +export { FlexWrapperHorizontalLayout } from "./flex.wrapper.horizontal"; +export { FlexWrapperVerticalCenter, FlexWrapperVerticalCenterAdapt } from "./flex.wrapper.vertical.center"; +export { FlexWrapperVerticalLayout } from "./flex.wrapper.vertical"; diff --git a/packages/fineui/src/core/wrapper/layout/float/float.absolute.center.js b/packages/fineui/src/core/wrapper/layout/float/float.absolute.center.js new file mode 100644 index 000000000..6aefbc1ac --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/float.absolute.center.js @@ -0,0 +1,42 @@ +import { shortcut } from "@/core/decorator"; +import { extend, isFunction } from "@/core/2.base"; +import { Layout } from "../../layout"; + +/** + * absolute实现的居中布局 + * @class FloatAbsoluteCenterLayout + * @extends Layout + */ +@shortcut() +export class FloatAbsoluteCenterLayout extends Layout { + static xtype = "bi.absolute_center_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-c-fl", + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const w = super._addElement(...arguments); + w.element.addClass("bi-abs-c-item").css({ + position: "absolute", + }); + + return w; + } + + populate(items) { + super.populate(...arguments); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/float/float.absolute.horizontal.js b/packages/fineui/src/core/wrapper/layout/float/float.absolute.horizontal.js new file mode 100644 index 000000000..8d2757217 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/float.absolute.horizontal.js @@ -0,0 +1,82 @@ +import { shortcut } from "@/core/decorator"; +import { extend, map, isEmptyObject, stripEL, isWidget } from "@/core/2.base"; +import { HorizontalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + * absolute实现的居中布局 + * @class FloatAbsoluteHorizontalLayout + * @extends Layout + */ +@shortcut() +export class FloatAbsoluteHorizontalLayout extends Layout { + static xtype = "bi.absolute_horizontal_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-h-fl", + horizontalAlign: HorizontalAlign.Center, + rowSize: [], + vgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.vtape", + horizontalAlign: o.horizontalAlign, + rowSize: o.rowSize, + items: this._formatItems(o.items), + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + ref: _ref => { + this.layout = _ref; + }, + hgap: "50%", + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + // lgap和rgap不传的话内部不会设置left和right + lgap: o.lgap, + rgap: o.rgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + _formatItems(items) { + const o = this.options; + if (o.horizontalAlign === HorizontalAlign.Left) { + return items; + } + const cls = o.horizontalAlign === HorizontalAlign.Right ? "bi-abs-r-x-item" : "bi-abs-c-x-item"; + + return map(items, (i, item) => { + if (!item || isEmptyObject(item)) { + return item; + } + const el = stripEL(item); + if (isWidget(el)) { + el.element.addClass(cls); + } else { + el.cls = (el.cls || "") + cls; + } + + return item; + }); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js b/packages/fineui/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js new file mode 100644 index 000000000..6a1893e08 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js @@ -0,0 +1,207 @@ +import { shortcut } from "@/core/decorator"; +import { extend, map, isEmptyObject, stripEL, isWidget, isArray, each } from "@/core/2.base"; +import { VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +@shortcut() +export class FloatAbsoluteLeftRightVerticalAdaptLayout extends Layout { + static xtype = "bi.absolute_left_right_vertical_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-lr-v-fl", + verticalAlign: VerticalAlign.Middle, + items: {}, + llgap: 0, + lrgap: 0, + lhgap: 0, + ltgap: 0, + lbgap: 0, + lvgap: 0, + rlgap: 0, + rrgap: 0, + rhgap: 0, + rtgap: 0, + rbgap: 0, + rvgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + items: this._formatItems(o.items), + vgap: "50%", + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + _formatItems(items) { + const o = this.options; + let left, right; + if (isArray(items)) { + each(items, (i, item) => { + if (item.left) { + left = item.left; + } + if (item.right) { + right = item.right; + } + }); + } + let leftItems = left || items.left || []; + let rightItems = right || items.right || []; + leftItems = map(leftItems, (i, item) => { + const el = stripEL(item); + if (o.verticalAlign === VerticalAlign.Middle) { + if (isWidget(el)) { + el.element.addClass("bi-abs-c-y-item"); + } else { + el.cls = `${el.cls || ""}bi-abs-c-y-item`; + } + } + const json = { + el, + width: item.width, + }; + // if (o.lvgap + o.ltgap + (item.tgap || 0) + (item.vgap || 0) !== 0) { + // json.tgap = o.lvgap + o.ltgap + (item.tgap || 0) + (item.vgap || 0); + // } + if (o.lhgap + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + } + if (o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + json.rgap = o.lhgap + o.lrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + } + // if (o.lvgap + o.lbgap + (item.bgap || 0) + (item.vgap || 0) !== 0) { + // json.bgap = o.lvgap + o.lbgap + (item.bgap || 0) + (item.vgap || 0); + // } + + return json; + }); + rightItems = map(rightItems, (i, item) => { + const el = stripEL(item); + if (o.verticalAlign === VerticalAlign.Middle) { + if (isWidget(el)) { + el.element.addClass("bi-abs-c-y-item"); + } else { + el.cls = `${el.cls || ""}bi-abs-c-y-item`; + } + } + const json = { + el, + width: item.width, + }; + // if (o.rvgap + o.rtgap + (item.tgap || 0) + (item.vgap || 0) !== 0) { + // json.tgap = o.rvgap + o.rtgap + (item.tgap || 0) + (item.vgap || 0); + // } + if (o.rhgap + o.rlgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + json.lgap = (i === 0 ? o.rhgap : 0) + o.rlgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + } + if (o.rhgap + o.rrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + json.rgap = o.rhgap + o.rrgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + } + // if (o.rvgap + o.rbgap + (item.bgap || 0) + (item.vgap || 0) !== 0) { + // json.bgap = o.rvgap + o.rbgap + (item.bgap || 0) + (item.vgap || 0); + // } + + return json; + }); + + return leftItems.concat({}, rightItems); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} + +@shortcut() +export class FloatAbsoluteRightVerticalAdaptLayout extends Layout { + static xtype = "bi.absolute_right_vertical_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-r-v-fl", + verticalAlign: VerticalAlign.Middle, + items: [], + lgap: 0, + rgap: 0, + hgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + ref: _ref => { + this.layout = _ref; + }, + verticalAlign: o.verticalAlign, + items: [{}].concat(this._formatItems(o.items)), + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + vgap: "50%", + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + _formatItems(items) { + if (this.options.verticalAlign !== VerticalAlign.Middle) { + return items; + } + + return map(items, (i, item) => { + if (!item || isEmptyObject(item)) { + return item; + } + const el = stripEL(item); + if (isWidget(el)) { + el.element.addClass("bi-abs-c-y-item"); + } else { + el.cls = `${el.cls || ""}bi-abs-c-y-item`; + } + + return item; + }); + } + + resize() { + this.layout.stroke([{}].concat(this._formatItems(this.options.items))); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate([{}].concat(this._formatItems(items))); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/float/float.absolute.vertical.js b/packages/fineui/src/core/wrapper/layout/float/float.absolute.vertical.js new file mode 100644 index 000000000..d55dba779 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/float.absolute.vertical.js @@ -0,0 +1,82 @@ +import { shortcut } from "@/core/decorator"; +import { extend, map, isEmptyObject, stripEL, isWidget } from "@/core/2.base"; +import { VerticalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + * absolute实现的居中布局 + * @class FloatAbsoluteVerticalLayout + * @extends Layout + */ +@shortcut() +export class FloatAbsoluteVerticalLayout extends Layout { + static xtype = "bi.absolute_vertical_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs-h-fl", + verticalAlign: VerticalAlign.Middle, + columnSize: [], + hgap: 0, + lgap: 0, + rgap: 0, + }); + } + + render() { + const o = this.options; + super.render(...arguments); + + return { + type: "bi.htape", + verticalAlign: o.verticalAlign, + columnSize: o.columnSize, + items: this._formatItems(o.items), + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + ref: _ref => { + this.layout = _ref; + }, + vgap: "50%", + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + // tgap和bgap不传的话内部不会设置top和bottom + tgap: o.tgap, + bgap: o.bgap, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + }; + } + + _formatItems(items) { + const o = this.options; + if (o.verticalAlign === VerticalAlign.Top) { + return items; + } + const cls = o.verticalAlign === VerticalAlign.Bottom ? "bi-abs-b-y-item" : "bi-abs-c-y-item"; + + return map(items, (i, item) => { + if (!item || isEmptyObject(item)) { + return item; + } + const el = stripEL(item); + if (isWidget(el)) { + el.element.addClass(cls); + } else { + el.cls = (el.cls || "") + cls; + } + + return item; + }); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/float/float.horizontal.js b/packages/fineui/src/core/wrapper/layout/float/float.horizontal.js new file mode 100644 index 000000000..9b3da1f9d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/float.horizontal.js @@ -0,0 +1,94 @@ +import { shortcut } from "@/core/decorator"; +import { extend, map } from "@/core/2.base"; +import { VerticalAlign, HorizontalAlign } from "@/core/constant"; +import { Layout } from "../../layout"; + +/** + * 浮动的水平居中布局 + */ +@shortcut() +export class FloatHorizontalLayout extends Layout { + static xtype = "bi.horizontal_float"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-h-fl", + horizontalAlign: HorizontalAlign.Center, + verticalAlign: VerticalAlign.Top, + rowSize: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + const o = this.options; + if (o.verticalAlign === VerticalAlign.Top) { + return { + type: "bi.vertical", + ref: _ref => { + this.layout = _ref; + }, + items: this._formatItems(o.items), + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + return { + type: "bi.inline", + items: [{ + el: { + type: "bi.vertical", + ref: _ref => { + this.layout = _ref; + }, + items: this._formatItems(o.items), + vgap: o.vgap, + tgap: o.tgap, + bgap: o.bgap, + }, + }], + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + innerHgap: o.innerHgap, + innerVgap: o.innerVgap, + scrollx: o.scrollx, + scrolly: o.scrolly, + scrollable: o.scrollable, + }; + } + + _formatItems(items) { + const o = this.options; + + return map(items, (i, item) => { + return { + el: { + type: "bi.inline_horizontal_adapt", + horizontalAlign: o.horizontalAlign, + items: [item], + hgap: o.hgap, + lgap: o.lgap, + rgap: o.rgap, + }, + }; + }); + } + + resize() { + this.layout.stroke(this._formatItems(this.options.items)); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/float/index.js b/packages/fineui/src/core/wrapper/layout/float/index.js new file mode 100644 index 000000000..97d5b1ff2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/float/index.js @@ -0,0 +1,5 @@ +export { FloatAbsoluteCenterLayout } from "./float.absolute.center"; +export { FloatAbsoluteHorizontalLayout } from "./float.absolute.horizontal"; +export { FloatAbsoluteLeftRightVerticalAdaptLayout, FloatAbsoluteRightVerticalAdaptLayout } from "./float.absolute.leftrightvertical"; +export { FloatAbsoluteVerticalLayout } from "./float.absolute.vertical"; +export { FloatHorizontalLayout } from "./float.horizontal"; diff --git a/packages/fineui/src/core/wrapper/layout/index.js b/packages/fineui/src/core/wrapper/layout/index.js new file mode 100644 index 000000000..9fd652878 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/index.js @@ -0,0 +1,23 @@ +export { AbsoluteLayout } from "./layout.absolute"; +export { AdaptiveLayout } from "./layout.adaptive"; +export { BorderLayout } from "./layout.border"; +export { CardLayout } from "./layout.card"; +export { DefaultLayout } from "./layout.default"; +export { DivisionLayout } from "./layout.division"; +export { FloatLeftLayout, FloatRightLayout } from "./layout.flow"; +export { GridLayout } from "./layout.grid"; +export { HorizontalLayout } from "./layout.horizontal"; +export { InlineLayout } from "./layout.inline"; +export { LatticeLayout } from "./layout.lattice"; +export { TableLayout } from "./layout.table"; +export { HTapeLayout, VTapeLayout } from "./layout.tape"; +export { TdLayout } from "./layout.td"; +export { VerticalLayout } from "./layout.vertical"; +export { WindowLayout } from "./layout.window"; +export * from "./adapt"; +export * from "./fill"; +export * from "./flex"; +export * from "./float"; +export * from "./middle"; +export * from "./responsive"; +export * from "./sticky"; diff --git a/packages/fineui/src/core/wrapper/layout/layout.absolute.js b/packages/fineui/src/core/wrapper/layout/layout.absolute.js new file mode 100644 index 000000000..7e88bd630 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.absolute.js @@ -0,0 +1,119 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, map, parseFloat, isKey, pick, isNotNull, isNumber } from "../../2.base"; + +/** + * 固定子组件上下左右的布局容器 + */ +@shortcut() +export class AbsoluteLayout extends Layout { + static xtype = "bi.absolute"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-abs", + hgap: null, + vgap: null, + lgap: null, + rgap: null, + tgap: null, + bgap: null, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let left = 0, right = 0, top = 0, bottom = 0; + let offsets = pick(item, ["top", "right", "bottom", "left"]); + + if (isKey(item.inset)) { + const insets = map((`${item.inset}`).split(" "), (i, str) => parseFloat(str)); + switch (insets.length) { + case 1: + offsets = { top: insets[0], bottom: insets[0], left: insets[0], right: insets[0] }; + break; + case 2: + offsets = { top: insets[0], bottom: insets[0], left: insets[1], right: insets[1] }; + break; + case 3: + offsets = { top: insets[0], left: insets[1], right: insets[1], bottom: insets[2] }; + break; + case 4: + default: + offsets = { top: insets[0], right: insets[1], bottom: insets[2], left: insets[3] }; + break; + } + } + if (isNotNull(offsets.left)) { + w.element.css({ left: isNumber(offsets.left) ? this._optimiseGap(offsets.left) : offsets.left }); + left += offsets.left; + } + if (isNotNull(offsets.right)) { + w.element.css({ right: isNumber(offsets.right) ? this._optimiseGap(offsets.right) : offsets.right }); + right += offsets.right; + } + if (isNotNull(offsets.top)) { + w.element.css({ top: isNumber(offsets.top) ? this._optimiseGap(offsets.top) : offsets.top }); + top += offsets.top; + } + if (isNotNull(offsets.bottom)) { + w.element.css({ bottom: isNumber(offsets.bottom) ? this._optimiseGap(offsets.bottom) : offsets.bottom }); + bottom += offsets.bottom; + } + + if (isNotNull(o.hgap)) { + left += o.hgap; + w.element.css({ left: this._optimiseGap(left) }); + right += o.hgap; + w.element.css({ right: this._optimiseGap(right) }); + } + if (isNotNull(o.vgap)) { + top += o.vgap; + w.element.css({ top: this._optimiseGap(top) }); + bottom += o.vgap; + w.element.css({ bottom: this._optimiseGap(bottom) }); + } + + if (isNotNull(o.lgap)) { + left += o.lgap; + w.element.css({ left: this._optimiseGap(left) }); + } + if (isNotNull(o.rgap)) { + right += o.rgap; + w.element.css({ right: this._optimiseGap(right) }); + } + if (isNotNull(o.tgap)) { + top += o.tgap; + w.element.css({ top: this._optimiseGap(top) }); + } + if (isNotNull(o.bgap)) { + bottom += o.bgap; + w.element.css({ bottom: this._optimiseGap(bottom) }); + } + + if (isNotNull(item.width)) { + w.element.css({ width: isNumber(item.width) ? this._optimiseGap(item.width) : item.width }); + } + if (isNotNull(item.height)) { + w.element.css({ height: isNumber(item.height) ? this._optimiseGap(item.height) : item.height }); + } + w.element.css({ position: "absolute" }); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.adaptive.js b/packages/fineui/src/core/wrapper/layout/layout.adaptive.js new file mode 100644 index 000000000..e11e23eb4 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.adaptive.js @@ -0,0 +1,70 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isNumber, isNotNull, isFunction } from "../../2.base"; + +@shortcut() +export class AdaptiveLayout extends Layout { + static xtype = "bi.adaptive"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-adaptive", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const self = this, o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + self.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const w = super._addElement(...arguments); + w.element.css({ position: "relative" }); + if (isNotNull(item.left)) { + w.element.css({ + left: isNumber(item.left) ? this._optimiseGap(item.left) : item.left, + }); + } + if (isNotNull(item.right)) { + w.element.css({ + right: isNumber(item.right) ? this._optimiseGap(item.right) : item.right, + }); + } + if (isNotNull(item.top)) { + w.element.css({ + top: isNumber(item.top) ? this._optimiseGap(item.top) : item.top, + }); + } + if (isNotNull(item.bottom)) { + w.element.css({ + bottom: isNumber(item.bottom) ? this._optimiseGap(item.bottom) : item.bottom, + }); + } + + this._handleGap(w, item); + + if (isNotNull(item.width)) { + w.element.css({ width: isNumber(item.width) ? this._optimiseGap(item.width) : item.width }); + } + if (isNotNull(item.height)) { + w.element.css({ height: isNumber(item.height) ? this._optimiseGap(item.height) : item.height }); + } + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.border.js b/packages/fineui/src/core/wrapper/layout/layout.border.js new file mode 100644 index 000000000..f3a00211e --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.border.js @@ -0,0 +1,150 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isNotNull, isFunction } from "../../2.base"; +import { _lazyCreateWidget } from "../../5.inject"; + +/** + * 上下的高度固定/左右的宽度固定,中间的高度/宽度自适应 + * + * @class BorderLayout + * @extends Layout + */ +@shortcut() +export class BorderLayout extends Layout { + static xtype = "bi.border"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-border-layout", + items: {}, + }); + } + + render() { + super.render(...arguments); + const self = this, o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + self.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(regions) { + let item; + let top = 0; + let bottom = 0; + let left = 0; + let right = 0; + if ("north" in regions) { + item = regions.north; + if (isNotNull(item)) { + if (item.el) { + if (!this.hasWidget(this._getChildName("north"))) { + const w = _lazyCreateWidget(item); + this.addWidget(this._getChildName("north"), w); + } + this.getWidgetByName(this._getChildName("north")).element.height(this._optimiseGap(item.height)) + .css({ + position: "absolute", + top: this._optimiseGap(item.top || 0), + left: this._optimiseGap(item.left || 0), + right: this._optimiseGap(item.right || 0), + bottom: "initial", + }); + } + top = (item.height || 0) + (item.top || 0) + (item.bottom || 0); + } + } + if ("south" in regions) { + item = regions.south; + if (isNotNull(item)) { + if (item.el) { + if (!this.hasWidget(this._getChildName("south"))) { + const w = _lazyCreateWidget(item); + this.addWidget(this._getChildName("south"), w); + } + this.getWidgetByName(this._getChildName("south")).element.height(this._optimiseGap(item.height)) + .css({ + position: "absolute", + bottom: this._optimiseGap(item.bottom || 0), + left: this._optimiseGap(item.left || 0), + right: this._optimiseGap(item.right || 0), + top: "initial", + }); + } + bottom = (item.height || 0) + (item.top || 0) + (item.bottom || 0); + } + } + if ("west" in regions) { + item = regions.west; + if (isNotNull(item)) { + if (item.el) { + if (!this.hasWidget(this._getChildName("west"))) { + const w = _lazyCreateWidget(item); + this.addWidget(this._getChildName("west"), w); + } + this.getWidgetByName(this._getChildName("west")).element.width(this._optimiseGap(item.width)) + .css({ + position: "absolute", + left: this._optimiseGap(item.left || 0), + top: this._optimiseGap(top), + bottom: this._optimiseGap(bottom), + right: "initial", + }); + } + left = (item.width || 0) + (item.left || 0) + (item.right || 0); + } + } + if ("east" in regions) { + item = regions.east; + if (isNotNull(item)) { + if (item.el) { + if (!this.hasWidget(this._getChildName("east"))) { + const w = _lazyCreateWidget(item); + this.addWidget(this._getChildName("east"), w); + } + this.getWidgetByName(this._getChildName("east")).element.width(this._optimiseGap(item.width)) + .css({ + position: "absolute", + right: this._optimiseGap(item.right || 0), + top: this._optimiseGap(top), + bottom: this._optimiseGap(bottom), + left: "initial", + }); + } + right = (item.width || 0) + (item.left || 0) + (item.right || 0); + } + } + if ("center" in regions) { + item = regions.center; + if (isNotNull(item)) { + if (!this.hasWidget(this._getChildName("center"))) { + const w = _lazyCreateWidget(item); + this.addWidget(this._getChildName("center"), w); + } + this.getWidgetByName(this._getChildName("center")).element + .css({ + position: "absolute", + top: this._optimiseGap(top), + bottom: this._optimiseGap(bottom), + left: this._optimiseGap(left), + right: this._optimiseGap(right), + }); + } + } + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.card.js b/packages/fineui/src/core/wrapper/layout/layout.card.js new file mode 100644 index 000000000..f2f717938 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.card.js @@ -0,0 +1,224 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, each, isNotNull, isFunction, findIndex, isWidget, some, map, isKey } from "../../2.base"; +import { _lazyCreateWidget } from "../../5.inject"; +import { Events } from "../../constant"; +import { Action } from "../../action"; + +/** + * 卡片布局,可以做到当前只显示一个组件,其他的都隐藏 + * @class CardLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {String} options.defaultShowName 默认展示的子组件名 + */ +@shortcut() +export class CardLayout extends Layout { + static xtype = "bi.card"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-card-layout", + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + stroke(items) { + const o = this.options; + this.showIndex = void 0; + each(items, (i, item) => { + if (item) { + let w; + if (!this.hasWidget(item.cardName)) { + w = _lazyCreateWidget(item); + w.on(Events.DESTROY, () => { + const index = findIndex(o.items, (i, tItem) => tItem.cardName === item.cardName); + if (index > -1) { + o.items.splice(index, 1); + } + }); + this.addWidget(this._getChildName(item.cardName), w); + } else { + w = this.getWidgetByName(this._getChildName(item.cardName)); + } + w.element.css({ + position: "relative", + top: "0", + left: "0", + width: "100%", + height: "100%", + }); + w.setVisible(false); + } + }); + } + + resize() { + // console.log("Card布局不需要resize"); + } + + update(opt) { + return this.forceUpdate(opt); + } + + empty(...args) { + super.empty(...args); + this.options.items = []; + } + + populate(...args) { + super.populate(...args); + this._mount(); + this.options.defaultShowName && this.showCardByName(this.options.defaultShowName); + } + + isCardExisted(cardName) { + return some(this.options.items, (i, item) => item.cardName == cardName && item.el); + } + + getCardByName(cardName) { + if (!this.isCardExisted(cardName)) { + throw new Error("cardName not exist", cardName); + } + + return this._children[this._getChildName(cardName)]; + } + + _deleteCardByName(cardName) { + delete this._children[this._getChildName(cardName)]; + const index = findIndex(this.options.items, (i, item) => item.cardName == cardName); + if (index > -1) { + this.options.items.splice(index, 1); + } + } + + deleteCardByName(cardName) { + if (!this.isCardExisted(cardName)) { + throw new Error("cardName not exist", cardName); + } + + const child = this._children[this._getChildName(cardName)]; + this._deleteCardByName(cardName); + child && child._destroy(); + } + + addCardByName(cardName, cardItem) { + if (this.isCardExisted(cardName)) { + throw new Error("cardName already exist", cardName); + } + const widget = _lazyCreateWidget(cardItem, this); + widget.element.css({ + position: "relative", + top: "0", + left: "0", + width: "100%", + height: "100%", + }).appendTo(this.element); + widget.invisible(); + this.addWidget(this._getChildName(cardName), widget); + this.options.items.push({ el: cardItem, cardName }); + + return widget; + } + + showCardByName(name, action, callback) { + // name不存在的时候全部隐藏 + const exist = this.isCardExisted(name); + if (isNotNull(this.showIndex)) { + this.lastShowIndex = this.showIndex; + } + this.showIndex = name; + let flag = false; + each(this.options.items, (i, item) => { + const el = this._children[this._getChildName(item.cardName)]; + if (el) { + if (name !== item.cardName) { + // 动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 + !flag && !exist && (Action && action instanceof Action) ? (action.actionBack(el), flag = true) : el.invisible(); + } else { + (Action && action instanceof Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), callback && callback()); + } + } + }); + } + + showLastCard() { + this.showIndex = this.lastShowIndex; + each(this.options.items, (i, item) => { + this._children[this._getChildName(item.cardName)].setVisible(this.showIndex === i); + }); + } + + setDefaultShowName(name) { + this.options.defaultShowName = name; + + return this; + } + + getDefaultShowName() { + return this.options.defaultShowName; + } + + getAllCardNames() { + return map(this.options.items, (i, item) => item.cardName); + } + + getShowingCard() { + if (!isKey(this.showIndex)) { + return void 0; + } + + return this.getWidgetByName(this._getChildName(this.showIndex)); + } + + deleteAllCard() { + each(this.getAllCardNames(), (i, name) => { + this.deleteCardByName(name); + }); + } + + hideAllCard() { + each(this.options.items, (i, item) => { + this._children[this._getChildName(item.cardName)].invisible(); + }); + } + + isAllCardHide() { + let flag = true; + some(this.options.items, (i, item) => { + if (this._children[this._getChildName(item.cardName)].isVisible()) { + flag = false; + + return false; + } + }); + + return flag; + } + + removeWidget(nameOrWidget) { + let removeName; + if (isWidget(nameOrWidget)) { + each(this._children, (name, child) => { + if (child === nameOrWidget) { + removeName = name; + } + }); + } else { + removeName = nameOrWidget; + } + if (removeName) { + this._deleteCardByName(removeName); + } + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.default.js b/packages/fineui/src/core/wrapper/layout/layout.default.js new file mode 100644 index 000000000..325be127e --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.default.js @@ -0,0 +1,47 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction } from "../../2.base"; + +/** + * 默认的布局方式 + * + * @class DefaultLayout + * @extends Layout + */ +@shortcut() +export class DefaultLayout extends Layout { + static xtype = "bi.default"; + + props() { + return extend(super.props(...arguments), { + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const w = super._addElement(...arguments); + this._handleGap(w, item); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.division.js b/packages/fineui/src/core/wrapper/layout/layout.division.js new file mode 100644 index 000000000..82f09bfc2 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.division.js @@ -0,0 +1,138 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, makeArray, each, isArray } from "../../2.base"; +import { Widget } from "../../4.widget"; +import { _lazyCreateWidget } from "../../5.inject"; + +/** + * 分隔容器的控件,按照宽度和高度所占比平分整个容器 + * + * @class DivisionLayout + * @extends Layout + */ +@shortcut() +export class DivisionLayout extends Layout { + static xtype = "bi.division"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-division", + columns: null, + rows: null, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + const rows = o.rows || o.items.length, columns = o.columns || ((o.items[0] && o.items[0].length) | 0); + const map = makeArray(rows), widths = {}, heights = {}; + + function firstElement (item, cls) { + item.addClass(cls); + + return item; + } + + function firstObject (item, cls) { + item.cls = (item.cls || "") + cls; + + return item; + } + + function first (item, cls) { + if (item instanceof Widget) { + firstElement(item.element, cls); + } else if (item.el instanceof Widget) { + firstElement(item.el.element, cls); + } else if (item.el) { + firstObject(item.el, cls); + } else { + firstObject(item, cls); + } + } + + each(map, i => { + map[i] = makeArray(columns); + }); + each(items, (i, item) => { + if (isArray(item)) { + each(item, (j, el) => { + widths[i] = (widths[i] || 0) + item.width; + heights[j] = (heights[j] || 0) + item.height; + map[i][j] = el; + }); + + return; + } + widths[item.row] = (widths[item.row] || 0) + item.width; + heights[item.column] = (heights[item.column] || 0) + item.height; + map[item.row][item.column] = item; + }); + for (let i = 0; i < rows; i++) { + let totalW = 0; + for (let j = 0; j < columns; j++) { + let w; + if (!map[i][j]) { + throw new Error(`item(${i}${j}) must exist`, map); + } + if (!this.hasWidget(this._getChildName(`${i}_${j}`))) { + w = _lazyCreateWidget(map[i][j]); + this.addWidget(this._getChildName(`${i}_${j}`), w); + } else { + w = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + } + const left = totalW * 100 / widths[i]; + w.element.css({ position: "absolute", left: `${left}%` }); + if (j > 0) { + const lastW = this.getWidgetByName(this._getChildName(`${i}_${j - 1}`)); + lastW.element.css({ right: `${100 - left}%` }); + } + if (j === o.columns - 1) { + w.element.css({ right: "0%" }); + } + first(w, this.getRowColumnCls(i, j, rows - 1, columns - 1)); + totalW += map[i][j].width; + } + } + for (let j = 0; j < o.columns; j++) { + let totalH = 0; + for (let i = 0; i < o.rows; i++) { + const w = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + const top = totalH * 100 / heights[j]; + w.element.css({ top: `${top}%` }); + if (i > 0) { + const lastW = this.getWidgetByName(this._getChildName(`${i - 1}_${j}`)); + lastW.element.css({ bottom: `${100 - top}%` }); + } + if (i === o.rows - 1) { + w.element.css({ bottom: "0%" }); + } + totalH += map[i][j].height; + } + } + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.flow.js b/packages/fineui/src/core/wrapper/layout/layout.flow.js new file mode 100644 index 000000000..0ab22e88d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.flow.js @@ -0,0 +1,196 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, isNotNull, isNumber } from "../../2.base"; +import { pixFormat } from "../../constant"; + +/** + * 靠左对齐的自由浮动布局 + * @class FloatLeftLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class FloatLeftLayout extends Layout { + static xtype = "bi.left"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-left clearfix", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + if (o.innerHgap !== 0) { + this.element.css({ + paddingLeft: this._optimiseGap(o.innerHgap), + paddingRight: this._optimiseGap(o.innerHgap), + }); + } + if (o.innerVgap !== 0) { + this.element.css({ + paddingTop: this._optimiseGap(o.innerVgap), + paddingBottom: this._optimiseGap(o.innerVgap), + }); + } + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + w.element.css({ position: "relative", "float": "left" }); + if (isNotNull(item.left)) { + w.element.css({ left: isNumber(item.left) ? this._optimiseGap(item.left) : item.left }); + } + if (isNotNull(item.right)) { + w.element.css({ right: isNumber(item.right) ? this._optimiseGap(item.right) : item.right }); + } + if (isNotNull(item.top)) { + w.element.css({ top: isNumber(item.top) ? this._optimiseGap(item.top) : item.top }); + } + if (isNotNull(item.bottom)) { + w.element.css({ bottom: isNumber(item.bottom) ? this._optimiseGap(item.bottom) : item.bottom }); + } + if (o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + const top = o.vgap / 2 + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-top": this._optimiseGap(top), + }); + } + if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + const left = o.hgap / 2 + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-left": this._optimiseGap(left), + }); + } + if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + const right = o.hgap / 2 + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-right": this._optimiseGap(right), + }); + } + if (o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + const bottom = o.vgap / 2 + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-bottom": this._optimiseGap(bottom), + }); + } + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} + +/** + * 靠右对齐的自由浮动布局 + * @class FloatRightLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class FloatRightLayout extends Layout { + static xtype = "bi.right"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-right clearfix", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + if (o.innerHgap !== 0) { + this.element.css({ + paddingLeft: this._optimiseGap(o.innerHgap), + paddingRight: this._optimiseGap(o.innerHgap), + }); + } + if (o.innerVgap !== 0) { + this.element.css({ + paddingTop: this._optimiseGap(o.innerVgap), + paddingBottom: this._optimiseGap(o.innerVgap), + }); + } + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + w.element.css({ position: "relative", "float": "right" }); + if (isNotNull(item.left)) { + w.element.css({ left: pixFormat(item.left) }); + } + if (isNotNull(item.right)) { + w.element.css({ right: pixFormat(item.right) }); + } + if (isNotNull(item.top)) { + w.element.css({ top: pixFormat(item.top) }); + } + if (isNotNull(item.bottom)) { + w.element.css({ bottom: pixFormat(item.bottom) }); + } + if (o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { + const top = o.vgap / 2 + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-top": this._optimiseGap(top), + }); + } + if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { + const left = o.hgap / 2 + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-left": this._optimiseGap(left), + }); + } + if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { + const right = o.hgap / 2 + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); + w.element.css({ + "margin-right": this._optimiseGap(right), + }); + } + if (o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { + const bottom = o.vgap / 2 + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + w.element.css({ + "margin-bottom": this._optimiseGap(bottom), + }); + } + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.grid.js b/packages/fineui/src/core/wrapper/layout/layout.grid.js new file mode 100644 index 000000000..780bc6015 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.grid.js @@ -0,0 +1,109 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, isArray, each } from "../../2.base"; +import { Widget } from "../../4.widget"; +import { _lazyCreateWidget } from "../../5.inject"; + +@shortcut() +export class GridLayout extends Layout { + static xtype = "bi.grid"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-grid", + columns: null, + rows: null, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem() { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + const rows = o.rows || o.items.length, columns = o.columns || ((o.items[0] && o.items[0].length) | 0); + const width = 100 / columns, height = 100 / rows; + const els = []; + for (let i = 0; i < rows; i++) { + els[i] = []; + } + + function firstElement (item, cls) { + item.addClass(cls); + + return item; + } + + function firstObject (item, cls) { + item.cls = (item.cls || "") + cls; + + return item; + } + + function first (item, row, col) { + if (item instanceof Widget) { + firstElement(item.element, row, col); + } else if (item.el instanceof Widget) { + firstElement(item.el.element, row, col); + } else if (item.el) { + firstObject(item.el, row, col); + } else { + firstObject(item, row, col); + } + } + + each(items, (i, item) => { + if (isArray(item)) { + each(item, (j, el) => { + els[i][j] = _lazyCreateWidget(el); + }); + + return; + } + els[item.row][item.column] = _lazyCreateWidget(item); + }); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + if (!els[i][j]) { + els[i][j] = _lazyCreateWidget({ + type: "bi.layout", + }); + } + first(els[i][j], this.getRowColumnCls(i, j, rows - 1, columns - 1)); + els[i][j].element.css({ + position: "absolute", + top: `${height * i}%`, + left: `${width * j}%`, + right: `${100 - (width * (j + 1))}%`, + bottom: `${100 - (height * (i + 1))}%`, + }); + this.addWidget(this._getChildName(`${i}_${j}`), els[i][j]); + } + } + } + + resize() { + // console.log("grid布局不需要resize") + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.horizontal.js b/packages/fineui/src/core/wrapper/layout/layout.horizontal.js new file mode 100644 index 000000000..32938ef93 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.horizontal.js @@ -0,0 +1,6 @@ +import { shortcut } from "../../decorator"; + +@shortcut() +export class HorizontalLayout { + static xtype = "bi.horizontal"; +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.inline.js b/packages/fineui/src/core/wrapper/layout/layout.inline.js new file mode 100644 index 000000000..e837af6fc --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.inline.js @@ -0,0 +1,107 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, isNull } from "../../2.base"; +import { pixFormat, HorizontalAlign, VerticalAlign } from "../../constant"; + +/** + * 内联布局 + * @class InlineLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class InlineLayout extends Layout { + static xtype = "bi.inline"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-i", + horizontalAlign: HorizontalAlign.Left, + verticalAlign: VerticalAlign.Top, + columnSize: [], + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.element.css({ + textAlign: o.horizontalAlign, + }); + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = null; + } + } + if (columnSize > 0) { + w.element.width(columnSize < 1 ? (`${(columnSize * 100).toFixed(1)}%`) : pixFormat(columnSize)); + } + w.element.css({ + position: "relative", + "vertical-align": o.verticalAlign, + }); + w.element.addClass("i-item"); + if (columnSize === "fill" || columnSize === "") { + let length = 0, gap = o.hgap + o.innerHgap; + let fillCount = 0, autoCount = 0; + for (let k = 0, len = o.columnSize.length || o.items.length; k < len; k++) { + let cz = o.columnSize.length > 0 ? o.columnSize[k] : o.items[k].width; + if (cz === "fill") { + fillCount++; + cz = 0; + } else if (cz === "" || isNull(cz)) { + autoCount++; + cz = 0; + } + gap += o.hgap + o.lgap + o.rgap + this._optimiseItemLgap(o.items[k]) + this._optimiseItemRgap(o.items[k]) + this._optimiseItemHgap(o.items[k]); + length += cz; + } + length = length > 0 && length < 1 ? `${(length * 100).toFixed(1)}%` : pixFormat(length); + gap = gap > 0 && gap < 1 ? `${(gap * 100).toFixed(1)}%` : pixFormat(gap); + if (columnSize === "fill") { + w.element.css("min-width", `calc((100% - ${length} - ${gap})${fillCount > 1 ? `/${fillCount}` : ""})`); + } + if (o.horizontalAlign === HorizontalAlign.Stretch || !(o.scrollable === true || o.scrollx === true)) { + if (columnSize === "fill") { + w.element.css("max-width", `calc((100% - ${length} - ${gap})${fillCount > 1 ? `/${fillCount}` : ""})`); + } else { + w.element.css("max-width", `calc((100% - ${length} - ${gap})${autoCount > 1 ? `/${autoCount}` : ""})`); + } + } + } + this._handleGap(w, item, i); + if (o.verticalAlign === VerticalAlign.Stretch && isNull(item.height)) { + const top = o.innerVgap + o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item), + bottom = o.innerVgap + o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); + const gap = (top + bottom) > 0 && (top + bottom) < 1 ? `${((top + bottom) * 100).toFixed(1)}%` : pixFormat(top + bottom); + w.element.css("height", `calc(100% - ${gap})`); + } + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.lattice.js b/packages/fineui/src/core/wrapper/layout/layout.lattice.js new file mode 100644 index 000000000..65d049976 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.lattice.js @@ -0,0 +1,52 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, sum } from "../../2.base"; + +/** + * 靠左对齐的自由浮动布局 + * @class LatticeLayout + * @extends Layout + * + * @cfg {JSON} options 配置属性 + * @cfg {Number} [hgap=0] 水平间隙 + * @cfg {Number} [vgap=0] 垂直间隙 + */ +@shortcut() +export class LatticeLayout extends Layout { + static xtype = "bi.lattice"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-lattice clearfix", + // columnSize: [0.2, 0.2, 0.6], + }); + } + + render() { + super.render(...arguments); + const self = this, o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + self.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let width; + if (o.columnSize && o.columnSize[i]) { + width = `${o.columnSize[i] / sum(o.columnSize) * 100}%`; + } else { + width = `${1 / this.options.items.length * 100}%`; + } + w.element.css({ position: "relative", "float": "left", width }); + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.table.js b/packages/fineui/src/core/wrapper/layout/layout.table.js new file mode 100644 index 000000000..ec75bc8f0 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.table.js @@ -0,0 +1,125 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, range, isArray, map, reduce, isEmpty, formatEL } from "../../2.base"; +import { Widget } from "../../4.widget"; +import { HorizontalAlign, VerticalAlign } from "../../constant"; + +/** + * 上下的高度固定/左右的宽度固定,中间的高度/宽度自适应 + * + * @class TableLayout + * @extends Layout + */ +@shortcut() +export class TableLayout extends Layout { + static xtype = "bi.table"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-t", + // scrolly: true, + columnSize: [], + rowSize: [], + horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + // rowSize: 30, // or [30,30,30] + hgap: 0, + vgap: 0, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + + const columnSize = o.columnSize.length > 0 ? o.columnSize : range(items[0].length).fill(""); + + if (columnSize.length > 0) { + const template = []; + for (let i = 0; i < columnSize.length; i++) { + if (columnSize[i] === "") { + template.push("auto"); + } else if (columnSize[i] === "fill") { + template.push("1fr"); + } else { + template.push(this._optimiseGap(columnSize[i])); + } + } + this.element.css({ + "grid-template-columns": template.join(" "), + "grid-template-rows": isArray(o.rowSize) ? map(o.rowSize, (i, size) => this._optimiseGap(size)).join(" ") : range(o.items.length).fill(this._optimiseGap(o.rowSize)).join(" "), + "grid-row-gap": this._optimiseGap(o.vgap), + "grid-column-gap": this._optimiseGap(o.hgap), + }); + } + + return { + type: "bi.default", + ref(_ref) { + this.layout = _ref; + }, + items: this._formatItems(items), + }; + } + + _formatItems(items) { + const o = this.options; + + function firstElement (item, cls) { + item.addClass(cls); + + return item; + } + + function firstObject (item, cls) { + item.cls = (item.cls || "") + cls; + + return item; + } + + function first (item, cls) { + if (item instanceof Widget) { + return firstElement(item.element, cls); + } else if (item.el instanceof Widget) { + return firstElement(item.el.element, cls); + } else if (item.el) { + return firstObject(item.el, cls); + } else { + return firstObject(item, cls); + } + } + + function wrapLayout (item) { + return { + type: "bi.horizontal_fill", + columnSize: ["fill"], + horizontalAlign: o.horizontalAlign, + verticalAlign: o.verticalAlign, + items: [formatEL(item)], + }; + } + + return reduce(items, (rowItems, result, rowIndex) => result.concat(map(rowItems, (colIndex, item) => { + const cls = this.getRowColumnCls(rowIndex, colIndex, items.length - 1, rowItems.length - 1); + if (isEmpty(item)) { + return first(wrapLayout({ + type: "bi.layout", + }), cls); + } + + return first(wrapLayout(item), cls); + })), []); + } + + resize() { + // console.log("table布局不需要resize"); + } + + populate(items) { + this.layout.populate(this._formatItems(items)); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.tape.js b/packages/fineui/src/core/wrapper/layout/layout.tape.js new file mode 100644 index 000000000..f5e32698a --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.tape.js @@ -0,0 +1,267 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, compact, each, isEmptyObject, isNumber, isNull, any, backAny } from "../../2.base"; +import { _lazyCreateWidget } from "../../5.inject"; +import { HorizontalAlign, VerticalAlign } from "../../constant"; + +/** + * 水平tape布局 + * @class HTapeLayout + * @extends Layout + */ +@shortcut() +export class HTapeLayout extends Layout { + static xtype = "bi.htape"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-h-tape", + verticalAlign: VerticalAlign.Top, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + columnSize: [], + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + items = compact(items); + each(items, (i, item) => { + let w; + if (isEmptyObject(item)) { + return; + } + if (!this.hasWidget(this._getChildName(i))) { + w = _lazyCreateWidget(item); + this.addWidget(this._getChildName(i), w); + } else { + w = this.getWidgetByName(this._getChildName(i)); + } + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = item.width; + } + } + w.element.css({ + position: "absolute", + top: this._optimiseGap(this._optimiseItemTgap(item) + this._optimiseItemVgap(item) + o.innerVgap + o.vgap + o.tgap), + bottom: this._optimiseGap(this._optimiseItemBgap(item) + this._optimiseItemVgap(item) + o.innerVgap + o.vgap + o.bgap), + width: isNumber(columnSize) ? this._optimiseGap(columnSize) : "", + }); + if (o.verticalAlign === VerticalAlign.Middle) { + w.element.css({ + marginTop: "auto", + marginBottom: "auto", + }); + } else if (o.verticalAlign === VerticalAlign.Bottom) { + w.element.css({ + marginTop: "auto", + }); + } + }); + + const left = {}, right = {}; + left[0] = o.innerHgap; + right[items.length - 1] = o.innerHgap; + + any(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.getWidgetByName(this._getChildName(i)); + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = item.width; + } + } + if (isNull(left[i])) { + const preColumnSize = o.columnSize.length > 0 ? o.columnSize[i - 1] : items[i - 1].width; + left[i] = left[i - 1] + preColumnSize + this._optimiseItemLgap(items[i - 1]) + this._optimiseItemRgap(items[i - 1]) + 2 * this._optimiseItemHgap(items[i - 1]) + o.hgap + o.lgap + o.rgap; + } + w.element.css({ + left: this._optimiseGap(left[i] + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) + o.hgap + o.lgap), + }); + + if (isNull(columnSize) || columnSize === "" || columnSize === "fill") { + return true; + } + }); + backAny(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.getWidgetByName(this._getChildName(i)); + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (isNull(right[i])) { + const nextColumnSize = o.columnSize.length > 0 ? o.columnSize[i + 1] : items[i + 1].width; + right[i] = right[i + 1] + nextColumnSize + this._optimiseItemLgap(items[i + 1]) + this._optimiseItemRgap(items[i + 1]) + 2 * this._optimiseItemHgap(items[i + 1]) + o.hgap + o.lgap + o.rgap; + } + w.element.css({ + right: this._optimiseGap(right[i] + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) + o.hgap + o.rgap), + }); + + if (isNull(columnSize) || columnSize === "" || columnSize === "fill") { + return true; + } + }); + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(items) { + super.populate(...arguments); + this._mount(); + } +} + +/** + * 垂直tape布局 + * @class VTapeLayout + * @extends Layout + */ +@shortcut() +export class VTapeLayout extends Layout { + static xtype = "bi.vtape"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-v-tape", + horizontalAlign: HorizontalAlign.Left, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + rowSize: [], + items: [], + }); + } + + render() { + super.render(...arguments); + this.populate(this.options.items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + items = compact(items); + each(items, (i, item) => { + let w; + if (isEmptyObject(item)) { + return; + } + if (!this.hasWidget(this._getChildName(i))) { + w = _lazyCreateWidget(item); + this.addWidget(this._getChildName(i), w); + } else { + w = this.getWidgetByName(this._getChildName(i)); + } + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = item.height; + } + } + w.element.css({ + position: "absolute", + left: this._optimiseGap(this._optimiseItemLgap(item) + this._optimiseItemHgap(item) + o.innerHgap + o.hgap + o.lgap), + right: this._optimiseGap(this._optimiseItemRgap(item) + this._optimiseItemHgap(item) + o.innerHgap + o.hgap + o.rgap), + height: isNumber(rowSize) ? this._optimiseGap(rowSize) : "", + }); + if (o.horizontalAlign === HorizontalAlign.Center) { + w.element.css({ + marginLeft: "auto", + marginRight: "auto", + }); + } else if (o.horizontalAlign === HorizontalAlign.Right) { + w.element.css({ + marginLeft: "auto", + }); + } + }); + + const top = {}, bottom = {}; + top[0] = o.innerVgap; + bottom[items.length - 1] = o.innerVgap; + + any(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.getWidgetByName(this._getChildName(i)); + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = item.height; + } + } + if (isNull(top[i])) { + const preRowSize = o.rowSize.length > 0 ? o.rowSize[i - 1] : items[i - 1].height; + top[i] = top[i - 1] + preRowSize + this._optimiseItemTgap(items[i - 1]) + this._optimiseItemBgap(items[i - 1]) + 2 * this._optimiseItemVgap(items[i - 1]) + o.vgap + o.tgap + o.bgap; + } + w.element.css({ + top: this._optimiseGap(top[i] + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) + o.vgap + o.tgap), + }); + + if (isNull(rowSize) || rowSize === "" || rowSize === "fill") { + return true; + } + }); + backAny(items, (i, item) => { + if (isEmptyObject(item)) { + return true; + } + const w = this.getWidgetByName(this._getChildName(i)); + const rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (isNull(bottom[i])) { + const nextRowSize = o.rowSize.length > 0 ? o.rowSize[i + 1] : items[i + 1].height; + bottom[i] = bottom[i + 1] + nextRowSize + this._optimiseItemTgap(items[i + 1]) + this._optimiseItemBgap(items[i + 1]) + 2 * this._optimiseItemVgap(items[i + 1]) + o.vgap + o.tgap + o.bgap; + } + w.element.css({ + bottom: this._optimiseGap(bottom[i] + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) + o.vgap + o.bgap), + }); + + if (isNull(rowSize) || rowSize === "" || rowSize === "fill") { + return true; + } + }); + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.td.js b/packages/fineui/src/core/wrapper/layout/layout.td.js new file mode 100644 index 000000000..e9228ca2d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.td.js @@ -0,0 +1,180 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, isOdd, some, isNumber, isNull } from "../../2.base"; +import { Widget } from "../../4.widget"; +import { _lazyCreateWidget } from "../../5.inject"; +import { HorizontalAlign, VerticalAlign } from "../../constant"; + +/** + * td布局 + * @class TdLayout + * @extends Layout + */ +@shortcut() +export class TdLayout extends Layout { + static xtype = "bi.td"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-td", + columnSize: [], + rowSize: [], + verticalAlign: VerticalAlign.Middle, + horizontalAlign: HorizontalAlign.Stretch, + hgap: 0, + vgap: 0, + tgap: 0, + bgap: 0, + lgap: 0, + rgap: 0, + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + this.$table = Widget._renderEngine.createElement("").attr({ cellspacing: 0, cellpadding: 0 }).css({ + position: "relative", + width: (o.horizontalAlign === HorizontalAlign.Center || o.horizontalAlign === HorizontalAlign.Stretch) ? "100%" : "auto", + height: (o.verticalAlign !== VerticalAlign.Top) ? "100%" : "auto", + "border-spacing": "0px", + border: "none", + "border-collapse": "separate", + }); + this.rows = 0; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(idx, arr) { + const o = this.options; + + function firstElement (item, row, col) { + if (row === 0) { + item.addClass("first-row"); + } + if (col === 0) { + item.addClass("first-col"); + } + item.addClass(isOdd(row + 1) ? "odd-row" : "even-row"); + item.addClass(isOdd(col + 1) ? "odd-col" : "even-col"); + item.addClass("center-element"); + } + + function firstObject (item, row, col) { + let cls = ""; + if (row === 0) { + cls += " first-row"; + } + if (col === 0) { + cls += " first-col"; + } + isOdd(row + 1) ? (cls += " odd-row") : (cls += " even-row"); + isOdd(col + 1) ? (cls += " odd-col") : (cls += " even-col"); + item.cls = `${(item.cls || "") + cls} center-element`; + } + + function first (item, row, col) { + if (item instanceof Widget) { + firstElement(item.element, row, col); + } else if (item.el instanceof Widget) { + firstElement(item.el.element, row, col); + } else if (item.el) { + firstObject(item.el, row, col); + } else { + firstObject(item, row, col); + } + } + + const height = isNumber(o.rowSize) ? this._optimiseGap(o.rowSize) : (o.rowSize[idx] === "" ? this._optimiseGap(1) : this._optimiseGap(o.rowSize[idx])); + const tr = _lazyCreateWidget({ + type: "bi.default", + tagName: "tr", + height, + css: { + "max-height": height, + "min-height": height, + }, + }); + + for (let i = 0; i < arr.length; i++) { + const w = _lazyCreateWidget(arr[i]); + if (o.verticalAlign === VerticalAlign.Stretch) { + const top = o.vgap + o.tgap + this._optimiseItemTgap(arr[i]) + this._optimiseItemVgap(arr[i]), + bottom = o.vgap + o.bgap + this._optimiseItemBgap(arr[i]) + this._optimiseItemVgap(arr[i]); + w.element.css("height", `calc(100% - ${this._optimiseGap(top + bottom)})`); + } + w.element.css({ position: "relative", top: "0", left: "0", margin: "0px auto" }); + const item = arr[i]; + this._handleGap(w, item, i); + first(w, this.rows++, i); + let width = ""; + const columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (columnSize > 0) { + width = this._optimiseGap(columnSize + (i === 0 ? o.hgap : 0) + o.hgap + o.lgap + o.rgap); + } + function hasFill() { + if (o.columnSize.length > 0) { + return o.columnSize.indexOf("fill") >= 0; + } + + return some(arr, (i, item) => { + if (item.width === "fill") { + return true; + } + }); + } + if ((isNull(columnSize) || columnSize === "") && hasFill()) { + width = 2; + } + const td = _lazyCreateWidget({ + type: "bi.default", + width, + tagName: "td", + items: [w], + }); + // 对于表现为td的元素设置最大宽度,有几点需要注意 + // 1、由于直接对td设置最大宽度是在规范中未定义的, 所以要使用类似td:firstChild来迂回实现 + // 2、不能给多个td设置最大宽度,这样只会平分宽度 + // 3、多百分比宽度就算了 + if (columnSize > 0) { + td.element.css({ + "max-width": width, + "min-width": width, + }); + } + td.element.css({ + position: "relative", + "vertical-align": o.verticalAlign, + margin: "0", + padding: "0", + border: "none", + }); + tr.addItem(td); + } + this.addWidget(this._getChildName(idx), tr); + + return tr; + } + + appendFragment(frag) { + this.$table.append(frag); + this.element.append(this.$table); + } + + resize() { + // console.log("td布局不需要resize"); + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.vertical.js b/packages/fineui/src/core/wrapper/layout/layout.vertical.js new file mode 100644 index 000000000..ada08e063 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.vertical.js @@ -0,0 +1,63 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction } from "../../2.base"; +import { HorizontalAlign } from "../../constant"; + +/** + * 垂直布局 + * @class VerticalLayout + * @extends Layout + */ +@shortcut() +export class VerticalLayout extends Layout { + static xtype = "bi.vertical"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-v", + horizontalAlign: HorizontalAlign.Stretch, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + scrolly: true, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + w.element.css({ + position: "relative", + }); + this._handleGap(w, item, null, i); + if (o.horizontalAlign === HorizontalAlign.Center) { + w.element.css({ + marginLeft: "auto", + marginRight: "auto", + }); + } else if (o.horizontalAlign === HorizontalAlign.Right) { + w.element.css({ + marginLeft: "auto", + }); + } + + return w; + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/layout.window.js b/packages/fineui/src/core/wrapper/layout/layout.window.js new file mode 100644 index 000000000..89357bd27 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/layout.window.js @@ -0,0 +1,187 @@ +import { shortcut } from "../../decorator"; +import { Layout } from "../layout"; +import { extend, isFunction, makeArray, isNumber, isNull } from "../../2.base"; +import { Widget } from "../../4.widget"; +import { _lazyCreateWidget } from "../../5.inject"; + +/** + * + * @class WindowLayout + * @extends Layout + */ +@shortcut() +export class WindowLayout extends Layout { + static xtype = "bi.window"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-window", + columns: 3, + rows: 2, + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + columnSize: [], + rowSize: [], + items: [], + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { + this.populate(newValue); + }) : o.items; + this.populate(items); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + stroke(items) { + const o = this.options; + if (isNumber(o.rowSize)) { + o.rowSize = makeArray(o.items.length, 1 / o.items.length); + } + if (isNumber(o.columnSize)) { + o.columnSize = makeArray(o.items[0].length, 1 / o.items[0].length); + } + + function firstElement (item, cls) { + item.addClass(cls); + + return item; + } + + function firstObject (item, cls) { + item.cls = (item.cls || "") + cls; + + return item; + } + + function first (item, row, col) { + if (item instanceof Widget) { + firstElement(item.element, row, col); + } else if (item.el instanceof Widget) { + firstElement(item.el.element, row, col); + } else if (item.el) { + firstObject(item.el, row, col); + } else { + firstObject(item, row, col); + } + } + + for (let i = 0; i < o.rows; i++) { + for (let j = 0; j < o.columns; j++) { + if (!o.items[i][j]) { + throw new Error("create items error", o.items); + } + if (!this.hasWidget(this._getChildName(`${i}_${j}`))) { + const w = _lazyCreateWidget(o.items[i][j]); + w.element.css({ position: "absolute" }); + this.addWidget(this._getChildName(`${i}_${j}`), w); + } + } + } + const left = {}, right = {}, top = {}, bottom = {}; + left[0] = 0; + top[0] = 0; + right[o.columns - 1] = 0; + bottom[o.rows - 1] = 0; + // 从上到下 + for (let i = 0; i < o.rows; i++) { + for (let j = 0; j < o.columns; j++) { + const wi = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + if (isNull(top[i])) { + top[i] = top[i - 1] + (o.rowSize[i - 1] < 1 ? o.rowSize[i - 1] : o.rowSize[i - 1] + o.vgap + o.bgap); + } + const t = this._optimiseGap(top[i] + o.vgap + o.tgap); + let h = ""; + if (isNumber(o.rowSize[i])) { + h = this._optimiseGap(o.rowSize[i]); + } + wi.element.css({ top: t, height: h }); + first(wi, this.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); + } + if (!isNumber(o.rowSize[i])) { + break; + } + } + // 从下到上 + for (let i = o.rows - 1; i >= 0; i--) { + for (let j = 0; j < o.columns; j++) { + const wi = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + if (isNull(bottom[i])) { + bottom[i] = bottom[i + 1] + (o.rowSize[i + 1] < 1 ? o.rowSize[i + 1] : o.rowSize[i + 1] + o.vgap + o.tgap); + } + const b = this._optimiseGap(bottom[i] + o.vgap + o.bgap); + let h = ""; + if (isNumber(o.rowSize[i])) { + h = this._optimiseGap(o.rowSize[i]); + } + wi.element.css({ bottom: b, height: h }); + first(wi, this.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); + } + if (!isNumber(o.rowSize[i])) { + break; + } + } + // 从左到右 + for (let j = 0; j < o.columns; j++) { + for (let i = 0; i < o.rows; i++) { + const wi = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + if (isNull(left[j])) { + left[j] = left[j - 1] + (o.columnSize[j - 1] < 1 ? o.columnSize[j - 1] : o.columnSize[j - 1] + o.hgap + o.rgap); + } + const l = this._optimiseGap(left[j] + o.hgap + o.lgap); + let w = ""; + if (isNumber(o.columnSize[j])) { + w = this._optimiseGap(o.columnSize[j]); + } + wi.element.css({ left: l, width: w }); + first(wi, this.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); + } + if (!isNumber(o.columnSize[j])) { + break; + } + } + // 从右到左 + for (let j = o.columns - 1; j >= 0; j--) { + for (let i = 0; i < o.rows; i++) { + const wi = this.getWidgetByName(this._getChildName(`${i}_${j}`)); + if (isNull(right[j])) { + right[j] = right[j + 1] + (o.columnSize[j + 1] < 1 ? o.columnSize[j + 1] : o.columnSize[j + 1] + o.hgap + o.lgap); + } + const r = this._optimiseGap(right[j] + o.hgap + o.rgap); + let w = ""; + if (isNumber(o.columnSize[j])) { + w = this._optimiseGap(o.columnSize[j]); + } + wi.element.css({ right: r, width: w }); + first(wi, this.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); + } + if (!isNumber(o.columnSize[j])) { + break; + } + } + } + + resize() { + // console.log("window布局不需要resize"); + } + + update(opt) { + return this.forceUpdate(opt); + } + + populate(...args) { + super.populate(...args); + this._mount(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/middle/index.js b/packages/fineui/src/core/wrapper/layout/middle/index.js new file mode 100644 index 000000000..c564fe1a6 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/middle/index.js @@ -0,0 +1,4 @@ +export { CenterLayout } from "./middle.center"; +export { FloatCenterLayout } from "./middle.float.center"; +export { HorizontalCenterLayout } from "./middle.horizontal"; +export { VerticalCenterLayout } from "./middle.vertical"; diff --git a/packages/fineui/src/core/wrapper/layout/middle/middle.center.js b/packages/fineui/src/core/wrapper/layout/middle/middle.center.js new file mode 100644 index 000000000..fe5396e31 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/middle/middle.center.js @@ -0,0 +1,80 @@ +import { shortcut } from "@/core/decorator"; +import { extend, each } from "@/core/2.base"; +import { _lazyCreateWidget } from "@/core/5.inject"; +import { Layout } from "../../layout"; + +/** + * 水平和垂直方向都居中容器, 非自适应,用于宽度高度固定的面板 + * @class CenterLayout + * @extends Layout + */ +@shortcut() +export class CenterLayout extends Layout { + static xtype = "bi.center"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-center", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options; + const list = [], items = o.items; + each(items, i => { + list.push({ + column: i, + row: 0, + el: _lazyCreateWidget({ + type: "bi.default", + cls: `center-element ${i === 0 ? "first-element " : ""}${i === items.length - 1 ? "last-element" : ""}`, + }), + }); + }); + each(items, (i, item) => { + if (item) { + const w = _lazyCreateWidget(item); + w.element.css({ + position: "absolute", + left: this._optimiseGap(o.hgap + o.lgap), + right: this._optimiseGap(o.hgap + o.rgap), + top: this._optimiseGap(o.vgap + o.tgap), + bottom: this._optimiseGap(o.vgap + o.bgap), + width: "auto", + height: "auto", + }); + list[i].el.addItem(w); + } + }); + + return { + type: "bi.grid", + ref: _ref => { + this.layout = _ref; + }, + columns: list.length, + rows: 1, + items: list, + }; + } + + resize() { + // console.log("center布局不需要resize"); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(...arguments); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/middle/middle.float.center.js b/packages/fineui/src/core/wrapper/layout/middle/middle.float.center.js new file mode 100644 index 000000000..11d38b2f6 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/middle/middle.float.center.js @@ -0,0 +1,80 @@ +import { shortcut } from "@/core/decorator"; +import { extend, each } from "@/core/2.base"; +import { _lazyCreateWidget } from "@/core/5.inject"; +import { Layout } from "../../layout"; + +/** + * 浮动布局实现的居中容器 + * @class FloatCenterLayout + * @extends Layout + */ +@shortcut() +export class FloatCenterLayout extends Layout { + static xtype = "bi.float_center"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-float-center", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options, items = o.items; + const list = [], width = 100 / items.length; + each(items, i => { + const widget = _lazyCreateWidget({ + type: "bi.default", + }); + widget.element.addClass(`center-element ${i === 0 ? "first-element " : ""}${i === items.length - 1 ? "last-element" : ""}`).css({ + width: `${width}%`, + height: "100%", + }); + list.push({ + el: widget, + }); + }); + each(items, (i, item) => { + if (item) { + const w = _lazyCreateWidget(item); + w.element.css({ + position: "absolute", + left: this._optimiseGap(o.hgap + o.lgap), + right: this._optimiseGap(o.hgap + o.rgap), + top: this._optimiseGap(o.vgap + o.tgap), + bottom: this._optimiseGap(o.vgap + o.bgap), + width: "auto", + height: "auto", + }); + list[i].el.addItem(w); + } + }); + + return { + type: "bi.left", + ref: _ref => { + this.layout = _ref; + }, + items: list, + }; + } + + resize() { + // console.log("floatcenter布局不需要resize"); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(...arguments); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/middle/middle.horizontal.js b/packages/fineui/src/core/wrapper/layout/middle/middle.horizontal.js new file mode 100644 index 000000000..a5c59b6bf --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/middle/middle.horizontal.js @@ -0,0 +1,79 @@ +import { shortcut } from "@/core/decorator"; +import { extend, each } from "@/core/2.base"; +import { _lazyCreateWidget } from "@/core/5.inject"; +import { Layout } from "../../layout"; + +/** + * 水平和垂直方向都居中容器, 非自适应,用于宽度高度固定的面板 + * @class HorizontalCenterLayout + * @extends Layout + */ +@shortcut() +export class HorizontalCenterLayout extends Layout { + static xtype = "bi.horizontal_center"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-h-center", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const o = this.options, items = o.items; + const list = []; + each(items, i => { + list.push({ + column: i, + row: 0, + el: _lazyCreateWidget({ + type: "bi.default", + cls: `center-element ${i === 0 ? "first-element " : ""}${i === items.length - 1 ? "last-element" : ""}`, + }), + }); + }); + each(items, (i, item) => { + if (item) { + const w = _lazyCreateWidget(item); + w.element.css({ + position: "absolute", + left: this._optimiseGap(o.hgap + o.lgap), + right: this._optimiseGap(o.hgap + o.rgap), + top: this._optimiseGap(o.vgap + o.tgap), + bottom: this._optimiseGap(o.vgap + o.bgap), + width: "auto", + }); + list[i].el.addItem(w); + } + }); + + return { + type: "bi.grid", + ref: _ref => { + this.layout = _ref; + }, + columns: list.length, + rows: 1, + items: list, + }; + } + + resize() { + // console.log("horizontal_center布局不需要resize"); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(...arguments); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/middle/middle.vertical.js b/packages/fineui/src/core/wrapper/layout/middle/middle.vertical.js new file mode 100644 index 000000000..30db63466 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/middle/middle.vertical.js @@ -0,0 +1,79 @@ +import { shortcut } from "@/core/decorator"; +import { extend, each } from "@/core/2.base"; +import { _lazyCreateWidget } from "@/core/5.inject"; +import { Layout } from "../../layout"; + +/** + * 垂直方向都居中容器, 非自适应,用于高度不固定的面板 + * @class VerticalCenterLayout + * @extends Layout + */ +@shortcut() +export class VerticalCenterLayout extends Layout { + static xtype = "bi.vertical_center"; + + props() { + return extend(super.props(...arguments), { + baseCls: "bi-v-center", + hgap: 0, + vgap: 0, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + }); + } + + render() { + super.render(...arguments); + const self = this, o = this.options, items = o.items; + const list = []; + each(items, i => { + list.push({ + column: 0, + row: i, + el: _lazyCreateWidget({ + type: "bi.default", + cls: `center-element ${i === 0 ? "first-element " : ""}${i === items.length - 1 ? "last-element" : ""}`, + }), + }); + }); + each(items, (i, item) => { + if (item) { + const w = _lazyCreateWidget(item); + w.element.css({ + position: "absolute", + left: self._optimiseGap(o.hgap + o.lgap), + right: self._optimiseGap(o.hgap + o.rgap), + top: self._optimiseGap(o.vgap + o.tgap), + bottom: self._optimiseGap(o.vgap + o.bgap), + height: "auto", + }); + list[i].el.addItem(w); + } + }); + + return { + type: "bi.grid", + ref: _ref => { + this.layout = _ref; + }, + columns: 1, + rows: list.length, + items: list, + }; + } + + resize() { + // console.log("vertical_center布局不需要resize"); + } + + addItem(item) { + // do nothing + throw new Error("Cannot add subwidget"); + } + + populate(items) { + this.layout.populate(...arguments); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/responsive/index.js b/packages/fineui/src/core/wrapper/layout/responsive/index.js new file mode 100644 index 000000000..89f0bb09d --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/responsive/index.js @@ -0,0 +1,3 @@ +export { ResponsiveFlexHorizontalLayout } from "./responsive.flex.horizontal"; +export { ResponsiveFlexWrapperHorizontalLayout } from "./responsive.flex.wrapper.horizontal"; +export { ResponsiveInlineLayout } from "./responsive.inline"; diff --git a/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js b/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js new file mode 100644 index 000000000..d52acb6c5 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js @@ -0,0 +1,59 @@ +import { shortcut } from "@/core/decorator"; +import { each } from "@/core/2.base"; +import { HorizontalAlign } from "@/core/constant"; +// import { Resizers } from "@/base/0.base"; +import { FlexHorizontalLayout } from "../flex"; + +/** + * 横向响应式布局 + * Created by GUY on 2016/12/2. + * + * @class ResponsiveFlexHorizontalLayout + * @extends FlexHorizontalLayout + */ +@shortcut() +export class ResponsiveFlexHorizontalLayout extends FlexHorizontalLayout { + static xtype = "bi.responsive_flex_horizontal"; + + mounted() { + const o = this.options; + if (o.horizontalAlign !== HorizontalAlign.Center) { + return; + } + const defaultResize = () => { + if (o.scrollable !== true && o.scrollx !== true) { + const clientWidth = document.body.clientWidth; + if (this.element.width() > 2 / 3 * clientWidth) { + if (clientWidth <= 768) { + each(this._children, (i, child) => { + this._clearGap(child); + this._handleReverseGap(child, o.items[i], i | 0); + }); + this.element.css("flex-direction", "column"); + } + } + } + }; + // const resize = () => { + // defaultResize(); + // if (o.scrollable !== true && o.scrollx !== true) { + // const clientWidth = document.body.clientWidth; + // if (this.element.width() > 2 / 3 * clientWidth) { + // if (clientWidth > 768) { + // each(this._children, (i, child) => { + // this._clearGap(child); + // }); + // this.resize(); + // this.element.css("flex-direction", "row"); + // } + // } + // } + // }; + // this.unResize = Resizers.add(this.getName(), resize); + defaultResize(); + } + + destroyed() { + this.unResize?.(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js b/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js new file mode 100644 index 000000000..52389036a --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js @@ -0,0 +1,61 @@ +import { shortcut } from "@/core/decorator"; +import { each } from "@/core/2.base"; +import { HorizontalAlign } from "@/core/constant"; +// import { Resizers } from "@/base/0.base"; +import { FlexWrapperHorizontalLayout } from "../flex"; + +/** + * 横向响应式布局 + * Created by GUY on 2016/12/2. + * + * @class ResponsiveFlexWrapperHorizontalLayout + * @extends FlexWrapperHorizontalLayout + */ +@shortcut() +export class ResponsiveFlexWrapperHorizontalLayout extends FlexWrapperHorizontalLayout { + static xtype = "bi.responsive_flex_scrollable_horizontal"; + + mounted() { + const o = this.options; + if (o.horizontalAlign !== HorizontalAlign.Center) { + return; + } + const defaultResize = () => { + if (o.scrollable !== true && o.scrollx !== true) { + const clientWidth = document.body.clientWidth; + if (this.element.width() > 2 / 3 * clientWidth) { + if (clientWidth <= 768) { + each(this._children, (i, child) => { + this._clearGap(child); + this._handleReverseGap(child, o.items[i], i | 0); + }); + this.element.css("flex-direction", "column"); + this.$wrapper.element.css("flex-direction", "column"); + } + } + } + }; + // const resize = () => { + // defaultResize(); + // if (o.scrollable !== true && o.scrollx !== true) { + // const clientWidth = document.body.clientWidth; + // if (this.element.width() > 2 / 3 * clientWidth) { + // if (clientWidth > 768) { + // each(this._children, (i, child) => { + // this._clearGap(child); + // }); + // this.resize(); + // this.element.css("flex-direction", "row"); + // this.$wrapper.element.css("flex-direction", "row"); + // } + // } + // } + // }; + // this.unResize = Resizers.add(this.getName(), resize); + defaultResize(); + } + + destroyed() { + this.unResize(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/responsive/responsive.inline.js b/packages/fineui/src/core/wrapper/layout/responsive/responsive.inline.js new file mode 100644 index 000000000..b0d23c09a --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/responsive/responsive.inline.js @@ -0,0 +1,58 @@ +import { shortcut } from "@/core/decorator"; +import { each } from "@/core/2.base"; +import { HorizontalAlign } from "@/core/constant"; +// import { Resizers } from "@/base/0.base"; +import { InlineLayout } from "../layout.inline"; + +/** + * 横向响应式布局 + * Created by GUY on 2016/12/2. + * + * @class ResponsiveInlineLayout + * @extends InlineLayout + */ +@shortcut() +export class ResponsiveInlineLayout extends InlineLayout { + static xtype = "bi.responsive_inline"; + + mounted() { + const o = this.options; + if (o.horizontalAlign !== HorizontalAlign.Center) { + return; + } + const defaultResize = () => { + if (o.scrollable !== true && o.scrollx !== true) { + const clientWidth = document.body.clientWidth; + if (this.element.width() > 2 / 3 * clientWidth) { + if (clientWidth <= 768) { + each(this._children, (i, child) => { + this._clearGap(child); + this._handleReverseGap(child, o.items[i], i | 0); + child.element.css("display", ""); + }); + } + } + } + }; + // const resize = () => { + // defaultResize(); + // if (o.scrollable !== true && o.scrollx !== true) { + // const clientWidth = document.body.clientWidth; + // if (this.element.width() > 2 / 3 * clientWidth) { + // if (clientWidth > 768) { + // each(this._children, (i, child) => { + // this._clearGap(child); + // }); + // this.resize(); + // } + // } + // } + // }; + // this.unResize = Resizers.add(this.getName(), resize); + defaultResize(); + } + + destroyed() { + this.unResize(); + } +} diff --git a/packages/fineui/src/core/wrapper/layout/sticky/index.js b/packages/fineui/src/core/wrapper/layout/sticky/index.js new file mode 100644 index 000000000..e4d9a91be --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/sticky/index.js @@ -0,0 +1,2 @@ +export { HorizontalStickyLayout } from "./sticky.horizontal"; +export { VerticalStickyLayout } from "./sticky.vertical"; diff --git a/packages/fineui/src/core/wrapper/layout/sticky/sticky.horizontal.js b/packages/fineui/src/core/wrapper/layout/sticky/sticky.horizontal.js new file mode 100644 index 000000000..d4b15cd66 --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/sticky/sticky.horizontal.js @@ -0,0 +1,63 @@ +import { shortcut } from "@/core/decorator"; +import { extend, count, isNotNull } from "@/core/2.base"; +import { VerticalAlign } from "@/core/constant"; +import { FlexHorizontalLayout } from "../flex"; + +/** + * 横向黏性布局 + */ +@shortcut() +export class HorizontalStickyLayout extends FlexHorizontalLayout { + static xtype = "bi.horizontal_sticky"; + + props() { + return extend(super.props(...arguments), { + extraCls: "bi-h-sticky", + scrollx: true, + // horizontalAlign: HorizontalAlign.Stretch, + verticalAlign: VerticalAlign.Stretch, + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; + if (o.columnSize.length > 0) { + if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { + columnSize = null; + } + } + if (columnSize !== "fill") { + let fillIndex; + count(0, o.items.length, index => { + if (isNotNull(fillIndex)) { + return; + } + if ((o.columnSize[index] === "fill" || o.items[index].width === "fill")) { + fillIndex = index; + } + }); + + if (fillIndex > i) { + w.element.css({ + position: "sticky", + zIndex: 1, + left: 0, + }); + } else { + w.element.css({ + position: "sticky", + zIndex: 1, + right: 0, + }); + } + } else { + w.element.css({ + overflow: "", + }); + } + + return w; + } +} diff --git a/packages/fineui/src/core/wrapper/layout/sticky/sticky.vertical.js b/packages/fineui/src/core/wrapper/layout/sticky/sticky.vertical.js new file mode 100644 index 000000000..7a05bb78b --- /dev/null +++ b/packages/fineui/src/core/wrapper/layout/sticky/sticky.vertical.js @@ -0,0 +1,63 @@ +import { shortcut } from "@/core/decorator"; +import { extend, count, isNotNull } from "@/core/2.base"; +import { HorizontalAlign } from "@/core/constant"; +import { FlexVerticalLayout } from "../flex"; + +/** + * 纵向黏性布局 + */ +@shortcut() +export class VerticalStickyLayout extends FlexVerticalLayout { + static xtype = "bi.vertical_sticky"; + + props() { + return extend(super.props(...arguments), { + extraCls: "bi-v-sticky", + scrolly: true, + horizontalAlign: HorizontalAlign.Stretch, + // verticalAlign: VerticalAlign.Stretch + }); + } + + _addElement(i, item) { + const o = this.options; + const w = super._addElement(...arguments); + let rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; + if (o.rowSize.length > 0) { + if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { + rowSize = null; + } + } + if (rowSize !== "fill") { + let fillIndex; + count(0, o.items.length, index => { + if (isNotNull(fillIndex)) { + return; + } + if ((o.rowSize[index] === "fill" || o.items[index].height === "fill")) { + fillIndex = index; + } + }); + + if (fillIndex > i) { + w.element.css({ + position: "sticky", + zIndex: 1, + top: 0, + }); + } else { + w.element.css({ + position: "sticky", + zIndex: 1, + bottom: 0, + }); + } + } else { + w.element.css({ + overflow: "", + }); + } + + return w; + } +} diff --git a/packages/fineui/src/fix/fix.compact.js b/packages/fineui/src/fix/fix.compact.js new file mode 100644 index 000000000..66aae8fc0 --- /dev/null +++ b/packages/fineui/src/fix/fix.compact.js @@ -0,0 +1,231 @@ +import { + _, + isArray, + each, + isKey, + isPlainObject, + extend, + isFunction, + Widget, + Providers +} from "@/core"; +import { Fix } from "./fix"; + +function initWatch(vm, watch) { + vm._watchers || (vm._watchers = []); + for (const key in watch) { + const handler = watch[key]; + if (isArray(handler)) { + for (let i = 0; i < handler.length; i++) { + vm._watchers.push(createWatcher(vm, key, handler[i])); + } + } else { + vm._watchers.push(createWatcher(vm, key, handler)); + } + } + each(vm.$watchDelayCallbacks, (i, watchDelayCallback) => { + let innerWatch = watchDelayCallback[0]; + const innerHandler = watchDelayCallback[1]; + if (isKey(innerWatch)) { + const key = innerWatch; + innerWatch = {}; + innerWatch[key] = innerHandler; + } + for (const key in innerWatch) { + const handler = innerWatch[key]; + if (isArray(handler)) { + for (let i = 0; i < handler.length; i++) { + vm._watchers.push(createWatcher(vm, key, handler[i])); + } + } else { + vm._watchers.push(createWatcher(vm, key, handler)); + } + } + }); +} + +function createWatcher(vm, keyOrFn, cb, options) { + if (isPlainObject(cb)) { + options = cb; + cb = cb.handler; + } + options = options || {}; + + return Fix.watch( + vm.model, + keyOrFn, + _.bind(cb, vm), + extend(options, { + store: vm.store + }) + ); +} + +let target = null; +const targetStack = []; + +function pushTarget(_target) { + if (target) targetStack.push(target); + Fix.Model.target = target = _target; +} + +function popTarget() { + Fix.Model.target = target = targetStack.pop(); +} + +export const Model = Fix.Model; + +const oldWatch = Fix.watch; +Fix.watch = function (model, expOrFn, cb, options) { + if (isPlainObject(cb)) { + options = cb; + cb = cb.handler; + } + if (typeof cb === "string") { + cb = model[cb]; + } + + return oldWatch.call( + this, + model, + expOrFn, + function () { + options && options.store && pushTarget(options.store); + let res; + try { + res = cb.apply(this, arguments); + } catch (e) { + console.error(e); + } + options && options.store && popTarget(); + + return res; + }, + options + ); +}; + +Widget.findStore = function findStore(widget) { + if (target != null) { + return target; + } + widget = widget || Widget.context; + let p = widget; + while (p) { + if (p instanceof Fix.Model || p.store || p.__cacheStore) { + break; + } + p = p._parent || (p.options && p.options.element) || p._context; + } + if (p) { + if (p instanceof Fix.Model) { + return (widget.__cacheStore = p); + } + widget.__cacheStore = p.store || p.__cacheStore; + + return p.__cacheStore || p.store; + } +}; + +export function createStore() { + let needPop = false; + const workerMode = + Providers.getProvider("bi.provider.system").getWorkerMode(); + if (workerMode && this._worker) { + return; + } + if (this.store) { + pushTarget(this.store); + + return true; + } + if (this._store || this.options._store) { + const store = Widget.findStore( + this.options.context || + this._parent || + this.options.element || + this._context + ); + if (store) { + pushTarget(store); + needPop = true; + } + this.store = (this._store || this.options._store).call(this); + this.store && (this.store._widget = this); + needPop && popTarget(); + needPop = false; + pushTarget(this.store); + if (this.store instanceof Fix.Model) { + this.model = this.store.model; + } else { + this.model = this.store; + } + needPop = true; + } + + return needPop; +} + +const _init = Widget.prototype._init; +Widget.prototype._init = function () { + const needPop = createStore.call(this); + try { + _init.apply(this, arguments); + } catch (e) { + console.error(e); + } + needPop && popTarget(); +}; + +const __initWatch = Widget.prototype.__initWatch; +Widget.prototype.__initWatch = function () { + __initWatch.apply(this, arguments); + const workerMode = + Providers.getProvider("bi.provider.system").getWorkerMode(); + if (workerMode && this._worker) { + return; + } + if (this._store) { + initWatch(this, this.watch); + } +}; + +const unMount = Widget.prototype.__destroy; +Widget.prototype.__destroy = function () { + try { + unMount.apply(this, arguments); + } catch (e) { + console.error(e); + } + this.store && isFunction(this.store.destroy) && this.store.destroy(); + each(this._watchers, (i, unwatches) => { + unwatches = isArray(unwatches) ? unwatches : [unwatches]; + each(unwatches, (j, unwatch) => { + unwatch(); + }); + }); + this._watchers && (this._watchers = []); + if (this.store) { + this.store._parent && (this.store._parent = null); + this.store._widget && (this.store._widget = null); + this.store = null; + } + delete this.__cacheStore; +}; + +_.each(["_render", "__afterRender", "_mount", "__afterMount"], (name) => { + const old = Widget.prototype[name]; + old && + (Widget.prototype[name] = function () { + this.store && pushTarget(this.store); + let res; + try { + res = old.apply(this, arguments); + } catch (e) { + console.error(e); + } + this.store && popTarget(); + + return res; + }); +}); diff --git a/packages/fineui/src/fix/fix.js b/packages/fineui/src/fix/fix.js new file mode 100644 index 000000000..92cba70f8 --- /dev/null +++ b/packages/fineui/src/fix/fix.js @@ -0,0 +1,1561 @@ +import { _ } from "@/core"; + +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} + +function noop(a, b, c) { +} + +function isNative(Ctor) { + return typeof Ctor === "function" && /native code/.test(Ctor.toString()); +} + +const hasProto = "__proto__" in {}; + +const _toString = Object.prototype.toString; + +function isPlainObject(obj) { + return _toString.call(obj) === "[object Object]"; +} + +function isConfigurable(obj, key) { + let configurable = true; + const property = + Object.getOwnPropertyDescriptor && + Object.getOwnPropertyDescriptor(obj, key); + if (property && property.configurable === false) { + configurable = false; + } + + return configurable; +} + +function isExtensible(obj) { + if (Object.isExtensible) { + return Object.isExtensible(obj); + } + let name = ""; + while (obj.hasOwnProperty(name)) { + name += "?"; + } + obj[name] = true; + const returnValue = obj.hasOwnProperty(name); + delete obj[name]; + + return returnValue; +} + +function remove(arr, item) { + if (arr && arr.length) { + const _index = arr.indexOf(item); + if (_index > -1) { + return arr.splice(_index, 1); + } + } +} + +// const bailRE = /[^\w.$]/ + +function parsePath(path) { + // 正常表达式比较慢,能不要的就不要了 + // if (bailRE.test(path)) { + // return + // } + const segments = path.split("."); + + return function(obj) { + for (let i = 0; i < segments.length; i++) { + if (!obj) return; + obj = obj[segments[i]]; + } + + return obj; + }; +} + +const nextTick = (function() { + const callbacks = []; + let pending = false; + let timerFunc = void 0; + + function nextTickHandler() { + pending = false; + const copies = callbacks.slice(0); + callbacks.length = 0; + for (let i = 0; i < copies.length; i++) { + copies[i](); + } + } + + // An asynchronous deferring mechanism. + // In pre 2.4, we used to use microtasks (Promise/MutationObserver) + // but microtasks actually has too high a priority and fires in between + // supposedly sequential events (e.g. #4521, #6690) or even between + // bubbling of the same event (#6566). Technically setImmediate should be + // the ideal choice, but it's not available everywhere; and the only polyfill + // that consistently queues the callback after all DOM events triggered in the + // same loop is by using MessageChannel. + /* istanbul ignore if */ + if (typeof setImmediate !== "undefined" && isNative(setImmediate)) { + timerFunc = function timerFunc() { + setImmediate(nextTickHandler); + }; + } else if ( + typeof MessageChannel !== "undefined" && + (isNative(MessageChannel) || + // PhantomJS + MessageChannel.toString() === "[object MessageChannelConstructor]") + ) { + const channel = new MessageChannel(); + const port = channel.port2; + channel.port1.onmessage = nextTickHandler; + timerFunc = function timerFunc() { + port.postMessage(1); + }; + } else if (typeof Promise !== "undefined" && isNative(Promise)) { + /* istanbul ignore next */ + // use microtask in non-DOM environments, e.g. Weex + const p = Promise.resolve(); + timerFunc = function timerFunc() { + p.then(nextTickHandler); + }; + } else { + // fallback to setTimeout + timerFunc = function timerFunc() { + setTimeout(nextTickHandler, 0); + }; + } + + return function queueNextTick(cb, ctx) { + let _resolve = void 0; + callbacks.push(() => { + if (cb) { + try { + cb.call(ctx); + } catch (e) { + console.error(e); + } + } else if (_resolve) { + _resolve(ctx); + } + }); + if (!pending) { + pending = true; + timerFunc(); + } + // $flow-disable-line + if (!cb && typeof Promise !== "undefined") { + return new Promise((resolve, reject) => { + _resolve = resolve; + }); + } + }; +})(); + +let falsy; +const $$skipArray = { + __ob__: falsy, + $accessors: falsy, + $vbthis: falsy, + $vbsetter: falsy +}; + +let uid = 0; + +/** + * A dep is an observable that can have multiple + * directives subscribing to it. + */ + +const Dep = (function() { + function Dep() { + _classCallCheck(this, Dep); + + this.id = uid++; + this.subs = []; + } + + Dep.prototype.addSub = function addSub(sub) { + this.subs.push(sub); + }; + + Dep.prototype.removeSub = function removeSub(sub) { + remove(this.subs, sub); + }; + + Dep.prototype.depend = function depend() { + if (Dep.target) { + Dep.target.addDep(this); + } + }; + + Dep.prototype.notify = function notify(options) { + // stabilize the subscriber list first + const subs = this.subs.slice(); + for (let i = 0, l = subs.length; i < l; i++) { + subs[i].update(options); + } + }; + + return Dep; +})(); + +// the current target watcher being evaluated. +// this is globally unique because there could be only one +// watcher being evaluated at any time. + +Dep.target = null; +const targetStack = []; + +function pushTarget(_target) { + if (Dep.target) targetStack.push(Dep.target); + Dep.target = _target; +} + +function popTarget() { + Dep.target = targetStack.pop(); +} + +// 如果浏览器不支持ecma262v5的Object.defineProperties或者存在BUG,比如IE8 +// 标准浏览器使用__defineGetter__, __defineSetter__实现 +let canHideProperty = true; +try { + Object.defineProperty({}, "_", { + value: "x" + }); + delete $$skipArray.$vbsetter; + delete $$skipArray.$vbthis; +} catch (e) { + /* istanbul ignore next*/ + canHideProperty = false; +} + +let createViewModel = Object.defineProperties; +let defineProperty = void 0; + +/* istanbul ignore if*/ +if (!canHideProperty) { + if ("__defineGetter__" in {}) { + defineProperty = function defineProperty(obj, prop, desc) { + if ("value" in desc) { + obj[prop] = desc.value; + } + if ("get" in desc) { + obj.__defineGetter__(prop, desc.get); + } + if ("set" in desc) { + obj.__defineSetter__(prop, desc.set); + } + + return obj; + }; + createViewModel = function createViewModel(obj, descs) { + for (const prop in descs) { + if (descs.hasOwnProperty(prop)) { + defineProperty(obj, prop, descs[prop]); + } + } + + return obj; + }; + } +} + +const createViewModel$1 = createViewModel; + +const queue = []; +const activatedChildren = []; +let has = {}; +let waiting = false; +let flushing = false; +let index = 0; + +function resetSchedulerState() { + index = queue.length = activatedChildren.length = 0; + has = {}; + waiting = flushing = false; +} + +function flushSchedulerQueue() { + flushing = true; + let watcher = void 0, + id = void 0, + options = void 0; + + // Sort queue before flush. + // This ensures that: + // 1. Components are updated from parent to child. (because parent is always + // created before the child) + // 2. A component's user watchers are run before its render watcher (because + // user watchers are created before the render watcher) + // 3. If a component is destroyed during a parent component's watcher run, + // its watchers can be skipped. + queue.sort((a, b) => a.id - b.id); + + // do not cache length because more watchers might be pushed + // as we run existing watchers + for (index = 0; index < queue.length; index++) { + watcher = queue[index].watcher; + options = queue[index].options; + id = watcher.id; + has[id] = null; + watcher.run(options); + } + + resetSchedulerState(); +} + +function queueWatcher(watcher, options) { + const id = watcher.id; + if (has[id] == null) { + has[id] = true; + if (!flushing) { + queue.push({ watcher, options }); + } else { + // if already flushing, splice the watcher based on its id + // if already past its id, it will be run next immediately. + let i = queue.length - 1; + while (i > index && queue[i].watcher.id > watcher.id) { + i--; + } + queue.splice(i + 1, 0, { watcher, options }); + } + // queue the flush + if (!waiting) { + waiting = true; + nextTick(flushSchedulerQueue); + } + } +} + +let uid$1 = 0; + +const Watcher = (function() { + function Watcher(vm, expOrFn, cb, options) { + _classCallCheck(this, Watcher); + + this.vm = vm; + // vm._watchers || (vm._watchers = []) + // vm._watchers.push(this) + // options + if (options) { + this.deep = !!options.deep; + this.user = !!options.user; + this.lazy = !!options.lazy; + this.sync = !!options.sync; + } else { + this.deep = this.user = this.lazy = this.sync = false; + } + this.cb = cb; + this.id = ++uid$1; // uid for batching + this.active = true; + this.dirty = this.lazy; // for lazy watchers + this.deps = []; + this.newDeps = []; + this.depIds = new Set(); + this.newDepIds = new Set(); + this.expression = ""; + // parse expression for getter + if (typeof expOrFn === "function") { + this.getter = expOrFn; + } else { + this.getter = parsePath(expOrFn); + if (!this.getter) { + this.getter = function() { + }; + } + } + this.value = this.lazy ? undefined : this.get(); + } + + Watcher.prototype.get = function get() { + pushTarget(this); + let value = void 0; + const vm = this.vm; + try { + value = this.getter.call(vm, vm); + } catch (e) { + // if (this.user) { + // } else { + // console.error(e) + // } + } finally { + // "touch" every property so they are all tracked as + // dependencies for deep watching + if (this.deep) { + traverse(value); + } + popTarget(); + this.cleanupDeps(); + } + + return value; + }; + + Watcher.prototype.addDep = function addDep(dep) { + const id = dep.id; + if (!this.newDepIds.has(id)) { + this.newDepIds.add(id); + this.newDeps.push(dep); + if (!this.depIds.has(id)) { + dep.addSub(this); + } + } + }; + + Watcher.prototype.cleanupDeps = function cleanupDeps() { + let i = this.deps.length; + while (i--) { + const dep = this.deps[i]; + if (!this.newDepIds.has(dep.id)) { + dep.removeSub(this); + } + } + let tmp = this.depIds; + this.depIds = this.newDepIds; + this.newDepIds = tmp; + this.newDepIds.clear(); + tmp = this.deps; + this.deps = this.newDeps; + this.newDeps = tmp; + this.newDeps.length = 0; + }; + + Watcher.prototype.update = function update(options) { + /* istanbul ignore else */ + if (this.lazy) { + this.dirty = true; + } else if (this.sync) { + this.run(options); + } else { + queueWatcher(this, options); + } + }; + + Watcher.prototype.run = function run(options) { + if (this.active) { + const value = this.get(); + if ( + value !== this.value || + // Deep watchers and watchers on Object/Arrays should fire even + // when the value is the same, because the value may + // have mutated. + (_.isObject(value) && options && options.refresh) || + this.deep + ) { + // set new value + const oldValue = this.value; + this.value = value; + if (this.user) { + try { + this.cb.call(this.vm, value, oldValue, options); + } catch (e) { + console.error(e); + } + } else { + try { + this.cb.call(this.vm, value, oldValue, options); + } catch (e) { + console.error(e); + } + } + } + } + }; + + Watcher.prototype.evaluate = function evaluate() { + this.value = this.get(); + this.dirty = false; + }; + + Watcher.prototype.depend = function depend() { + let i = this.deps.length; + while (i--) { + this.deps[i].depend(); + } + }; + + Watcher.prototype.teardown = function teardown() { + if (this.active) { + // remove self from vm's watcher list + // this is a somewhat expensive operation so we skip it + // if the vm is being destroyed. + remove(this.vm && this.vm._watchers, this); + let i = this.deps.length; + while (i--) { + this.deps[i].removeSub(this); + } + this.active = false; + } + }; + + return Watcher; +})(); + +const seenObjects = new Set(); + +function traverse(val) { + seenObjects.clear(); + _traverse(val, seenObjects); +} + +function _traverse(val, seen) { + let i = void 0, + keys = void 0; + const isA = _.isArray(val); + if (!isA && !_.isObject(val)) { + return; + } + if (val.__ob__) { + const depId = val.__ob__.dep.id; + if (seen.has(depId)) { + return; + } + seen.add(depId); + } + if (isA) { + i = val.length; + while (i--) { + _traverse(val[i], seen); + } + } else { + keys = _.keys(val); + i = keys.length; + while (i--) { + _traverse(val[keys[i]], seen); + } + } +} + +const arrayProto = Array.prototype; +const arrayMethods = []; +_.each( + ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"], + (method) => { + const original = arrayProto[method]; + arrayMethods[method] = function mutator() { + for ( + var _len = arguments.length, args = Array(_len), _key2 = 0; + _key2 < _len; + _key2++ + ) { + args[_key2] = arguments[_key2]; + } + + const ob = this.__ob__; + let inserted = void 0; + switch (method) { + case "push": + case "unshift": + inserted = args; + break; + case "splice": + inserted = args.slice(2); + break; + } + if (inserted) inserted = ob.observeArray(inserted); + switch (method) { + case "push": + case "unshift": + args = inserted; + break; + case "splice": + if (args.length > 2) { + args = [args[0], args[1]].concat( + inserted ? inserted : [] + ); + } + break; + } + const result = original.apply(this, args); + notify(ob.parent, ob.parentKey, ob.dep, true); + + return result; + }; + } +); + +const arrayKeys = _.keys(arrayMethods); + +const observerState = { + shouldConvert: true +}; + +function def(obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }); +} + +/** + * Observer class that are attached to each observed + * object. Once attached, the observer converts target + * object's property keys into getter/setters that + * collect dependencies and dispatches updates. + */ + +const Observer = (function() { + function Observer(value) { + _classCallCheck(this, Observer); + + this.value = value; + this.dep = new Dep(); + this.vmCount = 0; + if (_.isArray(value)) { + const augment = hasProto ? protoAugment : copyAugment; + augment(value, arrayMethods, arrayKeys); + this.model = this.observeArray(value); + } else { + this.model = this.walk(value); + } + def(this.model, "__ob__", this); + } + + Observer.prototype.walk = function walk(obj) { + return defineReactive(obj, this); + }; + + Observer.prototype.observeArray = function observeArray(items) { + for (let i = 0, l = items.length; i < l; i++) { + const ob = observe(items[i], this, i); + items[i] = ob ? ob.model : items[i]; + } + + return items; + }; + + return Observer; +})(); + +function protoAugment(target, src, keys) { + /* eslint-disable no-proto */ + Object.setPrototypeOf(target, src); + /* eslint-enable no-proto */ +} + +/* istanbul ignore next */ +function copyAugment(target, src, keys) { + for (let i = 0, l = keys.length; i < l; i++) { + const key = keys[i]; + target[key] = src[key]; + } +} + +function observe(value, parentObserver, parentKey) { + if (!_.isObject(value)) { + return; + } + let ob = void 0; + if (value.__ob__ instanceof Observer) { + ob = value.__ob__; + } else if ( + observerState.shouldConvert && + isExtensible(value) && + (_.isArray(value) || isPlainObject(value)) + ) { + ob = new Observer(value); + } + if (ob) { + ob.parent = parentObserver || ob.parent; + ob.parentKey = parentKey; + } + + return ob; +} + +function notify(observer, key, dep, refresh) { + dep.notify({ observer, key, refresh }); + if (observer) { + // 触发a.*绑定的依赖 + _.each(observer._deps, (dep) => { + dep.notify({ observer, key }); + }); + // 触发a.**绑定的依赖 + let parent = observer, + root = observer, + route = key || ""; + while (parent) { + _.each(parent._scopeDeps, (dep) => { + dep.notify({ observer, key }); + }); + if (parent.parentKey != null) { + route = `${parent.parentKey}.${route}`; + } + root = parent; + parent = parent.parent; + } + for (const _key in root._globalDeps) { + const reg = new RegExp(_key); + if (reg.test(route)) { + for (let i = 0; i < root._globalDeps[_key].length; i++) { + root._globalDeps[_key][i].notify({ + observer, + key: _key + }); + } + } + } + } +} + +function defineReactive(obj, observer, shallow) { + const props = {}; + let model = void 0; + _.each(obj, (val, key) => { + if (key in $$skipArray) { + return; + } + const configurable = isConfigurable(obj, key); + const dep = (observer && observer[`__dep${key}`]) || new Dep(); + observer && (observer[`__dep${key}`] = dep); + let childOb = configurable && !shallow && observe(val, observer, key); + props[key] = { + enumerable: true, + configurable: true, + get: function reactiveGetter() { + const value = childOb ? childOb.model : val; + if (Dep.target) { + dep.depend(); + if (childOb) { + childOb.dep.depend(); + if (_.isArray(value)) { + dependArray(value); + } + } + } + + return value; + }, + set: function reactiveSetter(newVal) { + const value = childOb ? childOb.model : val; + if ( + newVal === value || + (newVal !== newVal && value !== value) + ) { + return; + } + val = newVal; + childOb = + configurable && !shallow && observe(newVal, observer, key); + if (childOb && value && value.__ob__) { + childOb._scopeDeps = value.__ob__._scopeDeps; + childOb._deps = value.__ob__._deps; + } + obj[key] = childOb ? childOb.model : newVal; + notify(model.__ob__, key, dep); + } + }; + }); + + return (model = createViewModel$1(obj, props)); +} + +function defineReactiveProperty(obj, key, val, shallow) { + const dep = new Dep(); + + const configurable = isConfigurable(obj, key); + if (!configurable) { + return; + } + + if (arguments.length === 2) { + val = obj[key]; + } + + let childOb = !shallow && observe(val); + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + get: function reactiveGetter() { + const value = childOb ? childOb.model : val; + if (Dep.target) { + dep.depend(); + if (childOb) { + childOb.dep.depend(); + if (_.isArray(value)) { + dependArray(value); + } + } + } + + return value; + }, + set: function reactiveSetter(newVal) { + const value = childOb ? childOb.model : val; + if (newVal === value || (newVal !== newVal && value !== value)) { + return; + } + + childOb = configurable && !shallow && observe(newVal); + val = newVal; + obj[key] = childOb ? childOb.model : newVal; + dep.notify(); + } + }); +} + +/** + * Set a property on an object. Adds the new property and + * triggers change notification if the property doesn't + * already exist. + */ +function set(target, key, val) { + if (_.isArray(target)) { + target.length = Math.max(target.length, key); + target.splice(key, 1, val); + + return val; + } + if (_.has(target, key)) { + target[key] = val; + + return val; + } + const ob = target.__ob__; + if (!ob) { + target[key] = val; + + return val; + } + ob.value[key] = val; + target = defineReactive(ob.value, ob); + notify(ob, key, ob.dep); + + return target; +} + +function freeze() { + return Object.freeze.apply(null, arguments); +} + +/** + * Delete a property and trigger change if necessary. + */ +function del(target, key) { + if (_.isArray(target)) { + target.splice(key, 1); + + return; + } + const ob = target.__ob__; + if (!_.has(target, key)) { + return; + } + if (!ob) { + delete target[key]; + + return target; + } + delete ob.value[key]; + target = defineReactive(ob.value, ob); + notify(ob, key, ob.dep); + + return target; +} + +/** + * Collect dependencies on array elements when the array is touched, since + * we cannot intercept array element access like property getters. + */ +function dependArray(value) { + for (var e, i = 0, l = value.length; i < l; i++) { + e = value[i]; + e && e.__ob__ && e.__ob__.dep.depend(); + if (_.isArray(e)) { + dependArray(e); + } + } +} + +let falsy$1; +const operators = { + "||": falsy$1, + "&&": falsy$1, + "(": falsy$1, + ")": falsy$1 +}; + +function runBinaryFunction(binarys) { + let expr = ""; + for (let i = 0, len = binarys.length; i < len; i++) { + if (_.isBoolean(binarys[i]) || _.has(operators, binarys[i])) { + expr += binarys[i]; + } else { + expr += "false"; + } + } + + return new Function(`return ${expr}`)(); +} + +function routeToRegExp(route) { + route = route + .replace(/\*\*/g, "[a-zA-Z0-9_]+") + .replace(/\*./g, "[a-zA-Z0-9_]+."); + + return `^${route}$`; +} + +function watch(model, expOrFn, cb, options) { + if (isPlainObject(cb)) { + options = cb; + cb = cb.handler; + } + if (typeof cb === "string") { + cb = model[cb]; + } + options = options || {}; + options.user = true; + let exps = void 0; + if ( + _.isFunction(expOrFn) || + !(exps = expOrFn.match(/[a-zA-Z0-9_.*]+|[|][|]|[&][&]|[(]|[)]/g)) || + (exps.length === 1 && expOrFn.indexOf("*") < 0) + ) { + const watcher = new Watcher(model, expOrFn, cb, options); + if (options.immediate) { + cb(watcher.value); + } + + return function unwatchFn() { + watcher.teardown(); + }; + } + const watchers = []; + let fns = exps.slice(); + let complete = false, + running = false; + const callback = function callback(index, newValue, oldValue, attrs) { + if (complete === true) { + return; + } + fns[index] = true; + if (runBinaryFunction(fns)) { + complete = true; + cb(newValue, oldValue, attrs); + } + if (options && options.sync) { + complete = false; + running = false; + fns = exps.slice(); + } else { + if (!running) { + running = true; + nextTick(() => { + complete = false; + running = false; + fns = exps.slice(); + }); + } + } + }; + _.each(exps, (exp, i) => { + if (_.has(operators, exp)) { + return; + } + if (exp.indexOf("*") >= 0) { + // a.**或a.*形式 + if ( + /^[1-9a-zA-Z.]+(\*\*$|\*$)/.test(exp) || + exp === "**" || + exp === "*" + ) { + const isGlobal = exp.indexOf("**") >= 0; + if (isGlobal) { + // a.**的形式 + exp = exp.replace(".**", ""); + } else { + // a.*的形式 + exp = exp.replace(".*", ""); + } + const getter = + exp === "**" || exp === "*" + ? function(m) { + return m; + } + : parsePath(exp); + const v = getter.call(model, model); + if (v.__ob__) { + const _dep = new Dep(); + if (isGlobal) { + (v.__ob__._scopeDeps || (v.__ob__._scopeDeps = [])).push( + _dep + ); + } else { + (v.__ob__._deps || (v.__ob__._deps = [])).push(_dep); + } + const _w = new Watcher( + model, + () => { + _dep.depend(); + + return NaN; + }, + (newValue, oldValue, attrs) => { + callback( + i, + newValue, + oldValue, + _.extend({ index: i }, attrs) + ); + }, + options + ); + watchers.push(() => { + _w.teardown(); + v.__ob__._scopeDeps && remove(v.__ob__._scopeDeps, _dep); + v.__ob__._deps && remove(v.__ob__._deps, _dep); + }); + } + + return; + } + // **.a.**的情况,场景:a.b.c, 如果用b.**监听, a被重新赋值b上的_scopeDes就不存在了 + if (/^(\*\*\.)+[1-9a-zA-Z]+(\.\*\*$)/.test(exp)) { + // 先获取到能获取到的对象 + const _paths = exp.split("."); + const _currentModel = model[_paths[1]]; + + if (!_currentModel.__ob__) { + return; + } + + exp = `${_paths[1]}.**`; + // 补全路径 + let _parent = _currentModel.__ob__.parent, + _root = _currentModel.__ob__; + while (_parent) { + exp = `*.${exp}`; + _root = _parent; + _parent = _parent.parent; + } + const _regStr = routeToRegExp(exp); + const _dep2 = new Dep(); + _root._globalDeps || (_root._globalDeps = {}); + if (_.isArray(_root._globalDeps[_regStr])) { + _root._globalDeps[_regStr].push(_dep2); + } else { + _root._globalDeps[_regStr] = [_dep2]; + } + + const _w2 = new Watcher( + _currentModel, + () => { + _dep2.depend(); + + return NaN; + }, + (newValue, oldValue, attrs) => { + callback( + i, + newValue, + oldValue, + _.extend({ index: i }, attrs) + ); + }, + options + ); + watchers.push(() => { + if (_root._globalDeps) { + remove(_root._globalDeps[_regStr], _dep2); + + if (_root._globalDeps[_regStr].length === 0) { + delete _root._globalDeps[_regStr]; + _w2.teardown(); + } + } + }); + + return; + } + // 再有结尾有*的就不支持了 + if (exp[exp.length - 1] === "*") { + throw new Error("not support"); + } + // 其他含有*的情况,如*.a,*.*.a,a.*.a + let currentModel = model; + // 先获取到能获取到的对象 + const paths = exp.split("."); + for (let _i = 0, len = paths.length; _i < len; _i++) { + if (paths[_i] === "*") { + break; + } + currentModel = model[paths[_i]]; + } + + if (!currentModel.__ob__) { + return; + } + + exp = exp.substr(exp.indexOf("*")); + // 补全路径 + let parent = currentModel.__ob__.parent, + root = currentModel.__ob__; + while (parent) { + exp = `*.${exp}`; + root = parent; + parent = parent.parent; + } + const regStr = routeToRegExp(exp); + const dep = new Dep(); + root._globalDeps || (root._globalDeps = {}); + if (_.isArray(root._globalDeps[regStr])) { + root._globalDeps[regStr].push(dep); + } else { + root._globalDeps[regStr] = [dep]; + } + + const w = new Watcher( + currentModel, + () => { + dep.depend(); + + return NaN; + }, + (newValue, oldValue, attrs) => { + callback( + i, + newValue, + oldValue, + _.extend({ index: i }, attrs) + ); + }, + options + ); + watchers.push(() => { + if (root._globalDeps) { + remove(root._globalDeps[regStr], dep); + if (root._globalDeps[regStr].length === 0) { + delete root._globalDeps[regStr]; + w.teardown(); + } + } + }); + + return; + } + const watcher = new Watcher( + model, + exp, + (newValue, oldValue, attrs) => { + callback(i, newValue, oldValue, _.extend({ index: i }, attrs)); + }, + options + ); + watchers.push(() => { + watcher.teardown(); + }); + }); + + return watchers; +} + +const mixinInjection = {}; + +function getMixins(type) { + return mixinInjection[type]; +} + +function mixin(xtype, cls) { + mixinInjection[xtype] = _.cloneDeep(cls); +} + +const computedWatcherOptions = { lazy: true }; +let REACTIVE = true; + +function initState(vm, state) { + if (state) { + vm.$$state = REACTIVE ? observe(state).model : state; + } +} + +function initComputed(vm, computed) { + const watchers = (vm._computedWatchers = {}); + defineComputed(vm, computed); + for (const key in computed) { + watchers[key] = defineComputedWatcher(vm, computed[key]); + } +} + +function defineComputedWatcher(vm, userDef) { + const context = vm.$$model ? vm.model : vm; + const getter = typeof userDef === "function" ? userDef : userDef.get; + + return new Watcher(context, getter || noop, noop, computedWatcherOptions); +} + +function defineOneComputedGetter(vm, key, userDef) { + const shouldCache = true; + const sharedPropertyDefinition = { + enumerable: true, + configurable: true, + get: noop, + set: noop + }; + if (typeof userDef === "function") { + sharedPropertyDefinition.get = createComputedGetter(vm, key); + sharedPropertyDefinition.set = noop; + } else { + sharedPropertyDefinition.get = userDef.get + ? shouldCache && userDef.cache !== false + ? createComputedGetter(vm, key) + : userDef.get + : noop; + sharedPropertyDefinition.set = userDef.set ? userDef.set : noop; + } + + return sharedPropertyDefinition; +} + +function defineComputed(vm, computed) { + const props = {}; + for (const key in computed) { + if (!(key in vm)) { + props[key] = defineOneComputedGetter(vm, key, computed[key]); + } + } + vm.$$computed = createViewModel$1({}, props); +} + +function createComputedGetter(vm, key) { + return function computedGetter() { + const watcher = vm._computedWatchers && vm._computedWatchers[key]; + if (watcher) { + if (watcher.dirty) { + watcher.evaluate(); + } + if (REACTIVE && Dep.target) { + watcher.depend(); + } + + return watcher.value; + } + }; +} + +function initWatch(vm, watch$$1) { + vm._watchers || (vm._watchers = []); + for (const key in watch$$1) { + const handler = watch$$1[key]; + if (_.isArray(handler)) { + for (let i = 0; i < handler.length; i++) { + vm._watchers.push(createWatcher(vm, key, handler[i])); + } + } else { + vm._watchers.push(createWatcher(vm, key, handler)); + } + } +} + +function createWatcher(vm, keyOrFn, cb, options) { + if (isPlainObject(cb)) { + options = cb; + cb = cb.handler; + } + if (typeof cb === "string") { + cb = vm[cb]; + } + + return watch( + vm.model, + keyOrFn, + _.bind(cb, vm.$$model ? vm.model : vm), + options + ); +} + +function initMethods(vm, methods) { + for (const key in methods) { + vm[key] = + methods[key] == null + ? noop + : _.bind(methods[key], vm.$$model ? vm.model : vm); + } +} + +function initMixins(vm, mixins) { + mixins = (mixins || []).slice(0); + + _.each(mixins.reverse(), (mixinType) => { + const mixin$$1 = getMixins(mixinType); + + for (const key in mixin$$1) { + if (typeof mixin$$1[key] !== "function") continue; + + if (_.has(vm, key)) continue; + + vm[key] = _.bind(mixin$$1[key], vm.$$model ? vm.model : vm); + } + }); +} + +function defineProps(vm, keys) { + const props = {}; + // if (typeof Proxy === 'function') { + // return vm.model = new Proxy(props, { + // has: function (target, key) { + // return keys.indexOf(key) > -1; + // }, + // get: function (target, key) { + // if (key in $$skipArray) { + // return props[key] + // } + // if (vm.$$computed && key in vm.$$computed) { + // return vm.$$computed[key] + // } + // if (vm.$$state && key in vm.$$state) { + // return vm.$$state[key] + // } + // return vm.$$model[key] + // }, + // set: function (target, key, val) { + // if (key in $$skipArray) { + // return props[key] = val + // } + // if (vm.$$state && key in vm.$$state) { + // return vm.$$state[key] = val + // } + // if (vm.$$model && key in vm.$$model) { + // return vm.$$model[key] = val + // } + // } + // }) + // } + + const _loop = function _loop(i, len) { + const key = keys[i]; + if (!(key in $$skipArray)) { + props[key] = { + enumerable: true, + configurable: true, + get: function get() { + if (vm.$$computed && key in vm.$$computed) { + return vm.$$computed[key]; + } + if (vm.$$state && key in vm.$$state) { + return vm.$$state[key]; + } + if (vm.$$model && key in vm.$$model) { + return vm.$$model[key]; + } + let p = vm._parent; + while (p) { + if (p.$$context && key in p.$$context) { + return p.$$context[key]; + } + p = p._parent; + } + }, + set: function set(val) { + if (vm.$$state && key in vm.$$state) { + return (vm.$$state[key] = val); + } + if (vm.$$model && key in vm.$$model) { + return (vm.$$model[key] = val); + } + let p = vm._parent; + while (p) { + if (p.$$context && key in p.$$context) { + return (p.$$context[key] = val); + } + p = p._parent; + } + } + }; + } + }; + + for (let i = 0, len = keys.length; i < len; i++) { + _loop(i, len); + } + vm.model = createViewModel$1({}, props); +} + +function defineContext(vm, keys) { + const props = {}; + + const _loop2 = function _loop2(i, len) { + const key = keys[i]; + if (!(key in $$skipArray)) { + props[key] = { + enumerable: true, + configurable: true, + get: function get() { + return vm.model[key]; + }, + set: function set(val) { + return (vm.model[key] = val); + } + }; + } + }; + + for (let i = 0, len = keys.length; i < len; i++) { + _loop2(i, len); + } + vm.$$context = createViewModel$1({}, props); +} + +function getInjectValue(vm, key) { + let p = vm._parent; + while (p) { + if (p.$$context && key in p.$$context) { + return p.$$context[key]; + } + p = p._parent; + } +} + +function getInjectValues(vm) { + const inject = vm.inject || []; + const result = {}; + _.each(inject, (key) => { + result[key] = getInjectValue(vm, key); + }); + + return result; +} + +const Model = (function() { + function Model() { + _classCallCheck(this, Model); + } + + Model.prototype._constructor = function _constructor( + model, + destroyHandler + ) { + if (model instanceof Observer || model instanceof Model) { + model = model.model; + } + if (model && model.__ob__) { + this.$$model = model; + } else { + this.options = model || {}; + } + this._parent = Model.target; + const state = _.isFunction(this.state) ? this.state() : this.state; + const computed = this.computed; + const context = this.context; + const inject = this.inject; + const childContext = this.childContext; + const provide = this.provide; + const watch$$1 = this.watch; + const actions = this.actions; + const keys = _.keys(this.$$model) + .concat(_.keys(state)) + .concat(_.keys(computed)) + .concat(inject || []) + .concat(context || []); + const mixins = this.mixins; + defineProps(this, keys); + // deprecated + childContext && defineContext(this, childContext); + provide && defineContext(this, provide); + this.$$model && (this.model.__ob__ = this.$$model.__ob__); + initMixins(this, mixins); + this.init(); + initState(this, _.extend(getInjectValues(this), state)); + initComputed(this, computed); + REACTIVE && initWatch(this, watch$$1); + initMethods(this, actions); + this.created && this.created(); + this._destroyHandler = destroyHandler; + if (this.$$model) { + return this.model; + } + }; + + Model.prototype._init = function _init() { + }; + + Model.prototype.init = function init() { + this._init(); + }; + + Model.prototype.destroy = function destroy() { + for (const _key3 in this._computedWatchers) { + this._computedWatchers[_key3].teardown(); + } + _.each(this._watchers, (unwatches) => { + unwatches = _.isArray(unwatches) ? unwatches : [unwatches]; + _.each(unwatches, (unwatch) => { + unwatch(); + }); + }); + this._watchers && (this._watchers = []); + this.destroyed && this.destroyed(); + this.$$model = null; + this.$$computed = null; + this.$$state = null; + this._destroyHandler && this._destroyHandler(); + }; + + return Model; +})(); + +function define(model) { + return REACTIVE ? new Observer(model).model : model; +} + +const reactive = define; + +function config(options) { + options || (options = {}); + if ("reactive" in options) { + REACTIVE = options.reactive; + } +} + +function toJSON(model) { + let result = void 0; + if (_.isArray(model)) { + result = []; + for (let i = 0, len = model.length; i < len; i++) { + result[i] = toJSON(model[i]); + } + } else if (model && isPlainObject(model)) { + result = {}; + for (const _key4 in model) { + if (!_.has($$skipArray, _key4)) { + result[_key4] = toJSON(model[_key4]); + } + } + } else { + result = model; + } + + return result; +} + +const version = "2.0"; + +export const Fix = { + version, + $$skipArray, + mixin, + Model, + define, + reactive, + config, + observerState, + Observer, + observe, + notify, + defineReactive, + defineReactiveProperty, + set, + freeze, + del, + Watcher, + pushTarget, + popTarget, + watch, + toJSON +}; diff --git a/packages/fineui/src/fix/index.js b/packages/fineui/src/fix/index.js new file mode 100644 index 000000000..a4596c87d --- /dev/null +++ b/packages/fineui/src/fix/index.js @@ -0,0 +1,2 @@ +export * from "./fix"; +export * from "./fix.compact"; diff --git a/packages/fineui/src/index.js b/packages/fineui/src/index.js new file mode 100644 index 000000000..e84b98d9e --- /dev/null +++ b/packages/fineui/src/index.js @@ -0,0 +1,19 @@ +// sideEffects +import "./core/system"; +import "./core/platform/web/jquery"; +import jquery from "jquery"; + +export * from "./core"; +export * from "./base"; +export * from "./case"; +export * from "./widget"; +export * from "./component"; +export * from "./fix"; +export * from "./router"; +export * as Popper from "@popperjs/core"; +export const jQuery = jquery; +export const $ = jquery; + +import * as D from "@/core/decorator"; +import { Fix } from "./fix"; +export const Decorators = { ...D, Model: Fix.Model }; diff --git a/src/less/base/colorchooser/colorchooser.popup.less b/packages/fineui/src/less/base/colorchooser/colorchooser.popup.less similarity index 100% rename from src/less/base/colorchooser/colorchooser.popup.less rename to packages/fineui/src/less/base/colorchooser/colorchooser.popup.less diff --git a/src/less/base/colorchooser/colorchooser.trigger.less b/packages/fineui/src/less/base/colorchooser/colorchooser.trigger.less similarity index 100% rename from src/less/base/colorchooser/colorchooser.trigger.less rename to packages/fineui/src/less/base/colorchooser/colorchooser.trigger.less diff --git a/src/less/base/colorchooser/colorpicker/button.colorpicker.less b/packages/fineui/src/less/base/colorchooser/colorpicker/button.colorpicker.less similarity index 100% rename from src/less/base/colorchooser/colorpicker/button.colorpicker.less rename to packages/fineui/src/less/base/colorchooser/colorpicker/button.colorpicker.less diff --git a/src/less/base/colorchooser/colorpicker/button.colorshow.less b/packages/fineui/src/less/base/colorchooser/colorpicker/button.colorshow.less similarity index 100% rename from src/less/base/colorchooser/colorpicker/button.colorshow.less rename to packages/fineui/src/less/base/colorchooser/colorpicker/button.colorshow.less diff --git a/src/less/base/colorchooser/colorpicker/editor.colorpicker.less b/packages/fineui/src/less/base/colorchooser/colorpicker/editor.colorpicker.less similarity index 100% rename from src/less/base/colorchooser/colorpicker/editor.colorpicker.less rename to packages/fineui/src/less/base/colorchooser/colorpicker/editor.colorpicker.less diff --git a/src/less/base/colorchooser/farbtastic/farbtastic.less b/packages/fineui/src/less/base/colorchooser/farbtastic/farbtastic.less similarity index 100% rename from src/less/base/colorchooser/farbtastic/farbtastic.less rename to packages/fineui/src/less/base/colorchooser/farbtastic/farbtastic.less diff --git a/src/less/base/combo/combo.bubble.less b/packages/fineui/src/less/base/combo/combo.bubble.less similarity index 100% rename from src/less/base/combo/combo.bubble.less rename to packages/fineui/src/less/base/combo/combo.bubble.less diff --git a/src/less/base/combo/combo.less b/packages/fineui/src/less/base/combo/combo.less similarity index 100% rename from src/less/base/combo/combo.less rename to packages/fineui/src/less/base/combo/combo.less diff --git a/src/less/base/combo/combo.searchtextvalue.less b/packages/fineui/src/less/base/combo/combo.searchtextvalue.less similarity index 100% rename from src/less/base/combo/combo.searchtextvalue.less rename to packages/fineui/src/less/base/combo/combo.searchtextvalue.less diff --git a/src/less/base/combo/combo.textvalue.icon.less b/packages/fineui/src/less/base/combo/combo.textvalue.icon.less similarity index 100% rename from src/less/base/combo/combo.textvalue.icon.less rename to packages/fineui/src/less/base/combo/combo.textvalue.icon.less diff --git a/src/less/base/combo/combo.textvalue.less b/packages/fineui/src/less/base/combo/combo.textvalue.less similarity index 100% rename from src/less/base/combo/combo.textvalue.less rename to packages/fineui/src/less/base/combo/combo.textvalue.less diff --git a/src/less/base/combo/combo.textvaluecheck.less b/packages/fineui/src/less/base/combo/combo.textvaluecheck.less similarity index 100% rename from src/less/base/combo/combo.textvaluecheck.less rename to packages/fineui/src/less/base/combo/combo.textvaluecheck.less diff --git a/src/less/base/combo/combo.textvaluedownlist.less b/packages/fineui/src/less/base/combo/combo.textvaluedownlist.less similarity index 100% rename from src/less/base/combo/combo.textvaluedownlist.less rename to packages/fineui/src/less/base/combo/combo.textvaluedownlist.less diff --git a/src/less/base/combo/popup.bubble.bar.less b/packages/fineui/src/less/base/combo/popup.bubble.bar.less similarity index 100% rename from src/less/base/combo/popup.bubble.bar.less rename to packages/fineui/src/less/base/combo/popup.bubble.bar.less diff --git a/src/less/base/combo/popup.bubble.less b/packages/fineui/src/less/base/combo/popup.bubble.less similarity index 100% rename from src/less/base/combo/popup.bubble.less rename to packages/fineui/src/less/base/combo/popup.bubble.less diff --git a/src/less/base/editor/editor.search.less b/packages/fineui/src/less/base/editor/editor.search.less similarity index 100% rename from src/less/base/editor/editor.search.less rename to packages/fineui/src/less/base/editor/editor.search.less diff --git a/src/less/base/editor/editor.search.small.less b/packages/fineui/src/less/base/editor/editor.search.small.less similarity index 100% rename from src/less/base/editor/editor.search.small.less rename to packages/fineui/src/less/base/editor/editor.search.small.less diff --git a/src/less/base/foundation/bi.message.less b/packages/fineui/src/less/base/foundation/bi.message.less similarity index 100% rename from src/less/base/foundation/bi.message.less rename to packages/fineui/src/less/base/foundation/bi.message.less diff --git a/src/less/base/layer/layer.multiselect.less b/packages/fineui/src/less/base/layer/layer.multiselect.less similarity index 100% rename from src/less/base/layer/layer.multiselect.less rename to packages/fineui/src/less/base/layer/layer.multiselect.less diff --git a/src/less/base/layer/panel.less b/packages/fineui/src/less/base/layer/panel.less similarity index 100% rename from src/less/base/layer/panel.less rename to packages/fineui/src/less/base/layer/panel.less diff --git a/src/less/base/loader/sort.list.less b/packages/fineui/src/less/base/loader/sort.list.less similarity index 100% rename from src/less/base/loader/sort.list.less rename to packages/fineui/src/less/base/loader/sort.list.less diff --git a/src/less/base/pager/pager.all.count.less b/packages/fineui/src/less/base/pager/pager.all.count.less similarity index 100% rename from src/less/base/pager/pager.all.count.less rename to packages/fineui/src/less/base/pager/pager.all.count.less diff --git a/src/less/base/pager/pager.direction.less b/packages/fineui/src/less/base/pager/pager.direction.less similarity index 100% rename from src/less/base/pager/pager.direction.less rename to packages/fineui/src/less/base/pager/pager.direction.less diff --git a/src/less/base/pager/pager.less b/packages/fineui/src/less/base/pager/pager.less similarity index 100% rename from src/less/base/pager/pager.less rename to packages/fineui/src/less/base/pager/pager.less diff --git a/src/less/base/pane.less b/packages/fineui/src/less/base/pane.less similarity index 100% rename from src/less/base/pane.less rename to packages/fineui/src/less/base/pane.less diff --git a/src/less/base/segment/button.segment.less b/packages/fineui/src/less/base/segment/button.segment.less similarity index 100% rename from src/less/base/segment/button.segment.less rename to packages/fineui/src/less/base/segment/button.segment.less diff --git a/src/less/base/segment/segment.less b/packages/fineui/src/less/base/segment/segment.less similarity index 100% rename from src/less/base/segment/segment.less rename to packages/fineui/src/less/base/segment/segment.less diff --git a/src/less/base/single/button/button.half.less b/packages/fineui/src/less/base/single/button/button.half.less similarity index 100% rename from src/less/base/single/button/button.half.less rename to packages/fineui/src/less/base/single/button/button.half.less diff --git a/src/less/base/single/button/button.less b/packages/fineui/src/less/base/single/button/button.less similarity index 100% rename from src/less/base/single/button/button.less rename to packages/fineui/src/less/base/single/button/button.less diff --git a/src/less/base/single/button/switch.less b/packages/fineui/src/less/base/single/button/switch.less similarity index 100% rename from src/less/base/single/button/switch.less rename to packages/fineui/src/less/base/single/button/switch.less diff --git a/src/less/base/single/editor/editor.multifile.less b/packages/fineui/src/less/base/single/editor/editor.multifile.less similarity index 100% rename from src/less/base/single/editor/editor.multifile.less rename to packages/fineui/src/less/base/single/editor/editor.multifile.less diff --git a/src/less/base/single/editor/editor.textarea.less b/packages/fineui/src/less/base/single/editor/editor.textarea.less similarity index 100% rename from src/less/base/single/editor/editor.textarea.less rename to packages/fineui/src/less/base/single/editor/editor.textarea.less diff --git a/src/less/base/single/html.less b/packages/fineui/src/less/base/single/html.less similarity index 100% rename from src/less/base/single/html.less rename to packages/fineui/src/less/base/single/html.less diff --git a/src/less/base/single/input/checkbox.less b/packages/fineui/src/less/base/single/input/checkbox.less similarity index 100% rename from src/less/base/single/input/checkbox.less rename to packages/fineui/src/less/base/single/input/checkbox.less diff --git a/src/less/base/single/input/file.less b/packages/fineui/src/less/base/single/input/file.less similarity index 100% rename from src/less/base/single/input/file.less rename to packages/fineui/src/less/base/single/input/file.less diff --git a/src/less/base/single/input/input.less b/packages/fineui/src/less/base/single/input/input.less similarity index 100% rename from src/less/base/single/input/input.less rename to packages/fineui/src/less/base/single/input/input.less diff --git a/src/less/base/single/input/radio.less b/packages/fineui/src/less/base/single/input/radio.less similarity index 100% rename from src/less/base/single/input/radio.less rename to packages/fineui/src/less/base/single/input/radio.less diff --git a/src/less/base/single/instruction.less b/packages/fineui/src/less/base/single/instruction.less similarity index 100% rename from src/less/base/single/instruction.less rename to packages/fineui/src/less/base/single/instruction.less diff --git a/src/less/base/single/label.less b/packages/fineui/src/less/base/single/label.less similarity index 100% rename from src/less/base/single/label.less rename to packages/fineui/src/less/base/single/label.less diff --git a/packages/fineui/src/less/base/single/text.less b/packages/fineui/src/less/base/single/text.less new file mode 100644 index 000000000..dcdabf602 --- /dev/null +++ b/packages/fineui/src/less/base/single/text.less @@ -0,0 +1,9 @@ +@import "../../index.less"; + +.bi-text { + .overflow-hidden(); + .box-sizing(border-box); + // https://developer.mozilla.org/en-US/docs/Web/CSS/word-break 参考mdn最标准的规范. 不再接受任何质疑 + word-break: normal; + overflow-wrap: anywhere; +} \ No newline at end of file diff --git a/src/less/base/single/tip/tip.bubble.less b/packages/fineui/src/less/base/single/tip/tip.bubble.less similarity index 100% rename from src/less/base/single/tip/tip.bubble.less rename to packages/fineui/src/less/base/single/tip/tip.bubble.less diff --git a/src/less/base/single/tip/tip.less b/packages/fineui/src/less/base/single/tip/tip.less similarity index 100% rename from src/less/base/single/tip/tip.less rename to packages/fineui/src/less/base/single/tip/tip.less diff --git a/src/less/base/single/tip/tip.toast.less b/packages/fineui/src/less/base/single/tip/tip.toast.less similarity index 100% rename from src/less/base/single/tip/tip.toast.less rename to packages/fineui/src/less/base/single/tip/tip.toast.less diff --git a/src/less/base/single/tip/tip.tooltip.less b/packages/fineui/src/less/base/single/tip/tip.tooltip.less similarity index 100% rename from src/less/base/single/tip/tip.tooltip.less rename to packages/fineui/src/less/base/single/tip/tip.tooltip.less diff --git a/src/less/base/tree/tree.branch.less b/packages/fineui/src/less/base/tree/tree.branch.less similarity index 100% rename from src/less/base/tree/tree.branch.less rename to packages/fineui/src/less/base/tree/tree.branch.less diff --git a/src/less/base/tree/tree.display.less b/packages/fineui/src/less/base/tree/tree.display.less similarity index 100% rename from src/less/base/tree/tree.display.less rename to packages/fineui/src/less/base/tree/tree.display.less diff --git a/src/less/base/tree/tree.expander.less b/packages/fineui/src/less/base/tree/tree.expander.less similarity index 100% rename from src/less/base/tree/tree.expander.less rename to packages/fineui/src/less/base/tree/tree.expander.less diff --git a/src/less/base/tree/tree.list.display.less b/packages/fineui/src/less/base/tree/tree.list.display.less similarity index 100% rename from src/less/base/tree/tree.list.display.less rename to packages/fineui/src/less/base/tree/tree.list.display.less diff --git a/src/less/base/tree/ztree.less b/packages/fineui/src/less/base/tree/ztree.less similarity index 100% rename from src/less/base/tree/ztree.less rename to packages/fineui/src/less/base/tree/ztree.less diff --git a/src/less/base/trigger/trigger.less b/packages/fineui/src/less/base/trigger/trigger.less similarity index 100% rename from src/less/base/trigger/trigger.less rename to packages/fineui/src/less/base/trigger/trigger.less diff --git a/src/less/base/trigger/trigger.searchtextvalue.less b/packages/fineui/src/less/base/trigger/trigger.searchtextvalue.less similarity index 100% rename from src/less/base/trigger/trigger.searchtextvalue.less rename to packages/fineui/src/less/base/trigger/trigger.searchtextvalue.less diff --git a/src/less/base/trigger/trigger.selecttext.less b/packages/fineui/src/less/base/trigger/trigger.selecttext.less similarity index 100% rename from src/less/base/trigger/trigger.selecttext.less rename to packages/fineui/src/less/base/trigger/trigger.selecttext.less diff --git a/src/less/base/trigger/trigger.selecttextsmall.less b/packages/fineui/src/less/base/trigger/trigger.selecttextsmall.less similarity index 100% rename from src/less/base/trigger/trigger.selecttextsmall.less rename to packages/fineui/src/less/base/trigger/trigger.selecttextsmall.less diff --git a/src/less/base/trigger/trigger.text.less b/packages/fineui/src/less/base/trigger/trigger.text.less similarity index 100% rename from src/less/base/trigger/trigger.text.less rename to packages/fineui/src/less/base/trigger/trigger.text.less diff --git a/src/less/base/view/drawer.less b/packages/fineui/src/less/base/view/drawer.less similarity index 100% rename from src/less/base/view/drawer.less rename to packages/fineui/src/less/base/view/drawer.less diff --git a/src/less/base/view/popover.less b/packages/fineui/src/less/base/view/popover.less similarity index 100% rename from src/less/base/view/popover.less rename to packages/fineui/src/less/base/view/popover.less diff --git a/src/less/base/view/popupview.less b/packages/fineui/src/less/base/view/popupview.less similarity index 100% rename from src/less/base/view/popupview.less rename to packages/fineui/src/less/base/view/popupview.less diff --git a/src/less/box-model.less b/packages/fineui/src/less/box-model.less similarity index 100% rename from src/less/box-model.less rename to packages/fineui/src/less/box-model.less diff --git a/src/less/case/tree/tree.item.less b/packages/fineui/src/less/case/tree/tree.item.less similarity index 100% rename from src/less/case/tree/tree.item.less rename to packages/fineui/src/less/case/tree/tree.item.less diff --git a/src/less/component/form/form.less b/packages/fineui/src/less/component/form/form.less similarity index 100% rename from src/less/component/form/form.less rename to packages/fineui/src/less/component/form/form.less diff --git a/src/less/core/normalize.less b/packages/fineui/src/less/core/normalize.less similarity index 100% rename from src/less/core/normalize.less rename to packages/fineui/src/less/core/normalize.less diff --git a/src/less/core/normalize2.less b/packages/fineui/src/less/core/normalize2.less similarity index 100% rename from src/less/core/normalize2.less rename to packages/fineui/src/less/core/normalize2.less diff --git a/src/less/core/utils/animation.less b/packages/fineui/src/less/core/utils/animation.less similarity index 100% rename from src/less/core/utils/animation.less rename to packages/fineui/src/less/core/utils/animation.less diff --git a/src/less/core/utils/common.less b/packages/fineui/src/less/core/utils/common.less similarity index 100% rename from src/less/core/utils/common.less rename to packages/fineui/src/less/core/utils/common.less diff --git a/src/less/core/utils/cursor.less b/packages/fineui/src/less/core/utils/cursor.less similarity index 100% rename from src/less/core/utils/cursor.less rename to packages/fineui/src/less/core/utils/cursor.less diff --git a/packages/fineui/src/less/core/utils/list-item.less b/packages/fineui/src/less/core/utils/list-item.less new file mode 100644 index 000000000..ce5b6abb1 --- /dev/null +++ b/packages/fineui/src/less/core/utils/list-item.less @@ -0,0 +1,771 @@ +@import "../../index.less"; + +// hover的时候背景变化,文字变黑 +.bi-list-item { + &:hover, &.hover { + color: @color-bi-text-black; + & .bi-input { + color: @color-bi-text-black; + } + & .bi-textarea { + color: @color-bi-text-black; + } + .background-color(@color-bi-background-highlight, 10%); + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item { + &:hover, &.hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + .background-color(@color-bi-background-highlight, 10%); + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} + +// active的时候边框高亮 +.bi-list-item-border { + &:active, &.active { + border: 1px solid @color-bi-border-highlight; + } +} + +// 极简,hover的时候文字高亮 +.bi-list-item-simple { + &:hover, &.hover { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + } + &.disabled { + &, &:hover, &:active { + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-simple { + &.disabled { + &, &:hover, &:active { + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} + +// hover的时候文字变黑 +// active的时候文字高亮 +.bi-list-item-effect { + &:hover { + color: @color-bi-text-black; + & .bi-input { + color: @color-bi-text-black; + } + & .bi-textarea { + color: @color-bi-text-black; + } + } + &.active, &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + } + &.disabled { + &, &:hover, &:active { + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-effect { + &:hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + } + &.active, &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} + +// hover的时候背景变化,文字变黑 +// :active的时候文字高亮,背景变化 +.bi-list-item-active { + &:hover, &.hover { + color: @color-bi-text-black; + & .bi-input { + color: @color-bi-text-black; + } + & .bi-textarea { + color: @color-bi-text-black; + } + .background-color(@color-bi-background-highlight, 10%); + } + &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + .background-color(@color-bi-background-highlight, 15%); + } + &.active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-active { + &:hover, &.hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + .background-color(@color-bi-background-default, 5%); + } + &.active, &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + .background-color(@color-bi-background-default, 5%); + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} + +// hover的时候背景变化,文字变黑 +// active的时候文字高亮,背景变化 +.bi-list-item-active2 { + &:hover, &.hover { + color: @color-bi-text-black; + & .bi-input { + color: @color-bi-text-black; + } + & .bi-textarea { + color: @color-bi-text-black; + } + .background-color(@color-bi-background-highlight, 10%); + } + &:active, &.active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + .background-color(@color-bi-background-highlight, 15%); + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-active2 { + &:hover, &.hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + .background-color(@color-bi-background-highlight, 10%); + } + &:active, &.active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + .background-color(@color-bi-background-highlight, 15%); + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} + +// hover的时候背景变化 -- 变灰 +// active的时候文字高亮背景变化 -- 变灰 +.bi-list-item-active3, .bi-list-item-select3 { + &:hover, &.hover { + background-color: @color-bi-background-normal; + } + &:active, &.active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + background-color: @color-bi-background-normal; + } + &.disabled { + &:hover, &.hover, &:active, &.active { + background-color: @color-bi-background-default !important; + } + } +} + +.bi-theme-dark { + .bi-list-item-active3, .bi-list-item-select3 { + &:hover, &.hover { + background-color: @color-bi-background-normal-theme-dark; + } + &:active, &.active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + background-color: @color-bi-background-normal-theme-dark; + } + &.disabled { + &:hover, &.hover, &:active, &.active { + background-color: @color-bi-background-default-theme-dark !important; + } + } + } +} + +// hover的时候背景变化 +// active的时候背景高亮 +.bi-list-item-select { + &:hover, &.hover { + .background-color(@color-bi-background-highlight, 10%); + } + &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + .background-color(@color-bi-background-highlight, 15%); + } + &.active { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + background-color: @color-bi-background-highlight; + & .bi-high-light { + color: @color-bi-text; + } + } + &.button-success { + &:active, &.active { + color: @color-bi-text; + background-color: @color-bi-background-success; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + & .bi-high-light { + color: @color-bi-text; + } + &.bi-high-light-border { + border-color: @color-bi-border-success; + } + } + } + &.button-warning { + & { + color: @color-bi-text-failure; + & .bi-input { + color: @color-bi-text-failure; + } + & .bi-textarea { + color: @color-bi-text-failure; + } + & .bi-high-light { + color: @color-bi-text-failure; + } + &.bi-high-light-border { + border-color: @color-bi-border-failure; + } + } + &:hover, &.hover { + color: @color-bi-text-failure; + & .bi-input { + color: @color-bi-text-failure; + } + & .bi-textarea { + color: @color-bi-text-failure; + } + background-color: @color-bi-background-light-failure; + & .bi-high-light { + color: @color-bi-text-failure; + } + &.bi-high-light-border { + border-color: @color-bi-border-failure; + } + } + &:active, &.active { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + background-color: @color-bi-background-failure; + & .bi-high-light { + color: @color-bi-text; + } + &.bi-high-light-border { + border-color: @color-bi-border-failure; + } + } + } + &.disabled { + &, &:hover, &:active { + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + background-color: transparent !important; + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + &.bi-high-light-border { + border-color: @color-bi-border-disabled; + } + &.hover, &.active { + color: @color-bi-text !important; + & .bi-input { + color: @color-bi-text !important; + } + & .bi-textarea { + color: @color-bi-text !important; + } + background-color: @color-bi-background-dark-gray !important; + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + &.bi-high-light-border { + border-color: @color-bi-border-disabled; + } + } + } + } +} + +.bi-theme-dark { + .bi-list-item-select { + &:hover, &.hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + .background-color(@color-bi-background-default, 5%); + } + &:active { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + .background-color(@color-bi-background-default, 5%); + } + &.active { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + background-color: @color-bi-background-highlight; + & .bi-high-light { + color: @color-bi-text; + } + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + &.hover, &.active { + background-color: @background-color-black-theme-dark !important; + } + } + } +} + +// hover的时候边框高亮,文字变黑 +// :active的时候文字高亮,边框高亮 +// .active的时候背景高亮,边框高亮 +.bi-list-item-select2 { + &:hover, &.hover { + color: @color-bi-text-black; + & .bi-input { + color: @color-bi-text-black; + } + & .bi-textarea { + color: @color-bi-text-black; + } + &.bi-border { + border-color: @color-bi-border-highlight; + } + } + &:active { + color: @color-bi-text-highlight; + & .bi-input { + color: @color-bi-text-highlight; + } + & .bi-textarea { + color: @color-bi-text-highlight; + } + &.bi-border { + border-color: @color-bi-border-highlight; + } + } + &.active { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + &.bi-border { + border-color: @color-bi-border-highlight; + } + background-color: @color-bi-background-highlight; + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-select2 { + &:hover, &.hover { + color: @color-bi-text; + & .bi-input { + color: @color-bi-text; + } + & .bi-textarea { + color: @color-bi-text; + } + } + + &.active { + background-color: @color-bi-background-default-theme-dark; + } + + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + &.active { + background-color: @background-color-black-theme-dark !important; + } + } + } +} + +// 去掉list-item效果 +.bi-list-item-none { + &:hover, &.hover { + color: inherit; + & .bi-input { + color: inherit; + } + & .bi-textarea { + color: inherit; + } + background-color: transparent; + } + &:active, &.active { + color: inherit; + & .bi-input { + color: inherit; + } + & .bi-textarea { + color: inherit; + } + background-color: transparent; + & .bi-high-light { + color: inherit; + } + } + &.disabled { + &, &:hover, &:active { + color: @color-bi-text-disabled !important; + & .bi-input { + color: @color-bi-text-disabled !important; + } + & .bi-textarea { + color: @color-bi-text-disabled !important; + } + background-color: transparent !important; + & .bi-high-light { + color: @color-bi-text-disabled !important; + } + } + } +} + +.bi-theme-dark { + .bi-list-item-none { + &:hover, &.hover { + color: inherit; + & .bi-input { + color: inherit; + } + & .bi-textarea { + color: inherit; + } + background-color: transparent; + } + &:active, &.active { + color: inherit; + & .bi-input { + color: inherit; + } + & .bi-textarea { + color: inherit; + } + background-color: transparent; + & .bi-high-light { + color: inherit; + } + } + &.disabled { + &, &:hover, &:active { + background-color: transparent !important; + color: @color-bi-text-disabled-theme-dark !important; + & .bi-input { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-textarea { + color: @color-bi-text-disabled-theme-dark !important; + } + & .bi-high-light { + color: @color-bi-text-disabled-theme-dark !important; + } + } + } + } +} diff --git a/src/less/core/utils/motion/fade.less b/packages/fineui/src/less/core/utils/motion/fade.less similarity index 100% rename from src/less/core/utils/motion/fade.less rename to packages/fineui/src/less/core/utils/motion/fade.less diff --git a/src/less/core/utils/motion/move.less b/packages/fineui/src/less/core/utils/motion/move.less similarity index 100% rename from src/less/core/utils/motion/move.less rename to packages/fineui/src/less/core/utils/motion/move.less diff --git a/src/less/core/utils/motion/slide.less b/packages/fineui/src/less/core/utils/motion/slide.less similarity index 100% rename from src/less/core/utils/motion/slide.less rename to packages/fineui/src/less/core/utils/motion/slide.less diff --git a/src/less/core/utils/motion/zoom.less b/packages/fineui/src/less/core/utils/motion/zoom.less similarity index 100% rename from src/less/core/utils/motion/zoom.less rename to packages/fineui/src/less/core/utils/motion/zoom.less diff --git a/src/less/core/utils/position.less b/packages/fineui/src/less/core/utils/position.less similarity index 100% rename from src/less/core/utils/position.less rename to packages/fineui/src/less/core/utils/position.less diff --git a/src/less/core/utils/size.less b/packages/fineui/src/less/core/utils/size.less similarity index 100% rename from src/less/core/utils/size.less rename to packages/fineui/src/less/core/utils/size.less diff --git a/src/less/core/utils/sizing.less b/packages/fineui/src/less/core/utils/sizing.less similarity index 100% rename from src/less/core/utils/sizing.less rename to packages/fineui/src/less/core/utils/sizing.less diff --git a/src/less/core/utils/typographic.less b/packages/fineui/src/less/core/utils/typographic.less similarity index 100% rename from src/less/core/utils/typographic.less rename to packages/fineui/src/less/core/utils/typographic.less diff --git a/src/less/core/wrapper/flex.horizontal.less b/packages/fineui/src/less/core/wrapper/flex.horizontal.less similarity index 100% rename from src/less/core/wrapper/flex.horizontal.less rename to packages/fineui/src/less/core/wrapper/flex.horizontal.less diff --git a/src/less/core/wrapper/flex.vertical.less b/packages/fineui/src/less/core/wrapper/flex.vertical.less similarity index 100% rename from src/less/core/wrapper/flex.vertical.less rename to packages/fineui/src/less/core/wrapper/flex.vertical.less diff --git a/src/less/core/wrapper/flex.wrapper.horizontal.less b/packages/fineui/src/less/core/wrapper/flex.wrapper.horizontal.less similarity index 100% rename from src/less/core/wrapper/flex.wrapper.horizontal.less rename to packages/fineui/src/less/core/wrapper/flex.wrapper.horizontal.less diff --git a/src/less/core/wrapper/flex.wrapper.vertical.less b/packages/fineui/src/less/core/wrapper/flex.wrapper.vertical.less similarity index 100% rename from src/less/core/wrapper/flex.wrapper.vertical.less rename to packages/fineui/src/less/core/wrapper/flex.wrapper.vertical.less diff --git a/src/less/core/wrapper/float.absolute.less b/packages/fineui/src/less/core/wrapper/float.absolute.less similarity index 100% rename from src/less/core/wrapper/float.absolute.less rename to packages/fineui/src/less/core/wrapper/float.absolute.less diff --git a/src/less/core/wrapper/inline.less b/packages/fineui/src/less/core/wrapper/inline.less similarity index 100% rename from src/less/core/wrapper/inline.less rename to packages/fineui/src/less/core/wrapper/inline.less diff --git a/src/less/core/wrapper/inline.old.less b/packages/fineui/src/less/core/wrapper/inline.old.less similarity index 100% rename from src/less/core/wrapper/inline.old.less rename to packages/fineui/src/less/core/wrapper/inline.old.less diff --git a/src/less/core/wrapper/table.less b/packages/fineui/src/less/core/wrapper/table.less similarity index 100% rename from src/less/core/wrapper/table.less rename to packages/fineui/src/less/core/wrapper/table.less diff --git a/src/less/image.less b/packages/fineui/src/less/image.less similarity index 100% rename from src/less/image.less rename to packages/fineui/src/less/image.less diff --git a/src/less/index.less b/packages/fineui/src/less/index.less similarity index 100% rename from src/less/index.less rename to packages/fineui/src/less/index.less diff --git a/src/less/lib/background.less b/packages/fineui/src/less/lib/background.less similarity index 100% rename from src/less/lib/background.less rename to packages/fineui/src/less/lib/background.less diff --git a/src/less/lib/colors.less b/packages/fineui/src/less/lib/colors.less similarity index 100% rename from src/less/lib/colors.less rename to packages/fineui/src/less/lib/colors.less diff --git a/src/less/lib/constant.less b/packages/fineui/src/less/lib/constant.less similarity index 100% rename from src/less/lib/constant.less rename to packages/fineui/src/less/lib/constant.less diff --git a/src/less/lib/font.less b/packages/fineui/src/less/lib/font.less similarity index 100% rename from src/less/lib/font.less rename to packages/fineui/src/less/lib/font.less diff --git a/src/less/lib/icon.less b/packages/fineui/src/less/lib/icon.less similarity index 100% rename from src/less/lib/icon.less rename to packages/fineui/src/less/lib/icon.less diff --git a/src/less/lib/theme-modern.less b/packages/fineui/src/less/lib/theme-modern.less similarity index 100% rename from src/less/lib/theme-modern.less rename to packages/fineui/src/less/lib/theme-modern.less diff --git a/src/less/lib/theme.less b/packages/fineui/src/less/lib/theme.less similarity index 100% rename from src/less/lib/theme.less rename to packages/fineui/src/less/lib/theme.less diff --git a/src/less/motion.less b/packages/fineui/src/less/motion.less similarity index 100% rename from src/less/motion.less rename to packages/fineui/src/less/motion.less diff --git a/src/less/position.less b/packages/fineui/src/less/position.less similarity index 100% rename from src/less/position.less rename to packages/fineui/src/less/position.less diff --git a/src/less/resource/app.less b/packages/fineui/src/less/resource/app.less similarity index 100% rename from src/less/resource/app.less rename to packages/fineui/src/less/resource/app.less diff --git a/src/less/resource/background.less b/packages/fineui/src/less/resource/background.less similarity index 100% rename from src/less/resource/background.less rename to packages/fineui/src/less/resource/background.less diff --git a/src/less/resource/font.less b/packages/fineui/src/less/resource/font.less similarity index 100% rename from src/less/resource/font.less rename to packages/fineui/src/less/resource/font.less diff --git a/src/less/resource/icon.less b/packages/fineui/src/less/resource/icon.less similarity index 100% rename from src/less/resource/icon.less rename to packages/fineui/src/less/resource/icon.less diff --git a/src/less/theme/dark.less b/packages/fineui/src/less/theme/dark.less similarity index 100% rename from src/less/theme/dark.less rename to packages/fineui/src/less/theme/dark.less diff --git a/src/less/theme/default.less b/packages/fineui/src/less/theme/default.less similarity index 100% rename from src/less/theme/default.less rename to packages/fineui/src/less/theme/default.less diff --git a/src/less/theme/light.less b/packages/fineui/src/less/theme/light.less similarity index 100% rename from src/less/theme/light.less rename to packages/fineui/src/less/theme/light.less diff --git a/src/less/typographic.less b/packages/fineui/src/less/typographic.less similarity index 100% rename from src/less/typographic.less rename to packages/fineui/src/less/typographic.less diff --git a/src/less/var.less b/packages/fineui/src/less/var.less similarity index 100% rename from src/less/var.less rename to packages/fineui/src/less/var.less diff --git a/src/less/visual.less b/packages/fineui/src/less/visual.less similarity index 100% rename from src/less/visual.less rename to packages/fineui/src/less/visual.less diff --git a/src/less/widget/date/trigger.date.less b/packages/fineui/src/less/widget/date/trigger.date.less similarity index 100% rename from src/less/widget/date/trigger.date.less rename to packages/fineui/src/less/widget/date/trigger.date.less diff --git a/src/less/widget/downlist/popup.downlist.less b/packages/fineui/src/less/widget/downlist/popup.downlist.less similarity index 100% rename from src/less/widget/downlist/popup.downlist.less rename to packages/fineui/src/less/widget/downlist/popup.downlist.less diff --git a/src/less/widget/dynamicdatecombo/dynamicdatepopup.less b/packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatepopup.less similarity index 100% rename from src/less/widget/dynamicdatecombo/dynamicdatepopup.less rename to packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatepopup.less diff --git a/src/less/widget/dynamicdatecombo/dynamicdatetime.combo.less b/packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatetime.combo.less similarity index 100% rename from src/less/widget/dynamicdatecombo/dynamicdatetime.combo.less rename to packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatetime.combo.less diff --git a/src/less/widget/dynamicdatecombo/dynamicdatetimepopup.less b/packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatetimepopup.less similarity index 100% rename from src/less/widget/dynamicdatecombo/dynamicdatetimepopup.less rename to packages/fineui/src/less/widget/dynamicdatecombo/dynamicdatetimepopup.less diff --git a/src/less/widget/intervalslider/intervalslider.label.less b/packages/fineui/src/less/widget/intervalslider/intervalslider.label.less similarity index 100% rename from src/less/widget/intervalslider/intervalslider.label.less rename to packages/fineui/src/less/widget/intervalslider/intervalslider.label.less diff --git a/src/less/widget/intervalslider/intervalslider.less b/packages/fineui/src/less/widget/intervalslider/intervalslider.less similarity index 100% rename from src/less/widget/intervalslider/intervalslider.less rename to packages/fineui/src/less/widget/intervalslider/intervalslider.less diff --git a/src/less/widget/month/trigger.month.less b/packages/fineui/src/less/widget/month/trigger.month.less similarity index 100% rename from src/less/widget/month/trigger.month.less rename to packages/fineui/src/less/widget/month/trigger.month.less diff --git a/src/less/widget/multilayerselecttree/multilayerselecttree.combo.less b/packages/fineui/src/less/widget/multilayerselecttree/multilayerselecttree.combo.less similarity index 100% rename from src/less/widget/multilayerselecttree/multilayerselecttree.combo.less rename to packages/fineui/src/less/widget/multilayerselecttree/multilayerselecttree.combo.less diff --git a/src/less/widget/multilayerselecttree/multilayerselecttree.leveltree.less b/packages/fineui/src/less/widget/multilayerselecttree/multilayerselecttree.leveltree.less similarity index 100% rename from src/less/widget/multilayerselecttree/multilayerselecttree.leveltree.less rename to packages/fineui/src/less/widget/multilayerselecttree/multilayerselecttree.leveltree.less diff --git a/src/less/widget/multilayersingletree/multilayersingletree.combo.less b/packages/fineui/src/less/widget/multilayersingletree/multilayersingletree.combo.less similarity index 100% rename from src/less/widget/multilayersingletree/multilayersingletree.combo.less rename to packages/fineui/src/less/widget/multilayersingletree/multilayersingletree.combo.less diff --git a/src/less/widget/multilayersingletree/multilayersingletree.leveltree.less b/packages/fineui/src/less/widget/multilayersingletree/multilayersingletree.leveltree.less similarity index 100% rename from src/less/widget/multilayersingletree/multilayersingletree.leveltree.less rename to packages/fineui/src/less/widget/multilayersingletree/multilayersingletree.leveltree.less diff --git a/src/less/widget/multiselect/check/multiselect.check.pane.less b/packages/fineui/src/less/widget/multiselect/check/multiselect.check.pane.less similarity index 100% rename from src/less/widget/multiselect/check/multiselect.check.pane.less rename to packages/fineui/src/less/widget/multiselect/check/multiselect.check.pane.less diff --git a/src/less/widget/multiselect/multiselect.combo.less b/packages/fineui/src/less/widget/multiselect/multiselect.combo.less similarity index 100% rename from src/less/widget/multiselect/multiselect.combo.less rename to packages/fineui/src/less/widget/multiselect/multiselect.combo.less diff --git a/src/less/widget/multiselect/multiselect.insert.combo.less b/packages/fineui/src/less/widget/multiselect/multiselect.insert.combo.less similarity index 100% rename from src/less/widget/multiselect/multiselect.insert.combo.less rename to packages/fineui/src/less/widget/multiselect/multiselect.insert.combo.less diff --git a/src/less/widget/multiselect/search/multiselect.search.pane.less b/packages/fineui/src/less/widget/multiselect/search/multiselect.search.pane.less similarity index 100% rename from src/less/widget/multiselect/search/multiselect.search.pane.less rename to packages/fineui/src/less/widget/multiselect/search/multiselect.search.pane.less diff --git a/src/less/widget/multiselect/trigger/button.checkselected.less b/packages/fineui/src/less/widget/multiselect/trigger/button.checkselected.less similarity index 100% rename from src/less/widget/multiselect/trigger/button.checkselected.less rename to packages/fineui/src/less/widget/multiselect/trigger/button.checkselected.less diff --git a/src/less/widget/multistringlist/multistringlist.insert.less b/packages/fineui/src/less/widget/multistringlist/multistringlist.insert.less similarity index 100% rename from src/less/widget/multistringlist/multistringlist.insert.less rename to packages/fineui/src/less/widget/multistringlist/multistringlist.insert.less diff --git a/src/less/widget/multistringlist/multistringlist.less b/packages/fineui/src/less/widget/multistringlist/multistringlist.less similarity index 100% rename from src/less/widget/multistringlist/multistringlist.less rename to packages/fineui/src/less/widget/multistringlist/multistringlist.less diff --git a/src/less/widget/multitree/multi.tree.combo.less b/packages/fineui/src/less/widget/multitree/multi.tree.combo.less similarity index 100% rename from src/less/widget/multitree/multi.tree.combo.less rename to packages/fineui/src/less/widget/multitree/multi.tree.combo.less diff --git a/src/less/widget/multitree/popup.multi.tree.less b/packages/fineui/src/less/widget/multitree/popup.multi.tree.less similarity index 100% rename from src/less/widget/multitree/popup.multi.tree.less rename to packages/fineui/src/less/widget/multitree/popup.multi.tree.less diff --git a/src/less/widget/multitree/trigger/multi.tree.button.checkselected.less b/packages/fineui/src/less/widget/multitree/trigger/multi.tree.button.checkselected.less similarity index 100% rename from src/less/widget/multitree/trigger/multi.tree.button.checkselected.less rename to packages/fineui/src/less/widget/multitree/trigger/multi.tree.button.checkselected.less diff --git a/src/less/widget/numbereditor/number.editor.less b/packages/fineui/src/less/widget/numbereditor/number.editor.less similarity index 100% rename from src/less/widget/numbereditor/number.editor.less rename to packages/fineui/src/less/widget/numbereditor/number.editor.less diff --git a/src/less/widget/numberinterval/numberinterval.less b/packages/fineui/src/less/widget/numberinterval/numberinterval.less similarity index 100% rename from src/less/widget/numberinterval/numberinterval.less rename to packages/fineui/src/less/widget/numberinterval/numberinterval.less diff --git a/src/less/widget/quarter/trigger.quarter.less b/packages/fineui/src/less/widget/quarter/trigger.quarter.less similarity index 100% rename from src/less/widget/quarter/trigger.quarter.less rename to packages/fineui/src/less/widget/quarter/trigger.quarter.less diff --git a/src/less/widget/searchmultiselect/searchmultiselect.less b/packages/fineui/src/less/widget/searchmultiselect/searchmultiselect.less similarity index 100% rename from src/less/widget/searchmultiselect/searchmultiselect.less rename to packages/fineui/src/less/widget/searchmultiselect/searchmultiselect.less diff --git a/src/less/widget/singleselect/search/singleselect.search.pane.less b/packages/fineui/src/less/widget/singleselect/search/singleselect.search.pane.less similarity index 100% rename from src/less/widget/singleselect/search/singleselect.search.pane.less rename to packages/fineui/src/less/widget/singleselect/search/singleselect.search.pane.less diff --git a/src/less/widget/singleselect/singleselect.combo.less b/packages/fineui/src/less/widget/singleselect/singleselect.combo.less similarity index 100% rename from src/less/widget/singleselect/singleselect.combo.less rename to packages/fineui/src/less/widget/singleselect/singleselect.combo.less diff --git a/src/less/widget/singleslider/singlelider.label.less b/packages/fineui/src/less/widget/singleslider/singlelider.label.less similarity index 100% rename from src/less/widget/singleslider/singlelider.label.less rename to packages/fineui/src/less/widget/singleslider/singlelider.label.less diff --git a/src/less/widget/singleslider/singlelider.normal.less b/packages/fineui/src/less/widget/singleslider/singlelider.normal.less similarity index 100% rename from src/less/widget/singleslider/singlelider.normal.less rename to packages/fineui/src/less/widget/singleslider/singlelider.normal.less diff --git a/src/less/widget/singleslider/singleslider.less b/packages/fineui/src/less/widget/singleslider/singleslider.less similarity index 100% rename from src/less/widget/singleslider/singleslider.less rename to packages/fineui/src/less/widget/singleslider/singleslider.less diff --git a/src/less/widget/singleslider/slider/widget.slider.less b/packages/fineui/src/less/widget/singleslider/slider/widget.slider.less similarity index 100% rename from src/less/widget/singleslider/slider/widget.slider.less rename to packages/fineui/src/less/widget/singleslider/slider/widget.slider.less diff --git a/src/less/widget/singleslider/track/widget.track.less b/packages/fineui/src/less/widget/singleslider/track/widget.track.less similarity index 100% rename from src/less/widget/singleslider/track/widget.track.less rename to packages/fineui/src/less/widget/singleslider/track/widget.track.less diff --git a/src/less/widget/timecombo/timecombo.less b/packages/fineui/src/less/widget/timecombo/timecombo.less similarity index 100% rename from src/less/widget/timecombo/timecombo.less rename to packages/fineui/src/less/widget/timecombo/timecombo.less diff --git a/src/less/widget/timeinterval/dateinterval.less b/packages/fineui/src/less/widget/timeinterval/dateinterval.less similarity index 100% rename from src/less/widget/timeinterval/dateinterval.less rename to packages/fineui/src/less/widget/timeinterval/dateinterval.less diff --git a/src/less/widget/timeinterval/timeinterval.less b/packages/fineui/src/less/widget/timeinterval/timeinterval.less similarity index 100% rename from src/less/widget/timeinterval/timeinterval.less rename to packages/fineui/src/less/widget/timeinterval/timeinterval.less diff --git a/src/less/widget/year/popup.year.less b/packages/fineui/src/less/widget/year/popup.year.less similarity index 100% rename from src/less/widget/year/popup.year.less rename to packages/fineui/src/less/widget/year/popup.year.less diff --git a/src/less/widget/year/trigger.year.less b/packages/fineui/src/less/widget/year/trigger.year.less similarity index 100% rename from src/less/widget/year/trigger.year.less rename to packages/fineui/src/less/widget/year/trigger.year.less diff --git a/src/less/widget/yearinterval/yearinterval.less b/packages/fineui/src/less/widget/yearinterval/yearinterval.less similarity index 100% rename from src/less/widget/yearinterval/yearinterval.less rename to packages/fineui/src/less/widget/yearinterval/yearinterval.less diff --git a/src/less/widget/yearmonth/popup.yearmonth.less b/packages/fineui/src/less/widget/yearmonth/popup.yearmonth.less similarity index 100% rename from src/less/widget/yearmonth/popup.yearmonth.less rename to packages/fineui/src/less/widget/yearmonth/popup.yearmonth.less diff --git a/src/less/widget/yearmonthinterval/yearmonthinterval.less b/packages/fineui/src/less/widget/yearmonthinterval/yearmonthinterval.less similarity index 100% rename from src/less/widget/yearmonthinterval/yearmonthinterval.less rename to packages/fineui/src/less/widget/yearmonthinterval/yearmonthinterval.less diff --git a/src/less/widget/yearquarter/popup.yearquarter.less b/packages/fineui/src/less/widget/yearquarter/popup.yearquarter.less similarity index 100% rename from src/less/widget/yearquarter/popup.yearquarter.less rename to packages/fineui/src/less/widget/yearquarter/popup.yearquarter.less diff --git a/src/less/widget/yearquarterinterval/yearquarterinterval.less b/packages/fineui/src/less/widget/yearquarterinterval/yearquarterinterval.less similarity index 100% rename from src/less/widget/yearquarterinterval/yearquarterinterval.less rename to packages/fineui/src/less/widget/yearquarterinterval/yearquarterinterval.less diff --git a/packages/fineui/src/polyfill/index.js b/packages/fineui/src/polyfill/index.js new file mode 100644 index 000000000..2f0dcabd3 --- /dev/null +++ b/packages/fineui/src/polyfill/index.js @@ -0,0 +1 @@ +export * from "./number"; diff --git a/src/polyfill/number.js b/packages/fineui/src/polyfill/number.js similarity index 100% rename from src/polyfill/number.js rename to packages/fineui/src/polyfill/number.js diff --git a/packages/fineui/src/router/0.router.js b/packages/fineui/src/router/0.router.js new file mode 100644 index 000000000..8c055c6a3 --- /dev/null +++ b/packages/fineui/src/router/0.router.js @@ -0,0 +1,708 @@ +import { _ } from "@/core"; +import { _global } from "@/core/0.foundation"; + + +const Events = { + // Bind an event to a `callback` function. Passing `"all"` will bind + // the callback to all events fired. + on(name, callback, context) { + if (!eventsApi(this, "on", name, [callback, context]) || !callback) { + return this; + } + this._events || (this._events = {}); + const events = this._events[name] || (this._events[name] = []); + events.push({ + callback, + context, + ctx: context || this + }); + + return this; + }, + + // Bind an event to only be triggered a single time. After the first time + // the callback is invoked, it will be removed. + once(name, callback, context) { + if (!eventsApi(this, "once", name, [callback, context]) || !callback) { + return this; + } + const self = this; + var once = _.once(function () { + self.off(name, once); + callback.apply(this, arguments); + }); + once._callback = callback; + + return this.on(name, once, context); + }, + + // Remove one or many callbacks. If `context` is null, removes all + // callbacks with that function. If `callback` is null, removes all + // callbacks for the event. If `name` is null, removes all bound + // callbacks for all events. + off(name, callback, context) { + if ( + !this._events || + !eventsApi(this, "off", name, [callback, context]) + ) { + return this; + } + + // Remove all callbacks for all events. + if (!name && !callback && !context) { + this._events = void 0; + + return this; + } + + const names = name ? [name] : _.keys(this._events); + for (let i = 0, length = names.length; i < length; i++) { + name = names[i]; + + // Bail out if there are no events stored. + const events = this._events[name]; + if (!events) continue; + + // Remove all callbacks for this event. + if (!callback && !context) { + delete this._events[name]; + continue; + } + + // Find any remaining events. + const remaining = []; + for (let j = 0, k = events.length; j < k; j++) { + const event = events[j]; + if ( + (callback && + callback !== event.callback && + callback !== event.callback._callback) || + (context && context !== event.context) + ) { + remaining.push(event); + } + } + + // Replace events if there are any remaining. Otherwise, clean up. + if (remaining.length) { + this._events[name] = remaining; + } else { + delete this._events[name]; + } + } + + return this; + }, + + un() { + this.off.apply(this, arguments); + }, + + // Trigger one or many events, firing all bound callbacks. Callbacks are + // passed the same arguments as `trigger` is, apart from the event name + // (unless you're listening on `"all"`, which will cause your callback to + // receive the true name of the event as the first argument). + trigger(name) { + if (!this._events) return this; + const args = slice.call(arguments, 1); + if (!eventsApi(this, "trigger", name, args)) return this; + const events = this._events[name]; + const allEvents = this._events.all; + if (events) triggerEvents(events, args); + if (allEvents) triggerEvents(allEvents, arguments); + + return this; + }, + + fireEvent() { + this.trigger.apply(this, arguments); + }, + + // Inversion-of-control versions of `on` and `once`. Tell *this* object to + // listen to an event in another object ... keeping track of what it's + // listening to. + listenTo(obj, name, callback) { + const listeningTo = this._listeningTo || (this._listeningTo = {}); + const id = obj._listenId || (obj._listenId = _.uniqueId("l")); + listeningTo[id] = obj; + if (!callback && typeof name === "object") callback = this; + obj.on(name, callback, this); + + return this; + }, + + listenToOnce(obj, name, callback) { + if (typeof name === "object") { + for (const event in name) { + this.listenToOnce(obj, event, name[event]); + } + + return this; + } + if (eventSplitter.test(name)) { + const names = name.split(eventSplitter); + for (let i = 0, length = names.length; i < length; i++) { + this.listenToOnce(obj, names[i], callback); + } + + return this; + } + if (!callback) return this; + var once = _.once(function () { + this.stopListening(obj, name, once); + callback.apply(this, arguments); + }); + once._callback = callback; + + return this.listenTo(obj, name, once); + }, + + // Tell this object to stop listening to either specific events ... or + // to every object it's currently listening to. + stopListening(obj, name, callback) { + let listeningTo = this._listeningTo; + if (!listeningTo) return this; + const remove = !name && !callback; + if (!callback && typeof name === "object") callback = this; + if (obj) (listeningTo = {})[obj._listenId] = obj; + for (const id in listeningTo) { + obj = listeningTo[id]; + obj.off(name, callback, this); + if (remove || _.isEmpty(obj._events)) { + delete this._listeningTo[id]; + } + } + + return this; + } +}; + +// Regular expression used to split event strings. +var eventSplitter = /\s+/; + +// Implement fancy features of the Events API such as multiple event +// names `"change blur"` and jQuery-style event maps `{change: action}` +// in terms of the existing API. +var eventsApi = function (obj, action, name, rest) { + if (!name) return true; + + // Handle event maps. + if (typeof name === "object") { + for (const key in name) { + obj[action].apply(obj, [key, name[key]].concat(rest)); + } + + return false; + } + + // Handle space separated event names. + if (eventSplitter.test(name)) { + const names = name.split(eventSplitter); + for (let i = 0, length = names.length; i < length; i++) { + obj[action].apply(obj, [names[i]].concat(rest)); + } + + return false; + } + + return true; +}; + +// A difficult-to-believe, but optimized internal dispatch function for +// triggering events. Tries to keep the usual cases speedy (most internal +// BI events have 3 arguments). +var triggerEvents = function (events, args) { + let ev, + i = -1, + l = events.length, + a1 = args[0], + a2 = args[1], + a3 = args[2]; + switch (args.length) { + case 0: + while (++i < l) (ev = events[i]).callback.call(ev.ctx); + + return; + case 1: + while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); + + return; + case 2: + while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); + + return; + case 3: + while (++i < l) { + (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); + } + + return; + default: + while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); + + return; + } +}; + +// BI.Router +// --------------- + +// Routers map faux-URLs to actions, and fire events when routes are +// matched. Creating a new one sets its `routes` hash, if not set statically. +export const Router = function (options) { + options || (options = {}); + if (options.routes) this.routes = options.routes; + this._bindRoutes(); + this._init.apply(this, arguments); +}; + +// Cached regular expressions for matching named param parts and splatted +// parts of route strings. +const optionalParam = /\((.*?)\)/g; +const namedParam = /(\(\?)?:\w+/g; +const splatParam = /\*\w+/g; +const escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; + +// Set up all inheritable **BI.Router** properties and methods. +_.extend(Router.prototype, Events, { + // _init is an empty function by default. Override it with your own + // initialization logic. + _init() {}, + + // Manually bind a single named route to a callback. For example: + // + // this.route('search/:query/p:num', 'search', function(query, num) { + // ... + // }); + // + route(route, name, callback) { + if (!_.isRegExp(route)) route = this._routeToRegExp(route); + if (_.isFunction(name)) { + callback = name; + name = ""; + } + if (!callback) callback = this[name]; + const router = this; + history.route(route, (fragment) => { + const args = router._extractParameters(route, fragment); + if (router.execute(callback, args, name) !== false) { + router.trigger.apply(router, [`route:${name}`].concat(args)); + router.trigger("route", name, args); + history.trigger("route", router, name, args); + } + }); + + return this; + }, + + // Execute a route handler with the provided parameters. This is an + // excellent place to do pre-route setup or post-route cleanup. + execute(callback, args, name) { + if (callback) callback.apply(this, args); + }, + + // Simple proxy to `BI.history` to save a fragment into the history. + navigate(fragment, options) { + history.navigate(fragment, options); + + return this; + }, + + // Bind all defined routes to `BI.history`. We have to reverse the + // order of the routes here to support behavior where the most general + // routes can be defined at the bottom of the route map. + _bindRoutes() { + if (!this.routes) return; + this.routes = _.result(this, "routes"); + let route, + routes = _.keys(this.routes); + while ((route = routes.pop()) != null) { + this.route(route, this.routes[route]); + } + }, + + // Convert a route string into a regular expression, suitable for matching + // against the current location hash. + _routeToRegExp(route) { + route = route + .replace(escapeRegExp, "\\$&") + .replace(optionalParam, "(?:$1)?") + .replace(namedParam, (match, optional) => + optional ? match : "([^/?]+)" + ) + .replace(splatParam, "([^?]*?)"); + + return new RegExp(`^${route}(?:\\?([\\s\\S]*))?$`); + }, + + // Given a route, and a URL fragment that it matches, return the array of + // extracted decoded parameters. Empty or unmatched parameters will be + // treated as `null` to normalize cross-browser behavior. + _extractParameters(route, fragment) { + const params = route.exec(fragment).slice(1); + + return _.map(params, (param, i) => { + // Don't decode the search params. + if (i === params.length - 1) return param || null; + let resultParam = null; + if (param) { + try { + resultParam = decodeURIComponent(param); + } catch (e) { + resultParam = param; + } + } + + return resultParam; + }); + } +}); + +// History +// ---------------- + +// Handles cross-browser history management, based on either +// [pushState](http://diveintohtml5.info/history.html) and real URLs, or +// [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) +// and URL fragments. If the browser supports neither (old IE, natch), +// falls back to polling. +const History = function () { + this.handlers = []; + this.checkUrl = _.bind(this.checkUrl, this); + + // Ensure that `History` can be used outside of the browser. + if (typeof window !== "undefined") { + this.location = _global.location; + this.history = _global.history; + } +}; + +// Cached regex for stripping a leading hash/slash and trailing space. +const routeStripper = /^[#\/]|\s+$/g; + +// Cached regex for stripping leading and trailing slashes. +const rootStripper = /^\/+|\/+$/g; + +// Cached regex for stripping urls of hash. +const pathStripper = /#.*$/; + +// Has the history handling already been started? +History.started = false; + +// Set up all inheritable **BI.History** properties and methods. +_.extend(History.prototype, Events, { + // The default interval to poll for hash changes, if necessary, is + // twenty times a second. + interval: 50, + + // Are we at the app root? + atRoot() { + const path = this.location.pathname.replace(/[^\/]$/, "$&/"); + + return path === this.root && !this.getSearch(); + }, + + // In IE6, the hash fragment and search params are incorrect if the + // fragment contains `?`. + getSearch() { + const match = this.location.href.replace(/#.*/, "").match(/\?.+/); + + return match ? match[0] : ""; + }, + + // Gets the true hash value. Cannot use location.hash directly due to bug + // in Firefox where location.hash will always be decoded. + getHash(window) { + const match = (window || this).location.href.match(/#(.*)$/); + + return match ? match[1] : ""; + }, + + // Get the pathname and search params, without the root. + getPath() { + let path = this.location.pathname + this.getSearch(); + try { + path = decodeURI(path); + } catch (e) {} + const root = this.root.slice(0, -1); + if (!path.indexOf(root)) path = path.slice(root.length); + + return path.charAt(0) === "/" ? path.slice(1) : path; + }, + + // Get the cross-browser normalized URL fragment from the path or hash. + getFragment(fragment) { + if (fragment == null) { + if (this._hasPushState || !this._wantsHashChange) { + fragment = this.getPath(); + } else { + fragment = this.getHash(); + } + } + + return fragment.replace(routeStripper, ""); + }, + + // Start the hash change handling, returning `true` if the current URL matches + // an existing route, and `false` otherwise. + start(options) { + if (History.started) { + throw new Error("BI.history has already been started"); + } + History.started = true; + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? + this.options = _.extend({ root: "/" }, this.options, options); + this.root = this.options.root; + this._wantsHashChange = this.options.hashChange !== false; + this._hasHashChange = "onhashchange" in window; + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!( + this.options.pushState && + this.history && + this.history.pushState + ); + this.fragment = this.getFragment(); + + // Normalize root to always include a leading and trailing slash. + this.root = `/${this.root}/`.replace(rootStripper, "/"); + + // Transition from hashChange to pushState or vice versa if both are + // requested. + if (this._wantsHashChange && this._wantsPushState) { + // If we've started off with a route from a `pushState`-enabled + // browser, but we're currently in a browser that doesn't support it... + if (!this._hasPushState && !this.atRoot()) { + const root = this.root.slice(0, -1) || "/"; + this.location.replace(`${root}#${this.getPath()}`); + // Return immediately as browser will do redirect to new url + return true; + + // Or if we've started out with a hash-based route, but we're currently + // in a browser where it could be `pushState`-based instead... + } else if (this._hasPushState && this.atRoot()) { + this.navigate(this.getHash(), { replace: true }); + } + } + + // Proxy an iframe to handle location events if the browser doesn't + // support the `hashchange` event, HTML5 history, or the user wants + // `hashChange` but not `pushState`. + if ( + !this._hasHashChange && + this._wantsHashChange && + (!this._wantsPushState || !this._hasPushState) + ) { + const iframe = document.createElement("iframe"); + iframe.src = "javascript:0"; + iframe.style.display = "none"; + iframe.tabIndex = -1; + const body = document.body; + // Using `appendChild` will throw on IE < 9 if the document is not ready. + this.iframe = body.insertBefore( + iframe, + body.firstChild + ).contentWindow; + this.iframe.document.open().close(); + this.iframe.location.hash = `#${this.fragment}`; + } + + // Add a cross-platform `addEventListener` shim for older browsers. + const addEventListener = + _global.addEventListener || + function (eventName, listener) { + return attachEvent(`on${eventName}`, listener); + }; + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + addEventListener("popstate", this.checkUrl, false); + } else if ( + this._wantsHashChange && + this._hasHashChange && + !this.iframe + ) { + addEventListener("hashchange", this.checkUrl, false); + } else if (this._wantsHashChange) { + this._checkUrlInterval = setInterval(this.checkUrl, this.interval); + } + + if (!this.options.silent) return this.loadUrl(); + }, + + // Disable BI.history, perhaps temporarily. Not useful in a real app, + // but possibly useful for unit testing Routers. + stop() { + // Add a cross-platform `removeEventListener` shim for older browsers. + const removeEventListener = + _global.removeEventListener || + function (eventName, listener) { + return detachEvent(`on${eventName}`, listener); + }; + + // Remove window listeners. + if (this._hasPushState) { + removeEventListener("popstate", this.checkUrl, false); + } else if ( + this._wantsHashChange && + this._hasHashChange && + !this.iframe + ) { + removeEventListener("hashchange", this.checkUrl, false); + } + + // Clean up the iframe if necessary. + if (this.iframe) { + document.body.removeChild(this.iframe.frameElement); + this.iframe = null; + } + + // Some environments will throw when clearing an undefined interval. + if (this._checkUrlInterval) clearInterval(this._checkUrlInterval); + History.started = false; + }, + + // Add a route to be tested when the fragment changes. Routes added later + // may override previous routes. + route(route, callback) { + this.handlers.unshift({ route, callback }); + }, + + // check route is Exist. if exist, return the route + checkRoute(route) { + for (let i = 0; i < this.handlers.length; i++) { + if ( + this.handlers[i].route.toString() === + Router.prototype._routeToRegExp(route).toString() + ) { + return this.handlers[i]; + } + } + + return null; + }, + + // remove a route match in routes + unRoute(route) { + const index = _.findIndex(this.handlers, (handler) => + handler.route.test(route) + ); + if (index > -1) { + this.handlers.splice(index, 1); + } + }, + + // Checks the current URL to see if it has changed, and if it has, + // calls `loadUrl`, normalizing across the hidden iframe. + checkUrl(e) { + let current = this.getFragment(); + try { + // getFragment 得到的值是编码过的,而this.fragment是没有编码过的 + // 英文路径没有问题,遇上中文和空格有问题了 + current = decodeURIComponent(current); + } catch (e) {} + // If the user pressed the back button, the iframe's hash will have + // changed and we should use that for comparison. + if (current === this.fragment && this.iframe) { + current = this.getHash(this.iframe); + } + + if (current === this.fragment) return false; + if (this.iframe) this.navigate(current); + this.loadUrl(); + }, + + // Attempt to load the current URL fragment. If a route succeeds with a + // match, returns `true`. If no defined routes matches the fragment, + // returns `false`. + loadUrl(fragment) { + fragment = this.fragment = this.getFragment(fragment); + + return _.some(this.handlers, (handler) => { + if (handler.route.test(fragment)) { + handler.callback(fragment); + + return true; + } + }); + }, + + // Save a fragment into the hash history, or replace the URL state if the + // 'replace' option is passed. You are responsible for properly URL-encoding + // the fragment in advance. + // + // The options object can contain `trigger: true` if you wish to have the + // route callback be fired (not usually desirable), or `replace: true`, if + // you wish to modify the current URL without adding an entry to the history. + navigate(fragment, options) { + if (!History.started) return false; + if (!options || options === true) options = { trigger: !!options }; + + // Normalize the fragment. + fragment = this.getFragment(fragment || ""); + + // Don't include a trailing slash on the root. + let root = this.root; + if (fragment === "" || fragment.charAt(0) === "?") { + root = root.slice(0, -1) || "/"; + } + const url = root + fragment; + + // Strip the hash and decode for matching. + fragment = fragment.replace(pathStripper, ""); + try { + fragment = decodeURI(fragment); + } catch (e) {} + + if (this.fragment === fragment) return; + this.fragment = fragment; + + // If pushState is available, we use it to set the fragment as a real URL. + if (this._hasPushState) { + this.history[options.replace ? "replaceState" : "pushState"]( + {}, + document.title, + url + ); + + // If hash changes haven't been explicitly disabled, update the hash + // fragment to store history. + } else if (this._wantsHashChange) { + this._updateHash(this.location, fragment, options.replace); + if (this.iframe && fragment !== this.getHash(this.iframe)) { + // Opening and closing the iframe tricks IE7 and earlier to push a + // history entry on hash-tag change. When replace is true, we don't + // want this. + if (!options.replace) this.iframe.document.open().close(); + this._updateHash( + this.iframe.location, + fragment, + options.replace + ); + } + + // If you've told us that you explicitly don't want fallback hashchange- + // based history, then `navigate` becomes a page refresh. + } else { + return this.location.assign(url); + } + if (options.trigger) return this.loadUrl(fragment); + }, + + // Update the hash location, either replacing the current entry, or adding + // a new one to the browser history. + _updateHash(location, fragment, replace) { + if (replace) { + const href = location.href.replace(/(javascript:|#).*$/, ""); + location.replace(`${href}#${fragment}`); + } else { + // Some browsers require that `hash` contains a leading #. + location.hash = `#${fragment}`; + } + } +}); + +// Create the default BI.history. +export const history = new History(); \ No newline at end of file diff --git a/packages/fineui/src/router/index.js b/packages/fineui/src/router/index.js new file mode 100644 index 000000000..9e81827ef --- /dev/null +++ b/packages/fineui/src/router/index.js @@ -0,0 +1,2 @@ +export * from "./0.router"; +export * from "./router"; diff --git a/packages/fineui/src/router/router.js b/packages/fineui/src/router/router.js new file mode 100644 index 000000000..f58c8402b --- /dev/null +++ b/packages/fineui/src/router/router.js @@ -0,0 +1,3143 @@ +import { nextTick, shortcut, Widget, isNotNull, each } from '@/core'; +import { Tab } from '@/base'; +import { Router } from './0.router'; +import { Fix } from '../fix'; + +function assert(condition, message) { + if (!condition) { + throw new Error(`[vue-router] ${message}`); + } +} + +function warn(condition, message) { + if (!condition) { + typeof console !== 'undefined' && console.warn(`[vue-router] ${message}`); + } +} + +function extend(a, b) { + for (const key in b) { + a[key] = b[key]; + } + + return a; +} + +/* */ + +const encodeReserveRE = /[!'()*]/g; +const encodeReserveReplacer = function (c) { + return `%${c.charCodeAt(0).toString(16)}`; +}; +const commaRE = /%2C/g; + +// fixed encodeURIComponent which is more conformant to RFC3986: +// - escapes [!'()*] +// - preserve commas +const encode = function (str) { + return encodeURIComponent(str).replace(encodeReserveRE, encodeReserveReplacer).replace(commaRE, ','); +}; + +function decode(str) { + try { + return decodeURIComponent(str); + } catch (err) { + { + warn(false, `Error decoding "${str}". Leaving it intact.`); + } + } + + return str; +} + +function resolveQuery(query, extraQuery, _parseQuery) { + if (extraQuery === void 0) extraQuery = {}; + + const parse = _parseQuery || parseQuery; + let parsedQuery; + try { + parsedQuery = parse(query || ''); + } catch (e) { + warn(false, e.message); + parsedQuery = {}; + } + for (const key in extraQuery) { + const value = extraQuery[key]; + parsedQuery[key] = Array.isArray(value) ? value.map(castQueryParamValue) : castQueryParamValue(value); + } + + return parsedQuery; +} + +var castQueryParamValue = function (value) { + return value == null || typeof value === 'object' ? value : String(value); +}; + +function parseQuery(query) { + const res = {}; + + query = query.trim().replace(/^(\?|#|&)/, ''); + + if (!query) { + return res; + } + + query.split('&').forEach(param => { + const parts = param.replace(/\+/g, ' ').split('='); + const key = decode(parts.shift()); + const val = parts.length > 0 ? decode(parts.join('=')) : null; + + if (res[key] === undefined) { + res[key] = val; + } else if (Array.isArray(res[key])) { + res[key].push(val); + } else { + res[key] = [res[key], val]; + } + }); + + return res; +} + +function stringifyQuery(obj) { + const res = obj + ? Object.keys(obj) + .map(key => { + const val = obj[key]; + + if (val === undefined) { + return ''; + } + + if (val === null) { + return encode(key); + } + + if (Array.isArray(val)) { + const result = []; + val.forEach(val2 => { + if (val2 === undefined) { + return; + } + if (val2 === null) { + result.push(encode(key)); + } else { + result.push(`${encode(key)}=${encode(val2)}`); + } + }); + + return result.join('&'); + } + + return `${encode(key)}=${encode(val)}`; + }) + .filter(x => x.length > 0) + .join('&') + : null; + + return res ? `?${res}` : ''; +} + +/* */ + +const trailingSlashRE = /\/?$/; + +function createRoute(record, location, redirectedFrom, router) { + const stringifyQuery = router && router.options.stringifyQuery; + + let query = location.query || {}; + try { + query = clone(query); + } catch (e) {} + + const route = { + name: location.name || (record && record.name), + meta: (record && record.meta) || {}, + path: location.path || '/', + hash: location.hash || '', + query, + params: location.params || {}, + fullPath: getFullPath(location, stringifyQuery), + matched: record ? formatMatch(record) : [], + }; + if (redirectedFrom) { + route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery); + } + + return Object.freeze(route); +} + +function clone(value) { + if (Array.isArray(value)) { + return value.map(clone); + } else if (value && typeof value === 'object') { + const res = {}; + for (const key in value) { + res[key] = clone(value[key]); + } + + return res; + } else { + return value; + } +} + +// the starting route that represents the initial state +const START = createRoute(null, { + path: '/', +}); + +function formatMatch(record) { + const res = []; + while (record) { + res.unshift(record); + record = record.parent; + } + + return res; +} + +function getFullPath(ref, _stringifyQuery) { + const path = ref.path; + let query = ref.query; + if (query === void 0) query = {}; + let hash = ref.hash; + if (hash === void 0) hash = ''; + + const stringify = _stringifyQuery || stringifyQuery; + + return (path || '/') + stringify(query) + hash; +} + +function isSameRoute(a, b, onlyPath) { + if (b === START) { + return a === b; + } else if (!b) { + return false; + } else if (a.path && b.path) { + return ( + a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && + (onlyPath || (a.hash === b.hash && isObjectEqual(a.query, b.query))) + ); + } else if (a.name && b.name) { + return ( + a.name === b.name && + (onlyPath || (a.hash === b.hash && isObjectEqual(a.query, b.query) && isObjectEqual(a.params, b.params))) + ); + } else { + return false; + } +} + +function isObjectEqual(a, b) { + if (a === void 0) a = {}; + if (b === void 0) b = {}; + + // handle null value #1566 + if (!a || !b) { + return a === b; + } + const aKeys = Object.keys(a).sort(); + const bKeys = Object.keys(b).sort(); + if (aKeys.length !== bKeys.length) { + return false; + } + + return aKeys.every((key, i) => { + const aVal = a[key]; + const bKey = bKeys[i]; + if (bKey !== key) { + return false; + } + const bVal = b[key]; + // query values can be null and undefined + if (aVal == null || bVal == null) { + return aVal === bVal; + } + // check nested equality + if (typeof aVal === 'object' && typeof bVal === 'object') { + return isObjectEqual(aVal, bVal); + } + + return String(aVal) === String(bVal); + }); +} + +function isIncludedRoute(current, target) { + return ( + current.path.replace(trailingSlashRE, '/').indexOf(target.path.replace(trailingSlashRE, '/')) === 0 && + (!target.hash || current.hash === target.hash) && + queryIncludes(current.query, target.query) + ); +} + +function queryIncludes(current, target) { + for (const key in target) { + if (!(key in current)) { + return false; + } + } + + return true; +} + +function handleRouteEntered(route) { + for (let i = 0; i < route.matched.length; i++) { + const record = route.matched[i]; + for (const name in record.instances) { + const instance = record.instances[name]; + const cbs = record.enteredCbs[name]; + if (!instance || !cbs) { + continue; + } + delete record.enteredCbs[name]; + for (let i$1 = 0; i$1 < cbs.length; i$1++) { + if (!instance._isBeingDestroyed) { + cbs[i$1](instance); + } + } + } + } +} + +// var View = { +// name: 'RouterView', +// functional: true, +// props: { +// name: { +// type: String, +// default: 'default' +// } +// }, +// render: function render (_, ref) { +// var props = ref.props; +// var children = ref.children; +// var parent = ref.parent; +// var data = ref.data; + +// // used by devtools to display a router-view badge +// data.routerView = true; + +// // directly use parent context's createElement() function +// // so that components rendered by router-view can resolve named slots +// var h = parent.$createElement; +// var name = props.name; +// var route = parent.$route; +// var cache = parent._routerViewCache || (parent._routerViewCache = {}); + +// // determine current view depth, also check to see if the tree +// // has been toggled inactive but kept-alive. +// var depth = 0; +// var inactive = false; +// while (parent && parent._routerRoot !== parent) { +// var vnodeData = parent.$vnode ? parent.$vnode.data : {}; +// if (vnodeData.routerView) { +// depth++; +// } +// if (vnodeData.keepAlive && parent._directInactive && parent._inactive) { +// inactive = true; +// } +// parent = parent.$parent; +// } +// data.routerViewDepth = depth; + +// // render previous view if the tree is inactive and kept-alive +// if (inactive) { +// var cachedData = cache[name]; +// var cachedComponent = cachedData && cachedData.component; +// if (cachedComponent) { +// // #2301 +// // pass props +// if (cachedData.configProps) { +// fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps); +// } +// return h(cachedComponent, data, children) +// } else { +// // render previous empty view +// return h() +// } +// } + +// var matched = route.matched[depth]; +// var component = matched && matched.components[name]; + +// // render empty node if no matched route or no config component +// if (!matched || !component) { +// cache[name] = null; +// return h() +// } + +// // cache component +// cache[name] = { component: component }; + +// // attach instance registration hook +// // this will be called in the instance's injected lifecycle hooks +// data.registerRouteInstance = function (vm, val) { +// // val could be undefined for unregistration +// var current = matched.instances[name]; +// if ( +// (val && current !== vm) || +// (!val && current === vm) +// ) { +// matched.instances[name] = val; +// } +// } + +// // also register instance in prepatch hook +// // in case the same component instance is reused across different routes +// ;(data.hook || (data.hook = {})).prepatch = function (_, vnode) { +// matched.instances[name] = vnode.componentInstance; +// }; + +// // register instance in init hook +// // in case kept-alive component be actived when routes changed +// data.hook.init = function (vnode) { +// if (vnode.data.keepAlive && +// vnode.componentInstance && +// vnode.componentInstance !== matched.instances[name] +// ) { +// matched.instances[name] = vnode.componentInstance; +// } + +// // if the route transition has already been confirmed then we weren't +// // able to call the cbs during confirmation as the component was not +// // registered yet, so we call it here. +// handleRouteEntered(route); +// }; + +// var configProps = matched.props && matched.props[name]; +// // save route and configProps in cache +// if (configProps) { +// extend(cache[name], { +// route: route, +// configProps: configProps +// }); +// fillPropsinData(component, data, route, configProps); +// } + +// return h(component, data, children) +// } +// }; + +// function fillPropsinData (component, data, route, configProps) { +// // resolve props +// var propsToPass = data.props = resolveProps(route, configProps); +// if (propsToPass) { +// // clone to prevent mutation +// propsToPass = data.props = extend({}, propsToPass); +// // pass non-declared props as attrs +// var attrs = data.attrs = data.attrs || {}; +// for (var key in propsToPass) { +// if (!component.props || !(key in component.props)) { +// attrs[key] = propsToPass[key]; +// delete propsToPass[key]; +// } +// } +// } +// } + +// function resolveProps (route, config) { +// switch (typeof config) { +// case 'undefined': +// return +// case 'object': +// return config +// case 'function': +// return config(route) +// case 'boolean': +// return config ? route.params : undefined +// default: +// { +// warn( +// false, +// "props in \"" + (route.path) + "\" is a " + (typeof config) + ", " + +// "expecting an object, function or boolean." +// ); +// } +// } +// } + +/* */ + +function resolvePath(relative, base, append) { + const firstChar = relative.charAt(0); + if (firstChar === '/') { + return relative; + } + + if (firstChar === '?' || firstChar === '#') { + return base + relative; + } + + const stack = base.split('/'); + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop(); + } + + // resolve relative path + const segments = relative.replace(/^\//, '').split('/'); + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + if (segment === '..') { + stack.pop(); + } else if (segment !== '.') { + stack.push(segment); + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift(''); + } + + return stack.join('/'); +} + +function parsePath(path) { + let hash = ''; + let query = ''; + + const hashIndex = path.indexOf('#'); + if (hashIndex >= 0) { + hash = path.slice(hashIndex); + path = path.slice(0, hashIndex); + } + + const queryIndex = path.indexOf('?'); + if (queryIndex >= 0) { + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); + } + + return { + path, + query, + hash, + }; +} + +function cleanPath(path) { + return path.replace(/\/\//g, '/'); +} + +const isarray = + Array.isArray || + function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; + }; + +/** + * Expose `pathToRegexp`. + */ +const pathToRegexp_1 = pathToRegexp; +const parse_1 = parse; +const compile_1 = compile; +const tokensToFunction_1 = tokensToFunction; +const tokensToRegExp_1 = tokensToRegExp; + +/** + * The main path matching regexp utility. + * + * @type {RegExp} + */ +const PATH_REGEXP = new RegExp( + [ + // Match escaped characters that would otherwise appear in future matches. + // This allows the user to escape special characters that won't transform. + '(\\\\.)', + // Match Express-style parameters and un-named parameters with a prefix + // and optional suffixes. Matches appear as: + // + // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] + // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] + // "/*" => ["/", undefined, undefined, undefined, undefined, "*"] + '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))', + ].join('|'), + 'g' +); + +/** + * Parse a string for the raw tokens. + * + * @param {string} str + * @param {Object=} options + * @return {!Array} + */ +function parse(str, options) { + const tokens = []; + let key = 0; + let index = 0; + let path = ''; + const defaultDelimiter = (options && options.delimiter) || '/'; + let res; + + while ((res = PATH_REGEXP.exec(str)) != null) { + const m = res[0]; + const escaped = res[1]; + const offset = res.index; + path += str.slice(index, offset); + index = offset + m.length; + + // Ignore already escaped sequences. + if (escaped) { + path += escaped[1]; + continue; + } + + const next = str[index]; + const prefix = res[2]; + const name = res[3]; + const capture = res[4]; + const group = res[5]; + const modifier = res[6]; + const asterisk = res[7]; + + // Push the current path onto the tokens. + if (path) { + tokens.push(path); + path = ''; + } + + const partial = prefix != null && next != null && next !== prefix; + const repeat = modifier === '+' || modifier === '*'; + const optional = modifier === '?' || modifier === '*'; + const delimiter = res[2] || defaultDelimiter; + const pattern = capture || group; + + tokens.push({ + name: name || key++, + prefix: prefix || '', + delimiter, + optional, + repeat, + partial, + asterisk: !!asterisk, + pattern: pattern ? escapeGroup(pattern) : asterisk ? '.*' : `[^${escapeString(delimiter)}]+?`, + }); + } + + // Match any characters still remaining. + if (index < str.length) { + path += str.substr(index); + } + + // If the path exists, push it onto the end. + if (path) { + tokens.push(path); + } + + return tokens; +} + +/** + * Compile a string to a template function for the path. + * + * @param {string} str + * @param {Object=} options + * @return {!function(Object=, Object=)} + */ +function compile(str, options) { + return tokensToFunction(parse(str, options), options); +} + +/** + * Prettier encoding of URI path segments. + * + * @param {string} + * @return {string} + */ +function encodeURIComponentPretty(str) { + return encodeURI(str).replace(/[\/?#]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`); +} + +/** + * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. + * + * @param {string} + * @return {string} + */ +function encodeAsterisk(str) { + return encodeURI(str).replace(/[?#]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`); +} + +/** + * Expose a method for transforming tokens into the path function. + */ +function tokensToFunction(tokens, options) { + // Compile all the tokens into regexps. + const matches = new Array(tokens.length); + + // Compile all the patterns before compilation. + for (let i = 0; i < tokens.length; i++) { + if (typeof tokens[i] === 'object') { + matches[i] = new RegExp(`^(?:${tokens[i].pattern})$`, flags(options)); + } + } + + return function (obj, opts) { + let path = ''; + const data = obj || {}; + const options = opts || {}; + const encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent; + + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + + if (typeof token === 'string') { + path += token; + + continue; + } + + const value = data[token.name]; + var segment; + + if (value == null) { + if (token.optional) { + // Prepend partial segment prefixes. + if (token.partial) { + path += token.prefix; + } + + continue; + } else { + throw new TypeError(`Expected "${token.name}" to be defined`); + } + } + + if (isarray(value)) { + if (!token.repeat) { + throw new TypeError( + `Expected "${token.name}" to not repeat, but received \`${JSON.stringify(value)}\`` + ); + } + + if (value.length === 0) { + if (token.optional) { + continue; + } else { + throw new TypeError(`Expected "${token.name}" to not be empty`); + } + } + + for (let j = 0; j < value.length; j++) { + segment = encode(value[j]); + + if (!matches[i].test(segment)) { + throw new TypeError( + `Expected all "${token.name}" to match "${token.pattern}", but received \`${JSON.stringify( + segment + )}\`` + ); + } + + path += (j === 0 ? token.prefix : token.delimiter) + segment; + } + + continue; + } + + segment = token.asterisk ? encodeAsterisk(value) : encode(value); + + if (!matches[i].test(segment)) { + throw new TypeError(`Expected "${token.name}" to match "${token.pattern}", but received "${segment}"`); + } + + path += token.prefix + segment; + } + + return path; + }; +} + +/** + * Escape a regular expression string. + * + * @param {string} str + * @return {string} + */ +function escapeString(str) { + return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1'); +} + +/** + * Escape the capturing group by escaping special characters and meaning. + * + * @param {string} group + * @return {string} + */ +function escapeGroup(group) { + return group.replace(/([=!:$\/()])/g, '\\$1'); +} + +/** + * Attach the keys as a property of the regexp. + * + * @param {!RegExp} re + * @param {Array} keys + * @return {!RegExp} + */ +function attachKeys(re, keys) { + re.keys = keys; + + return re; +} + +/** + * Get the flags for a regexp from the options. + * + * @param {Object} options + * @return {string} + */ +function flags(options) { + return options && options.sensitive ? '' : 'i'; +} + +/** + * Pull out keys from a regexp. + * + * @param {!RegExp} path + * @param {!Array} keys + * @return {!RegExp} + */ +function regexpToRegexp(path, keys) { + // Use a negative lookahead to match only capturing groups. + const groups = path.source.match(/\((?!\?)/g); + + if (groups) { + for (let i = 0; i < groups.length; i++) { + keys.push({ + name: i, + prefix: null, + delimiter: null, + optional: false, + repeat: false, + partial: false, + asterisk: false, + pattern: null, + }); + } + } + + return attachKeys(path, keys); +} + +/** + * Transform an array into a regexp. + * + * @param {!Array} path + * @param {Array} keys + * @param {!Object} options + * @return {!RegExp} + */ +function arrayToRegexp(path, keys, options) { + const parts = []; + + for (let i = 0; i < path.length; i++) { + parts.push(pathToRegexp(path[i], keys, options).source); + } + + const regexp = new RegExp(`(?:${parts.join('|')})`, flags(options)); + + return attachKeys(regexp, keys); +} + +/** + * Create a path regexp from string input. + * + * @param {string} path + * @param {!Array} keys + * @param {!Object} options + * @return {!RegExp} + */ +function stringToRegexp(path, keys, options) { + return tokensToRegExp(parse(path, options), keys, options); +} + +/** + * Expose a function for taking tokens and returning a RegExp. + * + * @param {!Array} tokens + * @param {(Array|Object)=} keys + * @param {Object=} options + * @return {!RegExp} + */ +function tokensToRegExp(tokens, keys, options) { + if (!isarray(keys)) { + options = /** @type {!Object} */ (keys || options); + keys = []; + } + + options = options || {}; + + const strict = options.strict; + const end = options.end !== false; + let route = ''; + + // Iterate over the tokens and create our regexp string. + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + + if (typeof token === 'string') { + route += escapeString(token); + } else { + const prefix = escapeString(token.prefix); + let capture = `(?:${token.pattern})`; + + keys.push(token); + + if (token.repeat) { + capture += `(?:${prefix}${capture})*`; + } + + if (token.optional) { + if (!token.partial) { + capture = `(?:${prefix}(${capture}))?`; + } else { + capture = `${prefix}(${capture})?`; + } + } else { + capture = `${prefix}(${capture})`; + } + + route += capture; + } + } + + const delimiter = escapeString(options.delimiter || '/'); + const endsWithDelimiter = route.slice(-delimiter.length) === delimiter; + + // In non-strict mode we allow a slash at the end of match. If the path to + // match already ends with a slash, we remove it for consistency. The slash + // is valid at the end of a path match, not in the middle. This is important + // in non-ending mode, where "/test/" shouldn't match "/test//route". + if (!strict) { + route = `${endsWithDelimiter ? route.slice(0, -delimiter.length) : route}(?:${delimiter}(?=$))?`; + } + + if (end) { + route += '$'; + } else { + // In non-ending mode, we need the capturing groups to match as much as + // possible by using a positive lookahead to the end or next path segment. + route += strict && endsWithDelimiter ? '' : `(?=${delimiter}|$)`; + } + + return attachKeys(new RegExp(`^${route}`, flags(options)), keys); +} + +/** + * Normalize the given path string, returning a regular expression. + * + * An empty array can be passed in for the keys, which will hold the + * placeholder key descriptions. For example, using `/user/:id`, `keys` will + * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. + * + * @param {(string|RegExp|Array)} path + * @param {(Array|Object)=} keys + * @param {Object=} options + * @return {!RegExp} + */ +function pathToRegexp(path, keys, options) { + if (!isarray(keys)) { + options = /** @type {!Object} */ (keys || options); + keys = []; + } + + options = options || {}; + + if (path instanceof RegExp) { + return regexpToRegexp(path, /** @type {!Array} */ (keys)); + } + + if (isarray(path)) { + return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options); + } + + return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options); +} +pathToRegexp_1.parse = parse_1; +pathToRegexp_1.compile = compile_1; +pathToRegexp_1.tokensToFunction = tokensToFunction_1; +pathToRegexp_1.tokensToRegExp = tokensToRegExp_1; + +/* */ + +// $flow-disable-line +const regexpCompileCache = Object.create(null); + +function fillParams(path, params, routeMsg) { + params = params || {}; + try { + const filler = regexpCompileCache[path] || (regexpCompileCache[path] = pathToRegexp_1.compile(path)); + + // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }} + // and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string + if (typeof params.pathMatch === 'string') { + params[0] = params.pathMatch; + } + + return filler(params, { pretty: true }); + } catch (e) { + { + // Fix #3072 no warn if `pathMatch` is string + warn(typeof params.pathMatch === 'string', `missing param for ${routeMsg}: ${e.message}`); + } + + return ''; + } finally { + // delete the 0 if it was added + delete params[0]; + } +} + +/* */ + +function normalizeLocation(raw, current, append, router) { + let next = typeof raw === 'string' ? { path: raw } : raw; + // named target + if (next._normalized) { + return next; + } else if (next.name) { + next = extend({}, raw); + const params = next.params; + if (params && typeof params === 'object') { + next.params = extend({}, params); + } + + return next; + } + + // relative params + if (!next.path && next.params && current) { + next = extend({}, next); + next._normalized = true; + const params$1 = extend(extend({}, current.params), next.params); + if (current.name) { + next.name = current.name; + next.params = params$1; + } else if (current.matched.length) { + const rawPath = current.matched[current.matched.length - 1].path; + next.path = fillParams(rawPath, params$1, `path ${current.path}`); + } else { + warn(false, 'relative params navigation requires a current route.'); + } + + return next; + } + + const parsedPath = parsePath(next.path || ''); + const basePath = (current && current.path) || '/'; + const path = parsedPath.path ? resolvePath(parsedPath.path, basePath, append || next.append) : basePath; + + const query = resolveQuery(parsedPath.query, next.query, router && router.options.parseQuery); + + let hash = next.hash || parsedPath.hash; + if (hash && hash.charAt(0) !== '#') { + hash = `#${hash}`; + } + + return { + _normalized: true, + path, + query, + hash, + }; +} + +// var toTypes = [String, Object]; +// var eventTypes = [String, Array]; + +// var noop = function () {}; + +// var warnedCustomSlot; +// var warnedTagProp; +// var warnedEventProp; + +// var Link = { +// name: 'RouterLink', +// props: { +// to: { +// type: toTypes, +// required: true +// }, +// tag: { +// type: String, +// default: 'a' +// }, +// custom: Boolean, +// exact: Boolean, +// exactPath: Boolean, +// append: Boolean, +// replace: Boolean, +// activeClass: String, +// exactActiveClass: String, +// ariaCurrentValue: { +// type: String, +// default: 'page' +// }, +// event: { +// type: eventTypes, +// default: 'click' +// } +// }, +// render: function render (h) { +// var this$1 = this; + +// var router = this.$router; +// var current = this.$route; +// var ref = router.resolve( +// this.to, +// current, +// this.append +// ); +// var location = ref.location; +// var route = ref.route; +// var href = ref.href; + +// var classes = {}; +// var globalActiveClass = router.options.linkActiveClass; +// var globalExactActiveClass = router.options.linkExactActiveClass; +// // Support global empty active class +// var activeClassFallback = +// globalActiveClass == null ? 'router-link-active' : globalActiveClass; +// var exactActiveClassFallback = +// globalExactActiveClass == null +// ? 'router-link-exact-active' +// : globalExactActiveClass; +// var activeClass = +// this.activeClass == null ? activeClassFallback : this.activeClass; +// var exactActiveClass = +// this.exactActiveClass == null +// ? exactActiveClassFallback +// : this.exactActiveClass; + +// var compareTarget = route.redirectedFrom +// ? createRoute(null, normalizeLocation(route.redirectedFrom), null, router) +// : route; + +// classes[exactActiveClass] = isSameRoute(current, compareTarget, this.exactPath); +// classes[activeClass] = this.exact || this.exactPath +// ? classes[exactActiveClass] +// : isIncludedRoute(current, compareTarget); + +// var ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null; + +// var handler = function (e) { +// if (guardEvent(e)) { +// if (this$1.replace) { +// router.replace(location, noop); +// } else { +// router.push(location, noop); +// } +// } +// }; + +// var on = { click: guardEvent }; +// if (Array.isArray(this.event)) { +// this.event.forEach(function (e) { +// on[e] = handler; +// }); +// } else { +// on[this.event] = handler; +// } + +// var data = { class: classes }; + +// var scopedSlot = +// !this.$scopedSlots.$hasNormal && +// this.$scopedSlots.default && +// this.$scopedSlots.default({ +// href: href, +// route: route, +// navigate: handler, +// isActive: classes[activeClass], +// isExactActive: classes[exactActiveClass] +// }); + +// if (scopedSlot) { +// if (!this.custom) { +// !warnedCustomSlot && warn(false, 'In Vue Router 4, the v-slot API will by default wrap its content with an element. Use the custom prop to remove this warning:\n\n'); +// warnedCustomSlot = true; +// } +// if (scopedSlot.length === 1) { +// return scopedSlot[0] +// } else if (scopedSlot.length > 1 || !scopedSlot.length) { +// { +// warn( +// false, +// (" with to=\"" + (this.to) + "\" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.") +// ); +// } +// return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot) +// } +// } + +// { +// if ('tag' in this.$options.propsData && !warnedTagProp) { +// warn( +// false, +// "'s tag prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link." +// ); +// warnedTagProp = true; +// } +// if ('event' in this.$options.propsData && !warnedEventProp) { +// warn( +// false, +// "'s event prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link." +// ); +// warnedEventProp = true; +// } +// } + +// if (this.tag === 'a') { +// data.on = on; +// data.attrs = { href: href, 'aria-current': ariaCurrentValue }; +// } else { +// // find the first child and apply listener and href +// var a = findAnchor(this.$slots.default); +// if (a) { +// // in case the is a static node +// a.isStatic = false; +// var aData = (a.data = extend({}, a.data)); +// aData.on = aData.on || {}; +// // transform existing events in both objects into arrays so we can push later +// for (var event in aData.on) { +// var handler$1 = aData.on[event]; +// if (event in on) { +// aData.on[event] = Array.isArray(handler$1) ? handler$1 : [handler$1]; +// } +// } +// // append new listeners for router-link +// for (var event$1 in on) { +// if (event$1 in aData.on) { +// // on[event] is always a function +// aData.on[event$1].push(on[event$1]); +// } else { +// aData.on[event$1] = handler; +// } +// } + +// var aAttrs = (a.data.attrs = extend({}, a.data.attrs)); +// aAttrs.href = href; +// aAttrs['aria-current'] = ariaCurrentValue; +// } else { +// // doesn't have child, apply listener to self +// data.on = on; +// } +// } + +// return h(this.tag, data, this.$slots.default) +// } +// }; + +function guardEvent(e) { + // don't redirect with control keys + if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { + return; + } + // don't redirect when preventDefault called + if (e.defaultPrevented) { + return; + } + // don't redirect on right click + if (e.button !== undefined && e.button !== 0) { + return; + } + // don't redirect if `target="_blank"` + if (e.currentTarget && e.currentTarget.getAttribute) { + const target = e.currentTarget.getAttribute('target'); + if (/\b_blank\b/i.test(target)) { + return; + } + } + // this may be a Weex event which doesn't have this method + if (e.preventDefault) { + e.preventDefault(); + } + + return true; +} + +function findAnchor(children) { + if (children) { + let child; + for (let i = 0; i < children.length; i++) { + child = children[i]; + if (child.tag === 'a') { + return child; + } + if (child.children && (child = findAnchor(child.children))) { + return child; + } + } + } +} + +// var _Vue; + +// function install (Vue) { +// if (install.installed && _Vue === Vue) { return } +// install.installed = true; + +// _Vue = Vue; + +// var isDef = function (v) { return v !== undefined; }; + +// var registerInstance = function (vm, callVal) { +// var i = vm.$options._parentVnode; +// if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) { +// i(vm, callVal); +// } +// }; + +// Vue.mixin({ +// beforeCreate: function beforeCreate () { +// if (isDef(this.$options.router)) { +// this._routerRoot = this; +// this._router = this.$options.router; +// this._router.init(this); +// Vue.util.defineReactive(this, '_route', this._router.history.current); +// } else { +// this._routerRoot = (this.$parent && this.$parent._routerRoot) || this; +// } +// registerInstance(this, this); +// }, +// destroyed: function destroyed () { +// registerInstance(this); +// } +// }); + +// Object.defineProperty(Vue.prototype, '$router', { +// get: function get () { return this._routerRoot._router } +// }); + +// Object.defineProperty(Vue.prototype, '$route', { +// get: function get () { return this._routerRoot._route } +// }); + +// Vue.component('RouterView', View); +// Vue.component('RouterLink', Link); + +// var strats = Vue.config.optionMergeStrategies; +// // use the same hook merging strategy for route hooks +// strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created; +// } + +/* */ + +const inBrowser = typeof window !== 'undefined'; + +/* */ + +function createRouteMap(routes, oldPathList, oldPathMap, oldNameMap, parentRoute) { + // the path list is used to control path matching priority + const pathList = oldPathList || []; + // $flow-disable-line + const pathMap = oldPathMap || Object.create(null); + // $flow-disable-line + const nameMap = oldNameMap || Object.create(null); + + routes.forEach(route => { + addRouteRecord(pathList, pathMap, nameMap, route, parentRoute); + }); + + // ensure wildcard routes are always at the end + for (let i = 0, l = pathList.length; i < l; i++) { + if (pathList[i] === '*') { + pathList.push(pathList.splice(i, 1)[0]); + l--; + i--; + } + } + + { + // warn if routes do not include leading slashes + const found = pathList + // check for missing leading slash + .filter(path => path && path.charAt(0) !== '*' && path.charAt(0) !== '/'); + + if (found.length > 0) { + const pathNames = found.map(path => `- ${path}`).join('\n'); + warn( + false, + `Non-nested routes must include a leading slash character. Fix the following routes: \n${pathNames}` + ); + } + } + + return { + pathList, + pathMap, + nameMap, + }; +} + +function addRouteRecord(pathList, pathMap, nameMap, route, parent, matchAs) { + const path = route.path; + const name = route.name; + { + assert(path != null, '"path" is required in a route configuration.'); + assert( + typeof route.component !== 'string', + `route config "component" for path: ${String(path || name)} cannot be a ` + + 'string id. Use an actual component instead.' + ); + + warn( + // eslint-disable-next-line no-control-regex + !/[^\u0000-\u007F]+/.test(path), + `Route with path "${path}" contains unencoded characters, make sure ` + + 'your path is correctly encoded before passing it to the router. Use ' + + 'encodeURI to encode static segments of your path.' + ); + } + + const pathToRegexpOptions = route.pathToRegexpOptions || {}; + const normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict); + + if (typeof route.caseSensitive === 'boolean') { + pathToRegexpOptions.sensitive = route.caseSensitive; + } + + const record = { + path: normalizedPath, + regex: compileRouteRegex(normalizedPath, pathToRegexpOptions), + components: route.components || { default: route.component }, + alias: route.alias ? (typeof route.alias === 'string' ? [route.alias] : route.alias) : [], + instances: {}, + enteredCbs: {}, + name, + parent, + matchAs, + redirect: route.redirect, + beforeEnter: route.beforeEnter, + meta: route.meta || {}, + props: route.props == null ? {} : route.components ? route.props : { default: route.props }, + }; + + if (route.children) { + // Warn if route is named, does not redirect and has a default child route. + // If users navigate to this route by name, the default child will + // not be rendered (GH Issue #629) + { + if (route.name && !route.redirect && route.children.some(child => /^\/?$/.test(child.path))) { + warn( + false, + `Named Route '${route.name}' has a default child route. ` + + `When navigating to this named route (:to="{name: '${route.name}'"), ` + + 'the default child route will not be rendered. Remove the name from ' + + 'this route and use the name of the default child route for named ' + + 'links instead.' + ); + } + } + route.children.forEach(child => { + const childMatchAs = matchAs ? cleanPath(`${matchAs}/${child.path}`) : undefined; + addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs); + }); + } + + if (!pathMap[record.path]) { + pathList.push(record.path); + pathMap[record.path] = record; + } + + if (route.alias !== undefined) { + const aliases = Array.isArray(route.alias) ? route.alias : [route.alias]; + for (let i = 0; i < aliases.length; ++i) { + const alias = aliases[i]; + if (alias === path) { + warn( + false, + `Found an alias with the same value as the path: "${path}". You have to remove that alias. It will be ignored in development.` + ); + // skip in dev to make it work + continue; + } + + const aliasRoute = { + path: alias, + children: route.children, + }; + addRouteRecord( + pathList, + pathMap, + nameMap, + aliasRoute, + parent, + record.path || '/' // matchAs + ); + } + } + + if (name) { + if (!nameMap[name]) { + nameMap[name] = record; + } else if (!matchAs) { + warn(false, `${'Duplicate named routes definition: ' + '{ name: "'}${name}", path: "${record.path}" }`); + } + } +} + +function compileRouteRegex(path, pathToRegexpOptions) { + const regex = pathToRegexp_1(path, [], pathToRegexpOptions); + { + const keys = Object.create(null); + regex.keys.forEach(key => { + warn(!keys[key.name], `Duplicate param keys in route with path: "${path}"`); + keys[key.name] = true; + }); + } + + return regex; +} + +function normalizePath(path, parent, strict) { + if (!strict) { + path = path.replace(/\/$/, ''); + } + if (path[0] === '/') { + return path; + } + if (parent == null) { + return path; + } + + return cleanPath(`${parent.path}/${path}`); +} + +/* */ + +function createMatcher(routes, router) { + const ref = createRouteMap(routes); + const pathList = ref.pathList; + const pathMap = ref.pathMap; + const nameMap = ref.nameMap; + + function addRoutes(routes) { + createRouteMap(routes, pathList, pathMap, nameMap); + } + + function addRoute(parentOrRoute, route) { + const parent = typeof parentOrRoute !== 'object' ? nameMap[parentOrRoute] : undefined; + // $flow-disable-line + createRouteMap([route || parentOrRoute], pathList, pathMap, nameMap, parent); + + // add aliases of parent + if (parent && parent.alias.length) { + createRouteMap( + // $flow-disable-line route is defined if parent is + parent.alias.map(alias => { + return { path: alias, children: [route] }; + }), + pathList, + pathMap, + nameMap, + parent + ); + } + } + + function getRoutes() { + return pathList.map(path => pathMap[path]); + } + + function match(raw, currentRoute, redirectedFrom) { + const location = normalizeLocation(raw, currentRoute, false, router); + const name = location.name; + + if (name) { + const record = nameMap[name]; + { + warn(record, `Route with name '${name}' does not exist`); + } + if (!record) { + return _createRoute(null, location); + } + const paramNames = record.regex.keys.filter(key => !key.optional).map(key => key.name); + + if (typeof location.params !== 'object') { + location.params = {}; + } + + if (currentRoute && typeof currentRoute.params === 'object') { + for (const key in currentRoute.params) { + if (!(key in location.params) && paramNames.indexOf(key) > -1) { + location.params[key] = currentRoute.params[key]; + } + } + } + + location.path = fillParams(record.path, location.params, `named route "${name}"`); + + return _createRoute(record, location, redirectedFrom); + } else if (location.path) { + location.params = {}; + for (let i = 0; i < pathList.length; i++) { + const path = pathList[i]; + const record$1 = pathMap[path]; + if (matchRoute(record$1.regex, location.path, location.params)) { + return _createRoute(record$1, location, redirectedFrom); + } + } + } + // no match + return _createRoute(null, location); + } + + function redirect(record, location) { + const originalRedirect = record.redirect; + let redirect = + typeof originalRedirect === 'function' + ? originalRedirect(createRoute(record, location, null, router)) + : originalRedirect; + + if (typeof redirect === 'string') { + redirect = { path: redirect }; + } + + if (!redirect || typeof redirect !== 'object') { + { + warn(false, `invalid redirect option: ${JSON.stringify(redirect)}`); + } + + return _createRoute(null, location); + } + + const re = redirect; + const name = re.name; + const path = re.path; + let query = location.query; + let hash = location.hash; + let params = location.params; + query = re.hasOwnProperty('query') ? re.query : query; + hash = re.hasOwnProperty('hash') ? re.hash : hash; + params = re.hasOwnProperty('params') ? re.params : params; + + if (name) { + // resolved named direct + const targetRecord = nameMap[name]; + { + assert(targetRecord, `redirect failed: named route "${name}" not found.`); + } + + return match( + { + _normalized: true, + name, + query, + hash, + params, + }, + undefined, + location + ); + } else if (path) { + // 1. resolve relative redirect + const rawPath = resolveRecordPath(path, record); + // 2. resolve params + const resolvedPath = fillParams(rawPath, params, `redirect route with path "${rawPath}"`); + // 3. rematch with existing query and hash + return match( + { + _normalized: true, + path: resolvedPath, + query, + hash, + }, + undefined, + location + ); + } else { + { + warn(false, `invalid redirect option: ${JSON.stringify(redirect)}`); + } + + return _createRoute(null, location); + } + } + + function alias(record, location, matchAs) { + const aliasedPath = fillParams(matchAs, location.params, `aliased route with path "${matchAs}"`); + const aliasedMatch = match({ + _normalized: true, + path: aliasedPath, + }); + if (aliasedMatch) { + const matched = aliasedMatch.matched; + const aliasedRecord = matched[matched.length - 1]; + location.params = aliasedMatch.params; + + return _createRoute(aliasedRecord, location); + } + + return _createRoute(null, location); + } + + function _createRoute(record, location, redirectedFrom) { + if (record && record.redirect) { + return redirect(record, redirectedFrom || location); + } + if (record && record.matchAs) { + return alias(record, location, record.matchAs); + } + + return createRoute(record, location, redirectedFrom, router); + } + + return { + match, + addRoute, + getRoutes, + addRoutes, + }; +} + +function matchRoute(regex, path, params) { + const m = path.match(regex); + + if (!m) { + return false; + } else if (!params) { + return true; + } + + for (let i = 1, len = m.length; i < len; ++i) { + const key = regex.keys[i - 1]; + if (key) { + // Fix #1994: using * with props: true generates a param named 0 + params[key.name || 'pathMatch'] = typeof m[i] === 'string' ? decode(m[i]) : m[i]; + } + } + + return true; +} + +function resolveRecordPath(path, record) { + return resolvePath(path, record.parent ? record.parent.path : '/', true); +} + +/* */ + +// use User Timing api (if present) for more accurate key precision +const Time = inBrowser && window.performance && window.performance.now ? window.performance : Date; + +function genStateKey() { + return Time.now().toFixed(3); +} + +let _key = genStateKey(); + +function getStateKey() { + return _key; +} + +function setStateKey(key) { + return (_key = key); +} + +/* */ + +const positionStore = Object.create(null); + +function setupScroll() { + // Prevent browser scroll behavior on History popstate + if ('scrollRestoration' in window.history) { + window.history.scrollRestoration = 'manual'; + } + // Fix for #1585 for Firefox + // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 + // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with + // window.location.protocol + '//' + window.location.host + // location.host contains the port and location.hostname doesn't + const protocolAndPath = `${window.location.protocol}//${window.location.host}`; + const absolutePath = window.location.href.replace(protocolAndPath, ''); + // preserve existing history state as it could be overriden by the user + const stateCopy = extend({}, window.history.state); + stateCopy.key = getStateKey(); + window.history.replaceState(stateCopy, '', absolutePath); + window.addEventListener('popstate', handlePopState); + + return function () { + window.removeEventListener('popstate', handlePopState); + }; +} + +function handleScroll(router, to, from, isPop) { + if (!router.app) { + return; + } + + const behavior = router.options.scrollBehavior; + if (!behavior) { + return; + } + + { + assert(typeof behavior === 'function', 'scrollBehavior must be a function'); + } + + // wait until re-render finishes before scrolling + nextTick(() => { + const position = getScrollPosition(); + const shouldScroll = behavior.call(router, to, from, isPop ? position : null); + + if (!shouldScroll) { + return; + } + + if (typeof shouldScroll.then === 'function') { + shouldScroll + .then(shouldScroll => { + scrollToPosition(shouldScroll, position); + }) + .catch(err => { + { + assert(false, err.toString()); + } + }); + } else { + scrollToPosition(shouldScroll, position); + } + }); +} + +function saveScrollPosition() { + const key = getStateKey(); + if (key) { + positionStore[key] = { + x: window.pageXOffset, + y: window.pageYOffset, + }; + } +} + +function handlePopState(e) { + saveScrollPosition(); + if (e.state && e.state.key) { + setStateKey(e.state.key); + } +} + +function getScrollPosition() { + const key = getStateKey(); + if (key) { + return positionStore[key]; + } +} + +function getElementPosition(el, offset) { + const docEl = document.documentElement; + const docRect = docEl.getBoundingClientRect(); + const elRect = el.getBoundingClientRect(); + + return { + x: elRect.left - docRect.left - offset.x, + y: elRect.top - docRect.top - offset.y, + }; +} + +function isValidPosition(obj) { + return isNumber(obj.x) || isNumber(obj.y); +} + +function normalizePosition(obj) { + return { + x: isNumber(obj.x) ? obj.x : window.pageXOffset, + y: isNumber(obj.y) ? obj.y : window.pageYOffset, + }; +} + +function normalizeOffset(obj) { + return { + x: isNumber(obj.x) ? obj.x : 0, + y: isNumber(obj.y) ? obj.y : 0, + }; +} + +function isNumber(v) { + return typeof v === 'number'; +} + +const hashStartsWithNumberRE = /^#\d/; + +function scrollToPosition(shouldScroll, position) { + const isObject = typeof shouldScroll === 'object'; + if (isObject && typeof shouldScroll.selector === 'string') { + // getElementById would still fail if the selector contains a more complicated query like #main[data-attr] + // but at the same time, it doesn't make much sense to select an element with an id and an extra selector + const el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line + ? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line + : document.querySelector(shouldScroll.selector); + + if (el) { + let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {}; + offset = normalizeOffset(offset); + position = getElementPosition(el, offset); + } else if (isValidPosition(shouldScroll)) { + position = normalizePosition(shouldScroll); + } + } else if (isObject && isValidPosition(shouldScroll)) { + position = normalizePosition(shouldScroll); + } + + if (position) { + // $flow-disable-line + if ('scrollBehavior' in document.documentElement.style) { + window.scrollTo({ + left: position.x, + top: position.y, + // $flow-disable-line + behavior: shouldScroll.behavior, + }); + } else { + window.scrollTo(position.x, position.y); + } + } +} + +/* */ + +const supportsPushState = + inBrowser && + (function () { + const ua = window.navigator.userAgent; + + if ( + (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && + ua.indexOf('Mobile Safari') !== -1 && + ua.indexOf('Chrome') === -1 && + ua.indexOf('Windows Phone') === -1 + ) { + return false; + } + + return window.history && typeof window.history.pushState === 'function'; + })(); + +function pushState(url, replace) { + saveScrollPosition(); + // try...catch the pushState call to get around Safari + // DOM Exception 18 where it limits to 100 pushState calls + const history = window.history; + try { + if (replace) { + // preserve existing history state as it could be overriden by the user + const stateCopy = extend({}, history.state); + stateCopy.key = getStateKey(); + history.replaceState(stateCopy, '', url); + } else { + history.pushState({ key: setStateKey(genStateKey()) }, '', url); + } + } catch (e) { + window.location[replace ? 'replace' : 'assign'](url); + } +} + +function replaceState(url) { + pushState(url, true); +} + +/* */ + +function runQueue(queue, fn, cb) { + var step = function (index) { + if (index >= queue.length) { + cb(); + } else { + if (queue[index]) { + fn(queue[index], () => { + step(index + 1); + }); + } else { + step(index + 1); + } + } + }; + step(0); +} + +// When changing thing, also edit router.d.ts +const NavigationFailureType = { + redirected: 2, + aborted: 4, + cancelled: 8, + duplicated: 16, +}; + +function createNavigationRedirectedError(from, to) { + return createRouterError( + from, + to, + NavigationFailureType.redirected, + `Redirected when going from "${from.fullPath}" to "${stringifyRoute(to)}" via a navigation guard.` + ); +} + +function createNavigationDuplicatedError(from, to) { + const error = createRouterError( + from, + to, + NavigationFailureType.duplicated, + `Avoided redundant navigation to current location: "${from.fullPath}".` + ); + // backwards compatible with the first introduction of Errors + error.name = 'NavigationDuplicated'; + + return error; +} + +function createNavigationCancelledError(from, to) { + return createRouterError( + from, + to, + NavigationFailureType.cancelled, + `Navigation cancelled from "${from.fullPath}" to "${to.fullPath}" with a new navigation.` + ); +} + +function createNavigationAbortedError(from, to) { + return createRouterError( + from, + to, + NavigationFailureType.aborted, + `Navigation aborted from "${from.fullPath}" to "${to.fullPath}" via a navigation guard.` + ); +} + +function createRouterError(from, to, type, message) { + const error = new Error(message); + error._isRouter = true; + error.from = from; + error.to = to; + error.type = type; + + return error; +} + +const propertiesToLog = ['params', 'query', 'hash']; + +function stringifyRoute(to) { + if (typeof to === 'string') { + return to; + } + if ('path' in to) { + return to.path; + } + const location = {}; + propertiesToLog.forEach(key => { + if (key in to) { + location[key] = to[key]; + } + }); + + return JSON.stringify(location, null, 2); +} + +function isError(err) { + return Object.prototype.toString.call(err).indexOf('Error') > -1; +} + +function isNavigationFailure(err, errorType) { + return isError(err) && err._isRouter && (errorType == null || err.type === errorType); +} + +/* */ + +function resolveAsyncComponents(matched) { + return function (to, from, next) { + let hasAsync = false; + let pending = 0; + let error = null; + + flatMapComponents(matched, (def, _, match, key) => { + // if it's a function and doesn't have cid attached, + // assume it's an async component resolve function. + // we are not using Vue's default async resolving mechanism because + // we want to halt the navigation until the incoming component has been + // resolved. + if (typeof def === 'function' && def.cid === undefined) { + hasAsync = true; + pending++; + + const resolve = once(resolvedDef => { + if (isESModule(resolvedDef)) { + resolvedDef = resolvedDef.default; + } + // save resolved on async factory in case it's used elsewhere + def.resolved = resolvedDef; + match.components[key] = resolvedDef; + pending--; + if (pending <= 0) { + next(); + } + }); + + const reject = once(reason => { + const msg = `Failed to resolve async component ${key}: ${reason}`; + warn(false, msg); + if (!error) { + error = isError(reason) ? reason : new Error(msg); + next(error); + } + }); + + let res; + try { + res = def(resolve, reject); + } catch (e) { + reject(e); + } + if (res) { + if (typeof res.then === 'function') { + res.then(resolve, reject); + } else { + // new syntax in Vue 2.3 + const comp = res.component; + if (comp && typeof comp.then === 'function') { + comp.then(resolve, reject); + } + } + } + } + }); + + if (!hasAsync) { + next(); + } + }; +} + +function flatMapComponents(matched, fn) { + return flatten( + matched.map(m => Object.keys(m.components).map(key => fn(m.components[key], m.instances[key], m, key))) + ); +} + +function flatten(arr) { + return Array.prototype.concat.apply([], arr); +} + +const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; + +function isESModule(obj) { + return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module'); +} + +// in Webpack 2, require.ensure now also returns a Promise +// so the resolve/reject functions may get called an extra time +// if the user uses an arrow function shorthand that happens to +// return that Promise. +function once(fn) { + let called = false; + + return function () { + let args = [], + len = arguments.length; + while (len--) args[len] = arguments[len]; + + if (called) { + return; + } + called = true; + + return fn.apply(this, args); + }; +} + +/* */ + +const History = function History(router, base) { + this.router = router; + this.base = normalizeBase(base); + // start with a route object that stands for "nowhere" + this.current = START; + this.pending = null; + this.ready = false; + this.readyCbs = []; + this.readyErrorCbs = []; + this.errorCbs = []; + this.listeners = []; +}; + +History.prototype.listen = function listen(cb) { + this.cb = cb; +}; + +History.prototype.onReady = function onReady(cb, errorCb) { + if (this.ready) { + cb(); + } else { + this.readyCbs.push(cb); + if (errorCb) { + this.readyErrorCbs.push(errorCb); + } + } +}; + +History.prototype.onError = function onError(errorCb) { + this.errorCbs.push(errorCb); +}; + +History.prototype.transitionTo = function transitionTo(location, onComplete, onAbort) { + const this$1 = this; + + let route; + // catch redirect option https://github.com/vuejs/vue-router/issues/3201 + try { + route = this.router.match(location, this.current); + } catch (e) { + this.errorCbs.forEach(cb => { + cb(e); + }); + // Exception should still be thrown + throw e; + } + const prev = this.current; + this.confirmTransition( + route, + () => { + this$1.updateRoute(route); + onComplete && onComplete(route); + this$1.ensureURL(); + this$1.router.afterHooks.forEach(hook => { + hook && hook(route, prev); + }); + + // fire ready cbs once + if (!this$1.ready) { + this$1.ready = true; + this$1.readyCbs.forEach(cb => { + cb(route); + }); + } + }, + err => { + if (onAbort) { + onAbort(err); + } + if (err && !this$1.ready) { + // Initial redirection should not mark the history as ready yet + // because it's triggered by the redirection instead + // https://github.com/vuejs/vue-router/issues/3225 + // https://github.com/vuejs/vue-router/issues/3331 + if (!isNavigationFailure(err, NavigationFailureType.redirected) || prev !== START) { + this$1.ready = true; + this$1.readyErrorCbs.forEach(cb => { + cb(err); + }); + } + } + } + ); +}; + +History.prototype.confirmTransition = function confirmTransition(route, onComplete, onAbort) { + const this$1 = this; + + const current = this.current; + this.pending = route; + const abort = function (err) { + // changed after adding errors with + // https://github.com/vuejs/vue-router/pull/3047 before that change, + // redirect and aborted navigation would produce an err == null + if (!isNavigationFailure(err) && isError(err)) { + if (this$1.errorCbs.length) { + this$1.errorCbs.forEach(cb => { + cb(err); + }); + } else { + warn(false, 'uncaught error during route navigation:'); + console.error(err); + } + } + onAbort && onAbort(err); + }; + const lastRouteIndex = route.matched.length - 1; + const lastCurrentIndex = current.matched.length - 1; + if ( + isSameRoute(route, current) && + // in the case the route map has been dynamically appended to + lastRouteIndex === lastCurrentIndex && + route.matched[lastRouteIndex] === current.matched[lastCurrentIndex] + ) { + this.ensureURL(); + + return; + } + + const ref = resolveQueue(this.current.matched, route.matched); + const updated = ref.updated; + const deactivated = ref.deactivated; + const activated = ref.activated; + + const queue = [].concat( + // in-component leave guards + extractLeaveGuards(deactivated), + // global before hooks + this.router.beforeHooks, + // in-component update hooks + extractUpdateHooks(updated), + // in-config enter guards + activated.map(m => m.beforeEnter), + // async components + resolveAsyncComponents(activated) + ); + + const iterator = function (hook, next) { + if (this$1.pending !== route) { + return abort(createNavigationCancelledError(current, route)); + } + try { + hook(route, current, to => { + if (to === false) { + // next(false) -> abort navigation, ensure current URL + this$1.ensureURL(true); + abort(createNavigationAbortedError(current, route)); + } else if (isError(to)) { + this$1.ensureURL(true); + abort(to); + } else if ( + typeof to === 'string' || + (typeof to === 'object' && (typeof to.path === 'string' || typeof to.name === 'string')) + ) { + // next('/') or next({ path: '/' }) -> redirect + abort(createNavigationRedirectedError(current, route)); + if (typeof to === 'object' && to.replace) { + this$1.replace(to); + } else { + this$1.push(to); + } + } else { + // confirm transition and pass on the value + next(to); + } + }); + } catch (e) { + abort(e); + } + }; + + runQueue(queue, iterator, () => { + // wait until async components are resolved before + // extracting in-component enter guards + const enterGuards = extractEnterGuards(activated); + const queue = enterGuards.concat(this$1.router.resolveHooks); + runQueue(queue, iterator, () => { + if (this$1.pending !== route) { + return abort(createNavigationCancelledError(current, route)); + } + this$1.pending = null; + onComplete(route); + if (this$1.router.app) { + nextTick(() => { + handleRouteEntered(route); + }); + } + }); + }); +}; + +History.prototype.updateRoute = function updateRoute(route) { + this.current = route; + this.cb && this.cb(route); +}; + +History.prototype.setupListeners = function setupListeners() { + // Default implementation is empty +}; + +History.prototype.teardown = function teardown() { + // clean up event listeners + // https://github.com/vuejs/vue-router/issues/2341 + this.listeners.forEach(cleanupListener => { + cleanupListener(); + }); + this.listeners = []; + + // reset current history route + // https://github.com/vuejs/vue-router/issues/3294 + this.current = START; + this.pending = null; +}; + +function normalizeBase(base) { + if (!base) { + if (inBrowser) { + // respect tag + const baseEl = document.querySelector('base'); + base = (baseEl && baseEl.getAttribute('href')) || '/'; + // strip full URL origin + base = base.replace(/^https?:\/\/[^\/]+/, ''); + } else { + base = '/'; + } + } + // make sure there's the starting slash + if (base.charAt(0) !== '/') { + base = `/${base}`; + } + // remove trailing slash + return base.replace(/\/$/, ''); +} + +function resolveQueue(current, next) { + let i; + const max = Math.max(current.length, next.length); + for (i = 0; i < max; i++) { + if (current[i] !== next[i]) { + break; + } + } + + return { + updated: next.slice(0, i), + activated: next.slice(i), + deactivated: current.slice(i), + }; +} + +function extractGuards(records, name, bind, reverse) { + const guards = flatMapComponents(records, (def, instance, match, key) => { + const guard = extractGuard(def, name); + if (guard) { + return Array.isArray(guard) + ? guard.map(guard => bind(guard, instance, match, key)) + : bind(guard, instance, match, key); + } + }); + + return flatten(reverse ? guards.reverse() : guards); +} + +function extractGuard(def, key) { + if (typeof def !== 'function') { + // extend now so that global mixins are applied. + // def = _Vue.extend(def); + } + + return def[key]; +} + +function extractLeaveGuards(deactivated) { + return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true); +} + +function extractUpdateHooks(updated) { + return extractGuards(updated, 'beforeRouteUpdate', bindGuard); +} + +function bindGuard(guard, instance) { + if (instance) { + return function boundRouteGuard() { + return guard.apply(instance, arguments); + }; + } +} + +function extractEnterGuards(activated) { + return extractGuards(activated, 'beforeRouteEnter', (guard, _, match, key) => bindEnterGuard(guard, match, key)); +} + +function bindEnterGuard(guard, match, key) { + return function routeEnterGuard(to, from, next) { + return guard(to, from, cb => { + if (typeof cb === 'function') { + if (!match.enteredCbs[key]) { + match.enteredCbs[key] = []; + } + match.enteredCbs[key].push(cb); + } + next(cb); + }); + }; +} + +/* */ + +const HTML5History = /* @__PURE__*/ (function (History) { + function HTML5History(router, base) { + History.call(this, router, base); + + this._startLocation = getLocation(this.base); + } + + if (History) HTML5History.__proto__ = History; + HTML5History.prototype = Object.create(History && History.prototype); + HTML5History.prototype.constructor = HTML5History; + + HTML5History.prototype.setupListeners = function setupListeners() { + const this$1 = this; + + if (this.listeners.length > 0) { + return; + } + + const router = this.router; + const expectScroll = router.options.scrollBehavior; + const supportsScroll = supportsPushState && expectScroll; + + if (supportsScroll) { + this.listeners.push(setupScroll()); + } + + const handleRoutingEvent = function () { + const current = this$1.current; + + // Avoiding first `popstate` event dispatched in some browsers but first + // history route not updated since async guard at the same time. + const location = getLocation(this$1.base); + if (this$1.current === START && location === this$1._startLocation) { + return; + } + + this$1.transitionTo(location, route => { + if (supportsScroll) { + handleScroll(router, route, current, true); + } + }); + }; + window.addEventListener('popstate', handleRoutingEvent); + this.listeners.push(() => { + window.removeEventListener('popstate', handleRoutingEvent); + }); + }; + + HTML5History.prototype.go = function go(n) { + window.history.go(n); + }; + + HTML5History.prototype.push = function push(location, onComplete, onAbort) { + const this$1 = this; + + const ref = this; + const fromRoute = ref.current; + this.transitionTo( + location, + route => { + pushState(cleanPath(this$1.base + route.fullPath)); + handleScroll(this$1.router, route, fromRoute, false); + onComplete && onComplete(route); + }, + onAbort + ); + }; + + HTML5History.prototype.replace = function replace(location, onComplete, onAbort) { + const this$1 = this; + + const ref = this; + const fromRoute = ref.current; + this.transitionTo( + location, + route => { + replaceState(cleanPath(this$1.base + route.fullPath)); + handleScroll(this$1.router, route, fromRoute, false); + onComplete && onComplete(route); + }, + onAbort + ); + }; + + HTML5History.prototype.ensureURL = function ensureURL(push) { + if (getLocation(this.base) !== this.current.fullPath) { + const current = cleanPath(this.base + this.current.fullPath); + push ? pushState(current) : replaceState(current); + } + }; + + HTML5History.prototype.getCurrentLocation = function getCurrentLocation() { + return getLocation(this.base); + }; + + return HTML5History; +})(History); + +function getLocation(base) { + let path = window.location.pathname; + const pathLowerCase = path.toLowerCase(); + const baseLowerCase = base.toLowerCase(); + // base="/a" shouldn't turn path="/app" into "/a/pp" + // https://github.com/vuejs/vue-router/issues/3555 + // so we ensure the trailing slash in the base + if (base && (pathLowerCase === baseLowerCase || pathLowerCase.indexOf(cleanPath(`${baseLowerCase}/`)) === 0)) { + path = path.slice(base.length); + } + + return (path || '/') + window.location.search + window.location.hash; +} + +/* */ + +const HashHistory = /* @__PURE__*/ (function (History) { + function HashHistory(router, base, fallback) { + History.call(this, router, base); + // check history fallback deeplinking + if (fallback && checkFallback(this.base)) { + return; + } + ensureSlash(); + } + + if (History) HashHistory.__proto__ = History; + HashHistory.prototype = Object.create(History && History.prototype); + HashHistory.prototype.constructor = HashHistory; + + // this is delayed until the app mounts + // to avoid the hashchange listener being fired too early + HashHistory.prototype.setupListeners = function setupListeners() { + const this$1 = this; + + if (this.listeners.length > 0) { + return; + } + + const router = this.router; + const expectScroll = router.options.scrollBehavior; + const supportsScroll = supportsPushState && expectScroll; + + if (supportsScroll) { + this.listeners.push(setupScroll()); + } + + const handleRoutingEvent = function () { + const current = this$1.current; + if (!ensureSlash()) { + return; + } + this$1.transitionTo(getHash(), route => { + if (supportsScroll) { + handleScroll(this$1.router, route, current, true); + } + if (!supportsPushState) { + replaceHash(route.fullPath); + } + }); + }; + const eventType = supportsPushState ? 'popstate' : 'hashchange'; + window.addEventListener(eventType, handleRoutingEvent); + this.listeners.push(() => { + window.removeEventListener(eventType, handleRoutingEvent); + }); + }; + + HashHistory.prototype.push = function push(location, onComplete, onAbort) { + const this$1 = this; + + const ref = this; + const fromRoute = ref.current; + this.transitionTo( + location, + route => { + pushHash(route.fullPath); + handleScroll(this$1.router, route, fromRoute, false); + onComplete && onComplete(route); + }, + onAbort + ); + }; + + HashHistory.prototype.replace = function replace(location, onComplete, onAbort) { + const this$1 = this; + + const ref = this; + const fromRoute = ref.current; + this.transitionTo( + location, + route => { + replaceHash(route.fullPath); + handleScroll(this$1.router, route, fromRoute, false); + onComplete && onComplete(route); + }, + onAbort + ); + }; + + HashHistory.prototype.go = function go(n) { + window.history.go(n); + }; + + HashHistory.prototype.ensureURL = function ensureURL(push) { + const current = this.current.fullPath; + if (getHash() !== current) { + push ? pushHash(current) : replaceHash(current); + } + }; + + HashHistory.prototype.getCurrentLocation = function getCurrentLocation() { + return getHash(); + }; + + return HashHistory; +})(History); + +function checkFallback(base) { + const location = getLocation(base); + if (!/^\/#/.test(location)) { + window.location.replace(cleanPath(`${base}/#${location}`)); + + return true; + } +} + +function ensureSlash() { + const path = getHash(); + if (path.charAt(0) === '/') { + return true; + } + replaceHash(`/${path}`); + + return false; +} + +function getHash() { + // We can't use window.location.hash here because it's not + // consistent across browsers - Firefox will pre-decode it! + let href = window.location.href; + const index = href.indexOf('#'); + // empty path + if (index < 0) { + return ''; + } + + href = href.slice(index + 1); + + return href; +} + +function getUrl(path) { + const href = window.location.href; + const i = href.indexOf('#'); + const base = i >= 0 ? href.slice(0, i) : href; + + return `${base}#${path}`; +} + +function pushHash(path) { + if (supportsPushState) { + pushState(getUrl(path)); + } else { + window.location.hash = path; + } +} + +function replaceHash(path) { + if (supportsPushState) { + replaceState(getUrl(path)); + } else { + window.location.replace(getUrl(path)); + } +} + +/* */ + +const AbstractHistory = /* @__PURE__*/ (function (History) { + function AbstractHistory(router, base) { + History.call(this, router, base); + this.stack = []; + this.index = -1; + } + + if (History) AbstractHistory.__proto__ = History; + AbstractHistory.prototype = Object.create(History && History.prototype); + AbstractHistory.prototype.constructor = AbstractHistory; + + AbstractHistory.prototype.push = function push(location, onComplete, onAbort) { + const this$1 = this; + + this.transitionTo( + location, + route => { + this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route); + this$1.index++; + onComplete && onComplete(route); + }, + onAbort + ); + }; + + AbstractHistory.prototype.replace = function replace(location, onComplete, onAbort) { + const this$1 = this; + + this.transitionTo( + location, + route => { + this$1.stack = this$1.stack.slice(0, this$1.index).concat(route); + onComplete && onComplete(route); + }, + onAbort + ); + }; + + AbstractHistory.prototype.go = function go(n) { + const this$1 = this; + + const targetIndex = this.index + n; + if (targetIndex < 0 || targetIndex >= this.stack.length) { + return; + } + const route = this.stack[targetIndex]; + this.confirmTransition( + route, + () => { + const prev = this$1.current; + this$1.index = targetIndex; + this$1.updateRoute(route); + this$1.router.afterHooks.forEach(hook => { + hook && hook(route, prev); + }); + }, + err => { + if (isNavigationFailure(err, NavigationFailureType.duplicated)) { + this$1.index = targetIndex; + } + } + ); + }; + + AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation() { + const current = this.stack[this.stack.length - 1]; + + return current ? current.fullPath : '/'; + }; + + AbstractHistory.prototype.ensureURL = function ensureURL() { + // noop + }; + + return AbstractHistory; +})(History); + +/* */ + +const VueRouter = function VueRouter(options) { + if (options === void 0) options = {}; + + this.app = null; + this.apps = []; + this.options = options; + this.beforeHooks = []; + this.resolveHooks = []; + this.afterHooks = []; + this.matcher = createMatcher(options.routes || [], this); + + let mode = options.mode || 'hash'; + this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false; + if (this.fallback) { + mode = 'hash'; + } + if (!inBrowser) { + mode = 'abstract'; + } + this.mode = mode; + + switch (mode) { + case 'history': + this.history = new HTML5History(this, options.base); + break; + case 'hash': + this.history = new HashHistory(this, options.base, this.fallback); + break; + case 'abstract': + this.history = new AbstractHistory(this, options.base); + break; + default: { + assert(false, `invalid mode: ${mode}`); + } + } +}; + +const prototypeAccessors = { currentRoute: { configurable: true } }; + +VueRouter.prototype.match = function match(raw, current, redirectedFrom) { + return this.matcher.match(raw, current, redirectedFrom); +}; + +prototypeAccessors.currentRoute.get = function () { + return this.history && this.history.current; +}; + +VueRouter.prototype.init = function init(app /* Vue component instance */) { + const this$1 = this; + + this.apps.push(app); + + // set up app destroyed handler + // https://github.com/vuejs/vue-router/issues/2639 + app.once('hook:destroyed', () => { + // clean out app from this.apps array once destroyed + const index = this$1.apps.indexOf(app); + if (index > -1) { + this$1.apps.splice(index, 1); + } + // ensure we still have a main app or null if no apps + // we do not release the router so it can be reused + if (this$1.app === app) { + this$1.app = this$1.apps[0] || null; + } + + if (!this$1.app) { + this$1.history.teardown(); + } + }); + + // main app previously initialized + // return as we don't need to set up new history listener + if (this.app) { + return; + } + + this.app = app; + + const history = this.history; + + if (history instanceof HTML5History || history instanceof HashHistory) { + const handleInitialScroll = function (routeOrError) { + const from = history.current; + const expectScroll = this$1.options.scrollBehavior; + const supportsScroll = supportsPushState && expectScroll; + + if (supportsScroll && 'fullPath' in routeOrError) { + handleScroll(this$1, routeOrError, from, false); + } + }; + const setupListeners = function (routeOrError) { + history.setupListeners(); + handleInitialScroll(routeOrError); + }; + history.transitionTo(history.getCurrentLocation(), setupListeners, setupListeners); + } + + history.listen(route => { + this$1.apps.forEach(app => { + app._router.history.current = route; + }); + }); +}; + +VueRouter.prototype.beforeEach = function beforeEach(fn) { + return registerHook(this.beforeHooks, fn); +}; + +VueRouter.prototype.beforeResolve = function beforeResolve(fn) { + return registerHook(this.resolveHooks, fn); +}; + +VueRouter.prototype.afterEach = function afterEach(fn) { + return registerHook(this.afterHooks, fn); +}; + +VueRouter.prototype.onReady = function onReady(cb, errorCb) { + this.history.onReady(cb, errorCb); +}; + +VueRouter.prototype.onError = function onError(errorCb) { + this.history.onError(errorCb); +}; + +VueRouter.prototype.push = function push(location, onComplete, onAbort) { + const this$1 = this; + + // $flow-disable-line + if (!onComplete && !onAbort && typeof Promise !== 'undefined') { + return new Promise((resolve, reject) => { + this$1.history.push(location, resolve, reject); + }); + } else { + this.history.push(location, onComplete, onAbort); + } +}; + +VueRouter.prototype.replace = function replace(location, onComplete, onAbort) { + const this$1 = this; + + // $flow-disable-line + if (!onComplete && !onAbort && typeof Promise !== 'undefined') { + return new Promise((resolve, reject) => { + this$1.history.replace(location, resolve, reject); + }); + } else { + this.history.replace(location, onComplete, onAbort); + } +}; + +VueRouter.prototype.go = function go(n) { + this.history.go(n); +}; + +VueRouter.prototype.back = function back() { + this.go(-1); +}; + +VueRouter.prototype.forward = function forward() { + this.go(1); +}; + +VueRouter.prototype.getMatchedComponents = function getMatchedComponents(to) { + const route = to ? (to.matched ? to : this.resolve(to).route) : this.currentRoute; + if (!route) { + return []; + } + + return [].concat.apply( + [], + route.matched.map(m => Object.keys(m.components).map(key => m.components[key])) + ); +}; + +VueRouter.prototype.resolve = function resolve(to, current, append) { + current = current || this.history.current; + const location = normalizeLocation(to, current, append, this); + const route = this.match(location, current); + const fullPath = route.redirectedFrom || route.fullPath; + const base = this.history.base; + const href = createHref(base, fullPath, this.mode); + + return { + location, + route, + href, + // for backwards compat + normalizedTo: location, + resolved: route, + }; +}; + +VueRouter.prototype.getRoutes = function getRoutes() { + return this.matcher.getRoutes(); +}; + +VueRouter.prototype.addRoute = function addRoute(parentOrRoute, route) { + this.matcher.addRoute(parentOrRoute, route); + if (this.history.current !== START) { + this.history.transitionTo(this.history.getCurrentLocation()); + } +}; + +Object.defineProperties(VueRouter.prototype, prototypeAccessors); + +function registerHook(list, fn) { + list.push(fn); + + return function () { + const i = list.indexOf(fn); + if (i > -1) { + list.splice(i, 1); + } + }; +} + +function createHref(base, fullPath, mode) { + const path = mode === 'hash' ? `#${fullPath}` : fullPath; + + return base ? cleanPath(`${base}/${path}`) : path; +} + +// VueRouter.install = install; +VueRouter.version = '3.5.2'; +VueRouter.isNavigationFailure = isNavigationFailure; +VueRouter.NavigationFailureType = NavigationFailureType; +VueRouter.START_LOCATION = START; + +let $router; +const cbs = []; +@shortcut() +export class RouterWidget extends Widget { + static xtype = 'bi.router'; + + init() { + this.$router = + this._router = + Router.$router = + $router = + new VueRouter({ + mode: this.options.mode, + routes: this.options.routes, + base: this.options.base, + }); + Fix.defineReactiveProperty(Router.$router.history, 'current'); + this.$router.beforeEach((to, from, next) => { + if (to.matched.length === 0) { + // 如果上级也未匹配到路由则跳转主页面,如果上级能匹配到则转上级路由 + from.path ? next({ path: from.path }) : next('/'); + } else { + // 如果匹配到正确跳转 + next(); + } + }); + this.$router.afterEach(() => { + cbs.forEach(cb => { + cb(); + }); + }); + this.$router.init(this); + } +} + +@shortcut() +export class RouterView extends Widget { + static xtype = 'bi.router_view'; + + props = { + baseCls: 'bi-router-view', + deps: 0, + name: 'default', + }; + created() { + const self = this, + o = this.options; + cbs.push( + (this._callbackListener = function () { + const current = $router.history.current; + // 匹配的路径名(/component/:id) + let matchedPath = current.matched[o.deps] && current.matched[o.deps].path; + const component = current.matched[o.deps] && current.matched[o.deps].components[o.name]; + + if (isNotNull(component)) { + if (matchedPath) { + each(current.params, (key, value) => { + // 把 :id 替换成具体的值(/component/demo.td) + matchedPath = matchedPath.replace(`:${key}`, value); + }); + } + self.tab.setSelect(matchedPath || '/'); + } + }) + ); + // "bi.router_view"是由"bi.tab"实现的,cardCreator是一个异步过程,在"bi.router_view"创建之前,cbs里不会有创建子组件的方法,在初始化路由时,没法直接渲染到子组件,所以这里手动加了一次调用 + this._callbackListener(); + } + + render() { + const self = this, + o = this.options; + + return { + type: Tab.xtype, + ref(_ref) { + self.tab = _ref; + }, + single: o.single, // 是不是单页面 + keepAlives: o.keepAlives, + logic: { + dynamic: false, + }, + showIndex: false, + cardCreator(v) { + return $router.history.current.matched[o.deps].components[o.name]; + }, + }; + } + + destroyed() { + // BI.remove方法会把第二个参数当迭代器执行导致方法多执行一遍 + cbs.splice(cbs.indexOf(this._callbackListener), 1); + } +} + +Router.isSameRoute = isSameRoute; diff --git a/packages/fineui/src/third/sort.gb2312.js b/packages/fineui/src/third/sort.gb2312.js new file mode 100644 index 000000000..49efa3b8e --- /dev/null +++ b/packages/fineui/src/third/sort.gb2312.js @@ -0,0 +1,6 @@ +// eslint-disable-next-line no-useless-escape +const codes = " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺚⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠⻡⻢⻣⻤⻥⻦⻧⻨⻩⻪⻫⻬⻭⻮⻯⻰⻱⻲⻳⻴⻵⻶⻷⻸⻹⻺⻻⻼⻽⻾⻿⼀⼁⼂⼃⼄⼅⼆⼇⼈⼉⼊⼋⼌⼍⼎⼏⼐⼑⼒⼓⼔⼕⼖⼗⼘⼙⼚⼛⼜⼝⼞⼟⼠⼡⼢⼣⼤⼥⼦⼧⼨⼩⼪⼫⼬⼭⼮⼯⼰⼱⼲⼳⼴⼵⼶⼷⼸⼹⼺⼻⼼⼽⼾⼿⽀⽁⽂⽃⽄⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿⾀⾁⾂⾃⾄⾅⾆⾇⾈⾉⾊⾋⾌⾍⾎⾏⾐⾑⾒⾓⾔⾕⾖⾗⾘⾙⾚⾛⾜⾝⾞⾟⾠⾡⾢⾣⾤⾥⾦⾧⾨⾩⾪⾫⾬⾭⾮⾯⾰⾱⾲⾳⾴⾵⾶⾷⾸⾹⾺⾻⾼⾽⾾⾿⿀⿁⿂⿃⿄⿅⿆⿇⿈⿉⿊⿋⿌⿍⿎⿏⿐⿑⿒⿓⿔⿕⿖⿗⿘⿙⿚⿛⿜⿝⿞⿟⿠⿡⿢⿣⿤⿥⿦⿧⿨⿩⿪⿫⿬⿭⿮⿯⿰⿱⿲⿳⿴⿵⿶⿷⿸⿹⿺⿻⿼⿽⿾⿿ 、。〃〄々〆〇〈〉《》「」『』【】〒〓〔〕〖〗〘〙〚〛〜〝〞〟〠〡〢〣〤〥〦〧〨〩〪〭〮〯〫〬〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾〿぀ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ゗゘゙゚゛゜ゝゞゟ゠ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ㄀㄁㄂㄃㄄ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩㄪㄫㄬㄭㄮㄯ㄰ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ㆏㆐㆑㆒㆓㆔㆕㆖㆗㆘㆙㆚㆛㆜㆝㆞㆟ㆠㆡㆢㆣㆤㆥㆦㆧㆨㆩㆪㆫㆬㆭㆮㆯㆰㆱㆲㆳㆴㆵㆶㆷㆸㆹㆺㆻㆼㆽㆾㆿ㇀㇁㇂㇃㇄㇅㇆㇇㇈㇉㇊㇋㇌㇍㇎㇏㇐㇑㇒㇓㇔㇕㇖㇗㇘㇙㇚㇛㇜㇝㇞㇟㇠㇡㇢㇣㇤㇥㇦㇧㇨㇩㇪㇫㇬㇭㇮㇯ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㈝㈞㈟㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈪㈫㈬㈭㈮㈯㈰㈱㈲㈳㈴㈵㈶㈷㈸㈹㈺㈻㈼㈽㈾㈿㉀㉁㉂㉃㉄㉅㉆㉇㉈㉉㉊㉋㉌㉍㉎㉏㉐㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉼㉽㉾㉿㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㊊㊋㊌㊍㊎㊏㊐㊑㊒㊓㊔㊕㊖㊗㊘㊙㊚㊛㊜㊝㊞㊟㊠㊡㊢㊣㊤㊥㊦㊧㊨㊩㊪㊫㊬㊭㊮㊯㊰㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㋌㋍㋎㋏㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝㋞㋟㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽㋾㋿㌀㌁㌂㌃㌄㌅㌆㌇㌈㌉㌊㌋㌌㌍㌎㌏㌐㌑㌒㌓㌔㌕㌖㌗㌘㌙㌚㌛㌜㌝㌞㌟㌠㌡㌢㌣㌤㌥㌦㌧㌨㌩㌪㌫㌬㌭㌮㌯㌰㌱㌲㌳㌴㌵㌶㌷㌸㌹㌺㌻㌼㌽㌾㌿㍀㍁㍂㍃㍄㍅㍆㍇㍈㍉㍊㍋㍌㍍㍎㍏㍐㍑㍒㍓㍔㍕㍖㍗㍘㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍱㍲㍳㍴㍵㍶㍷㍸㍹㍺㍻㍼㍽㍾㍿㎀㎁㎂㎃㎄㎅㎆㎇㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏋㏌㏍㏎㏏㏐㏑㏒㏓㏔㏕㏖㏗㏘㏙㏚㏛㏜㏝㏞㏟㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㏿㐀㐁㐂㐃㐄㐅㐆㐇㐈㐉㐊㐋㐌㐍㐎㐏㐐㐑㐒㐓㐔㐕㐖㐗㐘㐙㐚㐛㐜㐝㐞㐟㐠㐡㐢㐣㐤㐥㐦㐧㐨㐩㐪㐫㐬㐭㐮㐯㐰㐱㐲㐳㐴㐵㐶㐷㐸㐹㐺㐻㐼㐽㐾㐿㑀㑁㑂㑃㑄㑅㑆㑇㑈㑉㑊㑋㑌㑍㑎㑏㑐㑑㑒㑓㑔㑕㑖㑗㑘㑙㑚㑛㑜㑝㑞㑟㑠㑡㑢㑣㑤㑥㑦㑧㑨㑩㑪㑫㑬㑭㑮㑯㑰㑱㑲㑳㑴㑵㑶㑷㑸㑹㑺㑻㑼㑽㑾㑿㒀㒁㒂㒃㒄㒅㒆㒇㒈㒉㒊㒋㒌㒍㒎㒏㒐㒑㒒㒓㒔㒕㒖㒗㒘㒙㒚㒛㒜㒝㒞㒟㒠㒡㒢㒣㒤㒥㒦㒧㒨㒩㒪㒫㒬㒭㒮㒯㒰㒱㒲㒳㒴㒵㒶㒷㒸㒹㒺㒻㒼㒽㒾㒿㓀㓁㓂㓃㓄㓅㓆㓇㓈㓉㓊㓋㓌㓍㓎㓏㓐㓑㓒㓓㓔㓕㓖㓗㓘㓙㓚㓛㓜㓝㓞㓟㓠㓡㓢㓣㓤㓥㓦㓧㓨㓩㓪㓫㓬㓭㓮㓯㓰㓱㓲㓳㓴㓵㓶㓷㓸㓹㓺㓻㓼㓽㓾㓿㔀㔁㔂㔃㔄㔅㔆㔇㔈㔉㔊㔋㔌㔍㔎㔏㔐㔑㔒㔓㔔㔕㔖㔗㔘㔙㔚㔛㔜㔝㔞㔟㔠㔡㔢㔣㔤㔥㔦㔧㔨㔩㔪㔫㔬㔭㔮㔯㔰㔱㔲㔳㔴㔵㔶㔷㔸㔹㔺㔻㔼㔽㔾㔿㕀㕁㕂㕃㕄㕅㕆㕇㕈㕉㕊㕋㕌㕍㕎㕏㕐㕑㕒㕓㕔㕕㕖㕗㕘㕙㕚㕛㕜㕝㕞㕟㕠㕡㕢㕣㕤㕥㕦㕧㕨㕩㕪㕫㕬㕭㕮㕯㕰㕱㕲㕳㕴㕵㕶㕷㕸㕹㕺㕻㕼㕽㕾㕿㖀㖁㖂㖃㖄㖅㖆㖇㖈㖉㖊㖋㖌㖍㖎㖏㖐㖑㖒㖓㖔㖕㖖㖗㖘㖙㖚㖛㖜㖝㖞㖟㖠㖡㖢㖣㖤㖥㖦㖧㖨㖩㖪㖫㖬㖭㖮㖯㖰㖱㖲㖳㖴㖵㖶㖷㖸㖹㖺㖻㖼㖽㖾㖿㗀㗁㗂㗃㗄㗅㗆㗇㗈㗉㗊㗋㗌㗍㗎㗏㗐㗑㗒㗓㗔㗕㗖㗗㗘㗙㗚㗛㗜㗝㗞㗟㗠㗡㗢㗣㗤㗥㗦㗧㗨㗩㗪㗫㗬㗭㗮㗯㗰㗱㗲㗳㗴㗵㗶㗷㗸㗹㗺㗻㗼㗽㗾㗿㘀㘁㘂㘃㘄㘅㘆㘇㘈㘉㘊㘋㘌㘍㘎㘏㘐㘑㘒㘓㘔㘕㘖㘗㘘㘙㘚㘛㘜㘝㘞㘟㘠㘡㘢㘣㘤㘥㘦㘧㘨㘩㘪㘫㘬㘭㘮㘯㘰㘱㘲㘳㘴㘵㘶㘷㘸㘹㘺㘻㘼㘽㘾㘿㙀㙁㙂㙃㙄㙅㙆㙇㙈㙉㙊㙋㙌㙍㙎㙏㙐㙑㙒㙓㙔㙕㙖㙗㙘㙙㙚㙛㙜㙝㙞㙟㙠㙡㙢㙣㙤㙥㙦㙧㙨㙩㙪㙫㙬㙭㙮㙯㙰㙱㙲㙳㙴㙵㙶㙷㙸㙹㙺㙻㙼㙽㙾㙿㚀㚁㚂㚃㚄㚅㚆㚇㚈㚉㚊㚋㚌㚍㚎㚏㚐㚑㚒㚓㚔㚕㚖㚗㚘㚙㚚㚛㚜㚝㚞㚟㚠㚡㚢㚣㚤㚥㚦㚧㚨㚩㚪㚫㚬㚭㚮㚯㚰㚱㚲㚳㚴㚵㚶㚷㚸㚹㚺㚻㚼㚽㚾㚿㛀㛁㛂㛃㛄㛅㛆㛇㛈㛉㛊㛋㛌㛍㛎㛏㛐㛑㛒㛓㛔㛕㛖㛗㛘㛙㛚㛛㛜㛝㛞㛟㛠㛡㛢㛣㛤㛥㛦㛧㛨㛩㛪㛫㛬㛭㛮㛯㛰㛱㛲㛳㛴㛵㛶㛷㛸㛹㛺㛻㛼㛽㛾㛿㜀㜁㜂㜃㜄㜅㜆㜇㜈㜉㜊㜋㜌㜍㜎㜏㜐㜑㜒㜓㜔㜕㜖㜗㜘㜙㜚㜛㜜㜝㜞㜟㜠㜡㜢㜣㜤㜥㜦㜧㜨㜩㜪㜫㜬㜭㜮㜯㜰㜱㜲㜳㜴㜵㜶㜷㜸㜹㜺㜻㜼㜽㜾㜿㝀㝁㝂㝃㝄㝅㝆㝇㝈㝉㝊㝋㝌㝍㝎㝏㝐㝑㝒㝓㝔㝕㝖㝗㝘㝙㝚㝛㝜㝝㝞㝟㝠㝡㝢㝣㝤㝥㝦㝧㝨㝩㝪㝫㝬㝭㝮㝯㝰㝱㝲㝳㝴㝵㝶㝷㝸㝹㝺㝻㝼㝽㝾㝿㞀㞁㞂㞃㞄㞅㞆㞇㞈㞉㞊㞋㞌㞍㞎㞏㞐㞑㞒㞓㞔㞕㞖㞗㞘㞙㞚㞛㞜㞝㞞㞟㞠㞡㞢㞣㞤㞥㞦㞧㞨㞩㞪㞫㞬㞭㞮㞯㞰㞱㞲㞳㞴㞵㞶㞷㞸㞹㞺㞻㞼㞽㞾㞿㟀㟁㟂㟃㟄㟅㟆㟇㟈㟉㟊㟋㟌㟍㟎㟏㟐㟑㟒㟓㟔㟕㟖㟗㟘㟙㟚㟛㟜㟝㟞㟟㟠㟡㟢㟣㟤㟥㟦㟧㟨㟩㟪㟫㟬㟭㟮㟯㟰㟱㟲㟳㟴㟵㟶㟷㟸㟹㟺㟻㟼㟽㟾㟿㠀㠁㠂㠃㠄㠅㠆㠇㠈㠉㠊㠋㠌㠍㠎㠏㠐㠑㠒㠓㠔㠕㠖㠗㠘㠙㠚㠛㠜㠝㠞㠟㠠㠡㠢㠣㠤㠥㠦㠧㠨㠩㠪㠫㠬㠭㠮㠯㠰㠱㠲㠳㠴㠵㠶㠷㠸㠹㠺㠻㠼㠽㠾㠿㡀㡁㡂㡃㡄㡅㡆㡇㡈㡉㡊㡋㡌㡍㡎㡏㡐㡑㡒㡓㡔㡕㡖㡗㡘㡙㡚㡛㡜㡝㡞㡟㡠㡡㡢㡣㡤㡥㡦㡧㡨㡩㡪㡫㡬㡭㡮㡯㡰㡱㡲㡳㡴㡵㡶㡷㡸㡹㡺㡻㡼㡽㡾㡿㢀㢁㢂㢃㢄㢅㢆㢇㢈㢉㢊㢋㢌㢍㢎㢏㢐㢑㢒㢓㢔㢕㢖㢗㢘㢙㢚㢛㢜㢝㢞㢟㢠㢡㢢㢣㢤㢥㢦㢧㢨㢩㢪㢫㢬㢭㢮㢯㢰㢱㢲㢳㢴㢵㢶㢷㢸㢹㢺㢻㢼㢽㢾㢿㣀㣁㣂㣃㣄㣅㣆㣇㣈㣉㣊㣋㣌㣍㣎㣏㣐㣑㣒㣓㣔㣕㣖㣗㣘㣙㣚㣛㣜㣝㣞㣟㣠㣡㣢㣣㣤㣥㣦㣧㣨㣩㣪㣫㣬㣭㣮㣯㣰㣱㣲㣳㣴㣵㣶㣷㣸㣹㣺㣻㣼㣽㣾㣿㤀㤁㤂㤃㤄㤅㤆㤇㤈㤉㤊㤋㤌㤍㤎㤏㤐㤑㤒㤓㤔㤕㤖㤗㤘㤙㤚㤛㤜㤝㤞㤟㤠㤡㤢㤣㤤㤥㤦㤧㤨㤩㤪㤫㤬㤭㤮㤯㤰㤱㤲㤳㤴㤵㤶㤷㤸㤹㤺㤻㤼㤽㤾㤿㥀㥁㥂㥃㥄㥅㥆㥇㥈㥉㥊㥋㥌㥍㥎㥏㥐㥑㥒㥓㥔㥕㥖㥗㥘㥙㥚㥛㥜㥝㥞㥟㥠㥡㥢㥣㥤㥥㥦㥧㥨㥩㥪㥫㥬㥭㥮㥯㥰㥱㥲㥳㥴㥵㥶㥷㥸㥹㥺㥻㥼㥽㥾㥿㦀㦁㦂㦃㦄㦅㦆㦇㦈㦉㦊㦋㦌㦍㦎㦏㦐㦑㦒㦓㦔㦕㦖㦗㦘㦙㦚㦛㦜㦝㦞㦟㦠㦡㦢㦣㦤㦥㦦㦧㦨㦩㦪㦫㦬㦭㦮㦯㦰㦱㦲㦳㦴㦵㦶㦷㦸㦹㦺㦻㦼㦽㦾㦿㧀㧁㧂㧃㧄㧅㧆㧇㧈㧉㧊㧋㧌㧍㧎㧏㧐㧑㧒㧓㧔㧕㧖㧗㧘㧙㧚㧛㧜㧝㧞㧟㧠㧡㧢㧣㧤㧥㧦㧧㧨㧩㧪㧫㧬㧭㧮㧯㧰㧱㧲㧳㧴㧵㧶㧷㧸㧹㧺㧻㧼㧽㧾㧿㨀㨁㨂㨃㨄㨅㨆㨇㨈㨉㨊㨋㨌㨍㨎㨏㨐㨑㨒㨓㨔㨕㨖㨗㨘㨙㨚㨛㨜㨝㨞㨟㨠㨡㨢㨣㨤㨥㨦㨧㨨㨩㨪㨫㨬㨭㨮㨯㨰㨱㨲㨳㨴㨵㨶㨷㨸㨹㨺㨻㨼㨽㨾㨿㩀㩁㩂㩃㩄㩅㩆㩇㩈㩉㩊㩋㩌㩍㩎㩏㩐㩑㩒㩓㩔㩕㩖㩗㩘㩙㩚㩛㩜㩝㩞㩟㩠㩡㩢㩣㩤㩥㩦㩧㩨㩩㩪㩫㩬㩭㩮㩯㩰㩱㩲㩳㩴㩵㩶㩷㩸㩹㩺㩻㩼㩽㩾㩿㪀㪁㪂㪃㪄㪅㪆㪇㪈㪉㪊㪋㪌㪍㪎㪏㪐㪑㪒㪓㪔㪕㪖㪗㪘㪙㪚㪛㪜㪝㪞㪟㪠㪡㪢㪣㪤㪥㪦㪧㪨㪩㪪㪫㪬㪭㪮㪯㪰㪱㪲㪳㪴㪵㪶㪷㪸㪹㪺㪻㪼㪽㪾㪿㫀㫁㫂㫃㫄㫅㫆㫇㫈㫉㫊㫋㫌㫍㫎㫏㫐㫑㫒㫓㫔㫕㫖㫗㫘㫙㫚㫛㫜㫝㫞㫟㫠㫡㫢㫣㫤㫥㫦㫧㫨㫩㫪㫫㫬㫭㫮㫯㫰㫱㫲㫳㫴㫵㫶㫷㫸㫹㫺㫻㫼㫽㫾㫿㬀㬁㬂㬃㬄㬅㬆㬇㬈㬉㬊㬋㬌㬍㬎㬏㬐㬑㬒㬓㬔㬕㬖㬗㬘㬙㬚㬛㬜㬝㬞㬟㬠㬡㬢㬣㬤㬥㬦㬧㬨㬩㬪㬫㬬㬭㬮㬯㬰㬱㬲㬳㬴㬵㬶㬷㬸㬹㬺㬻㬼㬽㬾㬿㭀㭁㭂㭃㭄㭅㭆㭇㭈㭉㭊㭋㭌㭍㭎㭏㭐㭑㭒㭓㭔㭕㭖㭗㭘㭙㭚㭛㭜㭝㭞㭟㭠㭡㭢㭣㭤㭥㭦㭧㭨㭩㭪㭫㭬㭭㭮㭯㭰㭱㭲㭳㭴㭵㭶㭷㭸㭹㭺㭻㭼㭽㭾㭿㮀㮁㮂㮃㮄㮅㮆㮇㮈㮉㮊㮋㮌㮍㮎㮏㮐㮑㮒㮓㮔㮕㮖㮗㮘㮙㮚㮛㮜㮝㮞㮟㮠㮡㮢㮣㮤㮥㮦㮧㮨㮩㮪㮫㮬㮭㮮㮯㮰㮱㮲㮳㮴㮵㮶㮷㮸㮹㮺㮻㮼㮽㮾㮿㯀㯁㯂㯃㯄㯅㯆㯇㯈㯉㯊㯋㯌㯍㯎㯏㯐㯑㯒㯓㯔㯕㯖㯗㯘㯙㯚㯛㯜㯝㯞㯟㯠㯡㯢㯣㯤㯥㯦㯧㯨㯩㯪㯫㯬㯭㯮㯯㯰㯱㯲㯳㯴㯵㯶㯷㯸㯹㯺㯻㯼㯽㯾㯿㰀㰁㰂㰃㰄㰅㰆㰇㰈㰉㰊㰋㰌㰍㰎㰏㰐㰑㰒㰓㰔㰕㰖㰗㰘㰙㰚㰛㰜㰝㰞㰟㰠㰡㰢㰣㰤㰥㰦㰧㰨㰩㰪㰫㰬㰭㰮㰯㰰㰱㰲㰳㰴㰵㰶㰷㰸㰹㰺㰻㰼㰽㰾㰿㱀㱁㱂㱃㱄㱅㱆㱇㱈㱉㱊㱋㱌㱍㱎㱏㱐㱑㱒㱓㱔㱕㱖㱗㱘㱙㱚㱛㱜㱝㱞㱟㱠㱡㱢㱣㱤㱥㱦㱧㱨㱩㱪㱫㱬㱭㱮㱯㱰㱱㱲㱳㱴㱵㱶㱷㱸㱹㱺㱻㱼㱽㱾㱿㲀㲁㲂㲃㲄㲅㲆㲇㲈㲉㲊㲋㲌㲍㲎㲏㲐㲑㲒㲓㲔㲕㲖㲗㲘㲙㲚㲛㲜㲝㲞㲟㲠㲡㲢㲣㲤㲥㲦㲧㲨㲩㲪㲫㲬㲭㲮㲯㲰㲱㲲㲳㲴㲵㲶㲷㲸㲹㲺㲻㲼㲽㲾㲿㳀㳁㳂㳃㳄㳅㳆㳇㳈㳉㳊㳋㳌㳍㳎㳏㳐㳑㳒㳓㳔㳕㳖㳗㳘㳙㳚㳛㳜㳝㳞㳟㳠㳡㳢㳣㳤㳥㳦㳧㳨㳩㳪㳫㳬㳭㳮㳯㳰㳱㳲㳳㳴㳵㳶㳷㳸㳹㳺㳻㳼㳽㳾㳿㴀㴁㴂㴃㴄㴅㴆㴇㴈㴉㴊㴋㴌㴍㴎㴏㴐㴑㴒㴓㴔㴕㴖㴗㴘㴙㴚㴛㴜㴝㴞㴟㴠㴡㴢㴣㴤㴥㴦㴧㴨㴩㴪㴫㴬㴭㴮㴯㴰㴱㴲㴳㴴㴵㴶㴷㴸㴹㴺㴻㴼㴽㴾㴿㵀㵁㵂㵃㵄㵅㵆㵇㵈㵉㵊㵋㵌㵍㵎㵏㵐㵑㵒㵓㵔㵕㵖㵗㵘㵙㵚㵛㵜㵝㵞㵟㵠㵡㵢㵣㵤㵥㵦㵧㵨㵩㵪㵫㵬㵭㵮㵯㵰㵱㵲㵳㵴㵵㵶㵷㵸㵹㵺㵻㵼㵽㵾㵿㶀㶁㶂㶃㶄㶅㶆㶇㶈㶉㶊㶋㶌㶍㶎㶏㶐㶑㶒㶓㶔㶕㶖㶗㶘㶙㶚㶛㶜㶝㶞㶟㶠㶡㶢㶣㶤㶥㶦㶧㶨㶩㶪㶫㶬㶭㶮㶯㶰㶱㶲㶳㶴㶵㶶㶷㶸㶹㶺㶻㶼㶽㶾㶿㷀㷁㷂㷃㷄㷅㷆㷇㷈㷉㷊㷋㷌㷍㷎㷏㷐㷑㷒㷓㷔㷕㷖㷗㷘㷙㷚㷛㷜㷝㷞㷟㷠㷡㷢㷣㷤㷥㷦㷧㷨㷩㷪㷫㷬㷭㷮㷯㷰㷱㷲㷳㷴㷵㷶㷷㷸㷹㷺㷻㷼㷽㷾㷿㸀㸁㸂㸃㸄㸅㸆㸇㸈㸉㸊㸋㸌㸍㸎㸏㸐㸑㸒㸓㸔㸕㸖㸗㸘㸙㸚㸛㸜㸝㸞㸟㸠㸡㸢㸣㸤㸥㸦㸧㸨㸩㸪㸫㸬㸭㸮㸯㸰㸱㸲㸳㸴㸵㸶㸷㸸㸹㸺㸻㸼㸽㸾㸿㹀㹁㹂㹃㹄㹅㹆㹇㹈㹉㹊㹋㹌㹍㹎㹏㹐㹑㹒㹓㹔㹕㹖㹗㹘㹙㹚㹛㹜㹝㹞㹟㹠㹡㹢㹣㹤㹥㹦㹧㹨㹩㹪㹫㹬㹭㹮㹯㹰㹱㹲㹳㹴㹵㹶㹷㹸㹹㹺㹻㹼㹽㹾㹿㺀㺁㺂㺃㺄㺅㺆㺇㺈㺉㺊㺋㺌㺍㺎㺏㺐㺑㺒㺓㺔㺕㺖㺗㺘㺙㺚㺛㺜㺝㺞㺟㺠㺡㺢㺣㺤㺥㺦㺧㺨㺩㺪㺫㺬㺭㺮㺯㺰㺱㺲㺳㺴㺵㺶㺷㺸㺹㺺㺻㺼㺽㺾㺿㻀㻁㻂㻃㻄㻅㻆㻇㻈㻉㻊㻋㻌㻍㻎㻏㻐㻑㻒㻓㻔㻕㻖㻗㻘㻙㻚㻛㻜㻝㻞㻟㻠㻡㻢㻣㻤㻥㻦㻧㻨㻩㻪㻫㻬㻭㻮㻯㻰㻱㻲㻳㻴㻵㻶㻷㻸㻹㻺㻻㻼㻽㻾㻿㼀㼁㼂㼃㼄㼅㼆㼇㼈㼉㼊㼋㼌㼍㼎㼏㼐㼑㼒㼓㼔㼕㼖㼗㼘㼙㼚㼛㼜㼝㼞㼟㼠㼡㼢㼣㼤㼥㼦㼧㼨㼩㼪㼫㼬㼭㼮㼯㼰㼱㼲㼳㼴㼵㼶㼷㼸㼹㼺㼻㼼㼽㼾㼿㽀㽁㽂㽃㽄㽅㽆㽇㽈㽉㽊㽋㽌㽍㽎㽏㽐㽑㽒㽓㽔㽕㽖㽗㽘㽙㽚㽛㽜㽝㽞㽟㽠㽡㽢㽣㽤㽥㽦㽧㽨㽩㽪㽫㽬㽭㽮㽯㽰㽱㽲㽳㽴㽵㽶㽷㽸㽹㽺㽻㽼㽽㽾㽿㾀㾁㾂㾃㾄㾅㾆㾇㾈㾉㾊㾋㾌㾍㾎㾏㾐㾑㾒㾓㾔㾕㾖㾗㾘㾙㾚㾛㾜㾝㾞㾟㾠㾡㾢㾣㾤㾥㾦㾧㾨㾩㾪㾫㾬㾭㾮㾯㾰㾱㾲㾳㾴㾵㾶㾷㾸㾹㾺㾻㾼㾽㾾㾿㿀㿁㿂㿃㿄㿅㿆㿇㿈㿉㿊㿋㿌㿍㿎㿏㿐㿑㿒㿓㿔㿕㿖㿗㿘㿙㿚㿛㿜㿝㿞㿟㿠㿡㿢㿣㿤㿥㿦㿧㿨㿩㿪㿫㿬㿭㿮㿯㿰㿱㿲㿳㿴㿵㿶㿷㿸㿹㿺㿻㿼㿽㿾㿿䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿䁀䁁䁂䁃䁄䁅䁆䁇䁈䁉䁊䁋䁌䁍䁎䁏䁐䁑䁒䁓䁔䁕䁖䁗䁘䁙䁚䁛䁜䁝䁞䁟䁠䁡䁢䁣䁤䁥䁦䁧䁨䁩䁪䁫䁬䁭䁮䁯䁰䁱䁲䁳䁴䁵䁶䁷䁸䁹䁺䁻䁼䁽䁾䁿䂀䂁䂂䂃䂄䂅䂆䂇䂈䂉䂊䂋䂌䂍䂎䂏䂐䂑䂒䂓䂔䂕䂖䂗䂘䂙䂚䂛䂜䂝䂞䂟䂠䂡䂢䂣䂤䂥䂦䂧䂨䂩䂪䂫䂬䂭䂮䂯䂰䂱䂲䂳䂴䂵䂶䂷䂸䂹䂺䂻䂼䂽䂾䂿䃀䃁䃂䃃䃄䃅䃆䃇䃈䃉䃊䃋䃌䃍䃎䃏䃐䃑䃒䃓䃔䃕䃖䃗䃘䃙䃚䃛䃜䃝䃞䃟䃠䃡䃢䃣䃤䃥䃦䃧䃨䃩䃪䃫䃬䃭䃮䃯䃰䃱䃲䃳䃴䃵䃶䃷䃸䃹䃺䃻䃼䃽䃾䃿䄀䄁䄂䄃䄄䄅䄆䄇䄈䄉䄊䄋䄌䄍䄎䄏䄐䄑䄒䄓䄔䄕䄖䄗䄘䄙䄚䄛䄜䄝䄞䄟䄠䄡䄢䄣䄤䄥䄦䄧䄨䄩䄪䄫䄬䄭䄮䄯䄰䄱䄲䄳䄴䄵䄶䄷䄸䄹䄺䄻䄼䄽䄾䄿䅀䅁䅂䅃䅄䅅䅆䅇䅈䅉䅊䅋䅌䅍䅎䅏䅐䅑䅒䅓䅔䅕䅖䅗䅘䅙䅚䅛䅜䅝䅞䅟䅠䅡䅢䅣䅤䅥䅦䅧䅨䅩䅪䅫䅬䅭䅮䅯䅰䅱䅲䅳䅴䅵䅶䅷䅸䅹䅺䅻䅼䅽䅾䅿䆀䆁䆂䆃䆄䆅䆆䆇䆈䆉䆊䆋䆌䆍䆎䆏䆐䆑䆒䆓䆔䆕䆖䆗䆘䆙䆚䆛䆜䆝䆞䆟䆠䆡䆢䆣䆤䆥䆦䆧䆨䆩䆪䆫䆬䆭䆮䆯䆰䆱䆲䆳䆴䆵䆶䆷䆸䆹䆺䆻䆼䆽䆾䆿䇀䇁䇂䇃䇄䇅䇆䇇䇈䇉䇊䇋䇌䇍䇎䇏䇐䇑䇒䇓䇔䇕䇖䇗䇘䇙䇚䇛䇜䇝䇞䇟䇠䇡䇢䇣䇤䇥䇦䇧䇨䇩䇪䇫䇬䇭䇮䇯䇰䇱䇲䇳䇴䇵䇶䇷䇸䇹䇺䇻䇼䇽䇾䇿䈀䈁䈂䈃䈄䈅䈆䈇䈈䈉䈊䈋䈌䈍䈎䈏䈐䈑䈒䈓䈔䈕䈖䈗䈘䈙䈚䈛䈜䈝䈞䈟䈠䈡䈢䈣䈤䈥䈦䈧䈨䈩䈪䈫䈬䈭䈮䈯䈰䈱䈲䈳䈴䈵䈶䈷䈸䈹䈺䈻䈼䈽䈾䈿䉀䉁䉂䉃䉄䉅䉆䉇䉈䉉䉊䉋䉌䉍䉎䉏䉐䉑䉒䉓䉔䉕䉖䉗䉘䉙䉚䉛䉜䉝䉞䉟䉠䉡䉢䉣䉤䉥䉦䉧䉨䉩䉪䉫䉬䉭䉮䉯䉰䉱䉲䉳䉴䉵䉶䉷䉸䉹䉺䉻䉼䉽䉾䉿䊀䊁䊂䊃䊄䊅䊆䊇䊈䊉䊊䊋䊌䊍䊎䊏䊐䊑䊒䊓䊔䊕䊖䊗䊘䊙䊚䊛䊜䊝䊞䊟䊠䊡䊢䊣䊤䊥䊦䊧䊨䊩䊪䊫䊬䊭䊮䊯䊰䊱䊲䊳䊴䊵䊶䊷䊸䊹䊺䊻䊼䊽䊾䊿䋀䋁䋂䋃䋄䋅䋆䋇䋈䋉䋊䋋䋌䋍䋎䋏䋐䋑䋒䋓䋔䋕䋖䋗䋘䋙䋚䋛䋜䋝䋞䋟䋠䋡䋢䋣䋤䋥䋦䋧䋨䋩䋪䋫䋬䋭䋮䋯䋰䋱䋲䋳䋴䋵䋶䋷䋸䋹䋺䋻䋼䋽䋾䋿䌀䌁䌂䌃䌄䌅䌆䌇䌈䌉䌊䌋䌌䌍䌎䌏䌐䌑䌒䌓䌔䌕䌖䌗䌘䌙䌚䌛䌜䌝䌞䌟䌠䌡䌢䌣䌤䌥䌦䌧䌨䌩䌪䌫䌬䌭䌮䌯䌰䌱䌲䌳䌴䌵䌶䌷䌸䌹䌺䌻䌼䌽䌾䌿䍀䍁䍂䍃䍄䍅䍆䍇䍈䍉䍊䍋䍌䍍䍎䍏䍐䍑䍒䍓䍔䍕䍖䍗䍘䍙䍚䍛䍜䍝䍞䍟䍠䍡䍢䍣䍤䍥䍦䍧䍨䍩䍪䍫䍬䍭䍮䍯䍰䍱䍲䍳䍴䍵䍶䍷䍸䍹䍺䍻䍼䍽䍾䍿䎀䎁䎂䎃䎄䎅䎆䎇䎈䎉䎊䎋䎌䎍䎎䎏䎐䎑䎒䎓䎔䎕䎖䎗䎘䎙䎚䎛䎜䎝䎞䎟䎠䎡䎢䎣䎤䎥䎦䎧䎨䎩䎪䎫䎬䎭䎮䎯䎰䎱䎲䎳䎴䎵䎶䎷䎸䎹䎺䎻䎼䎽䎾䎿䏀䏁䏂䏃䏄䏅䏆䏇䏈䏉䏊䏋䏌䏍䏎䏏䏐䏑䏒䏓䏔䏕䏖䏗䏘䏙䏚䏛䏜䏝䏞䏟䏠䏡䏢䏣䏤䏥䏦䏧䏨䏩䏪䏫䏬䏭䏮䏯䏰䏱䏲䏳䏴䏵䏶䏷䏸䏹䏺䏻䏼䏽䏾䏿䐀䐁䐂䐃䐄䐅䐆䐇䐈䐉䐊䐋䐌䐍䐎䐏䐐䐑䐒䐓䐔䐕䐖䐗䐘䐙䐚䐛䐜䐝䐞䐟䐠䐡䐢䐣䐤䐥䐦䐧䐨䐩䐪䐫䐬䐭䐮䐯䐰䐱䐲䐳䐴䐵䐶䐷䐸䐹䐺䐻䐼䐽䐾䐿䑀䑁䑂䑃䑄䑅䑆䑇䑈䑉䑊䑋䑌䑍䑎䑏䑐䑑䑒䑓䑔䑕䑖䑗䑘䑙䑚䑛䑜䑝䑞䑟䑠䑡䑢䑣䑤䑥䑦䑧䑨䑩䑪䑫䑬䑭䑮䑯䑰䑱䑲䑳䑴䑵䑶䑷䑸䑹䑺䑻䑼䑽䑾䑿䒀䒁䒂䒃䒄䒅䒆䒇䒈䒉䒊䒋䒌䒍䒎䒏䒐䒑䒒䒓䒔䒕䒖䒗䒘䒙䒚䒛䒜䒝䒞䒟䒠䒡䒢䒣䒤䒥䒦䒧䒨䒩䒪䒫䒬䒭䒮䒯䒰䒱䒲䒳䒴䒵䒶䒷䒸䒹䒺䒻䒼䒽䒾䒿䓀䓁䓂䓃䓄䓅䓆䓇䓈䓉䓊䓋䓌䓍䓎䓏䓐䓑䓒䓓䓔䓕䓖䓗䓘䓙䓚䓛䓜䓝䓞䓟䓠䓡䓢䓣䓤䓥䓦䓧䓨䓩䓪䓫䓬䓭䓮䓯䓰䓱䓲䓳䓴䓵䓶䓷䓸䓹䓺䓻䓼䓽䓾䓿䔀䔁䔂䔃䔄䔅䔆䔇䔈䔉䔊䔋䔌䔍䔎䔏䔐䔑䔒䔓䔔䔕䔖䔗䔘䔙䔚䔛䔜䔝䔞䔟䔠䔡䔢䔣䔤䔥䔦䔧䔨䔩䔪䔫䔬䔭䔮䔯䔰䔱䔲䔳䔴䔵䔶䔷䔸䔹䔺䔻䔼䔽䔾䔿䕀䕁䕂䕃䕄䕅䕆䕇䕈䕉䕊䕋䕌䕍䕎䕏䕐䕑䕒䕓䕔䕕䕖䕗䕘䕙䕚䕛䕜䕝䕞䕟䕠䕡䕢䕣䕤䕥䕦䕧䕨䕩䕪䕫䕬䕭䕮䕯䕰䕱䕲䕳䕴䕵䕶䕷䕸䕹䕺䕻䕼䕽䕾䕿䖀䖁䖂䖃䖄䖅䖆䖇䖈䖉䖊䖋䖌䖍䖎䖏䖐䖑䖒䖓䖔䖕䖖䖗䖘䖙䖚䖛䖜䖝䖞䖟䖠䖡䖢䖣䖤䖥䖦䖧䖨䖩䖪䖫䖬䖭䖮䖯䖰䖱䖲䖳䖴䖵䖶䖷䖸䖹䖺䖻䖼䖽䖾䖿䗀䗁䗂䗃䗄䗅䗆䗇䗈䗉䗊䗋䗌䗍䗎䗏䗐䗑䗒䗓䗔䗕䗖䗗䗘䗙䗚䗛䗜䗝䗞䗟䗠䗡䗢䗣䗤䗥䗦䗧䗨䗩䗪䗫䗬䗭䗮䗯䗰䗱䗲䗳䗴䗵䗶䗷䗸䗹䗺䗻䗼䗽䗾䗿䘀䘁䘂䘃䘄䘅䘆䘇䘈䘉䘊䘋䘌䘍䘎䘏䘐䘑䘒䘓䘔䘕䘖䘗䘘䘙䘚䘛䘜䘝䘞䘟䘠䘡䘢䘣䘤䘥䘦䘧䘨䘩䘪䘫䘬䘭䘮䘯䘰䘱䘲䘳䘴䘵䘶䘷䘸䘹䘺䘻䘼䘽䘾䘿䙀䙁䙂䙃䙄䙅䙆䙇䙈䙉䙊䙋䙌䙍䙎䙏䙐䙑䙒䙓䙔䙕䙖䙗䙘䙙䙚䙛䙜䙝䙞䙟䙠䙡䙢䙣䙤䙥䙦䙧䙨䙩䙪䙫䙬䙭䙮䙯䙰䙱䙲䙳䙴䙵䙶䙷䙸䙹䙺䙻䙼䙽䙾䙿䚀䚁䚂䚃䚄䚅䚆䚇䚈䚉䚊䚋䚌䚍䚎䚏䚐䚑䚒䚓䚔䚕䚖䚗䚘䚙䚚䚛䚜䚝䚞䚟䚠䚡䚢䚣䚤䚥䚦䚧䚨䚩䚪䚫䚬䚭䚮䚯䚰䚱䚲䚳䚴䚵䚶䚷䚸䚹䚺䚻䚼䚽䚾䚿䛀䛁䛂䛃䛄䛅䛆䛇䛈䛉䛊䛋䛌䛍䛎䛏䛐䛑䛒䛓䛔䛕䛖䛗䛘䛙䛚䛛䛜䛝䛞䛟䛠䛡䛢䛣䛤䛥䛦䛧䛨䛩䛪䛫䛬䛭䛮䛯䛰䛱䛲䛳䛴䛵䛶䛷䛸䛹䛺䛻䛼䛽䛾䛿䜀䜁䜂䜃䜄䜅䜆䜇䜈䜉䜊䜋䜌䜍䜎䜏䜐䜑䜒䜓䜔䜕䜖䜗䜘䜙䜚䜛䜜䜝䜞䜟䜠䜡䜢䜣䜤䜥䜦䜧䜨䜩䜪䜫䜬䜭䜮䜯䜰䜱䜲䜳䜴䜵䜶䜷䜸䜹䜺䜻䜼䜽䜾䜿䝀䝁䝂䝃䝄䝅䝆䝇䝈䝉䝊䝋䝌䝍䝎䝏䝐䝑䝒䝓䝔䝕䝖䝗䝘䝙䝚䝛䝜䝝䝞䝟䝠䝡䝢䝣䝤䝥䝦䝧䝨䝩䝪䝫䝬䝭䝮䝯䝰䝱䝲䝳䝴䝵䝶䝷䝸䝹䝺䝻䝼䝽䝾䝿䞀䞁䞂䞃䞄䞅䞆䞇䞈䞉䞊䞋䞌䞍䞎䞏䞐䞑䞒䞓䞔䞕䞖䞗䞘䞙䞚䞛䞜䞝䞞䞟䞠䞡䞢䞣䞤䞥䞦䞧䞨䞩䞪䞫䞬䞭䞮䞯䞰䞱䞲䞳䞴䞵䞶䞷䞸䞹䞺䞻䞼䞽䞾䞿䟀䟁䟂䟃䟄䟅䟆䟇䟈䟉䟊䟋䟌䟍䟎䟏䟐䟑䟒䟓䟔䟕䟖䟗䟘䟙䟚䟛䟜䟝䟞䟟䟠䟡䟢䟣䟤䟥䟦䟧䟨䟩䟪䟫䟬䟭䟮䟯䟰䟱䟲䟳䟴䟵䟶䟷䟸䟹䟺䟻䟼䟽䟾䟿䠀䠁䠂䠃䠄䠅䠆䠇䠈䠉䠊䠋䠌䠍䠎䠏䠐䠑䠒䠓䠔䠕䠖䠗䠘䠙䠚䠛䠜䠝䠞䠟䠠䠡䠢䠣䠤䠥䠦䠧䠨䠩䠪䠫䠬䠭䠮䠯䠰䠱䠲䠳䠴䠵䠶䠷䠸䠹䠺䠻䠼䠽䠾䠿䡀䡁䡂䡃䡄䡅䡆䡇䡈䡉䡊䡋䡌䡍䡎䡏䡐䡑䡒䡓䡔䡕䡖䡗䡘䡙䡚䡛䡜䡝䡞䡟䡠䡡䡢䡣䡤䡥䡦䡧䡨䡩䡪䡫䡬䡭䡮䡯䡰䡱䡲䡳䡴䡵䡶䡷䡸䡹䡺䡻䡼䡽䡾䡿䢀䢁䢂䢃䢄䢅䢆䢇䢈䢉䢊䢋䢌䢍䢎䢏䢐䢑䢒䢓䢔䢕䢖䢗䢘䢙䢚䢛䢜䢝䢞䢟䢠䢡䢢䢣䢤䢥䢦䢧䢨䢩䢪䢫䢬䢭䢮䢯䢰䢱䢲䢳䢴䢵䢶䢷䢸䢹䢺䢻䢼䢽䢾䢿䣀䣁䣂䣃䣄䣅䣆䣇䣈䣉䣊䣋䣌䣍䣎䣏䣐䣑䣒䣓䣔䣕䣖䣗䣘䣙䣚䣛䣜䣝䣞䣟䣠䣡䣢䣣䣤䣥䣦䣧䣨䣩䣪䣫䣬䣭䣮䣯䣰䣱䣲䣳䣴䣵䣶䣷䣸䣹䣺䣻䣼䣽䣾䣿䤀䤁䤂䤃䤄䤅䤆䤇䤈䤉䤊䤋䤌䤍䤎䤏䤐䤑䤒䤓䤔䤕䤖䤗䤘䤙䤚䤛䤜䤝䤞䤟䤠䤡䤢䤣䤤䤥䤦䤧䤨䤩䤪䤫䤬䤭䤮䤯䤰䤱䤲䤳䤴䤵䤶䤷䤸䤹䤺䤻䤼䤽䤾䤿䥀䥁䥂䥃䥄䥅䥆䥇䥈䥉䥊䥋䥌䥍䥎䥏䥐䥑䥒䥓䥔䥕䥖䥗䥘䥙䥚䥛䥜䥝䥞䥟䥠䥡䥢䥣䥤䥥䥦䥧䥨䥩䥪䥫䥬䥭䥮䥯䥰䥱䥲䥳䥴䥵䥶䥷䥸䥹䥺䥻䥼䥽䥾䥿䦀䦁䦂䦃䦄䦅䦆䦇䦈䦉䦊䦋䦌䦍䦎䦏䦐䦑䦒䦓䦔䦕䦖䦗䦘䦙䦚䦛䦜䦝䦞䦟䦠䦡䦢䦣䦤䦥䦦䦧䦨䦩䦪䦫䦬䦭䦮䦯䦰䦱䦲䦳䦴䦵䦶䦷䦸䦹䦺䦻䦼䦽䦾䦿䧀䧁䧂䧃䧄䧅䧆䧇䧈䧉䧊䧋䧌䧍䧎䧏䧐䧑䧒䧓䧔䧕䧖䧗䧘䧙䧚䧛䧜䧝䧞䧟䧠䧡䧢䧣䧤䧥䧦䧧䧨䧩䧪䧫䧬䧭䧮䧯䧰䧱䧲䧳䧴䧵䧶䧷䧸䧹䧺䧻䧼䧽䧾䧿䨀䨁䨂䨃䨄䨅䨆䨇䨈䨉䨊䨋䨌䨍䨎䨏䨐䨑䨒䨓䨔䨕䨖䨗䨘䨙䨚䨛䨜䨝䨞䨟䨠䨡䨢䨣䨤䨥䨦䨧䨨䨩䨪䨫䨬䨭䨮䨯䨰䨱䨲䨳䨴䨵䨶䨷䨸䨹䨺䨻䨼䨽䨾䨿䩀䩁䩂䩃䩄䩅䩆䩇䩈䩉䩊䩋䩌䩍䩎䩏䩐䩑䩒䩓䩔䩕䩖䩗䩘䩙䩚䩛䩜䩝䩞䩟䩠䩡䩢䩣䩤䩥䩦䩧䩨䩩䩪䩫䩬䩭䩮䩯䩰䩱䩲䩳䩴䩵䩶䩷䩸䩹䩺䩻䩼䩽䩾䩿䪀䪁䪂䪃䪄䪅䪆䪇䪈䪉䪊䪋䪌䪍䪎䪏䪐䪑䪒䪓䪔䪕䪖䪗䪘䪙䪚䪛䪜䪝䪞䪟䪠䪡䪢䪣䪤䪥䪦䪧䪨䪩䪪䪫䪬䪭䪮䪯䪰䪱䪲䪳䪴䪵䪶䪷䪸䪹䪺䪻䪼䪽䪾䪿䫀䫁䫂䫃䫄䫅䫆䫇䫈䫉䫊䫋䫌䫍䫎䫏䫐䫑䫒䫓䫔䫕䫖䫗䫘䫙䫚䫛䫜䫝䫞䫟䫠䫡䫢䫣䫤䫥䫦䫧䫨䫩䫪䫫䫬䫭䫮䫯䫰䫱䫲䫳䫴䫵䫶䫷䫸䫹䫺䫻䫼䫽䫾䫿䬀䬁䬂䬃䬄䬅䬆䬇䬈䬉䬊䬋䬌䬍䬎䬏䬐䬑䬒䬓䬔䬕䬖䬗䬘䬙䬚䬛䬜䬝䬞䬟䬠䬡䬢䬣䬤䬥䬦䬧䬨䬩䬪䬫䬬䬭䬮䬯䬰䬱䬲䬳䬴䬵䬶䬷䬸䬹䬺䬻䬼䬽䬾䬿䭀䭁䭂䭃䭄䭅䭆䭇䭈䭉䭊䭋䭌䭍䭎䭏䭐䭑䭒䭓䭔䭕䭖䭗䭘䭙䭚䭛䭜䭝䭞䭟䭠䭡䭢䭣䭤䭥䭦䭧䭨䭩䭪䭫䭬䭭䭮䭯䭰䭱䭲䭳䭴䭵䭶䭷䭸䭹䭺䭻䭼䭽䭾䭿䮀䮁䮂䮃䮄䮅䮆䮇䮈䮉䮊䮋䮌䮍䮎䮏䮐䮑䮒䮓䮔䮕䮖䮗䮘䮙䮚䮛䮜䮝䮞䮟䮠䮡䮢䮣䮤䮥䮦䮧䮨䮩䮪䮫䮬䮭䮮䮯䮰䮱䮲䮳䮴䮵䮶䮷䮸䮹䮺䮻䮼䮽䮾䮿䯀䯁䯂䯃䯄䯅䯆䯇䯈䯉䯊䯋䯌䯍䯎䯏䯐䯑䯒䯓䯔䯕䯖䯗䯘䯙䯚䯛䯜䯝䯞䯟䯠䯡䯢䯣䯤䯥䯦䯧䯨䯩䯪䯫䯬䯭䯮䯯䯰䯱䯲䯳䯴䯵䯶䯷䯸䯹䯺䯻䯼䯽䯾䯿䰀䰁䰂䰃䰄䰅䰆䰇䰈䰉䰊䰋䰌䰍䰎䰏䰐䰑䰒䰓䰔䰕䰖䰗䰘䰙䰚䰛䰜䰝䰞䰟䰠䰡䰢䰣䰤䰥䰦䰧䰨䰩䰪䰫䰬䰭䰮䰯䰰䰱䰲䰳䰴䰵䰶䰷䰸䰹䰺䰻䰼䰽䰾䰿䱀䱁䱂䱃䱄䱅䱆䱇䱈䱉䱊䱋䱌䱍䱎䱏䱐䱑䱒䱓䱔䱕䱖䱗䱘䱙䱚䱛䱜䱝䱞䱟䱠䱡䱢䱣䱤䱥䱦䱧䱨䱩䱪䱫䱬䱭䱮䱯䱰䱱䱲䱳䱴䱵䱶䱷䱸䱹䱺䱻䱼䱽䱾䱿䲀䲁䲂䲃䲄䲅䲆䲇䲈䲉䲊䲋䲌䲍䲎䲏䲐䲑䲒䲓䲔䲕䲖䲗䲘䲙䲚䲛䲜䲝䲞䲟䲠䲡䲢䲣䲤䲥䲦䲧䲨䲩䲪䲫䲬䲭䲮䲯䲰䲱䲲䲳䲴䲵䲶䲷䲸䲹䲺䲻䲼䲽䲾䲿䳀䳁䳂䳃䳄䳅䳆䳇䳈䳉䳊䳋䳌䳍䳎䳏䳐䳑䳒䳓䳔䳕䳖䳗䳘䳙䳚䳛䳜䳝䳞䳟䳠䳡䳢䳣䳤䳥䳦䳧䳨䳩䳪䳫䳬䳭䳮䳯䳰䳱䳲䳳䳴䳵䳶䳷䳸䳹䳺䳻䳼䳽䳾䳿䴀䴁䴂䴃䴄䴅䴆䴇䴈䴉䴊䴋䴌䴍䴎䴏䴐䴑䴒䴓䴔䴕䴖䴗䴘䴙䴚䴛䴜䴝䴞䴟䴠䴡䴢䴣䴤䴥䴦䴧䴨䴩䴪䴫䴬䴭䴮䴯䴰䴱䴲䴳䴴䴵䴶䴷䴸䴹䴺䴻䴼䴽䴾䴿䵀䵁䵂䵃䵄䵅䵆䵇䵈䵉䵊䵋䵌䵍䵎䵏䵐䵑䵒䵓䵔䵕䵖䵗䵘䵙䵚䵛䵜䵝䵞䵟䵠䵡䵢䵣䵤䵥䵦䵧䵨䵩䵪䵫䵬䵭䵮䵯䵰䵱䵲䵳䵴䵵䵶䵷䵸䵹䵺䵻䵼䵽䵾䵿䶀䶁䶂䶃䶄䶅䶆䶇䶈䶉䶊䶋䶌䶍䶎䶏䶐䶑䶒䶓䶔䶕䶖䶗䶘䶙䶚䶛䶜䶝䶞䶟䶠䶡䶢䶣䶤䶥䶦䶧䶨䶩䶪䶫䶬䶭䶮䶯䶰䶱䶲䶳䶴䶵䶶䶷䶸䶹䶺䶻䶼䶽䶾䶿䷀䷁䷂䷃䷄䷅䷆䷇䷈䷉䷊䷋䷌䷍䷎䷏䷐䷑䷒䷓䷔䷕䷖䷗䷘䷙䷚䷛䷜䷝䷞䷟䷠䷡䷢䷣䷤䷥䷦䷧䷨䷩䷪䷫䷬䷭䷮䷯䷰䷱䷲䷳䷴䷵䷶䷷䷸䷹䷺䷻䷼䷽䷾䷿乥乲兙兛兝兞兡兣兺匁厼叾哛唜唟喸嗧囕夞巼怾旕朩朰栍桛椧烪猠瓧瓩瓰瓱瓲瓼甅硛硳穒縇莻虄襨迲闏鞥啊腌錒锕阿哀哎唉埃挨溾銰鎄锿凒啀嘊捱敱敳溰癌皑皚磑娾昹毐濭矮蔼藹譪躷霭靄伌僾叆嗳噯塧壒嫒嬡愛懓懝暧曖爱瑷璦皧瞹砹硋碍礙艾薆譺賹鑀隘靉餲馤鱫鴱侒偣啽媕安峖庵桉氨痷盦盫腤菴萻葊蓭誝諳谙鞌鞍韽馣鮟鵪鶕鹌儑玵雸俺唵垵埯揞罯銨铵堓屵岸按晻暗案洝胺荌豻貋錌闇隌黯肮骯岇昂昻枊盎醠凹柪梎熬爊軪厫嗷嗸嶅廒慠摮敖滶獒獓璈磝翱翶翺聱蔜螯謷謸遨鏖隞骜鰲鳌鷔鼇媪媼抝艹芺袄襖镺傲坳垇墺奡奥奧嫯岙岰嶴懊拗擙澚澳鏊隩驁丷仈八叭吧哵夿岜巴扒扷捌朳柭玐疤笆粑羓芭蚆豝釟魞鲃叐妭抜拔炦癹胈茇菝詙跋軷颰魃鼥把鈀钯靶坝垻壩弝欛灞爸矲罢罷耙覇跁霸鮁鲅挀掰白佰捭摆擺柏栢瓸百竡粨絔襬庍拜拝敗猈稗粺薭贁败韛扳搬攽斑斒班瘢癍肦般螌褩辬頒颁鳻坂岅昄板版瓪粄舨蝂鈑钣闆阪魬伴办半坢姅怑扮拌湴瓣秚絆绊辦鉡靽垹帮幇幚幫捠梆浜縍邦邫鞤榜牓綁绑膀髈傍塝挷搒棒棓玤磅稖艕蒡蚌蜯謗谤鎊镑佨剝勹包孢枹煲笣胞苞蕔裦褒襃闁齙龅窇薄雹保堡堢媬宝宲寚寳寶怉珤緥葆藵褓賲靌飹飽饱駂鳵鴇鸨儤勽嚗報忁报抱暴曓爆犦菢虣蚫袌豹趵鉋鑤铇骲髱鮑鲍卑庳悲揹杯柸桮椑盃碑背藣陂鵯鹎北鉳俻倍偝偹備僃备孛悖惫愂憊昁梖焙牬犕狈狽珼琲碚禙糒苝蓓蛽被褙誖貝贝軰輩辈邶郥鄁鋇鐾钡鞁鞴骳呗唄喯奔栟泍漰犇錛锛奙本楍畚翉苯倴坋坌捹撪桳渀笨逩伻嗙嘣奟崩嵭痭祊絣綳繃绷閍甭甮埄埲琣琫菶鞛塴揼泵甏蹦迸逬鏰镚偪屄楅榌毴螕豍逼鎞鰏鲾鵖嬶荸鼻佊俾匕啚夶妣彼朼柀比毞沘疕秕笔筆粃聛舭貏鄙佖咇哔嗶坒堛壁奰妼婢嬖币幣幤庇廦弊弻弼彃必怭怶愊愎敝斃朇柲梐毕毖毙湢滗滭潷濞煏熚狴獘獙珌璧畀畁畢疪痹痺皕睤睥碧禆筚箅箆篦篳粊綼縪繴罼腷臂芘苾荜萆萞蓖蓽蔽薜蜌袐襅襞襣觱詖诐貱賁贔贲赑跸蹕躃躄避邲鄨鄪鉍鏎鐴铋閇閉閟闭陛鞸韠飶饆馝駜驆髀髲魓鮅鷝鷩鼊炞煸牑猵獱甂砭笾箯籩糄編编萹蝙边邉邊鍽鞕鞭鯾鯿鳊匾惼扁揙碥稨窆藊褊貶贬鴘便卞变変峅弁徧忭抃昪汳汴玣緶缏艑苄覍諚變辡辧辨辩辫辮辯遍釆閞儦墂幖彪标標檦淲滮瀌熛爂猋瘭磦穮脿膘臕蔈藨謤贆鏢鑣镖镳颩颮颷飆飇飈飊飑飙飚驫骉骠髟嫑婊表裱褾諘錶俵摽鳔憋瘪癟虌蟞鱉鳖鼈龞別别徶莂蛂襒蹩彆傧儐宾彬斌梹椕槟檳汃滨濒濱濵瀕玢瑸璸繽缤虨豩豳賓賔邠鑌镔霦頻顮摈擯殡殯膑臏髌髕髩鬂鬓鬢仌仒兵冫冰掤氷蛃鋲丙偋寎怲抦昞昺柄棅炳眪禀秉稟苪邴鈵鉼陃鞆鞞餅餠饼並併倂傡垪并幷庰摒栤病窉竝誁靐鮩僠剥嶓拨撥播波溊玻癶癷盋砵碆礡紴缽菠袰蹳鉢钵餑饽驋鱍亳仢伯侼僰勃博帛愽懪挬搏桲欂泊浡淿渤煿牔狛猼瓝瓟礴秡箔簙糪肑胉脖膊舶艊萡葧袯袹襏襮謈踣郣鈸鉑鋍鎛鑮钹铂镈餺馎馛馞駁駮驳髆髉鮊鲌鵓鹁跛孹擘檗簸蘗譒啵蔔峬庯晡誧逋鈽錻钸餔鵏轐醭鳪卜卟哺捕补補鸔不佈勏吥咘埗埠布廍怖悑抪捗柨步歨歩瓿篰簿荹蔀踄部郶鈈钚餢嚓擦攃礤礸遪偲猜才材纔裁財财倸啋埰婇寀彩採棌毝睬綵跴踩采縩菜蔡傪参參叄叅喰嬠湌爘飡餐驂骖惭慙慚残殘蚕蝅蠶蠺惨慘憯朁穇黪黲儏澯灿燦璨粲薒謲仓仺伧倉傖凔嵢沧滄濸獊舱艙苍蒼螥鶬鸧欌藏鑶賶撡操糙嘈嶆慒曹曺槽漕艚蓸螬褿鏪愺懆艸草騲肏襙鄵鼜侧側冊册厕厠夨廁恻惻憡拺敇测測畟笧策筞筴箣簎粣荝萗萴蓛嵾篸埁岑涔笒噌层層嶒曽曾竲驓蹭偛叉嗏扠挿插揷杈疀臿艖銟鍤锸餷馇垞察嵖搽查査槎檫猹碴秅茬茶詧靫蹅鑔镲侘刹剎奼姹岔差汊紁衩詫诧拆肞芆釵钗侪儕喍柴犲祡豺茝囆瘥虿蠆袃訍幨掺搀摻攙梴裧襜覘觇辿鋓儃儳劖嚵壥婵嬋孱巉廛棎欃毚湹潹潺澶瀍瀺煘獑磛禅緾纏纒缠艬苂蝉螹蟐蟬蟾誗讒谗躔鄽酁鋋鑱镵饞馋丳产冁刬剗剷囅嵼幝摌斺旵浐滻灛燀產産簅繟蒇蕆諂譂讇谄醦鏟铲閳闡阐骣忏懴懺摲硟羼韂顫颤伥倀娼昌椙淐猖琩菖裮錩锠閶阊鯧鲳鼚仧仩偿償兏嘗嚐塲嫦尝常徜瑺瓺甞肠腸膓苌萇裳長镸长鱨鲿僘厂厰场場廠惝敞昶氅鋹倡唱怅悵暢焻玚瑒畅畼誯韔鬯弨怊抄欩窼訬超鈔钞嘲巢巣晁朝樔漅潮牊窲罺謿轈鄛鼂鼌吵巐炒焣煼眧麨仦仯耖觘伡俥唓砗硨莗蛼車车偖扯撦勶坼屮彻徹掣撤澈烢爡瞮硩聅迠頙嗔抻捵棽琛瞋諃謓賝郴塵宸尘忱愖敐敶晨曟栕桭梣樄沉煁瘎臣茞莀莐蔯薼螴訦諶谌軙辰迧鈂陈陳霃鷐麎墋夦硶碜磣贂趻踸鍖儭嚫榇櫬疢衬襯讖谶趁趂齓齔龀偁僜憆摚撐撑晿柽棦橕檉泟浾爯牚琤瞠碀称稱穪竀緽罉蛏蟶赪赬鏿鐣阷靗頳饓丞乗乘呈城埕堘塍塖娍宬峸惩憕懲成承挰掁揨朾枨棖椉橙檙洆溗澂澄瀓珵珹畻程窚筬絾脭荿裎誠诚郕酲鋮铖騬鯎侱庱徎悜睈逞騁骋秤吃哧喫嗤噄妛媸彨彲摛攡殦瓻痴癡眵瞝笞粚絺胵蚩螭訵誺魑鴟鵄鸱黐齝匙墀弛持池漦竾筂箎篪茌荎蚳謘貾赿踟迟迡遅遟遲鍉馳驰伬侈卶叺呎垑尺恥欼歯耻肔胣蚇袲袳裭褫豉鉹齒齿侙傺勅勑叱啻彳恜慗憏懘抶敕斥杘湁灻炽烾熾痸瘛翄翅翤翨腟赤趩遫鉓銐雴飭饬鶒鷘麶充冲嘃忡憃憧摏沖浺珫罿翀舂艟茺衝蹖崇崈漴爞緟虫蝩蟲褈隀埫宠寵揰銃铳抽搊犨犫瘳篘紬仇俦儔嬦帱幬惆愁懤栦梼椆檮燽畴疇皗稠筹籌絒綢绸菗薵裯詶讎讐踌躊酧酬醻雔雠雦丑丒偢吜杽瞅矁醜魗殠臭臰遚鮘出初岀摴榋樗貙齣刍厨媰幮廚橱櫉櫥滁犓篨耡芻蒢蒭蜍蟵豠趎蹰躇躕鉏鋤锄除雏雛鶵储儲杵椘楚楮檚濋璴础礎禇處齭齼亍俶傗儊処埱处怵憷搐敊斶欪歜泏滀珿畜矗竌竐絀绌臅触觸諔豖鄐閦黜搋膗揣膪踹巛川氚瑏穿传傳剶圌暷椽篅舡舩船輲遄僢喘堾歂舛荈踳串汌猭玔賗釧钏鶨刅摐牎牕疮瘡窓窗窻噇幢床牀傸磢闖闯创刱剏剙創怆愴吹炊龡倕垂埀捶搥桘棰槌箠腄菙錘鎚锤陲顀媋旾春暙杶椿槆橁櫄瑃箺萅蝽輴鰆鶞唇浱淳湻滣漘犉純纯脣莼蒓蓴醇醕錞陙鯙鶉鹑偆惷睶萶蠢賰戳繛趠踔逴哾啜嚽娕娖婥惙擉歠涰磭綽绰踀輟辍辵辶酫鑡餟齪龊偨玼疵縒蠀趀跐骴髊齹垐嬨慈柌濨珁瓷甆磁礠祠糍茨薋詞词辝辞辤辭雌飺餈鴜鶿鷀鹚佌此泚皉鮆伺佽刺刾庛朿栨次絘茦莿蛓螆賜赐匆囪囱忩怱悤暰枞棇樅樬漗潨熜瑽璁瞛篵繱聡聦聪聰苁茐葱蓯蔥蟌鍯鏓鏦騘驄骢丛从叢婃孮従徔徖從悰樷欉淙漎潀潈灇爜琮藂誴賨賩錝愡憁謥凑楱湊腠輳辏怚橻粗觕麁麄麤徂殂促噈媨憱猝瘄瘯簇縬脨蔟誎趗踧踿蹙蹴蹵醋顣鼀撺攛汆蹿躥鑹镩巑櫕欑穳殩熶爨窜竄篡簒催凗墔崔嵟慛摧榱槯磪縗缞脺鏙漼璀皠趡伜倅啐啛忰悴毳淬濢焠琗疩瘁竁粋粹紣綷翆翠脃脆膬膵臎萃襊顇村澊皴竴膥邨侟壿存拵刌忖寸籿搓撮瑳磋蹉遳醝鎈嵯嵳痤睉矬蒫蔖虘酂酇鹺鹾脞剉剒厝夎庴挫措莝莡蓌逪銼錯锉错咑哒嗒噠墶搭撘笚耷褡鎉鎝剳匒呾垯妲怛溚炟燵畗畣瘩笪答羍荅荙薘蟽詚跶达迏迖迚逹達鐽靼鞑韃龖龘打亣大眔繨呆呔懛獃傣歹代侢叇垈埭岱帒带帯帶廗待怠戴曃柋殆瀻玳瑇甙簤紿緿绐艜蚮蝳袋襶貣貸贷跢蹛軑軚軩轪迨逮霴靆鴏黛黱丹儋勯匰单単單妉媅担擔殚殫甔眈砃箪簞耼耽聃聸褝襌躭郸鄲酖頕亶伔刐抌掸撢撣玬瓭疸紞胆膽衴賧赕馾黕黵但僤唌啖啗啿嘾噉嚪帎惮憚憺旦柦氮沊泹淡澹狚疍瘅癉癚禫窞繵腅萏蓞蛋蜑觛訑誕诞贉霮餤饏駳髧鴠黮儅噹当澢珰璫當筜簹艡蟷裆襠鐺铛闣党挡擋攩欓灙譡讜谠黨凼圵垱壋婸宕愓档檔氹潒璗瓽盪瞊砀碭礑簜荡菪蕩蘯趤逿雼刀刂叨忉朷氘舠螩釖魛鱽捯倒壔导導岛島嶋嶌嶹捣搗擣槝祷禂禱蹈陦隝隯到噵悼椡檤焘燾瓙盗盜稲稻纛翢翿艔菿衜衟軇辺道嘚得徳德恴悳惪棏淂鍀锝的扥扽噔嬁灯燈璒登竳簦艠豋蹬戥等凳墱嶝櫈瞪磴覴邓鄧鐙镫隥仾低啲埞堤奃岻彽樀氐滴磾秪羝袛趆隄鞮唙啇嘀嚁嫡廸敌敵梑涤滌狄笛籴糴翟苖荻蔋蔐藡覿觌豴蹢迪鏑镝靮頔馰髢鸐厎呧坘坻底弤抵拞掋柢牴砥聜菧觝詆诋軧邸阺骶鯳俤偙僀地坔埅埊墑墬娣媂嶳帝弟怟慸摕旳杕枤梊棣楴焍玓珶甋眱睇碲祶禘第締缔腣苐菂蒂蔕蝃蝭螮諦谛踶递逓遆遞遰釱鉪嗲傎厧嵮巅巓巔掂攧敁槇槙滇瘨癫癲蹎顚顛颠齻典嚸奌婰敟椣点碘蒧蕇跕踮點佃坫垫墊壂奠婝店惦扂橂殿淀澱玷琔电甸癜磹簟蜔鈿钿阽電靛驔凋刁刟叼奝弴彫汈琱瞗碉簓虭蛁貂錭雕鮉鯛鲷鳭鵰鼦屌扚伄吊弔掉瘹盄窎窵竨蓧藋訋調釣鈟銚銱鋽鑃钓铞铫雿魡爹褺跌叠咥喋垤堞峌嵽幉恎惵戜挕昳曡楪殜氎牃牒瓞畳疂疉疊眣眰碟絰绖耊耋胅臷艓苵蜨蝶螲褋詄諜谍趃跮蹀迭镻鰈鲽鴩哋丁仃叮帄玎疔盯耵虰酊釘钉靪奵嵿濎艼薡鐤頂顶鼎鼑啶定忊椗矴碇碠磸聢腚萣蝊訂订錠锭顁飣饤丟丢銩铥东倲冬咚埬娻岽崠崬徚昸東氡氭涷笗苳菄蝀鮗鯟鶇鶫鸫鼕嬞懂箽董蕫諌侗働冻凍动動垌姛恫戙挏栋棟洞湩硐胨胴腖迵霘駧兜兠吺唗枓橷篼蔸都唞乧抖蚪鈄钭阧陡吋斗斣梪毭浢痘窦竇脰荳豆逗郖酘閗闘餖饾鬥鬦鬪鬬鬭剢厾嘟督醏闍阇凟匵嬻椟櫝殰毒涜渎瀆牍牘犊犢独獨瓄皾裻読讀讟读豄贕錖鑟韇韣韥騳髑黩黷堵琽睹笃篤覩賭赌妒妬度杜殬渡秺肚芏荰螙蠧蠹鍍镀靯偳媏端耑褍鍴短塅断斷椴段毈煅瑖碫簖籪緞缎腶葮躖鍛锻垖堆塠痽磓鐓鐜镦鴭頧兊兌兑对対對怼憝憞懟濧瀩碓祋綐薱譈譵轛队陮隊吨噸墩墪惇撉撴敦犜獤礅蜳蹲蹾驐盹趸躉伅庉沌潡炖燉盾砘碷踲逇遁遯鈍钝頓顿剟咄哆嚉多夛掇敠敪毲畓裰凙剫喥夺奪敓敚痥踱鈬鐸铎亸哚嚲垛垜埵奲崜挆朵朶椯綞缍趓躱躲軃鬌刴剁堕墮墯尮惰憜挅柮桗舵跥跺陊陏飿饳鵽妸妿娿婀屙俄吪囮娥峉峨峩涐珴皒睋磀莪蛾訛誐譌讹迗鈋鋨锇頟額额魤鵝鵞鹅噁枙砨頋騀鵈偔僫匎卾厄呃呝咢咹噩垩堊堨堮姶岋崿廅恶悪惡愕戹扼搤搹擜櫮歞歺湂琧砈砐硆礘腭苊萼蕚蚅蝁覨諤讍谔豟軛軶轭遌遏遻鄂鈪鍔鑩锷閼阏阨阸頞顎颚餓餩饿鰐鰪鱷鳄鶚鹗齃齶誒诶欸奀恩煾蒽峎嗯摁侕儿児兒唲峏栭洏粫而耏聏胹荋袻輀轜陑隭髵鮞鲕鴯鸸尒尓尔栮毦洱爾珥耳薾衈趰迩邇鉺铒餌饵駬二佴刵咡弍弐樲誀貮貳贰髶冹发彂沷発發乏伐傠坺垡墢姂栰橃浌疺瞂笩筏罚罰罸茷藅閥阀佱峜法灋砝鍅珐琺蕟髪髮勫噃嬏帆幡忛憣旙旛畨番籓繙翻藩轓颿飜鱕凡凢凣匥墦杋柉棥樊瀿烦煩燔璠矾礬笲籵緐繁羳膰舤舧蕃薠蘩蠜襎蹯釩鐇鐢钒鷭仮反払橎返奿嬎梵氾汎泛滼瀪犯畈盕笵範范訉販贩軓軬輽飯飰饭匚坊堏方枋汸淓牥芳蚄趽邡鈁錺钫鴋妨房肪防魴鲂仿倣旊昉昘瓬眆紡纺舫訪访髣鶭放啡妃婓婔扉暃渄猆緋绯菲蜚裶霏非靟飛飝飞餥馡騑騛鯡鲱淝肥腓蜰匪奜悱斐朏棐榧篚翡胐蕜誹诽俷剕厞吠屝废廃廢昲曊杮櫠沸濷狒疿痱癈肺胇芾萉蟦費费鐨镄陫靅鼣分吩帉昐朆梤棻氛竕紛纷翂芬衯訜躮酚鈖雰餴饙馚坟墳妢岎幩朌枌棼橨汾濆炃焚燌燓獖羒羵蒶蕡蚠蚡豮豶轒鐼隫馩魵黂鼖鼢粉黺份偾僨奋奮弅忿愤憤瀵瞓秎粪糞膹鱝鲼丰仹偑僼凨凬凮堼妦寷封峯峰崶枫桻楓檒沣沨渢灃烽犎猦琒疯瘋盽砜碸篈葑蘴蜂蠭豐鄷酆鋒鎽鏠锋霻靊風飌风麷冯堸夆摓浲溄漨綘縫缝艂逢馮唪覂諷讽俸凤奉湗焨煈賵赗鳯鳳鴌覅仏佛坲梻紑否妚殕缶缹缻雬鴀伕呋夫妋姇娐孵尃怤懯敷旉柎玞砆稃筟粰糐紨綒肤胕膚荂荴衭趺跗邞鄜酜鈇鳺麩麬麱麸乀伏俘凫刜匐咈哹垘孚岪巿帗幅幞弗怫扶拂服枎柫栿桴棴榑氟泭洑浮涪澓炥烰玸琈甶畉畐癁砩祓福稪符笰箙紱紼絥綍绂绋罘罦翇艀艴芙芣苻茀茯莩菔葍虙蚨蜉蝠袚袱襆襥諨豧踾輻辐郛鉘鉜韍韨颫髴鮄鮲鳧鳬鴔鵩鶝黻乶俌俛俯呒嘸府弣抚拊捬撫斧椨滏焤甫盙簠脯腐腑蜅輔辅郙釜釡阝頫鬴黼付偩傅冨副咐坿复妇婏婦媍嬔富峊彿復椱父祔禣秿竎緮縛缚腹萯蕧蚥蚹蛗蝜蝮袝複褔覄覆訃詂讣負賦賻负赋赙赴輹鍑鍢阜附馥駙驸鮒鰒鲋鳆嘎嘠旮噶尜釓錷钆尕玍尬魀侅垓姟峐晐畡祴絯荄該该豥賅賌赅郂陔忋改絠丐乢匃匄戤摡概槩槪溉漑瓂盖葢蓋鈣钙凲坩尲尴尶尷干忓攼杆柑泔漧玕甘疳矸竿筸粓肝苷迀酐魐鳱仠感擀敢桿橄澉澸皯秆稈簳芉衦赶趕鱤鳡倝凎幹旰榦檊汵淦灨盰紺绀詌贑贛赣骭冈冮刚剛堈堽岡掆摃棡牨犅疘矼綱纲缸罁罡肛釭鋼鎠钢岗崗港戅戆戇杠槓焵焹筻槔槹橰櫜皋皐睾篙糕羔膏臯韟餻高髙鷎鷱鼛夰搞杲槀槁檺稁稾稿縞缟菒藁藳鎬镐勂吿告峼祮祰禞筶誥诰郜鋯锆割哥圪彁戈戓戨搁擱歌滒牫犵疙肐胳袼謌鎶饹鴚鴿鸽佫佮匌呄嗝塥愅挌搿敋格槅櫊滆獦膈臵葛蛒蛤裓觡諽輵轕鎘镉閣阁隔革鞈鞷韐韚騔骼鬲鮯哿嗰笴舸个亇個各箇茖虼鉻铬給给根跟哏亘亙揯搄艮茛刯庚椩浭焿畊絚緪縆羮羹耕菮賡赓鶊鹒哽埂峺挭梗綆绠耿莄郠骾鯁鲠堩更侊公功匑匔厷塨宫宮工幊弓恭愩慐攻杛碽篢糼糿肱蚣觥觵躬躳髸龏龔龚巩廾拱拲栱汞珙輁鞏供共唝嗊熕貢贡佝勾沟溝痀篝簼緱缑芶袧褠鈎鉤钩鞲韝岣枸狗玽笱耇耈耉苟蚼豿冓啂坸垢够夠姤媾彀搆撀构構煹覯觏訽詬诟購购遘雊估咕唂唃姑嫴孤巬巭杚柧橭沽泒稒笟箍箛篐罛苽菇菰蓇蛄觚軱軲轱辜酤鈲鮕鴣鸪傦古啒嘏夃尳愲扢榖毂汩淈濲瀔牯皷皼盬瞽穀糓縎罟羖股脵臌薣蛊蠱詁诂谷轂逧鈷钴餶馉骨鶻鹘鼓鼔僱凅固堌崓崮故梏棝榾牿痼祻錮锢雇顧顾鯝鲴刮劀呱栝桰歄煱瓜緺胍趏踻颪颳騧鴰鸹冎剐剮叧寡卦啩坬挂掛絓罣褂詿诖乖叏拐枴柺箉罫夬怪恠倌关官棺涫瘝癏窤蒄覌観觀观関闗關鰥鱞鳏琯璭痯筦管舘輨錧館馆鳤丱冠卝悹悺惯慣掼摜樌欟毌泴潅灌爟瓘盥矔礶祼罆罐貫贯躀遦鏆鑵雚鱹鸛鹳僙光咣垙姯桄洸灮炗炚炛烡珖胱茪輄銧黆广広廣犷獷臩俇臦逛亀圭妫媯嫢嬀嶲巂帰廆归摫椝槻槼櫷歸珪瑰璝瓌皈瞡硅胿茥蘬袿規规邽郌閨闺雟騩鬶鬹鮭鲑龜龟佹匦匭厬垝姽宄庋庪恑攱晷氿湀癸祪簋蛫蟡觤詭诡軌轨陒鬼刽刿劊劌撌攰昋柜桂桧椢槶樻檜櫃猤癐眭瞆瞶禬筀蓕螝襘貴贵跪鐀鑎鞼鱖鱥鳜丨惃滚滾磙緄緷绲蓘蔉衮袞輥辊鮌鯀鲧棍睔謴啯嘓埚堝墎崞彉彍懖楇濄猓瘑聒蝈蟈郭鈛鍋锅囯囶囻国圀國帼幗慖掴摑漍簂聝腘膕蔮虢馘惈果椁槨淉粿綶菓蜾裹褁輠餜馃腂过過鐹哈紦鉿铪咍嗨孩还骸塰海烸胲酼醢亥嗐妎害氦餀饚駭駴骇佄哻嫨憨犴蚶谽酣頇顸馠魽鼾函凾含唅圅娢寒崡嵅晗梒浛涵澏焓琀甝筨虷蜬邗邯鋡韓韩丆喊浫罕豃傼厈垾屽悍憾扞捍撖撼旱晘暵汉汗涆漢瀚焊熯猂皔睅翰莟菡蔊蛿蜭螒譀輚釬銲鋎閈闬雗頷顄颔馯駻鶾兯爳夯吭垳斻杭笐筕絎绗航苀蚢裄貥迒頏颃魧沆嚆茠蒿薅薧乚儫嗥嘷噑嚎壕椃毜毫濠獆獋獔竓籇蚝蠔譹豪好郝侴傐号哠恏悎昊昦晧暠暤暭曍浩淏滈澔灏灝皓皜皞皡皥秏耗聕薃號鄗顥颢鰝呵喝嗬抲欱蠚訶诃何劾合咊和啝姀峆惒敆曷朅柇核楁毼河涸渮澕熆狢皬盇盉盍盒礉禾篕籺粭紇纥翮荷菏萂螛覈訸詥貈貉郃釛鉌鑉閡閤闔阂阖鞨頜颌餄饸魺鲄鶡鹖麧齕龁龢哬嗃嚇垎壑寉焃煂熇燺爀癋碋翯袔褐謞賀贺赫靍靎靏鶮鶴鸖鹤嘿潶黑黒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒撗桁横橫烆珩胻蘅衡鑅鴴鵆鸻啈叿呍哄嚝揈渹灴烘焢硡薨訇谾軣輷轟轰鍧仜吰垬妅娂宏宖屸弘彋汯沗泓洪浤渱潂玒玜硔竑竤篊粠紅紘紭綋红纮羾翃翝耾苰荭葒葓虹谹谼鈜鉷鋐閎闳霐霟鞃魟鴻鸿黉黌晎撔澒蕻訌讧銾閧闀闂鬨齁侯喉帿猴瘊睺矦篌糇翭翵葔鄇銗鍭餱骺鯸吼吽犼候厚后垕堠後洉茩豞逅郈鮜鱟鲎鲘乎乯匢匫呼唿嘑垀寣幠忽恗惚昒曶歑泘淴滹烀糊膴苸虍虖謼軤轷雐雽喖嘝囫壶壷壺媩弧抇搰斛楜槲湖瀫焀煳狐猢瑚瓳箶絗縠胡葫蔛蝴螜衚觳醐鍸隺頶餬鬍魱鰗鵠鶘鶦鹄鹕乕俿唬汻浒滸琥萀虎虝錿鯱互冱嗀嚛婟嫭嫮岵帍弖怘怙戶户戸戽扈护摢昈枑槴沍沪滬熩瓠祜笏簄粐綔芐蔰護豰鄠鍙頀鱯鳠鳸鸌鹱埖婲椛硴糀花蒊蘤誮錵划劃华呚哗嘩姡搳撶滑猾磆華蕐螖譁釪釫鋘鏵铧驊骅鷨化夻婳嫿嬅崋摦杹枠桦槬樺澅画畫畵繣舙觟話諙諣譮话黊徊怀懐懷槐櫰淮瀤耲蘹褢褱踝咶坏壊壞蘾孉懽欢歓歡犿獾讙貛酄驩鴅鵍圜堚嬛寏寰峘桓洹澴狟獂环環瓛糫絙綄繯缳羦荁萈萑豲貆還鍰鐶锾镮闤阛雈鬟鹮睆緩缓唤喚喛嚾奂奐宦嵈幻患愌换換擐攌梙槵浣涣渙漶澣烉焕煥瑍痪瘓肒藧豢轘逭鯇鯶鰀鲩塃宺巟慌朚肓荒衁偟凰喤堭墴媓崲徨惶揘楻湟潢煌熿獚瑝璜癀皇磺穔篁簧艎葟蝗蟥諻趪遑鍠鐄锽隍韹餭騜鰉鱑鳇鷬黃黄兤奛幌怳恍晃晄櫎炾熀縨詤謊谎愰曂榥滉皝皩鎤咴噅噕婎媈幑徽恢拻挥揮撝晖暉楎洃瀈灰灳烣煇睢睳禈翚翬蘳袆褘詼诙豗輝辉隓隳鰴麾佪囘回囬廻廽恛洄烠痐茴蚘蛔蛕蜖迴逥鮰悔檓毀毁毇燬虺譭会僡儶匯卉喙嘒嚖圚嬒寭屶屷彗彙彚徻恚恵惠慧憓懳晦暳會槥橞檅櫘汇泋湏滙潓濊烩燴獩璤璯瘣瞺秽穢篲絵繢繪绘缋翙翽芔荟蔧蕙薈薉藱蟪詯誨諱譓譿讳诲賄贿鏸鐬闠阓靧頮顪颒餯婚惛昏昬棔殙涽睧睯荤葷蔒轋閽阍忶浑渾珲琿餛馄魂鼲俒倱圂婫尡慁掍混溷焝睴觨諢诨劐吙攉秴耠豁騞佸活秮秳伙夥漷火灬煷邩鈥钬俰剨咟喐嚄嚯嚿奯彟彠惑或捇掝擭旤曤檴沎湱濩瀖獲癨眓矆矐祸禍穫窢耯臛艧获蒦藿蠖謋貨货鍃鑊锪镬閄雘霍靃韄乩僟击刉刏剞叽咭唧喞嗘嘰圾基墼姬屐嵆嵇撃擊朞机枅槣樭機櫅毄激犄玑璣畸畿癪矶磯禨积稘稽積笄筓箕簊綨緁緝缉羁羇羈耭肌芨虀覉覊觭譏譤讥賫賷赍跻踑躋躸銈錤鐖鑇鑙隮雞鞿韲飢饑饥魕鳮鶏鶺鷄鸄鸡鹡齏齑亟亼亽伋佶偮卙即卽及叝吉堲塉姞嫉岌嶯彶忣急愱戢揤极棘楖楫極槉檝殛汲湒潗濈焏疾瘠皀皍磼笈箿籍級级耤膌艥蒺蕀蕺蝍螏襋觙谻趌踖蹐躤輯轚辑郆銡鍓鏶集雧霵齎丮几妀嵴己幾戟挤掎撠擠橶泲犱穖脊虮蟣魢鱾麂伎偈兾冀剂剤劑勣哜嚌坖垍塈妓季寂寄廭彐彑徛忌悸惎懻技旡既旣暨暩曁梞檕檵洎济済漃漈濟瀱璾痵癠祭禝稩稷穄穊穧紀紒継績繋繼纪继绩罽臮芰茍茤荠葪蓟蔇薊薺蘎蘮蘻裚襀覬觊計記誋諅计记跡跽蹟迹际際霁霽驥骥髻鬾魝魥鯚鯽鰶鰿鱀鱭鲚鲫鵋鷑齌乫伽佳傢加嘉家徍抸拁枷梜毠泇浃浹犌猳珈痂笳糘耞腵葭袈豭貑跏迦鉫鎵镓鴐麚唊圿夹夾忦恝戛戞扴脥荚莢蛱蛺袷裌郏郟鋏铗頬頰颊鴶鵊假叚婽岬徦斚斝椵榎槚檟玾甲瘕胛賈贾鉀钾价價嫁幏架榢稼駕驾兼冿囏坚堅奸姦姧尖幵惤戋戔搛椷椾樫櫼歼殱殲湔瀐瀸煎熞熸牋犍猏玪瑊监監睷碊礛礷笺箋緘縑缄缣肩艰艱菅菺葌蒹蔪蕑蕳虃譼豜豣鋻鑯間间雃靬鞯韀韉餰馢鰔鰜鰹鲣鳒鳽鵑鵳鶼鹣麉俭倹儉减剪囝堿帴弿彅戩戬拣挸捡揀揃撿暕枧柬梘检検檢減湕瀽瑐睑瞼硷碱礆笕筧简篯簡籛絸繭翦茧藆蠒裥襇襉襺詃謇謭譾谫趼蹇鐗鐧锏鬋鰎鹸鹻鹼件俴健僭剑剣剱劍劎劒劔墹寋建徤擶旔栫楗榗槛檻毽洊涧渐溅漸澗濺瀳牮珔瞷磵礀箭糋繝腱臶舰艦荐薦袸見覵覸见諓諫譛谏賎賤贱趝跈践踐踺轞鉴鍳鍵鏩鐱鑑鑒鑬鑳键鞬餞饯僵壃姜将將摪橿殭江浆漿畕畺疅疆礓繮缰翞茳葁薑螀螿豇韁鱂鳉傋塂奖奨奬桨槳獎耩膙蒋蔣講讲顜勥匞匠夅嵹弜弶摾櫤洚滰犟糡糨絳绛謽酱醤醬降交僬姣娇嬌峧嶕嶣憍椒浇澆焦燋礁穚簥胶膠膲艽茭茮蕉虠蛟蟭跤轇郊鐎驕骄鮫鲛鵁鷦鷮鹪嚼佼侥僥儌剿劋勦孂徺徼憿挢捁搅摷撟撹攪敫敽敿晈暞曒灚烄煍燞狡璬皎皦矫矯笅筊絞繳纐绞缴脚腳臫蟜角譑賋踋鉸铰餃饺鱎龣叫呌嘂嘄嘦噍噭嬓嶠挍敎教斠滘漖潐獥珓皭窌窖藠訆譥趭較轎轿较酵醮釂喈喼嗟堦媘嫅接掲揭擑椄楬湝煯疖痎癤皆秸稭脻菨蝔街謯阶階鞂鶛倢偼傑刦刧刼劫劼卩卪婕媫孑尐岊崨嵥嶻巀幯截拮捷掶搩擮昅杢杰桀桔桝楶榤洁滐潔狤疌睫碣礍竭節結结羯节莭蓵蛣蜐蠘蠞蠽衱袺訐詰誱讦诘跲踕迼鉣鍻镼鞊頡颉鮚鲒姐媎檞毑解觧飷丯介借吤唶堺屆届岕庎徣悈戒楐犗玠琾界畍疥砎芥藉蚧蛶衸褯誡诫鎅骱魪今仐堇堻巾惍斤津珒琎琻璡矜矝砛禁筋紟荕衿襟觔金釒釿钅鹶黅仅侭僅儘卺厪嫤巹廑慬槿漌瑾紧緊菫蓳謹谨錦锦饉馑伒僸凚劤劲勁唫噤嚍墐壗妗嬧尽搢晉晋枃歏殣浕浸溍濅濜烬煡燼瑨璶盡祲縉缙荩藎覲觐賮贐赆近进進靳齽京亰兢坕坙婛巠惊旌旍晶橸泾涇猄睛秔稉粳精経經綡经聙腈茎荆荊菁葏驚鯨鲸鶁鶄麖麠鼱丼井儆刭剄坓宑幜憬憼景暻殌汫汬澋璄璟璥穽肼蟼警阱頚頸颈俓傹净凈境妌婙婧弪弳径徑敬曔桱梷浄淨瀞獍痉痙竞竟竧竫競竸胫脛莖誩踁迳逕鏡镜靓靖静靚靜鵛冂冋坰埛扃絅蘏蘔駉駫侰僒冏囧泂浻澃炅炯烱煚煛熲燛窘綗褧迥逈顈颎丩勼啾揂揪揫摎朻樛牞究糺糾纠萛赳阄鬏鬮鳩鸠久乆九乣奺杦汣灸玖紤舏酒镹韭韮倃僦匓匛匶厩咎就廄廏廐慦捄救旧柩柾桕欍殧疚臼舅舊鯦鷲鹫麔齨凥匊娵婮居岨崌抅拘掬梮椐檋毩毱泃涺狙琚疽眗砠罝腒艍苴蜛裾諊跔跙踘躹鋦锔陱雎鞠鞫駒驹鮈鴡鶋侷啹婅局巈挶椈橘泦淗湨焗犑狊粷繘菊蘜趜跼蹫輂郹閰駶驧鵙鵴鶪鼰鼳举咀弆挙擧椇榉榘櫸欅沮矩筥聥舉莒蒟襷踽齟龃乬俱倨倶具剧劇勮句埧埾壉姖寠屦屨岠巨巪怇惧愳懅懼拒拠据據昛歫洰澽炬烥犋秬窭窶簴粔耟聚苣虡蚷袓詎讵豦貗距踞躆遽邭醵鉅鋸鐻钜锯颶飓駏鮔勬姢娟捐朘涓焆脧蠲裐鋑鎸鐫镌鹃卷呟埍巻捲臇菤錈锩倦劵勌奆婘帣弮惓慻桊淃狷獧瓹眷睊睠絭絹绢罥羂腃蔨讂鄄餋噘屩屫撅撧亅决刔劂匷厥噊噱孒孓崛崫嶡嶥弡彏憠憰戄抉挗捔掘攫斍桷橛橜櫭欮氒決泬灍焳熦爑爝爴爵獗玃玦玨珏瑴疦瘚矍矡砄絕絶绝臄芵蕝蕨虳蚗蟨蟩覐覚覺觉觖觮觼訣譎诀谲貜赽趉趹蹶蹷躩鈌鐍鐝钁镢駃鴂鴃鷢倔军君均桾汮皲皸皹碅莙菌蚐袀覠軍鈞銁銞鍕钧頵鮶鲪麇麏麕俊儁呁埈寯峻懏捃攈攟晙棞浚濬燇珺畯竣箘箟葰蜠賐郡陖隽雋餕馂駿骏鵔鵕鵘咖喀佧卡咔咯垰胩裃鉲奒开揩鐦锎開凯凱剀剴嘅垲塏嵦恺愷慨暟楷蒈輆鍇鎧铠锴闓闿颽勓忾愾欬炌烗鎎刊勘堪嵁戡栞龕龛侃偘冚凵坎惂欿歁砍竷莰輡轗顑墈崁看瞰矙磡衎闞阚鬫嫝嵻康忼慷槺漮砊穅粇糠躿鏮閌鱇扛亢伉匟囥抗炕犺邟鈧钪闶尻嵪髛丂拷攷栲洘烤考犒銬铐靠鮳鯌鲓匼嗑嵙搕柯棵榼樖牁牱犐珂疴痾瞌砢磕礚科稞窠苛萪薖蚵蝌趷軻轲醘鈳钶頦顆颏颗髁咳壳揢殻殼翗可坷岢嵑嶱敤渇渴炣克刻勀勊堁娔客尅峇恪愘愙氪溘碦礊緙缂艐衉課课錁锞騍骒剋啃垦墾恳懇肎肯肻豤貇錹掯硍裉褃劥坑妔挳摼牼硁硜硻誙銵鍞鏗铿阬倥埪崆悾涳硿空箜躻錓鵼孔恐控鞚剾彄抠摳眍瞘芤劶口冦叩宼寇怐扣敂滱瞉窛筘簆蔲蔻釦鷇刳哭圐堀枯桍矻窟跍郀骷鮬楛狜苦俈喾嚳库庫廤焅瘔秙絝绔袴裤褲酷咵夸姱舿誇侉垮銙挎胯趶跨骻擓蒯侩儈凷哙噲圦块塊墤巜廥快旝欳浍澮狯獪筷糩脍膾郐鄶鱠鲙宽寛寬臗鑧髋髖梡欵款歀窽窾劻匡匩哐恇洭硄筐筺誆诓軭邼忹抂狂狅誑诳軖軠鵟儣夼懭况圹壙岲懬旷昿曠框況爌眖眶矌矿砿礦穬絋絖纊纩貺贶軦邝鄺鉱鋛鑛黋亏刲岿巋悝盔窥窺聧虧闚顝喹夔奎巙戣揆晆暌楏楑櫆犪睽葵藈蘷虁蝰躨逵鄈鍨鍷頯馗騤骙魁傀煃磈跬蹞頍匮匱喟嘳媿嬇尯愦愧憒殨溃潰篑簣籄聩聭聵膭蒉蕢謉餽饋馈坤堃堒崐崑昆晜潉焜熴猑琨瑻菎蜫裈裩褌醌錕锟騉髠髡髨鯤鲲鵾鶤鹍壸壼悃捆梱硱祵稇稛綑裍閫閸阃困涃睏廓扩拡括挄擴濶筈萿葀蛞闊阔霩鞟鞹韕頢髺鬠啦垃拉搚柆菈邋嚹旯磖喇藞剌揦揧攋楋櫴溂爉瓎瘌翋腊臈臘蜡蝋蝲蠟辢辣鑞镴鬎鯻鞡來俫倈婡崃崍庲徕徠来梾棶涞淶猍琜筙箂莱萊逨郲錸铼騋鯠鶆麳襰唻濑瀨瀬癞癩睐睞籁籟藾賚賴赉赖頼顂鵣儖兰啉囒婪岚嵐幱惏懢拦攔斓斕栏欄欗澜瀾灆灡燣燷璼篮籃籣繿葻蓝藍蘫蘭褴襕襤襴襽譋讕谰躝鑭镧闌阑韊壈嬾孄孏懒懶揽擥攬榄欖浨漤灠爦纜缆罱覧覽览醂顲嚂滥濫烂燗爁爛爤瓓糷钄啷勆嫏廊斏桹榔樃欴狼琅瑯硠稂筤艆蓈蜋螂躴郎郒郞鋃鎯锒塱崀朖朗朤烺蓢誏埌浪莨蒗閬阆捞撈粩僗劳労勞哰崂嶗憥朥浶牢痨癆磱窂簩蟧醪鐒铹顟髝佬咾姥恅栳潦狫珯硓老耂荖蛯轑銠铑鮱唠嗠嘮嫪憦橯涝澇烙耢耮躼軂酪乐仂勒叻忇扐楽樂氻泐玏砳竻簕艻阞韷餎鰳鱳鳓了儽嫘擂攂樏檑櫑欙瓃畾礌礧累縲纍纝缧罍羸蔂蘲虆轠鐳鑘镭雷靁鱩鼺傫儡厽垒塁壘壨櫐洡灅癗矋磊磥礨絫耒蕌蕾藟蘽蠝誄讄诔鑸鸓泪涙淚禷类纇肋蘱酹銇錑頛頪類颣嘞唥塄棱楞碐稜薐冷倰堎愣睖踜刕剓剺劙厘喱嚟囄嫠孷廲悡斄梨梸棃樆漓灕犁犂狸琍璃瓈盠睝离穲竰筣篱籬糎縭纚缡罹艃荲菞蓠蔾藜蘺蟍蟸蠫褵謧貍邌醨釐鋫錅鏫鑗離驪骊鯏鯬鱺鲡鵹鸝鹂黎黧俚娌峛峢峲李欚浬澧理礼禮粴蠡裏裡豊逦邐醴里鋰锂鯉鱧鱱鲤鳢丽例俐俪傈儮儷凓利力励勵历厉厤厯厲叓吏呖唎唳嚦囇坜塛壢娳婯孋屴岦巁悧悷慄戾搮擽攊攦攭暦曆曞朸枥栃栎栗栛棙檪櫔櫟櫪欐歴歷沥沴浰涖溧濿瀝爄爏犡猁珕瑮瓅瓑瓥疠疬痢癘癧皪盭睙砅砬砺砾磿礪礫礰禲秝立笠篥粒粝糲綟脷苈苙茘荔莅莉蒚蒞藶蚸蛎蛠蜊蜧蝷蠇蠣觻詈讈赲跞躒轢轣轹郦酈鉝隶隷隸雳靂靋鬁鳨鴗鷅麗麜哩亷劆匲匳嗹噒奁奩嫾帘廉怜慩憐梿槤櫣涟溓漣濂濓瀮熑燫磏簾籢籨縺翴联聨聫聮聯臁莲蓮薕螊蠊裢褳覝謰蹥连連鎌鐮镰鬑鰱鲢嬚摙敛斂歛琏璉羷脸臉蔹蘝蘞裣襝鄻僆堜媡恋戀楝殓殮湅潋澰瀲炼煉瑓練纞练萰錬鍊鏈链鰊俍凉墚梁椋樑涼粮粱糧良踉輬辌駺両两俩倆兩唡啢掚緉脼蜽裲魉魎亮倞哴喨悢晾湸諒谅輌輛辆量鍄撩蹽僚嘹嫽寥寮尞屪嵺嶚嶛廫憀敹暸橑漻燎爎爒獠璙疗療竂簝繚缭聊膋膫藔蟟豂賿蹘辽遼飉髎鷯鹩憭曢瞭蓼鄝釕钌镽尥尦廖撂料炓窷鐐镣咧挘毟儠冽列劣劽哷埒埓姴巤挒捩擸栵洌浖烈烮煭犣猎猟獵聗脟茢蛚裂趔躐迾颲鬛鬣鮤鱲鴷拎临冧厸壣崊嶙斴晽暽林淋潾瀶燐獜琳璘疄瞵碄磷箖粦粼綝繗翷臨轔辚遴邻鄰鏻阾隣霖驎鱗鳞麐麟亃僯凛凜廩廪懍懔撛檁檩澟癛癝菻吝恡悋橉焛甐膦蔺藺賃赁蹸躏躙躪轥閵〇伶凌刢呤囹坽夌姈婈孁崚彾掕昤朎柃棂櫺欞泠淩澪灵燯爧狑玲琌瓴皊砱祾秢竛笭紷綾绫羐羚翎聆舲苓菱蓤蔆蕶蛉衑裬詅跉軨輘酃醽鈴錂铃閝陵零霊霗霛霝駖魿鯪鲮鴒鸰鹷麢齡齢龄龗岭岺嶺袊領领令另炩蘦靈溜澑熘蹓刘劉嚠媹嵧懰斿旈旒榴橊流浏瀏琉瑠瑬璢畄留畱疁瘤癅硫磂蒥蓅藰蟉裗鎏鎦鏐鐂镏镠飀飅飗駠駵騮驑骝鰡鶹鹠麍嬼柳栁桞桺橮熮珋綹绺罶羀鋶锍六塯廇磟翏遛雡霤飂餾馏鬸鷚鹨咙嚨尨嶐巃巄昽曨朧栊槞櫳泷湰滝漋瀧爖珑瓏癃眬矓砻礱礲窿竜笼篭籠聋聾胧茏蘢蠪蠬襱豅躘鏧鑨隆霳靇驡鸗龍龒龓龙儱垄垅壟壠拢攏竉陇隴哢徿梇贚剅喽嘍娄婁廔楼樓溇漊熡瞜耧耬艛蒌蔞蝼螻謱軁遱鞻髅髏鷜塿嵝嶁搂摟甊篓簍屚漏瘘瘺瘻鏤镂陋露噜嚕撸擼謢卢嚧垆壚庐廬攎曥枦栌櫨泸瀘炉爐獹玈璷瓐盧矑籚纑罏胪臚舮舻艫芦蘆蠦轤轳鈩鑪顱颅馿髗魲鱸鲈鸕鸬黸卤塷掳擄樐橹櫓氇氌滷澛瀂硵磠穞艣艪蓾虏虜鏀鐪鑥镥魯鲁鹵侓僇剹勎勠圥坴塶娽峍廘彔录戮摝椂樚淕淥渌漉潞熝琭璐甪盝睩硉碌祿禄稑穋箓簏簬簵簶籙粶膔菉蔍蕗虂螰賂赂趢路踛蹗輅轆辂辘逯醁錄録錴鏕鏴陆陸騄騼鯥鴼鵦鵱鷺鹭鹿麓圝圞奱娈孌孪孿峦巒挛攣曫栾欒滦灓灤癴癵羉脔臠虊銮鑾鵉鸞鸾卵乱亂釠抡掄仑伦侖倫囵圇婨崘崙棆沦淪碖磮綸纶耣腀芲菕蜦踚輪轮錀陯鯩埨惀稐溣論论啰囉捋頱儸囖攞椤欏猡玀箩籮罗羅脶腡萝蘿螺覶覼逻邏鏍鑼锣镙饠騾驘骡鸁倮剆曪瘰癳臝蓏蠃裸躶峈摞泺洛洜漯濼犖珞硌硦笿絡纙络荦落詻雒駱骆鮥鵅榈櫚氀膢藘閭闾驢驴侣侶偻僂儢吕呂屡屢履慺挔捛旅梠焒祣稆穭絽縷缕膂膐褛褸郘鋁铝勴垏嵂律慮櫖氯滤濾爈率箻綠緑繂绿膟葎虑鑢圙寽掠略畧稤鋝鋢锊妈媽嫲嘛犘痲痳蔴蟆蟇麻杩溤犸獁玛瑪码碼蚂螞遤鎷馬马鰢鷌傌嘜榪睰祃禡罵閁駡骂鬕吗嗎埋薶霾买嘪荬蕒買鷶佅劢勱卖唛売脈脉衇賣迈邁霡霢麥麦顢颟姏悗慲摱樠瞒瞞蛮蠻謾谩鞔饅馒鬗鬘鰻鳗娨屘満满滿矕螨蟎襔鏋僈墁嫚幔慢曼槾漫澷熳獌縵缦蔄蔓蘰鄤鏝镘牤厖吂哤娏忙恾杗杧汒浝牻狵痝盲盳硭笀芒茫蘉蛖邙釯鋩铓駹壾漭硥茻莽莾蟒蠎猫貓堥旄枆楙毛氂渵牦犛矛罞芼茅茆蝥蟊軞酕鉾錨锚髦髳鶜乮冇卯夘峁戼昴泖笷蓩鉚铆冃冐冒媢帽愗懋暓柕毷瑁皃眊瞀耄茂萺蝐袤覒貌貿贸鄚鄮嚒嚰濹么麼麽坆堳塺媒嵋徾攗枚栂梅楣楳槑沒没湄湈煤猸玫珻瑂眉睂禖脄脢腜苺莓葿郿酶鋂鎇镅霉鶥鹛黴凂媄媺嬍嵄挴毎每浼渼燘美羙躾鎂镁黣嚜妹媚寐抺旀昧沬煝痗眛睸祙篃蝞袂跊韎鬽魅椚们們扪捫玧璊穈菛虋鍆钔門閅门悶懑懣暪焖燜闷掹擝矇蒙儚幪懞曚朦橗檬氋氓溕濛獴甍甿盟瞢矒礞艨莔萌蕄虻蝱鄳鄸霿靀顭饛鯍鸏鹲冡勐懵猛艋蜢蠓錳锰鯭鼆夢夣孟懜梦癦霥咪眯瞇冞弥彌戂擟攠瀰爢猕獼瓕祢禰糜縻蒾藌蘪蘼袮詸謎谜迷醚醾醿釄镾靡鸍麊麋麛麿侎孊弭敉沵洣渳濔灖米粎羋脒芈葞蔝銤冖冪嘧塓宓宻密峚幂幎幦怽榓樒櫁汨沕泌淧滵漞濗熐祕秘簚糸羃蔤蜜覓覔覛觅謐谧鼏婂媔嬵宀杣棉檰櫋眠矈矊矏綿緜绵臱芇蝒丏偭免冕勉勔喕娩愐汅沔渑湎澠眄睌絻緬缅腼葂靦鮸糆面靣麪麫麵麺喵媌嫹描瞄緢苗鶓鹋劰杪淼渺眇秒篎緲缈藐邈妙庙庿廟玅竗乜吀咩哶孭幭懱搣櫗滅瀎灭烕礣篾蔑薎蠛衊鑖鱴鴓垊姄岷崏怋慜捪旻旼民玟珉琘琝瑉痻盿砇碈緍緡缗罠苠鈱錉鍲鴖僶冺刡勄忞忟悯惽愍憫抿敃敏敯暋泯湣潣皿笢笽簢蠠閔閩闵闽鰵鳘黽黾冥名嫇明暝朙榠洺溟猽眀眳瞑茗蓂螟覭詺鄍銘铭鳴鸣佲凕姳慏酩命掵謬谬嚤摸劘嫫嬤嬷尛庅摩摹擵模橅磨糢膜蘑謨謩谟饃饝馍髍魔魹懡抹嗼圽塻墨妺嫼寞帓帞昩末枺歾歿殁沫漠爅獏瘼皌眜眽眿瞐瞙砞礳秣絈纆耱茉莈莫蓦藦蛨蟔貃貊貘銆鏌镆陌靺驀魩默黙哞侔劺呣恈牟眸繆缪蛑謀谋踎鍪鴾麰某毪氁亩姆峔拇母牡牳畂畆畒畝畞畮砪胟踇鉧仫凩募坶墓幕幙慔慕暮暯木楘毣沐炑牧狇目睦穆縸艒苜莯蚞鉬钼雮霂鞪嗱拏拿搻鎿镎乸哪雫吶呐妠捺笝納纳肭蒳衲袦豽貀軜那郍鈉钠靹魶孻腉乃倷奶嬭廼氖疓艿迺釢奈柰渿耐萘螚褦錼鼐囡侽南喃娚抩暔枏柟楠男畘莮諵遖难難戁揇湳煵腩萳蝻赧婻囔乪嚢囊欜蠰饢馕擃攮曩灢儾齉孬呶夒峱嶩巎怓憹挠撓猱獶獿硇碙蛲蟯詉譊鐃铙匘垴堖嫐恼悩惱瑙碯脑脳腦淖臑閙闹鬧抐疒眲訥讷呢娞脮腇餒馁鮾鯘內内氝氞錗嫩嫰恁能妮倪坭埿婗尼屔怩棿泥淣猊秜籾聣臡蚭蜺觬貎跜輗郳鈮铌霓馜鯢鲵麑齯伱伲你儗儞妳孴抳拟掜擬旎晲柅檷狔聻苨薿隬匿堄嫟嬺屰惄愵昵暱氼溺眤睨縌胒腻膩誽逆拈蔫哖姩年秊秥粘鮎鯰鲇鲶鵇黏捻撚撵攆涊淰焾碾簐蹍蹨躎輦辇卄唸埝廿念惗艌娘嬢孃酿醸釀嫋嬝嬲樢茑蔦袅裊褭鳥鸟尿脲捏揑苶啮嗫噛嚙囁囓圼孼孽嵲嶭巕帇摰敜枿槷櫱涅湼痆篞籋糱糵聂聶臬臲菍蘖蠥讘踂踗踙蹑躡錜鎳鑈鑷钀镊镍闑陧隉顳颞齧囜您脌拰儜凝咛嚀嬣宁寍寕寗寜寧擰柠橣檸狞獰甯聍聹薴鑏鬡鸋拧矃佞侫倿泞澝濘妞汼牛牜忸扭杻炄狃紐纽莥鈕钮靵侬儂农哝噥檂欁浓濃燶禯秾穠脓膿蕽襛譨農辳醲鬞繷弄挊挵癑齈羺槈檽獳耨鎒鐞伮奴孥帑笯駑驽努弩砮胬傉怒搙奻暖渜煖煗餪黁傩儺娜挪梛橠喏愞懦懧掿搦榒稬穤糑糥糯諾诺蹃逽鍩锘女籹釹钕恧朒沑衂衄婩疟瘧硸虐喔噢哦筽塸櫙欧歐殴毆熰瓯甌膒藲謳讴鏂鴎鷗鸥偶吘呕嘔耦腢蕅藕怄慪沤漚啪妑皅舥苩葩趴掱杷潖爬琶筢帊帕怕袙拍俳徘排棑牌犤猅箄簰簲輫哌沠派渒湃蒎鎃攀潘眅萠丬媻幋搫柈槃洀瀊爿盘盤磐磻縏蒰蟠跘蹒蹣鎜鞶冸判叛沜泮溿炍牉畔盼聁袢襻詊鋬鑻頖鵥乓滂胮膖雱霶厐嫎庞庬彷徬旁舽螃逄鰟鳑龎龐耪覫炐眫肨胖抛拋脬萢刨匏咆垉庖炰爮狍袍褜軳鞄麃麅跑奅泡炮疱皰砲礟礮靤麭呸怌肧胚衃醅培婄毰裴裵賠赔錇锫阫陪俖伂佩姵帔斾旆沛浿犻珮蓜轡辔配霈馷喷噴歕湓瓫盆葐呠翸剻匉嘭怦恲抨梈泙烹砰硑磞軯閛駍倗傰堋塜塳弸彭憉捀朋棚椖樥澎熢硼稝竼篣篷纄膨芃莑蓬蘕蟚蟛袶輣錋鑝韸韼騯髼鬅鬔鵬鹏捧淎皏掽椪槰碰踫丕伓伾劈噼坯岯悂憵批披抷旇枈炋狉狓砒磇礔礕秛秠紕纰翍耚豾邳釽鈚鉟銔錃錍陴霹駓髬魾啤埤壀崥枇毗毘焷琵疲皮笓篺罴羆肶脾腗膍蚍蚽蚾蜱螷蠯裨豼貔郫鈹铍阰隦魮鮍鲏鵧鼙仳匹吡噽嚭圮嶏庀擗疋痞癖脴苉諀銢鴄僻媲嫓屁揊淠潎澼甓疈稫譬辟闢鷿鸊偏囨媥楄犏篇翩鍂鶣楩胼腁賆跰蹁駢騈骈骿覑諞谝貵片騗騙骗魸剽勡嘌彯慓旚漂犥翲螵飃飄飘魒嫖瓢薸闝殍皫瞟篻縹缥醥顠僄徱票驃鰾撆撇暼氕瞥覕丿苤鐅嫳姘拚拼砏礗穦馪驞嚬娦嫔嬪玭琕矉薲蘋蠙貧贫顰频颦品榀汖牝聘乒俜娉涄甹砯聠艵頩凭凴呯坪塀屏岼帡帲幈平慿憑枰檘洴淜焩玶瓶甁竮箳簈缾胓苹荓萍蓱蚲蛢評评軿輧郱鮃鲆屛坡岥泼溌潑酦醗醱釙鏺钋頗颇嘙嚩婆櫇皤蔢鄱叵尀笸箥鉕钷駊哱奤岶廹敀昢洦湐烞珀破砶粕蒪迫魄剖娝垺抔抙捊箁裒咅哣掊犃仆噗扑撲攴攵潽炇痡鋪铺陠鯆僕匍圤墣濮獛璞瞨穙纀莆菐菩葡蒱蒲贌酺鏷镤圃圑埔擈普暜朴樸檏氆浦溥烳諩譜谱蹼鐠镨曝瀑舖舗七倛傶僛凄嘁墄妻娸悽慼慽戚捿攲敧期柒栖桤桼棲榿欹欺沏淒漆紪緀萋褄諆踦蹊迉郪鏚霋魌鶈丌亓亝其剘圻埼奇岐岓崎嵜帺忯愭懠掑斉斊旂旗棊棋檱櫀歧淇濝猉玂琦琪璂畦疧碁碕祁祈祺禥竒簯簱籏粸綥綦耆肵脐臍艩芪萁萕蕲藄蘄蚑蚔蚚蛴蜝蜞螧蠐褀跂軝鄿釮錡锜陭隑頎颀騎騏騹骐骑鬐鬿鯕鰭鲯鳍鵸鶀麒麡齊齐乞企启呇唘啓啔啟婍屺岂晵杞棨玘盀綺绮芑諬豈起邔闙呮咠唭噐器夡契弃愒憇憩摖暣栔棄槭欫气気氣汔汽泣湆湇滊炁甈盵矵砌碛碶磜磧磩罊芞葺藒蟿訖讫迄鐑掐擖葜峠拤跒酠鞐冾圶帢恰殎洽硈胢髂仟佥僉千厱圱圲奷婜孯岍悭愆慳扦拪掔搴撁攐攑攓杄檶櫏欦汘汧牵牽竏签簽籖籤粁臤芊茾蚈褰諐謙谦谸迁遷釺鈆鉛鏲钎铅阡韆顅騫骞鬜鬝鵮鹐乹乾亁仱偂前墘媊岒忴扲拑掮揵榩橬歬潛潜濳灊箝羬荨葥蕁虔軡鈐鉗銭錢鎆钤钱钳騚騝鰬黔黚槏浅淺繾缱肷膁蜸譴谴遣鑓伣俔倩傔儙刋堑塹壍嬱嵌悓慊棈椠槧欠歉皘篏篟綪縴芡茜蒨蔳輤呛啌嗆嗴嶈戕戗戧搶摤斨枪椌槍溬牄猐獇玱瑲篬羌羗羫腔蜣謒跄蹌蹡鎗鏘锖锵墙墻嫱嬙廧強强彊樯檣漒牆艢蔃蔷薔蘠墏抢繈繦羟羥襁鏹镪唴炝熗羻劁勪墝墽帩幧悄敲橇毃燆硗磽繑繰缲趬跷踍蹺蹻郻鄡鄥鍫鍬鐰锹頝骹乔侨僑喬嘺墧嫶峤憔桥槗樵橋櫵犞癄睄瞧硚礄翘翹荍荞菬蕎藮譙谯趫鐈鞒鞽顦巧愀釥髜俏僺峭撬撽窍竅誚诮躈陗鞘鞩韒髚切苆癿聺茄且匧厒妾怯悏惬愜挈洯淁穕窃竊笡箧篋籡蛪趄踥郄鍥锲鯜亲侵兓媇寴嵚嵰嶔欽綅衾親誛钦顉駸骎鮼勤嗪噙埐嫀嶜庈懃懄捦擒斳檎澿珡琴琹瘽禽秦耹肣芩芹菦菳蚙螓蠄鈙鈫雂靲鳹鵭坅寑寖寝寢昑梫笉螼赾鋟锓吢吣唚抋揿搇撳沁瀙菣藽倾傾卿圊埥寈氢氫淸清蜻軽輕轻郬錆鑋靑青鯖鲭剠勍啨夝情擎擏晴暒棾樈檠殑氰甠硘葝黥庼廎檾漀苘請謦请頃顷儬凊庆慶掅櫦殸濪碃磬箐綮罄靘儝卭宆惸憌桏橩焪焭煢熍琼璚瓊瓗睘瞏穷穹窮竆笻筇舼茕藑藭蛩蛬赹跫邛銎丘丠坵媝恘恷楸湫湬秋秌穐篍緧萩蓲蘒蚯蝵蟗蠤趥邱鞦鞧鰌鰍鳅鶖鹙龝俅叴唒囚崷巯巰扏朹梂殏毬求汓泅浗渞湭煪犰玌球璆皳盚紌絿肍芁莍虬虯蛷蝤裘觓觩訄訅賕赇逎逑遒酋醔釚釻銶頄鮂鯄鰽鼽搝糗伹佉匤区區呿坥屈岖岴嶇憈抾敺浀焌煀祛筁粬紶胠蛆蛐袪覰詘誳诎趋趍趨躯軀阹駆駈驅驱髷魼鰸鱋鶌麯麴麹黢佢劬忂戵斪朐欋欔氍淭渠灈爠璖璩癯瞿磲籧絇翑胊臞菃葋蕖蘧螶蟝蠷蠼衐衢躣軥鑺鴝鸜鸲鼩取娶曲竘竬蝺詓齲龋刞厺去耝覷覻觑趣閴闃阒麮鼁圈圏奍悛棬椦箞鐉佺全啳埢姾峑巏恮拳搼权楾権權泉洤湶牷犈瑔痊硂筌絟縓荃葲蜷蠸觠詮诠跧踡輇辁醛銓铨闎顴颧駩騡鬈鰁鳈齤烇犬犭犮畎綣绻虇券劝勧勸牶韏炔缺缼蒛阙瘸傕却卻埆塙崅悫愨慤搉棤榷燩琷皵硞确碏確碻礐礭趞闋闕阕雀鵲鹊囷夋踆逡宭峮帬羣群裙裠呥嘫然燃繎肰蚦蚺衻袇袡髥髯冄冉姌媣染橪珃苒蒅儴勷瀼獽瓤禳穣穰蘘躟鬤嚷壌壤攘爙懹譲讓让娆嬈桡橈荛蕘襓饒饶扰擾隢繞绕遶惹热熱人亻仁壬忈忎朲秂芢銋魜鵀忍栠栣棯秹稔綛荏荵躵仞仭任刃刄妊姙屻岃扨杒梕牣祍紉紝絍纫纴肕腍衽袵訒認认讱軔轫鈓靭靱韌韧飪餁饪扔仍礽芿辸陾囸日衵釰釼鈤馹驲傛媶嫆嬫容峵嵘嵤嶸戎搈搑曧栄榕榮榵槦毧溶瀜烿熔爃狨瑢穁絨縙绒羢肜茙茸荣蓉蝾融螎蠑褣鎔镕駥傇冗坈宂氄軵穃厹媃揉柔楺渘煣瑈瓇禸粈糅脜腬葇蝚蹂輮鍒鞣騥鰇鶔韖宍肉譳嶿侞儒嚅如嬬孺帤挐曘桇渪濡筎繻茹蒘蕠薷蝡蠕袽襦邚醹銣铷顬颥鱬鴑鴽乳擩汝肗辱鄏入嗕媷扖杁洳溽縟缛蓐褥鳰堧壖撋偄媆朊瑌瓀碝礝緛耎腝軟輭软阮桵甤緌蕤壡惢橤繠蕊蕋蘂蘃叡枘汭瑞睿芮蚋蜹銳鋭锐瞤橍润潤膶閏閠闰挼捼偌叒婼嵶弱楉渃焫爇箬篛若蒻鄀鰙鰯鶸仨撒洒灑訯躠靸卅摋櫒脎萨蕯薩鈒钑隡颯飒馺嘥噻塞愢揌毢毸腮顋鰓鳃嗮僿簺賽赛三厁叁弎毵毶毿犙鬖伞傘糁糝糣糤繖鏒鏾饊馓俕散潵閐壭桑桒槡嗓搡磉褬鎟顙颡丧喪慅掻搔溞繅缫臊螦颾騒騷骚鰠鱢鳋嫂扫掃埽氉瘙矂髞閪啬嗇懎摵擌栜歮歰洓涩渋澀澁濇濏瀒瑟璱瘷穑穡穯繬色譅轖銫鏼铯雭飋森椮槮襂僧鬙乷唦杀桬榝樧殺毮沙煞猀痧砂硰粆紗繺纱蔱裟鎩铩閷髿魦鯊鯋鲨啥傻儍倽厦唼啑喢嗄帹廈歃箑翜翣萐閯霎筛篩簁簛籭晒曬傓删刪剼嘇圸姍姗山幓彡挻搧杉柵檆潸澘煽狦珊痁笘縿羴羶脠膻舢芟苫衫跚軕邖釤钐閊鯅晱炶煔熌睒覢閃闪陕陝僐善墠墡嬗扇掞擅敾椫樿歚汕灗疝磰禪繕缮膳蟮蟺訕謆譱讪贍赡赸鄯銏鐥饍騸骟鱓鱔鳝伤傷商墒慯殇殤滳漡熵禓蔏螪觞觴謪鬺垧扄晌樉賞贘赏鋿鏛鑜丄上尙尚恦緔绱鞝弰捎旓梢烧焼燒稍筲艄莦萷蕱輎髾鮹勺杓柖玿芍韶少劭卲哨娋潲紹綤绍袑邵奓奢檨猞畬畭畲賒賖赊輋佘揲舌虵蛇蛥捨舍厍厙射弽慑慴懾摂摄攝欇涉涻渉滠灄社舎蔎蠂設设赦韘騇麝伸侁兟呻堔妽姺娠屾峷扟敒曑柛氠深燊珅甡甧申眒砷穼籶籸糂紳绅罙罧莘葠蓡蔘薓裑訷詵诜身駪鯓鯵鰺鲹鵢什榊神鉮鰰哂婶嬸审宷審弞曋沈渖瀋瞫矤矧覾訠諗讅谂谉邥頣魫侺愼慎昚涁渗滲甚瘆瘮眘祳肾胂脤腎葚蜃蜄鋠升呏声斘昇曻枡殅泩湦焺牲狌珄生甥竔笙聲苼鉎鍟阩陞陹鵿鼪憴縄繉繩绳譝偗渻省眚剩剰勝圣墭嵊晟晠榺橳琞盛聖胜蕂貹賸呞失尸屍师師施浉湤湿溮溼濕狮獅瑡箷絁葹蒒蓍虱蝨褷襹詩诗邿酾釃釶鉇鍦鯴鰤鲺鳲鳾鶳鸤乭十埘塒姼实実寔實峕嵵拾时旹時榯湜溡炻石祏竍蚀蝕識识遈鉐食飠饣鮖鰣鲥鼫鼭乨使兘史始宩屎榁矢笶豕鉂駛驶世丗亊事仕侍冟势勢卋呩嗜噬士奭嬕室崼市式弑弒徥忕恀恃戺拭揓是昰枾柹柿栻氏澨烒煶眂眎眡睗示礻秲筮簭舐舓莳蒔螫襫視视觢試誓諟諡謚试谥貰贳軾轼适逝適遾釈释釋鈰鉃鉽銴铈飾餙餝饰鰘籂辻収收垨守手扌艏首兽受售嘼壽夀寿授涭狩獣獸痩瘦綬绶膄鏉书倏倐儵叔姝婌抒掓摅攄書杸枢梳樞橾殊殳毹毺淑瀭焂琡疎疏紓綀纾舒菽蔬跾踈軗輸输鄃陎鮛鵨塾孰尗熟璹秫贖赎属屬数數暏暑曙潻癙糬署薥薯藷蜀蠴襡襩鱪鱰黍鼠鼡侸咰墅尌庶庻怷恕戍捒朮术束树樹沭漱潄澍濖竖竪絉腧荗蒁虪術裋豎述鉥錰鏣霔鶐刷唰耍誜摔衰甩卛帅帥蟀拴栓閂闩涮腨双孀孇欆礵艭雙霜騻驦骦鷞鸘鹴塽慡漺爽縔鏯灀脽誰谁水氵氺閖帨涗涚睡祱稅税裞吮楯橓瞚瞬舜蕣順顺鬊說説说妁搠朔槊欶烁爍獡矟硕碩箾蒴鎙鑠铄丝俬凘厮厶司咝嘶噝媤廝思恖撕斯楒泀澌燍磃禗禠私糹絲緦纟缌罳蕬虒蛳蜤螄蟖蟴鉰銯鋖鍶鐁锶颸飔騦鷥鸶鼶死亖似佀価俟儩兕嗣四姒娰孠寺巳杫枱柶梩榹汜泗泤洍洠涘瀃牭祀禩竢笥耛耜肂肆蕼覗貄釲鈶鈻飤飼饲駟騃驷倯凇娀崧嵩庺忪憽松枀枩柗梥檧淞濍硹菘鬆傱嵷怂悚愯慫楤竦耸聳駷宋訟誦讼诵送鎹頌颂餸凁嗖廀廋捜搜摉摗溲獀艘蒐蓃螋鄋醙鎪锼颼飕餿馊騪傁叜叟嗾擻櫢瞍籔薮藪嗽擞瘶囌櫯甦稣穌窣苏蘇蘓酥鯂俗傃僳嗉塐塑夙嫊宿愫愬憟梀榡樎樕橚殐泝洬涑溯溸潚潥玊珟璛碿簌粛粟素縤肃肅膆莤蔌藗觫訴謖诉谡趚蹜速遡遬鋉餗驌骕鱐鷫鹔狻痠酸匴祘笇筭算蒜倠哸夊浽滖濉熣芕荽荾虽雖鞖瓍綏绥遀隋随隨髄瀡膸髓亗埣嬘岁嵗旞檖歲歳澻煫燧璲睟砕碎祟禭穂穗穟繀繐繸襚誶譢谇賥遂邃鐆鐩隧韢孙孫搎槂狲猻荪蓀蕵薞飧飱损損榫笋筍箰簨鎨隼鶽傞唆嗍嗦娑挱挲摍桫梭睃簑簔縮缩羧莎莏蓑趖鮻乺唢嗩所暛溑獕琐琑瑣索褨鎍鎖鎻鏁锁溹蜶逤他塌她它榙溻牠祂褟趿鉈铊闧塔墖獭獺鮙鰨鳎傝嚃嚺崉挞搨撻榻橽毾沓涾澾濌狧禢粏誻譶踏蹋蹹躂躢遝遢錔闒闥闼阘鞜鞳侤囼孡胎儓台坮嬯抬擡旲檯炱炲箈籉臺苔菭薹跆邰颱駘骀鮐鲐冭太夳忲态態汏汰汱泰溙燤肽舦酞鈦钛啴嘽坍怹摊擹攤滩潬灘痑瘫癱舑貪贪倓坛埮墰墵壇壜婒弹弾彈惔憛昙曇榃橝檀潭燂痰罈罎藫覃談譚譠谈谭貚郯醈醰錟锬顃僋嗿坦忐憳憻暺毯璮菼袒襢醓鉭钽叹嘆探歎湠炭碳舕劏嘡汤湯羰薚蝪蹚鏜镗鞺鼞傏唐啺坣堂塘嵣搪棠榶樘橖溏漟煻瑭磄禟篖糃糖糛膅膛蓎螗螳赯踼鄌醣鎕闛隚餹饄鶶伖倘偒傥儻戃曭淌爣矘耥躺鎲钂镋摥烫燙趟鐋铴夲嫍幍弢慆掏搯槄涛滔濤瑫絛縚縧绦詜謟轁鞱韜韬飸饕匋咷啕桃洮淘祹綯绹萄蜪裪迯逃醄鋾陶鞀鞉饀駣騊鼗討讨套忑忒慝特脦蟘鋱铽熥膯鼟儯幐滕漛疼痋籐籘縢腾藤虅螣誊謄邆駦騰驣鰧霯剔擿梯踢銻锑鷈鷉偍厗啼嗁媞崹徲惿提渧漽瑅睼碮禔禵稊綈緹绨缇罤蕛褆謕趧蹄蹏醍鍗題题騠鮷鯷鳀鵜鶗鶙鷤鹈体挮躰軆骵體倜剃嚏嚔屉屜悌悐惕惖戻掦揥替朑歒殢涕瓋笹籊薙褅趯逖逷髰鬀鬄兲天婖添酟靔靝黇塡填屇恬搷沺湉璳甛甜田畋畑碵磌窴緂胋菾闐阗鴫鷆鷏倎唺忝悿晪殄淟琠痶睓腆舔覥觍賟錪餂掭瑱舚佻庣恌挑旫祧聎岧岹条條樤祒笤芀苕萔蓚蓨蜩调迢鋚鎥鞗髫鯈鰷鲦齠龆嬥宨晀朓窕窱脁誂眺粜糶絩覜趒跳怗聑萜貼贴僣帖蛈鉄銕鐡鐵铁驖呫飻餮厅厛听庁廰廳桯汀烃烴綎耓聴聼聽鞓亭停婷嵉庭廷楟榳渟筳聤莛葶蜓蝏諪邒閮霆鼮侹圢娗挺梃涏烶珽町甼脡艇誔鋌铤頲颋嗵樋炵痌絧蓪通仝佟僮勭同哃峂峒峝庝彤晍曈朣桐橦氃浵潼烔燑犝狪獞眮瞳砼秱穜童粡膧茼蚒詷赨酮鉖鉵銅铜餇鮦鲖捅桶筒筩統綂统恸慟憅痛衕偷偸婾媮緰鋀鍮亠头投頭骰妵敨斢紏蘣黈透凸堗宊嶀怢捸涋湥痜禿秃突葖鋵鵚鼵凃図图圖圗塗屠峹嵞庩廜徒悇捈揬梌涂潳瑹瘏稌筡腯荼蒤跿途酴鈯鍎馟駼鵌鶟鷋鷵吐唋土圡釷钍兎兔堍莵菟迌鵵汢圕湍煓猯貒剸团団團慱抟摶槫檲漙篿糰鏄鷒鷻墥畽疃彖湪褖推蓷藬尵弚橔穨蘈蹪隤頹頺頽颓魋俀僓腿蹆骽娧煺蛻蜕螁褪退駾吞呑噋旽暾朜涒焞囤坉屯忳臀臋芚蛌豘豚軘霕飩饨魨鲀黗氽乇仛侂咃咜托扡拕拖挩捝杔汑沰涶脫脱莌袥託讬飥饦馲魠鮵佗侻坨堶媠岮柁槖橐沱沲狏砣砤碢紽袉詑跎酡阤陀陁馱駄駝駞騨驒驝驮驼鮀鴕鸵鼉鼍鼧妥嫷庹彵椭楕橢鰖鵎唾嶞拓柝毤毻箨籜萚蘀跅劸哇嗗娲媧屲挖搲攨洼溛漥瓾畖穵窊窐窪蛙韈鼃娃佤咓瓦砙邷嗢聉腽膃袜襪韤呙咼喎歪竵外顡剜塆壪婠帵弯彎湾潫灣睕蜿豌丸刓完岏忨抏捖汍烷玩琓笂紈纨翫芄貦頑顽倇唍埦婉宛惋挽晚晥晩晼梚椀涴琬畹皖盌碗箢綩綰绾脘莞菀萖踠輓鋔万卍卐妧捥杤澫瞣脕腕萬薍蟃贃贎輐鋄錽鎫尣尩尪尫汪亡亾仼兦王莣蚟彺往徃惘暀枉棢瀇網网罒罓罔罖菵蛧蝄誷輞辋魍妄忘旺望朢迋偎危厃喴威媙崴嵔嶶巍微愄揋揻椳楲溦烓煨燰癓縅葨葳薇蜲蝛覣詴逶隇隈霺鰃鰄鳂唯喡囗囲围圍壝媁峗峞嵬帏帷幃惟桅欈沩洈涠湋溈潍潙潿濰為爲犩琟矀硙維维蓶覹违違鄬醀鍏闈闱韋韦鮠亹伟伪偉偽僞儰委娓寪尾屗崣嶉徫愇捤撱斖暐梶椲洧浘渨濻瀢炜煒猥玮瑋痏痿硊碨緯纬腲艉芛苇荱萎葦蒍蔿諉诿踓鍡隗韑韙韡韪頠颹骩骪骫鮪鲔为位卫叞味喂墛媦尉慰懀未渭煟熭犚猬畏緭罻胃苿菋蔚藯蘶蜼蝟螱衛衞褽謂讆讏谓躗躛軎轊鏏霨餧餵饖魏鮇鳚塭昷榅榲殟温溫瑥瘟豱輼轀辒鎾鞰饂鰛鰮鳁彣文炆珳瘒紋繧纹聞芠蚉蚊螡蟁閺閿闅闦闻阌雯馼駇魰鳼鴍鼤伆刎吻呅呡抆桽稳穏穩紊肳脗問妏揾搵汶渂璺莬问顐嗡翁聬螉鎓鶲鹟勜塕奣嵡攚暡滃瞈蓊瓮甕罋蕹齆倭唩挝涡涹渦猧窝窩莴萵蜗蝸踒婐婑我捰仴偓卧媉幄捾握斡枂楃沃渥濣焥瓁瞃硪肟腛臒臥齷龌乌剭呜嗚圬屋巫弙杇歍汙汚污洿烏窏箼螐誈誣诬邬鄔鎢钨鰞鴮吳吴吾呉墲娪峿无梧橆毋洖浯無珸璑祦芜茣莁蕪蜈蟱譕郚鋙铻鯃鵐鷡鹀鼯乄五仵伍侮倵儛午啎妩娒娬嫵庑廡忤怃憮捂摀武潕熓牾玝珷瑦甒瞴碔舞躌迕逜陚鵡鹉俉兀务務勿卼唔坞塢奦婺寤屼岉嵍嵨忢悞悟悮戊扤敄旿晤杌溩焐熃物痦矹窹粅芴蘁誤误鋈阢隖雺雾霚霧靰騖骛鶩鹜鼿齀俙傒僖兮凞卥厀吸唏唽嘻噏嚱夕奚娭嬆嬉屖嵠巇希徆徯忚怸恓息悉悕惁惜扱扸昔晞晰晳暿曦析桸榽樨橀欷歙氥汐浠淅渓溪潝烯焁焈焟焬煕熄熈熙熹熺熻燨爔牺犀犠犧狶琋瘜皙睎瞦矽硒磎礂稀穸窸粞糦緆繥羲翕翖肸肹膝舾莃菥蒠蜥螅螇蟋蠵裼西覡觹觽觿譆谿豀豨豯貕赥邜郗鄎酅醯釸錫鏭鐊鑴锡隵餏饎饻鯑鵗鸂鼷习喺媳嶍席椺槢檄漝習蒵蓆薂袭襲觋謵趘郋鎴隰霫飁騱騽驨鰼鳛喜囍壐屣徙憘憙枲橲歖洗漇玺璽矖禧縰葈葸蓰蟢諰謑蹝躧鈢鉨鉩鱚係匸卌呬墍屃屓屭忥怬恄慀戏戯戱戲椞欯潟澙熂犔盻磶禊稧系細綌縘繫细绤舃舄蕮虩衋覤赩趇郤釳闟阋隙隟霼餼饩鬩黖傄呷煆瞎虲虾蝦谺閕颬鰕侠俠匣埉峡峽敮暇柙炠烚狎狭狹珨瑕硖硤碬磍祫筪縖翈舝舺蕸赮轄辖遐鍜鎋陜陿霞騢魻鶷黠閜丅下乤吓圷夏夓懗梺疜睱罅諕鎼鏬仙仚佡僊僲先嘕奾嬐孅屳廯忺憸掀攕暹杴枮氙珗祆秈籼繊纎纖纤苮莶薟褼襳跹蹮躚酰銛銽鍁铦锨韯韱馦鮮鱻鲜鶱伭咁咸啣嗛妶娴娹婱嫌嫺嫻弦憪挦撏涎湺澖甉痫癇癎盷瞯礥稴絃胘舷藖蚿蛝衔衘誸諴賢贒贤輱醎銜鑦閑閒闲鷳鷴鷼鹇鹹麙冼尟尠崄嶮幰搟攇显櫶毨灦烍燹狝猃獫獮玁禒筅箲藓蘚蚬蜆譣赻跣銑鍌铣险険險韅顕顯僩僴县咞哯垷埳塪壏姭娊宪岘峴憲撊晛橌橺涀瀗献獻现現県睍粯糮絤綫線縣线缐羡羨腺臔臽苋莧誢豏鋧錎限陥陷霰餡馅麲鼸乡厢廂忀楿欀湘瓖相稥箱緗纕缃膷芗萫葙薌襄郷鄉鄊鄕鑲镶香驤骧鱜麘佭庠栙瓨祥絴翔詳详跭享亯响想晑蚃蠁銄響飨餉饗饟饷鮝鯗鱶鲞像勨向嚮姠嶑巷曏橡珦缿蟓衖襐象鐌項项鱌侾削呺哓嘐嘵嚣嚻囂婋宯宵庨彇憢揱撨枭枵梟櫹歊毊消潇瀟灱灲烋焇猇獢痚痟硝硣穘窙箫簘簫綃绡翛肖膮萧蕭藃虈虓蛸蟂蟏蟰蠨踃逍銷销霄颵驍骁髇髐魈鴞鴵鷍鸮崤殽洨淆訤誵郩小晓暁曉皛皢筱筿篠謏俲傚効咲哮啸嘋嘨嘯孝恔效敩斅斆校歗涍熽笑詨誟些娎揳楔歇猲蝎蠍偕劦勰协協嗋嚡垥奊孈峫恊愶拹挟挾携撷擕擷攜斜旪熁燲瑎絜綊緳縀缬翓胁脅脇脋膎蝢衺襭諧讗谐邪鞋鞵龤写冩寫藛血亵伳偞偰僁卨卸噧塮夑媟屑屟屧嶰廨徢懈暬械榍榭泄泻洩渫澥瀉瀣灺炧炨烲焎燮爕獬祄禼糏紲絏絬緤繲纈绁缷薢薤蟹蠏褉褻謝谢躞邂靾鞢韰齂齘齛齥俽噷噺妡嬜廞心忄忻惞新昕杺欣歆盺芯薪訢辛邤鈊鋅鑫锌馨馫枔襑鐔镡伈伩信囟孞炘焮脪舋衅訫軐釁阠顖馸垶惺星曐煋猩瑆皨箵篂腥興觪觲謃騂骍鮏鯹侀刑哘型娙形洐滎硎荥蛵行邢郉鈃鉶銒鋞钘铏陉陘餳饧擤睲醒倖兴姓婞嬹幸性悻杏涬緈臖荇莕葕兄兇凶匂匈哅忷恟汹洶胷胸芎訩詾讻賯熊熋雄焸焽夐敻詗诇休俢修咻庥樇烌羞脙脩臹貅銝鎀鏅飍饈馐髤髹鮴鱃鵂鸺苬朽滫潃糔嗅嚊岫峀溴珛琇璓秀綉繍繡绣螑袖褎褏銹鏥鏽锈齅偦吁嘘噓圩墟媭嬃戌揟旴楈欨欻歔歘燸疞盱砉綇縃胥蕦虗虚虛蝑裇訏許諝譃谞鑐需須须顼驉鬚魆魖俆冔徐禑蒣呴喣姁暊栩湑珝盨稰糈詡諿许诩鄦醑伵侐勖勗卹叙垿壻婿序怴恤慉敍敘旭昫晇朂槒欰殈汿沀洫溆漵潊烅烼煦獝珬盢瞁稸絮続緒緖續绪续聓聟芧蓄蓿藇藚訹賉酗銊頊鱮儇吅喧塇媗宣弲愃愋懁揎昍晅暄梋煊瑄睻矎禤箮翧翾萱萲蓒蕿藼蘐蝖蠉諠諼譞谖軒轩鋗鍹鞙駽鰚嫙悬懸旋暶檈漩玄玹琁璇璿痃蜁咺暅烜癣癬选選怰昡楥楦泫渲炫琄眩眴碹絢縼繏绚蔙衒袨贙鉉鏇铉镟颴疶蒆薛辥辪靴鞾乴壆学學峃嶨斈泶澩燢穴茓袕觷踅鷽鸴樰膤艝轌雪鱈鳕吷坹岤桖瀥狘瞲謔谑趐勋勛勲勳嚑坃埙塤壎壦曛焄熏燻爋獯矄纁臐薫薰蘍醺偱噚姰寻尋峋巡廵循恂揗攳旬杊栒桪樳毥洵浔潯灥燅燖珣璕畃紃荀蟳詢询郇鄩駨鱏鱘鲟伨侚卂噀奞巺巽徇愻殉殾汛潠狥稄蕈訊訓訙训讯迅迿逊遜鑂顨馴驯丫压吖呀圧垭壓孲庘押枒桠椏錏鐚铔鴉鴨鵶鸦鸭伢厑厓堐岈崕崖涯漄牙猚琊睚笌芽蚜衙齖厊哑唖啞庌疨痖瘂蕥雅亚亜亞俹冴劜圔圠埡娅婭挜掗揠氩氬犽猰玡砑稏窫聐襾覀訝讶軋轧迓齾傿剦嫣嬮崦嶖恹懕懨樮歅淊淹渰湮漹烟焉焑煙珚硽篶胭臙菸鄢醃閹阉黫严厳啱喦嚴埏塩壛壧妍姸娫娮岩嵒嵓巌巖巗延揅昖楌檐櫩欕沿炎炏狿琂盐研硏碞礹筵簷綖莚蔅虤蜒言訁訮詽讠郔閆閻闫阎顏顔颜鹽麣乵俨偃儼兖兗剡匽厣厴噞夵奄孍嵃巘巚弇愝戭扊抁掩揜曮棪椼檿沇渷演琰甗眼縯罨萒蝘衍裺褗躽遃郾酓隒顩魇魘鰋鶠黡黤黬黭黶鼴鼹齴龑偐厌厭咽唁喭嚈嚥囐堰墕妟姲嬊嬿宴彥彦敥晏暥曕曣椻溎滟灎灔灧灩烻焔焰焱熖燄燕爓牪猒砚硯艳艶艷覎觃觾諺讌讞谚谳豓豔贋贗赝軅酀酽醶醼釅隁雁餍饜騐験騴驗驠验鬳鳫鴈鴳鷃鷰齞央姎抰殃泱眏秧胦鉠鍈雵鞅鴦鸯佯劷垟崵崸徉扬揚敭旸昜暘杨楊氜洋炀烊煬珜疡瘍眻羊羏蛘諹輰鍚钖阦阳陽霷颺飏鰑鴹鸉仰佒傟养卬咉坱岟慃懩攁柍楧氧氱瀁炴痒癢礢紻蝆軮飬養駚怏恙样様樣漾羕詇吆喓夭妖幺楆殀祅腰葽訞邀鴁鴢倄傜嗂垚堯姚媱尧尭峣嶢嶤徭愮揺搖摇摿暚榣滧烑爻猺珧瑤瑶磘窑窯窰繇肴蘨謠謡谣軺轺遙遥邎鎐顤颻飖餆餚鰩鱙鳐仸偠咬婹宎岆崾抭杳枖柼榚溔狕眑窅窈舀苭蓔闄騕鷕齩曜熎燿獟矅穾窔筄纅耀艞药葯薬藥袎要覞詏讑靿鷂鹞鼼倻吔噎擨暍椰歋潱蠮捓揶爷爺瑘耶釾鋣鎁铘也冶嘢埜壄漜野业亱僷叶墷夜嶪嶫抴捙掖擛擪擫晔曄曅曗曳曵枼枽業殗洂液澲烨煠燁爗璍皣瞱瞸礏腋葉謁谒邺鄴鍱鎑鐷靥靨頁页餣饁馌驜鵺鸈亪一乊伊依医吚咿噫壱壹夁嫛嬄弌悘揖撎檹毉洢渏漪猗瑿畩祎禕稦繄蛜衣衤譩辷郼醫銥铱鷖鹥黟黳乁仪侇儀冝匜咦圯夷姨媐宐宜宧寲峓嶬嶷巸彛彜彝彞怡恞扅拸暆杝柂栘桋椬椸沂沶洟熪狋珆瓵疑痍眙移簃籎羠胰荑萓蛦螔袘觺詒誃謻讉诒貽贻跠迻遗遺鏔頉頤頥顊颐飴饴鮧鴺乙乛以佁倚偯嬟崺已庡扆攺敼旑旖椅檥矣礒笖舣艤苡苢蚁螘蟻裿輢轙迆迤迱逘酏釔鈘鉯钇顗鳦齮乂义亄亦亿仡伇伿佚佾俋億兿刈劓劮勚勩匇呓呭呹唈嗌囈圛坄垼埶埸墿奕嫕嬑寱屹峄嶧帟帠幆廙异弈弋役忆忔怈怿悒悥意憶懌懿抑挹敡斁易晹曀曎杙枍枻栧棭榏槸檍欭歝殔殪殹毅泆浂浥浳湙溢潩澺瀷炈焲熠熤熼燚燡燱獈玴異疫痬瘗瘞瘱癔益睪瞖秇穓竩篒縊繶繹绎缢羛義羿翊翌翳翼耴肄肊膉臆艗艺芅苅萟蓺薏藙藝蘙虉蛡蜴螠衪袣裔裛褹襼訲訳詍詣誼譯議讛议译诣谊豙豛豷貖貤贀跇軼轶逸邑鄓醳醷釴鈠鎰鐿镒镱阣隿霬饐駅驛驿骮鮨鯣鶂鶃鶍鷁鷊鷧鷾鸃鹝鹢黓齸弬侌凐喑噾囙因垔堙姻婣愔慇栶殷氤洇溵濦瘖磤禋秵筃絪緸茵荫蒑蔭裀諲銦铟闉阥阴陰陻隂霒霠鞇音韾駰骃齗乑冘吟噖嚚圁垠夤婬寅峾崟崯斦檭殥泿淫滛烎犾狺珢璌碒荶蔩蟫訔訚訡誾鄞鈝銀银霪鷣齦龂龈吲尹嶾廴引朄檃檼櫽淾濥瘾癮粌蘟蚓螾讔赺趛輑鈏隐隠隱靷飮飲饮印垽堷廕慭憖憗懚洕湚猌癊窨胤茚酳鮣偀嘤噟嚶婴媖嫈嬰孆孾应応愥應撄攖朠桜樱櫻渶瀴煐珱瑛璎瓔甇甖碤礯緓纓绬缨罂罃罌膺英莺蘡蝧蠳褮譍譻賏軈鑍锳霙韺鴬鶑鶧鶯鷪鷹鸎鸚鹦鹰僌営塋嬴巆攍楹櫿溁溋滢潆濙濚濴瀅瀛瀠瀯灐灜熒營瑩盁盈禜籝籯縈茔荧莹萤营萦萾蓥藀蛍蝇蝿螢蠅覮謍贏赢迎鎣巊廮影摬梬浧潁瘿癭矨穎郢鐛頴颍颕颖媵映暎硬膡鱦哟唷喲佣傭嗈噰墉壅嫞庸廱慵拥擁滽澭灉牅痈癕癰臃邕郺鄘鏞镛雍雝饔鱅鳙鷛喁顒颙鰫俑勇勈咏埇塎嵱彮怺恿悀惥愑愹慂柡栐永泳涌湧甬硧蛹詠踊踴鯒鲬用砽苚蒏醟优優呦嚘峳幽忧怮悠憂懮攸櫌泑浟滺瀀纋羪耰逌鄾麀偤尢尤庮怞怣楢沋油游犹猶猷由甴疣秞肬莜莸蕕蚰蝣訧輏輶逰遊邮郵鈾铀駀魷鮋鱿鲉丣卣友有栯梄槱湵牖牗禉羑聈苃莠蜏酉銪铕黝亴佑佦侑又右哊唀囿姷孧宥峟幼柚櫾牰狖祐蚴誘诱貁迶酭釉鼬唹扜扝淤瘀盓穻箊紆纡込迂迃陓乻予于亐伃余俞兪堣堬妤娛娯娱媀嬩崳嵎嵛愉愚扵揄於旟杅桙楡楰榆欤歈歟歶渔渝湡漁澞牏狳玗玙瑜璵盂睮禺窬竽籅羭腴臾舁舆艅茰萮萸蕍蘛虞虶蝓螸衧褕覦觎諛謣谀踰輿轝逾邘酑鍝隃隅雓雩餘馀騟骬髃魚魣鮽鯲鰅鱼鷠鸆齵与伛俁俣偊傴匬噳圄圉宇寙屿嶼庾懙挧敔斔斞楀瑀瘐祤禹穥窳羽與萭語语貐鄅雨頨麌齬龉俼僪儥喅喩喻圫域堉妪嫗寓峪嶎庽彧御忬悆惐愈慾戫昱棛棜棫櫲欎欝欥欲毓浴淢淯滪潏澦灪焴煜燏燠爩狱獄玉琙瘉癒矞砡硢硲礇礖礜禦秗稢稶篽籞籲粖緎罭聿肀育艈芋芌茟蒮蓣蓹蕷薁蘌蜟蜮袬裕誉諭譽谕豫軉輍逳遇遹郁醧鈺銉鋊錥鐭钰閾阈雤霱預预飫饇饫馭驈驭鬰鬱鬻魊鱊鳿鴥鴧鴪鵒鷸鸒鹆鹬冤剈囦嬽寃悁惌棩淵渁渆渊渕灁眢肙葾蒬蜎蜵裷駌鳶鴛鵷鸢鸳鹓鼘鼝元円原厡厵员員园圆圎園圓垣塬媴嫄援杬榞榬橼櫞沅湲源溒爰猨猿笎緣縁缘羱芫茒蒝薗蚖蝝蝯螈袁褤謜貟贠轅辕邍邧酛鈨鎱騵魭鶢鶰黿鼋盶薳远逺遠鋺傆噮垸夗妴媛怨愿掾瑗禐苑衏裫褑院願啘曰曱矱箹約约哕噦刖妜嬳岄岳嶽恱悅悦戉抈捳月樾泧瀹爚玥礿禴篗籆籥籰粤粵蘥蚎蚏越跀跃躍軏鈅鉞鑰钥钺閱閲阅鸑鸙黦龠龥奫晕暈氲氳煴熅蒀蒕蝹贇赟馧云伝勻匀囩妘愪抣昀橒沄涢溳澐熉畇眃秐筠筼篔紜縜纭耘耺芸蒷蕓郧鄖鋆雲允喗夽抎殒殞狁磒荺賱鈗阭陨隕霣馻齫齳傊孕恽惲愠慍枟熨緼縕缊腪蕰蕴薀藴蘊褞运運郓鄆酝醖醞韗韞韫韵韻餫匝咂帀扎拶桚沞臜臢迊鉔魳囃杂沯砸襍雑雜雥韴咋哉栽渽溨災灾烖甾畠睵賳宰崽傤儎再在扗洅縡載载酨兂橵簪簮糌鐕鐟鵤偺咱喒儧儹噆寁揝撍攅攒攢昝趱趲囋暂暫濽灒瓉瓒瓚禶襸讃讚賛贊赞蹔鄼錾鏨饡匨牂羘臧賍賘贓贜赃髒駔驵塟奘弉脏臓臟葬蔵銺傮糟蹧遭醩凿鑿早枣栆棗澡璅璪薻藻蚤唕唣喿噪慥梍灶煰燥皁皂竃竈簉艁譟趮躁造则則啧啫嘖嫧帻幘択择擇樍歵沢泎泽溭滜澤皟瞔矠礋箦簀舴蔶蠌襗諎謮責賾责赜迮鸅齚齰仄崱庂捑昃昗汄戝蠈賊贼鰂鱡鲗怎譖谮増增憎橧璔矰磳繒缯罾譄鄫鱛囎熷甑贈赠鋥锃鬵偧劄哳喳抯挓揸摣柤楂樝渣皶皻紥紮觰譇齄齇札牐箚耫蚻譗鍘铡閘闸霅厏拃眨砟鮓鮺鲊鲝乍吒咤宱搾栅榨溠灹炸痄蚱詐诈醡夈捚摘斋斎榸粂齋宅檡窄鉙债債寨瘵砦噡岾嶦惉旃旜枬栴毡氈氊沾瞻薝蛅詀詹譫谵趈邅閚霑飦饘驙魙鱣鳣鸇鹯讝嫸展崭嶃嶄搌斩斬榐橏琖盏盞輾辗醆颭飐佔偡僝占嶘战戦戰栈桟棧湛站綻绽菚蘸虥虦覱譧轏驏傽嫜张張彰慞暲樟漳獐璋章粻蔁蟑遧鄣鏱餦騿鱆麞仉幥掌涨漲礃丈仗墇嶂帐帳幛扙杖涱痮瘬瘴瞕粀胀脹賬账障佋妱巶招昭皽釗鉊鍣钊駋找沼爪爫瑵兆召垗旐曌枛棹櫂炤照燳狣瞾笊箌罀罩羄肁肇肈詔诏赵趙鮡嗻嫬遮厇哲啠喆嚞埑悊折摺晢晣歽矺砓磔籷粍虴蛰蜇蟄袩詟謫謺讁讋谪輒輙轍辄辙銸鮿乽者褶襵赭踷鍺锗柘樜浙淛蔗蟅这這鷓鹧侦偵嫃寊帧帪幀搸斟桢椹楨榛樼殝浈湞溱潧澵獉珍珎瑧甄眞真砧碪祯禎禛箴籈胗臻葴蒖蓁薽貞贞轃遉酙針鉁錱鍼针鱵姫屒弫抮昣枕畛疹眕稹紾縝縥缜聄萙袗裖覙診诊軫轸辴駗鬒黰侲圳塦挋振揕朕栚甽眹紖絼纼誫賑赈鋴鎭鎮镇阵陣震鴆鸩争佂凧埩姃媜峥崝崢征徰徴徵怔掙揁炡烝爭狰猙癥眐睁睜筝箏篜糽聇脀蒸踭鉦錚鏳钲铮鬇愸抍拯掟撜整晸氶塣幁挣政正症証諍證证诤郑鄭靕鴊之倁卮吱巵憄搘支枝栀栺梔椥榰汁汥泜疷知祗祬秓稙綕織织肢胑胝脂臸芝蘵蜘衼隻馶鳷鴲鼅侄値值埴執妷姪嬂慹戠执摭植樴殖淔漐潪犆瓡直禃絷縶聀职職膱蟙跖踯蹠躑軄釞馽凪劧只咫址坁坧墌夂帋恉扺抧指旨枳止汦沚洔淽疻砋祇祉秖紙纸芷茋藢衹襧訨趾軹轵酯阯黹乿俧偫傂儨制剬劕厔垁墆娡寘峙崻帙帜幟庢庤廌彘徏徝志忮懥懫扻挃挚掷搱摨摯擲擳旘晊智柣栉桎梽櫍櫛歭治洷滍滞滯潌瀄炙熫狾猘璏瓆畤疐痓痔痣瘈礩祑秩秷稚稺穉窒筫紩緻置翐膣至致芖蛭袟袠製覟觗觯觶誌豑豒豸貭質贄质贽跱踬躓輊轾迣郅銍鋕鑕铚锧陟隲雉駤騭騺驇骘鯯鴙鷙鸷中伀刣妐幒彸忠柊汷泈炂盅籦終终舯蔠蜙螤螽衳衷蹱鈡銿鍾鐘钟锺鴤鼨冢喠塚尰徸歱煄瘇种種肿腫踵仲众偅堹妕媑狆眾祌筗茽蚛衆衶諥重侜周啁喌嚋婤州徟洲淍炿烐珘盩矪粥舟謅譸诌诪賙赒輈輖辀週郮銂霌駲騆鵃鸼妯碡軸轴帚晭疛睭箒肘菷鯞伷僽冑呪咒咮噣宙昼晝甃皱皺籀籒籕粙紂縐纣绉胄荮葤詋酎駎驟骤侏朱株槠橥櫧櫫洙潴瀦猪珠硃秼絑茱蕏藸蛛蝫蠩袾誅諸诛诸豬跦邾銖铢駯鮢鯺鴸鼄劚孎斸曯欘灟炢烛燭爥瘃窋竹竺笁笜篴舳茿蓫蠋蠾躅逐逫钃鱁丶主劯嘱囑宔帾拄渚濐煑煮燝瞩矚罜褚詝陼鸀麈乼伫佇住助坾墸壴嵀拀杼柱柷樦殶注炷疰眝砫祝祩竚筑筯箸築篫簗紵紸纻羜翥苎苧莇著蛀註貯贮跓軴迬鉒鋳鑄铸飳馵駐驻麆抓撾檛簻膼髽跩拽专叀塼嫥専專瑼甎砖磗磚膞蟤諯鄟顓颛鱄孨竱轉转僎啭囀堟撰灷瑑篆篹籑縳腞蒃襈譔賺赚転饌馔妆妝娤庄庒桩梉樁湷粧糚荘莊装裝壮壯壵撞焋状狀椎追錐锥隹騅骓鵻沝坠墜娷惴甀畷硾礈笍綴縋缀缒腏膇諈贅赘醊錣鑆啍宒窀肫衠諄谆迍准凖埻準綧稕訰倬拙捉桌梲棁棳槕涿炪焯穛穱窧鐯丵劅卓叕啄啅圴妰娺彴撯擆擢斀斫斮斱斲斵晫椓櫡汋浊浞濁濯灂灼烵犳琢琸着硺禚窡篧籗籱罬茁蠗蠿諁諑謶诼酌鋜鐲镯鵫鷟兹呲咨嗞姕姿孖孜孳孶崰嵫栥椔淄湽滋澬玆禌秶稵粢紎緇緕纃缁茊茲菑葘觜訾諮谘貲資赀资赼趑趦輜輺辎鄑鈭錙鍿鎡锱镃頾頿髭鯔鰦鲻鶅鼒齍齜龇蓻仔吇呰啙姉姊子杍梓榟橴滓矷秄秭笫籽紫耔胏茈虸訿釨倳剚字恣渍漬牸眥眦胔胾自芓茡荢嗭倧堫宗嵏嵕惾朡棕椶熧猣磫稯綜緃緵繌综翪腙葼蝬豵踨踪蹤鍐鑁騌騣骔鬃鬉鬷鯮鯼倊偬傯嵸总惣捴揔搃摠焧燪総緫縂總蓗昮猔疭瘲碂粽糉糭縦縱纵掫棷棸箃緅菆諏诹邹郰鄒鄹陬騶驺鯫鲰黀齱齺走赱鯐奏揍租菹葅蒩卆卒哫崒崪族椊箤足踤鏃镞俎唨爼珇祖組组詛诅鎺阻靻劗躜躦鉆鑚鑽钻籫繤纂纉纘缵攥厜嗺樶纗蟕嘴噿嶊璻冣嶵晬最栬槜檇檌祽稡絊罪蕞辠酔酻醉鋷錊噂墫尊嶟樽繜罇遵鐏鱒鳟鶎鷷僔撙譐捘銌嘬穝捽昨秨稓笮筰苲莋鈼佐左繓作侳做唑坐岝岞座怍柞祚糳胙葃葄蓙袏酢阼飵咗龦龧龨龩龪龫龬龭龮龯龰龱龲龳龴龵龶龷龸龹龺龻龼龽龾龿鿀鿁鿂鿃鿄鿅鿆鿇鿈鿉鿊鿋鿌鿍鿎鿏鿐"; +export const CODE_INDEX = {}; +for (let i = 0; i < codes.length; i++) { + CODE_INDEX[codes[i]] = i; +} diff --git a/packages/fineui/src/widget/collapse/collapse.js b/packages/fineui/src/widget/collapse/collapse.js new file mode 100644 index 000000000..5c7b1c5ac --- /dev/null +++ b/packages/fineui/src/widget/collapse/collapse.js @@ -0,0 +1,135 @@ +import { + VerticalLayout, + shortcut, + Widget, + map, + extend, + isFunction, + contains, + each, + isKey, + isNotEmptyArray +} from "@/core"; +import { ArrowNode } from "@/case"; +import { Expander } from "@/base"; + +@shortcut() +export class Collapse extends Widget { + static xtype = "bi.collapse"; + + static EVENT_EXPAND = "EVENT_EXPAND"; + + props = { + baseCls: "bi-collapse", + items: [], + value: [], + trigger: "click", + accordion: false, + bordered: true, + ghost: false, + isDefaultInit: false, + openMotion: { + animation: "bi-slide-up", + animationDuring: 200, + }, + }; + + render() { + const o = this.options; + + const collapseCls = o.ghost ? "" : `bi-background ${o.bordered ? "bi-border bi-border-radius" : ""}`; + + this.expanders = {}; + + return { + type: VerticalLayout.xtype, + cls: collapseCls, + items: this._getItems(this.options.items), + }; + } + + _getItems(items) { + const o = this.options; + + return map(items, (index, item) => { + const isActive = contains(this._getCurrentValue(o.value), item.value); + const cls = o.ghost || index === 0 ? "" : "bi-border-top"; + + const el = extend( + { + type: ArrowNode.xtype, + height: 30, + text: item.text, + value: item.value, + open: isActive, + }, + item.el + ); + + const popup = extend( + { + animation: o.openMotion.animation, + animationDuring: o.openMotion.animationDuring, + }, + item.popup + ); + + return extend( + { + type: Expander.xtype, + cls, + isDefaultInit: o.isDefaultInit, + trigger: o.trigger, + listeners: [ + { + eventName: Expander.EVENT_EXPAND, + action: () => { + this._hideOtherExpander(item.value); + this.fireEvent(Collapse.EVENT_EXPAND, item.value); + }, + } + ], + }, + item, + { + el, + popup, + ref: _ref => { + isFunction(item.ref) && item.ref(_ref); + this.expanders[item.value] = _ref; + }, + } + ); + }); + } + + _hideOtherExpander(expandKey) { + if (this.options.accordion) { + each(this.expanders, (key, expander) => { + key !== `${expandKey}` && expander.hideView(); + }); + } + } + + _getCurrentValue(v) { + const values = isNotEmptyArray(v) ? v : isKey(v) ? [v] : []; + + return this.options.accordion ? values.slice(0, 1) : values; + } + + getValue() { + const value = []; + each(this.expanders, (key, expander) => { + expander.isExpanded() && value.push(key); + }); + + return value; + } + + setValue(v) { + const values = map(this._getCurrentValue(v), (idx, value) => `${value}`); + each(this.expanders, (key, expander) => { + contains(values, key) ? expander.showView() : expander.hideView(); + }); + } +} diff --git a/packages/fineui/src/widget/date/calendar/combo.month.date.js b/packages/fineui/src/widget/date/calendar/combo.month.date.js new file mode 100644 index 000000000..cb01f09d2 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/combo.month.date.js @@ -0,0 +1,84 @@ +import { DateTriangleTrigger } from "./trigger.triangle.date"; +import { MonthPopup } from "./popup.month"; +import { Combo, Trigger } from "@/base"; +import { VerticalLayout, shortcut, extend, createWidget } from "@/core"; + +/** + * 日期控件中的月份下拉框 + * + * Created by GUY on 2015/9/7. + * @class MonthDateCombo + * @extends Trigger + */ +@shortcut() +export class MonthDateCombo extends Trigger { + static xtype = "bi.month_date_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-month-combo", + height: 24, + container: null, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.trigger = createWidget({ + type: DateTriangleTrigger.xtype, + }); + + this.popup = createWidget({ + type: MonthPopup.xtype, + allowMonths: o.allowMonths, + behaviors: o.behaviors, + }); + + this.popup.on(MonthPopup.EVENT_CHANGE, () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(MonthDateCombo.EVENT_CHANGE); + }); + + this.combo = createWidget({ + type: Combo.xtype, + offsetStyle: "center", + container: o.container, + element: this, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + el: this.trigger, + popup: { + minWidth: 100, + stopPropagation: false, + el: { + type: VerticalLayout.xtype, + hgap: 6, + vgap: 5, + items: [this.popup], + }, + }, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.doBehavior(); + }); + } + + populate() { + this.popup.populate(...arguments); + } + + setValue(v) { + this.trigger.setValue(v); + this.popup.setValue(v); + } + + getValue() { + return this.popup.getValue(); + } +} diff --git a/packages/fineui/src/widget/date/calendar/combo.year.date.js b/packages/fineui/src/widget/date/calendar/combo.year.date.js new file mode 100644 index 000000000..5cd38b3b8 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/combo.year.date.js @@ -0,0 +1,93 @@ +import { DateTriangleTrigger } from "./trigger.triangle.date"; +import { YearPopup } from "./popup.year"; +import { Combo, Trigger } from "@/base"; +import { shortcut, extend, createWidget } from "@/core"; + +/** + * 年份下拉框 + * + * Created by GUY on 2015/9/7. + * @class YearDateCombo + * @extends Trigger + */ +@shortcut() +export class YearDateCombo extends Trigger { + static xtype = "bi.year_date_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-year-combo", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + behaviors: {}, + height: 24, + container: null, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.trigger = createWidget({ + type: DateTriangleTrigger.xtype, + }); + + this.popup = createWidget({ + type: YearPopup.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + width: 122, + }); + + this.popup.on(YearPopup.EVENT_CHANGE, () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(YearDateCombo.EVENT_CHANGE); + }); + + this.combo = createWidget({ + type: Combo.xtype, + offsetStyle: "center", + element: this, + container: o.container, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + el: this.trigger, + popup: { + minWidth: 100, + stopPropagation: false, + el: this.popup, + }, + }); + this.combo.on(Combo.EVENT_CHANGE, () => { + this.fireEvent(YearDateCombo.EVENT_CHANGE); + }); + // BI-22551 popup未初始化传入的behavior无效 + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.doBehavior(); + this.fireEvent(YearDateCombo.EVENT_BEFORE_POPUPVIEW); + }); + } + + setMinDate(minDate) { + this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + this.popup.setMaxDate(maxDate); + } + + setValue(v) { + this.trigger.setValue(v); + this.popup.setValue(v); + } + + getValue() { + return this.popup.getValue(); + } +} diff --git a/packages/fineui/src/widget/date/calendar/index.js b/packages/fineui/src/widget/date/calendar/index.js new file mode 100644 index 000000000..26a397d24 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/index.js @@ -0,0 +1,8 @@ +export { MonthDateCombo } from "./combo.month.date"; +export { YearDateCombo } from "./combo.year.date"; +export { DatePicker } from "./picker.date"; +export { YearPicker } from "./picker.year"; +export { DateCalendarPopup } from "./popup.calendar.date"; +export { MonthPopup } from "./popup.month"; +export { YearPopup } from "./popup.year"; +export { DateTriangleTrigger } from "./trigger.triangle.date"; diff --git a/packages/fineui/src/widget/date/calendar/picker.date.js b/packages/fineui/src/widget/date/calendar/picker.date.js new file mode 100644 index 000000000..c0cdc54d4 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/picker.date.js @@ -0,0 +1,246 @@ +import { IconButton } from "@/base"; +import { YearDateCombo } from "./combo.year.date"; +import { MonthDateCombo } from "./combo.month.date"; +import { + HTapeLayout, + CenterAdaptLayout, + shortcut, + Widget, + extend, + createWidget, + contains, + isNull, + getDate, + filter, + range, + checkDateVoid, + parseDateTime, + parseInt, + print +} from "@/core"; + +/** + * Created by GUY on 2015/9/7. + * @class DatePicker + * @extends Widget + */ +@shortcut() +export class DatePicker extends Widget { + static xtype = "bi.date_picker"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-date-picker", + height: 40, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this._year = getDate().getFullYear(); + this._month = getDate().getMonth() + 1; + this.left = createWidget({ + type: IconButton.xtype, + cls: "pre-page-h-font", + width: 24, + height: 24, + }); + this.left.on(IconButton.EVENT_CHANGE, () => { + if (this._month === 1) { + this.setValue({ + year: this.year.getValue() - 1 || getDate().getFullYear() - 1, + month: 12, + }); + } else { + this.setValue({ + year: this.year.getValue() || getDate().getFullYear(), + month: this.month.getValue() - 1 || getDate().getMonth(), + }); + } + this.fireEvent(DatePicker.EVENT_CHANGE); + // this._checkLeftValid(); + // this._checkRightValid(); + }); + + this.right = createWidget({ + type: IconButton.xtype, + cls: "next-page-h-font", + width: 24, + height: 24, + }); + + this.right.on(IconButton.EVENT_CHANGE, () => { + if (this._month === 12) { + this.setValue({ + year: this.year.getValue() + 1 || getDate().getFullYear() + 1, + month: 1, + }); + } else { + this.setValue({ + year: this.year.getValue() || getDate().getFullYear(), + month: this.month.getValue() + 1 || getDate().getMonth() + 2, + }); + } + this.fireEvent(DatePicker.EVENT_CHANGE); + // this._checkLeftValid(); + // this._checkRightValid(); + }); + + this.year = createWidget({ + type: YearDateCombo.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + }); + this.year.on(YearDateCombo.EVENT_CHANGE, () => { + this.setValue({ + year: this.year.getValue(), + month: this._refreshMonth(), + }); + this.fireEvent(DatePicker.EVENT_CHANGE); + }); + this.year.on(YearDateCombo.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }); + this.month = createWidget({ + type: MonthDateCombo.xtype, + behaviors: o.behaviors, + allowMonths: this._getAllowMonths(), + }); + this.month.on(MonthDateCombo.EVENT_CHANGE, () => { + this.setValue({ + year: this.year.getValue() || this._year, + month: this.month.getValue(), + }); + this.fireEvent(DatePicker.EVENT_CHANGE); + }); + this.month.on(YearDateCombo.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }); + + createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.left], + }, + width: 24, + }, + { + el: { + type: CenterAdaptLayout.xtype, + hgap: 10, + items: [this.year, this.month], + }, + }, + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.right], + }, + width: 24, + } + ], + }); + this.setValue({ + year: this._year, + month: this._month, + }); + } + + _refreshMonth(defaultMonth) { + let month = this.month.getValue(); + this.month.populate(this._getAllowMonths()); + const allowMonth = this._getAllowMonths(); + if (!contains(allowMonth, month)) { + month = defaultMonth || allowMonth[0]; + } + this.month.setValue(month); + + return month; + } + + _getAllowMonths() { + const obj = this._getCheckMinMaxDate(); + const year = this.year.getValue() || this._year; + + return filter(range(1, 13), (idx, v) => !checkDateVoid(year, v, 1, obj.min, obj.max)[0]); + } + + _checkLeftValid() { + const obj = this._getCheckMinMaxDate(); + const year = this._month === 1 ? this._year - 1 : this._year; + const month = this._month === 1 ? 12 : this._month - 1; + const valid = isNull(checkDateVoid(year, month, 1, obj.min, obj.max)[0]); + this.left.setEnable(valid); + + return valid; + } + + _checkRightValid() { + const obj = this._getCheckMinMaxDate(); + const year = this._month === 12 ? this._year + 1 : this._year; + const month = this._month === 12 ? 1 : this._month + 1; + const valid = isNull(checkDateVoid(year, month, 1, obj.min, obj.max)[0]); + this.right.setEnable(valid); + + return valid; + } + + _getCheckMinMaxDate() { + const o = this.options; + const minDate = parseDateTime(o.min, "%Y-%X-%d"); + const maxDate = parseDateTime(o.max, "%Y-%X-%d"); + minDate.setDate(1); + maxDate.setDate(1); + + return { + min: print(minDate, "%Y-%X-%d"), + max: print(maxDate, "%Y-%X-%d"), + }; + } + + setMinDate(minDate) { + this.options.min = minDate; + this.year.setMinDate(minDate); + this._refreshMonth(this._month); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + setMaxDate(maxDate) { + this.options.max = maxDate; + this.year.setMaxDate(maxDate); + this._refreshMonth(this._month); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + setValue(ob) { + this._year = parseInt(ob.year); + this._month = parseInt(ob.month); + this.year.setValue(ob.year); + this._refreshMonth(this._month); + this.month.setValue(ob.month); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + getValue() { + return { + year: this.year.getValue(), + month: this.month.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/date/calendar/picker.year.js b/packages/fineui/src/widget/date/calendar/picker.year.js new file mode 100644 index 000000000..06bb277d9 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/picker.year.js @@ -0,0 +1,141 @@ +import { YearDateCombo } from "./combo.year.date"; +import { HTapeLayout, CenterAdaptLayout, shortcut, Widget, extend, createWidget, getDate, parseDateTime } from "@/core"; +import { IconButton } from "@/base"; + +@shortcut() +export class YearPicker extends Widget { + static xtype = "bi.year_picker"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-year-picker", + behaviors: {}, + height: 40, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this._year = getDate().getFullYear(); + this.left = createWidget({ + type: IconButton.xtype, + cls: "pre-page-h-font", + width: 25, + height: 25, + }); + this.left.on(IconButton.EVENT_CHANGE, () => { + this.setValue(this.year.getValue() - 1); + this.fireEvent(YearPicker.EVENT_CHANGE); + // this._checkLeftValid(); + // this._checkRightValid(); + }); + + this.right = createWidget({ + type: IconButton.xtype, + cls: "next-page-h-font", + width: 25, + height: 25, + }); + + this.right.on(IconButton.EVENT_CHANGE, () => { + this.setValue(this.year.getValue() + 1); + this.fireEvent(YearPicker.EVENT_CHANGE); + // this._checkLeftValid(); + // this._checkRightValid(); + }); + + this.year = createWidget({ + type: YearDateCombo.xtype, + min: o.min, + behaviors: o.behaviors, + max: o.max, + width: 50, + }); + this.year.on(YearDateCombo.EVENT_CHANGE, () => { + this.setValue(this.year.getValue()); + this.fireEvent(YearPicker.EVENT_CHANGE); + }); + this.year.on(YearDateCombo.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(YearPicker.EVENT_BEFORE_POPUPVIEW); + }); + + createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.left], + }, + width: 25, + }, + { + type: CenterAdaptLayout.xtype, + items: [ + { + el: this.year, + } + ], + }, + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.right], + }, + width: 25, + } + ], + }); + this.setValue(this._year); + } + + _checkLeftValid() { + const o = this.options; + const valid = this._year > parseDateTime(o.min, "%Y-%X-%d").getFullYear(); + this.left.setEnable(valid); + + return valid; + } + + _checkRightValid() { + const o = this.options; + const valid = this._year < parseDateTime(o.max, "%Y-%X-%d").getFullYear(); + this.right.setEnable(valid); + + return valid; + } + + setMinDate(minDate) { + this.options.min = minDate; + this.year.setMinDate(minDate); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + setMaxDate(maxDate) { + this.options.max = maxDate; + this.year.setMaxDate(maxDate); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + setValue(v) { + this._year = v; + this.year.setValue(v); + // this._checkLeftValid(); + // this._checkRightValid(); + } + + getValue() { + return this.year.getValue(); + } +} diff --git a/packages/fineui/src/widget/date/calendar/popup.calendar.date.js b/packages/fineui/src/widget/date/calendar/popup.calendar.date.js new file mode 100644 index 000000000..df5d81a43 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/popup.calendar.date.js @@ -0,0 +1,174 @@ +import { Calendar } from "@/case"; +import { DatePicker } from "./picker.date"; +import { Navigation } from "@/base"; +import { + VerticalLayout, + AbsoluteLayout, + Layout, + shortcut, + Widget, + createWidget, + bind, + getDate, + each, + isNotEmptyString +} from "@/core"; + +/** + * Created by GUY on 2015/9/7. + * @class DateCalendarPopup + * @extends Widget + */ +@shortcut() +export class DateCalendarPopup extends Widget { + static xtype = "bi.date_calendar_popup"; + + props = { + baseCls: "bi-date-calendar-popup", + min: "1900-01-01", + max: "2099-12-31", + selectedTime: null, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _createNav(v) { + const date = Calendar.getDateJSONByPage(v); + const calendar = createWidget({ + type: Calendar.xtype, + logic: { + dynamic: true, + }, + min: this.options.min, + max: this.options.max, + year: date.year, + month: date.month, + // BI-45616 此处为确定当前应该展示哪个年月对应的Calendar, day不是关键数据, 给1号就可 + day: 1, + }); + + return calendar; + } + + render() { + const o = this.options; + this.today = getDate(); + this._year = this.today.getFullYear(); + this._month = this.today.getMonth() + 1; + this._day = this.today.getDate(); + + this.selectedTime = o.selectedTime || { + year: this._year, + month: this._month, + day: this._day, + }; + this.datePicker = createWidget({ + type: DatePicker.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + }); + + this.calendar = createWidget({ + direction: "top", + logic: { + dynamic: true, + }, + type: Navigation.xtype, + tab: this.datePicker, + cardCreator: bind(this._createNav, this), + + afterCardCreated() {}, + + afterCardShow: () => { + this.calendar.setValue(this.selectedTime); + }, + }); + + this.datePicker.on(DatePicker.EVENT_CHANGE, () => { + this.selectedTime = this.datePicker.getValue(); + this.selectedTime.day = 1; + this.calendar.setSelect(Calendar.getPageByDateJSON(this.selectedTime)); + }); + + this.datePicker.on(DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, () => { + this.fireEvent(DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }); + + this.calendar.on(Navigation.EVENT_CHANGE, () => { + this.selectedTime = this.calendar.getValue(); + this.setValue(this.selectedTime); + this.fireEvent(DateCalendarPopup.EVENT_CHANGE); + }); + + return [ + { + type: VerticalLayout.xtype, + items: [ + { + el: this.calendar, + hgap: 12, + bgap: 7, + } + ], + }, + { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "bi-split-top", + }, + height: 1, + top: 40, + left: 0, + right: 0, + } + ], + } + ]; + } + + _checkMin() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMinDate(o.min); + }); + } + + _checkMax() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMaxDate(o.max); + }); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + this.datePicker.setMinDate(minDate); + this._checkMin(); + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + this.datePicker.setMaxDate(maxDate); + this._checkMax(); + } + } + + setValue(timeOb) { + this.datePicker.setValue(timeOb); + this.calendar.setSelect(Calendar.getPageByDateJSON(timeOb)); + this.calendar.setValue(timeOb); + this.selectedTime = timeOb; + } + + getValue() { + return this.selectedTime; + } +} diff --git a/packages/fineui/src/widget/date/calendar/popup.month.js b/packages/fineui/src/widget/date/calendar/popup.month.js new file mode 100644 index 000000000..9a989ecdd --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/popup.month.js @@ -0,0 +1,130 @@ +import { ButtonGroup, TextItem } from "@/base"; +import { + CenterAdaptLayout, + shortcut, + Widget, + extend, + Controller, + createWidget, + Events, + createItems, + toPix, + map, + contains, + getDate, + LogicFactory, + parseInt, + SIZE_CONSANTS +} from "@/core"; + +/** + * 月份展示面板 + * + * Created by GUY on 2015/9/2. + * @class MonthPopup + * @extends Widget + */ +@shortcut() +export class MonthPopup extends Widget { + static xtype = "bi.month_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-month-popup", + behaviors: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.selectedMonth = getDate().getMonth() + 1; + + this.month = createWidget({ + type: ButtonGroup.xtype, + element: this, + behaviors: o.behaviors, + items: createItems(this._getItems(o.allowMonths), {}), + layouts: [ + LogicFactory.createLogic( + "table", + extend( + { + dynamic: true, + }, + { + columns: 2, + rows: 6, + columnSize: [1 / 2, 1 / 2], + rowSize: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + } + ) + ), + { + type: CenterAdaptLayout.xtype, + vgap: 2, + } + ], + value: o.value, + }); + + this.month.on(Controller.EVENT_CHANGE, (...args) => { + const [type, value] = args; + this.selectedMonth = value; + this.fireEvent(Controller.EVENT_CHANGE, ...args); + if (type === Events.CLICK) { + this.fireEvent(MonthPopup.EVENT_CHANGE); + } + }); + } + + _getItems(m) { + Widget.pushContext(this); + // 纵向排列月 + const month = [1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12]; + let items = []; + items.push(month.slice(0, 2)); + items.push(month.slice(2, 4)); + items.push(month.slice(4, 6)); + items.push(month.slice(6, 8)); + items.push(month.slice(8, 10)); + items.push(month.slice(10, 12)); + items = map(items, (i, item) => + map(item, (j, td) => { + return { + type: TextItem.xtype, + cls: "bi-border-radius bi-list-item-select", + textAlign: "center", + whiteSpace: "nowrap", + once: false, + forceSelected: true, + height: toPix(SIZE_CONSANTS.LIST_ITEM_HEIGHT, 1), + width: 30, + value: td, + text: td, + disabled: !contains(m, td), + }; + }) + ); + Widget.popContext(); + + return items; + } + + populate(months) { + this.month.populate(this._getItems(months)); + } + + getValue() { + return this.selectedMonth; + } + + setValue(v) { + v = parseInt(v); + this.selectedMonth = v; + this.month.setValue([v]); + } +} diff --git a/packages/fineui/src/widget/date/calendar/popup.year.js b/packages/fineui/src/widget/date/calendar/popup.year.js new file mode 100644 index 000000000..a835bfb7d --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/popup.year.js @@ -0,0 +1,155 @@ +import { YearCalendar } from "@/case"; +import { IconButton, Navigation } from "@/base"; +import { + shortcut, + Widget, + extend, + createWidget, + isKey, + Controller, + bind, + isNotNull, + isNotEmptyString, + getDate, + parseInt +} from "@/core"; + +/** + * 年份展示面板 + * + * Created by GUY on 2015/9/2. + * @class YearPopup + * @extends Widget + */ +@shortcut() +export class YearPopup extends Widget { + static xtype = "bi.year_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-year-popup", + behaviors: {}, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + }); + } + + _createYearCalendar(v) { + const o = this.options, + y = this._year; + + const calendar = createWidget({ + type: YearCalendar.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + logic: { + dynamic: true, + }, + year: y + v * 12, + }); + calendar.setValue(this._year); + + return calendar; + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.selectedYear = this._year = getDate().getFullYear(); + + this.backBtn = createWidget({ + type: IconButton.xtype, + cls: "pre-page-h-font", + width: 24, + height: 24, + value: -1, + }); + + this.preBtn = createWidget({ + type: IconButton.xtype, + cls: "next-page-h-font", + width: 24, + height: 24, + value: 1, + }); + + this.navigation = createWidget({ + type: Navigation.xtype, + element: this, + single: true, + logic: { + dynamic: true, + }, + tab: { + cls: "year-popup-navigation bi-high-light bi-split-top", + height: 24, + items: [this.backBtn, this.preBtn], + }, + cardCreator: bind(this._createYearCalendar, this), + afterCardCreated: () => { + this.navigation.setValue(this.selectedYear); + }, + }); + + this.navigation.on(Navigation.EVENT_CHANGE, (...args) => { + this.selectedYear = this.navigation.getValue(); + this.fireEvent(Controller.EVENT_CHANGE, ...args); + this.fireEvent(YearPopup.EVENT_CHANGE, this.selectedYear); + }); + + if (isKey(o.value)) { + this.setValue(o.value); + } + } + + _checkMin() { + const calendar = this.navigation.getSelectedCard(); + if (isNotNull(calendar)) { + calendar.setMinDate(this.options.min); + } + } + + _checkMax() { + const calendar = this.navigation.getSelectedCard(); + if (isNotNull(calendar)) { + calendar.setMaxDate(this.options.max); + } + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + this._checkMin(); + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + this._checkMax(); + } + } + + getValue() { + return this.selectedYear; + } + + setValue(v) { + v = parseInt(v); + // 切换年不受范围限制 + // 对于年控件来说,只要传入的minDate和maxDate的year区间包含v就是合法的 + // var startDate = parseDateTime(o.min, "%Y-%X-%d"); + // var endDate = parseDateTime(o.max, "%Y-%X-%d"); + // if (checkDateVoid(v, 1, 1, print(getDate(startDate.getFullYear(), 0, 1), "%Y-%X-%d"), print(getDate(endDate.getFullYear(), 0, 1), "%Y-%X-%d"))[0]) { + // v = getDate().getFullYear(); + // } + + this.selectedYear = v; + this.navigation.setSelect(YearCalendar.getPageByYear(v)); + this.navigation.setValue(v); + } +} diff --git a/packages/fineui/src/widget/date/calendar/trigger.triangle.date.js b/packages/fineui/src/widget/date/calendar/trigger.triangle.date.js new file mode 100644 index 000000000..d1b013618 --- /dev/null +++ b/packages/fineui/src/widget/date/calendar/trigger.triangle.date.js @@ -0,0 +1,74 @@ +import { Label, IconLabel, Trigger } from "@/base"; +import { VerticalAdaptLayout, shortcut, extend, createWidget } from "@/core"; + +/** + * 日期控件中的年份或月份trigger + * + * Created by GUY on 2015/9/7. + * @class DateTriangleTrigger + * @extends Trigger + */ +@shortcut() +export class DateTriangleTrigger extends Trigger { + static xtype = "bi.date_triangle_trigger"; + + _const = { + height: 24, + iconWidth: 12, + iconHeight: 12, + }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-date-triangle-trigger solid-triangle-bottom-font cursor-pointer", + height: 24, + }); + } + + _init() { + super._init(...arguments); + const o = this.options, + c = this._const; + this.text = createWidget({ + type: Label.xtype, + cls: "list-item-text", + textAlign: "right", + text: o.text, + value: o.value, + height: c.height, + }); + + createWidget({ + type: VerticalAdaptLayout.xtype, + element: this, + items: [ + { + el: this.text, + rgap: 5, + }, + { + type: IconLabel.xtype, + width: 16, + } + ], + }); + } + + setValue(v) { + this.text.setValue(v); + } + + getValue() { + return this.text.getValue(); + } + + setText(v) { + this.text.setText(v); + } + + getText() { + return this.item.getText(); + } + + getKey() {} +} diff --git a/packages/fineui/src/widget/date/index.js b/packages/fineui/src/widget/date/index.js new file mode 100644 index 000000000..9b964cb02 --- /dev/null +++ b/packages/fineui/src/widget/date/index.js @@ -0,0 +1 @@ +export * from "./calendar"; \ No newline at end of file diff --git a/src/widget/datepane/__test__/datepane.test.js b/packages/fineui/src/widget/datepane/__test__/datepane.test.js similarity index 100% rename from src/widget/datepane/__test__/datepane.test.js rename to packages/fineui/src/widget/datepane/__test__/datepane.test.js diff --git a/packages/fineui/src/widget/datepane/card.static.datepane.js b/packages/fineui/src/widget/datepane/card.static.datepane.js new file mode 100644 index 000000000..44c506080 --- /dev/null +++ b/packages/fineui/src/widget/datepane/card.static.datepane.js @@ -0,0 +1,211 @@ +import { DatePicker, DateCalendarPopup } from "../date/calendar"; +import { Navigation } from "@/base"; +import { + VTapeLayout, + AbsoluteLayout, + Layout, + shortcut, + Widget, + extend, + createWidget, + bind, + isNull, + each, + isNotEmptyString, + getDate, + getMonthDays +} from "@/core"; +import { Calendar } from "@/case"; + +@shortcut() +export class StaticDatePaneCard extends Widget { + static xtype = "bi.static_date_pane_card"; + + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-date-pane", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + selectedTime: null, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.today = getDate(); + this._year = this.today.getFullYear(); + this._month = this.today.getMonth() + 1; + + this.selectedTime = o.selectedTime || { + year: this._year, + month: this._month, + }; + + this.datePicker = createWidget({ + type: DatePicker.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + }); + this.datePicker.on(DatePicker.EVENT_CHANGE, () => { + const value = this.datePicker.getValue(); + const monthDay = getMonthDays(getDate(value.year, value.month - 1, 1)); + let day = this.selectedTime.day || 0; + if (day > monthDay) { + day = monthDay; + } + this.selectedTime = { + year: value.year, + month: value.month, + }; + day !== 0 && (this.selectedTime.day = day); + this.calendar.setSelect(Calendar.getPageByDateJSON(this.selectedTime)); + this.calendar.setValue(this.selectedTime); + day !== 0 && this.fireEvent(DateCalendarPopup.EVENT_CHANGE); + }); + this.datePicker.on(DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, () => { + this.fireEvent(StaticDatePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }); + + this.calendar = createWidget({ + direction: "custom", + // logic: { + // dynamic: false + // }, + type: Navigation.xtype, + tab: this.datePicker, + cardCreator: bind(this._createNav, this), + }); + this.calendar.on(Navigation.EVENT_CHANGE, () => { + this.selectedTime = this.calendar.getValue(); + this.calendar.empty(); + this.setValue(this.selectedTime); + this.fireEvent(DateCalendarPopup.EVENT_CHANGE); + }); + this.setValue(o.selectedTime); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + el: this.datePicker, + height: 40, + }, + this.calendar + ], + hgap: 10, + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Layout.xtype, + cls: "bi-split-top", + }, + height: 1, + top: 40, + left: 0, + right: 0, + } + ], + }); + } + + _createNav(v) { + const date = Calendar.getDateJSONByPage(v); + const calendar = createWidget({ + type: Calendar.xtype, + logic: { + dynamic: false, + }, + min: this.options.min, + max: this.options.max, + year: date.year, + month: date.month, + day: this.selectedTime.day, + }); + + return calendar; + } + + _getNewCurrentDate() { + const today = getDate(); + + return { + year: today.getFullYear(), + month: today.getMonth() + 1, + }; + } + + _setCalenderValue(date) { + this.calendar.setSelect(Calendar.getPageByDateJSON(date)); + this.calendar.setValue(date); + this.selectedTime = date; + } + + _setDatePicker(timeOb) { + if (isNull(timeOb) || isNull(timeOb.year) || isNull(timeOb.month)) { + this.datePicker.setValue(this._getNewCurrentDate()); + } else { + this.datePicker.setValue(timeOb); + } + } + + _setCalendar(timeOb) { + if (isNull(timeOb) || isNull(timeOb.day)) { + this.calendar.empty(); + this._setCalenderValue(this._getNewCurrentDate()); + } else { + this._setCalenderValue(timeOb); + } + } + + _checkMin() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMinDate(o.min); + }); + } + + _checkMax() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMaxDate(o.max); + }); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + this.datePicker.setMinDate(minDate); + this._checkMin(); + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + this.datePicker.setMaxDate(maxDate); + this._checkMax(); + } + } + + setValue(timeOb) { + this._setDatePicker(timeOb); + this._setCalendar(timeOb); + } + + getValue() { + return this.selectedTime; + } +} diff --git a/packages/fineui/src/widget/datepane/datepane.js b/packages/fineui/src/widget/datepane/datepane.js new file mode 100644 index 000000000..a408c3287 --- /dev/null +++ b/packages/fineui/src/widget/datepane/datepane.js @@ -0,0 +1,262 @@ +import { + VTapeLayout, + CenterLayout, + shortcut, + Widget, + createItems, + i18nText, + isEmptyObject, + isNull, + isEmptyString, + isNotEmptyObject, + getDate +} from "@/core"; +import { LinearSegment } from "@/case"; +import { Tab, TextButton, ButtonGroup } from "@/base"; +import { StaticDatePaneCard } from "./card.static.datepane"; +import { DynamicDateCard, DynamicDateHelper, DynamicDateCombo, DynamicDatePopup } from "../dynamicdate"; + +@shortcut() +export class DynamicDatePane extends Widget { + static xtype = "bi.dynamic_date_pane"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + static Static = 1; + static Dynamic = 2; + + props = { + baseCls: "bi-dynamic-date-pane", + minDate: "1900-01-01", + maxDate: "2099-12-31", + supportDynamic: true, + }; + + render() { + const o = this.options; + + return { + type: VTapeLayout.xtype, + items: [ + { + el: { + type: LinearSegment.xtype, + invisible: !o.supportDynamic, + cls: "bi-split-bottom", + height: 30, + items: createItems( + [ + { + text: i18nText("BI-Multi_Date_YMD"), + value: DynamicDatePane.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicDatePane.Dynamic, + } + ], + { + textAlign: "center", + } + ), + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: () => { + let date; + const value = this.switcher.getValue()[0]; + this.dateTab.setSelect(value); + switch (value) { + case DynamicDatePane.Static: + date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + break; + case DynamicDatePane.Dynamic: + this.dynamicPane.setValue({ + year: 0, + }); + break; + default: + break; + } + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.switcher = _ref; + }, + }, + height: o.supportDynamic ? 30 : 0, + }, + { + type: Tab.xtype, + ref: _ref => { + this.dateTab = _ref; + }, + showIndex: DynamicDatePane.Static, + cardCreator: v => { + switch (v) { + case DynamicDatePane.Static: + return { + type: StaticDatePaneCard.xtype, + min: o.minDate, + max: o.maxDate, + behaviors: o.behaviors, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + }, + }, + { + eventName: "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW", + action: () => { + this.fireEvent(DynamicDatePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + } + ], + ref: _ref => { + this.ymd = _ref; + }, + }; + case DynamicDatePane.Dynamic: + default: + return { + type: VTapeLayout.xtype, + items: [ + { + type: DynamicDateCard.xtype, + min: o.minDate, + max: o.maxDate, + ref: _ref => { + this.dynamicPane = _ref; + }, + }, + { + el: { + type: CenterLayout.xtype, + items: [ + { + type: TextButton.xtype, + cls: "bi-high-light bi-border-top", + shadow: true, + text: i18nText("BI-Basic_Clear"), + textHeight: 23, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.setValue(); + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-border-left bi-high-light bi-border-top", + textHeight: 23, + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent( + DynamicDatePopup.EVENT_CHANGE + ); + } else { + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + } + }, + } + ], + } + ], + }, + height: 24, + } + ], + }; + } + }, + } + ], + }; + } + + created() { + this.setValue(this.options.value); + } + + _checkValueValid(value) { + return isNull(value) || isEmptyObject(value) || isEmptyString(value); + } + + _checkValue(v) { + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: + default: + return true; + } + } + + setMinDate(minDate) { + if (this.options.minDate !== minDate) { + this.options.minDate = minDate; + this.ymd.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.maxDate !== maxDate) { + this.options.maxDate = maxDate; + this.ymd.setMaxDate(maxDate); + } + } + + setValue(v) { + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + this.switcher.setValue(type); + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + break; + case DynamicDateCombo.Static: + default: + if (this._checkValueValid(value)) { + const date = getDate(); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + }); + } else { + this.ymd.setValue(value); + } + break; + } + } + + getValue() { + const type = this.dateTab.getSelect(); + + return { + type, + value: type === DynamicDatePane.Static ? this.dateTab.getValue() : this.dynamicPane.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/datepane/index.js b/packages/fineui/src/widget/datepane/index.js new file mode 100644 index 000000000..240c9dd1a --- /dev/null +++ b/packages/fineui/src/widget/datepane/index.js @@ -0,0 +1,2 @@ +export { StaticDatePaneCard } from "./card.static.datepane"; +export { DynamicDatePane } from "./datepane"; diff --git a/src/widget/datetime/__test__/datetime.test.js b/packages/fineui/src/widget/datetime/__test__/datetime.test.js similarity index 100% rename from src/widget/datetime/__test__/datetime.test.js rename to packages/fineui/src/widget/datetime/__test__/datetime.test.js diff --git a/packages/fineui/src/widget/datetime/datetime.combo.js b/packages/fineui/src/widget/datetime/datetime.combo.js new file mode 100644 index 000000000..f332a31ac --- /dev/null +++ b/packages/fineui/src/widget/datetime/datetime.combo.js @@ -0,0 +1,135 @@ +import { DateTimeTrigger } from "./datetime.trigger"; +import { DateTimePopup } from "./datetime.popup"; +import { Combo, IconButton, Single } from "@/base"; +import { HTapeLayout, shortcut, extend, getDate, isNotNull, createWidget } from "@/core"; + +@shortcut() +export class DateTimeCombo extends Single { + static xtype = "bi.date_time_combo"; + + constants = { + popupHeight: 290, + popupWidth: 270, + comboAdjustHeight: 1, + border: 1, + iconWidth: 24, + }; + + static EVENT_CANCEL = "EVENT_CANCEL"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig(conf) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-date-time-combo bi-focus-shadow ${ + conf.simple ? "bi-border-bottom" : "bi-border bi-border-radius" + }`, + width: 200, + height: 24, + minDate: "1900-01-01", + maxDate: "2099-12-31", + }); + } + + _init() { + super._init(...arguments); + const opts = this.options; + const date = getDate(); + this.storeValue = isNotNull(opts.value) + ? opts.value + : { + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + }; + this.trigger = createWidget({ + type: DateTimeTrigger.xtype, + height: opts.height, + min: opts.minDate, + max: opts.maxDate, + value: opts.value, + }); + + this.popup = createWidget({ + type: DateTimePopup.xtype, + behaviors: opts.behaviors, + min: opts.minDate, + max: opts.maxDate, + value: opts.value, + }); + this.setValue(this.storeValue); + + this.popup.on(DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE, () => { + this.setValue(this.storeValue); + this.hidePopupView(); + this.fireEvent(DateTimeCombo.EVENT_CANCEL); + }); + this.popup.on(DateTimePopup.BUTTON_OK_EVENT_CHANGE, () => { + this.storeValue = this.popup.getValue(); + this.setValue(this.storeValue); + this.hidePopupView(); + this.fireEvent(DateTimeCombo.EVENT_CONFIRM); + }); + this.combo = createWidget({ + type: Combo.xtype, + container: opts.container, + toggle: false, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + el: this.trigger, + adjustLength: this.constants.comboAdjustHeight, + popup: { + el: this.popup, + width: this.constants.popupWidth, + stopPropagation: false, + }, + // DEC-4250 和复选下拉一样,点击不收起 + hideChecker(e) { + return triggerBtn.element.find(e.target).length === 0; + }, + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.popup.setValue(this.storeValue); + this.fireEvent(DateTimeCombo.EVENT_BEFORE_POPUPVIEW); + }); + + const triggerBtn = createWidget({ + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-font", + width: this.constants.iconWidth, + height: opts.height, + }); + triggerBtn.on(IconButton.EVENT_CHANGE, () => { + if (this.combo.isViewVisible()) { + // this.combo.hideView(); + } else { + this.combo.showView(); + } + }); + + createWidget({ + type: HTapeLayout.xtype, + columnSize: ["", this.constants.iconWidth], + element: this, + items: [this.combo, triggerBtn], + }); + } + + setValue(v) { + this.storeValue = v; + this.popup.setValue(v); + this.trigger.setValue(v); + } + + getValue() { + return this.storeValue; + } + + hidePopupView() { + this.combo.hideView(); + } +} diff --git a/packages/fineui/src/widget/datetime/datetime.popup.js b/packages/fineui/src/widget/datetime/datetime.popup.js new file mode 100644 index 000000000..999e10779 --- /dev/null +++ b/packages/fineui/src/widget/datetime/datetime.popup.js @@ -0,0 +1,140 @@ +import { TextButton } from "@/base"; +import { DateCalendarPopup } from "../date/calendar"; +import { + GridLayout, + VTapeLayout, + CenterAdaptLayout, + shortcut, + Widget, + extend, + createWidget, + i18nText, + isNull, + getDate +} from "@/core"; +import { DynamicDateTimeSelect } from "../dynamicdatetime"; + +@shortcut() +export class DateTimePopup extends Widget { + static xtype = "bi.date_time_popup"; + + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static BUTTON_CANCEL_EVENT_CHANGE = "BUTTON_CANCEL_EVENT_CHANGE"; + static CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-date-time-popup", + width: 268, + height: 374, + }); + } + + _init() { + super._init(...arguments); + const opts = this.options; + this.cancelButton = createWidget({ + type: TextButton.xtype, + cls: "multidate-popup-button bi-border-top bi-border-right", + shadow: true, + text: i18nText("BI-Basic_Cancel"), + }); + this.cancelButton.on(TextButton.EVENT_CHANGE, () => { + this.fireEvent(DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE); + }); + + this.okButton = createWidget({ + type: TextButton.xtype, + cls: "multidate-popup-button bi-border-top", + shadow: true, + text: i18nText("BI-Basic_OK"), + }); + this.okButton.on(TextButton.EVENT_CHANGE, () => { + this.fireEvent(DateTimePopup.BUTTON_OK_EVENT_CHANGE); + }); + + this.dateCombo = createWidget({ + type: DateCalendarPopup.xtype, + behaviors: opts.behaviors, + min: this.options.min, + max: this.options.max, + }); + this.dateCombo.on(DateCalendarPopup.EVENT_CHANGE, () => { + this.fireEvent(DateTimePopup.CALENDAR_EVENT_CHANGE); + }); + + this.dateButton = createWidget({ + type: GridLayout.xtype, + items: [[this.cancelButton, this.okButton]], + }); + createWidget({ + element: this, + type: VTapeLayout.xtype, + items: [ + { + el: this.dateCombo, + }, + { + el: { + type: CenterAdaptLayout.xtype, + cls: "bi-split-top", + items: [ + { + type: DynamicDateTimeSelect.xtype, + ref: _ref => { + this.timeSelect = _ref; + }, + } + ], + }, + height: 50, + }, + { + el: this.dateButton, + height: 30, + } + ], + }); + this.setValue(opts.value); + } + + setValue(v) { + const value = v; + let date; + if (isNull(value)) { + date = getDate(); + this.dateCombo.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + this.timeSelect.setValue({ + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + }); + } else { + this.dateCombo.setValue({ + year: value.year, + month: value.month, + day: value.day, + }); + this.timeSelect.setValue({ + hour: value.hour, + minute: value.minute, + second: value.second, + }); + } + } + + getValue() { + return extend( + { + year: this.dateCombo.getValue().year, + month: this.dateCombo.getValue().month, + day: this.dateCombo.getValue().day, + }, + this.timeSelect.getValue() + ); + } +} diff --git a/packages/fineui/src/widget/datetime/datetime.trigger.js b/packages/fineui/src/widget/datetime/datetime.trigger.js new file mode 100644 index 000000000..cdbd7896c --- /dev/null +++ b/packages/fineui/src/widget/datetime/datetime.trigger.js @@ -0,0 +1,68 @@ +import { Label, Trigger } from "@/base"; +import { HTapeLayout, shortcut, extend, createWidget, isNull, getDate, print } from "@/core"; + +@shortcut() +export class DateTimeTrigger extends Trigger { + static xtype = "bi.date_time_trigger"; + + _const = { + hgap: 4, + iconWidth: 24, + }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-date-time-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + width: 200, + }); + } + + _init() { + super._init(...arguments); + const o = this.options, + c = this._const; + this.text = createWidget({ + type: Label.xtype, + textAlign: "left", + height: o.height, + width: o.width, + hgap: c.hgap, + }); + + createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: this.text, + }, + { + el: createWidget(), + width: this._const.iconWidth, + } + ], + }); + this.setValue(o.value); + } + + _printTime(v) { + return v < 10 ? `0${v}` : v; + } + + setValue(v) { + let value = v, + dateStr; + if (isNull(value)) { + value = getDate(); + dateStr = print(value, "%Y-%X-%d %H:%M:%S"); + } else { + const date = getDate(value.year, value.month - 1, value.day, value.hour, value.minute, value.second); + dateStr = print(date, "%Y-%X-%d %H:%M:%S"); + } + this.text.setText(dateStr); + this.text.setTitle(dateStr); + } +} diff --git a/packages/fineui/src/widget/datetime/index.js b/packages/fineui/src/widget/datetime/index.js new file mode 100644 index 000000000..3a292c518 --- /dev/null +++ b/packages/fineui/src/widget/datetime/index.js @@ -0,0 +1,3 @@ +export { DateTimeCombo } from "./datetime.combo"; +export { DateTimePopup } from "./datetime.popup"; +export { DateTimeTrigger } from "./datetime.trigger"; diff --git a/src/widget/datetimepane/__test__/datetimepane.test.js b/packages/fineui/src/widget/datetimepane/__test__/datetimepane.test.js similarity index 100% rename from src/widget/datetimepane/__test__/datetimepane.test.js rename to packages/fineui/src/widget/datetimepane/__test__/datetimepane.test.js diff --git a/packages/fineui/src/widget/datetimepane/card.static.datetimepane.js b/packages/fineui/src/widget/datetimepane/card.static.datetimepane.js new file mode 100644 index 000000000..24f706cc0 --- /dev/null +++ b/packages/fineui/src/widget/datetimepane/card.static.datetimepane.js @@ -0,0 +1,238 @@ +import { DatePicker, DateCalendarPopup } from "../date/calendar"; +import { Navigation } from "@/base"; +import { + VTapeLayout, + AbsoluteLayout, + Layout, + shortcut, + Widget, + extend, + getDate, + createWidget, + bind, + isNull, + each, + isNotEmptyString, + getMonthDays +} from "@/core"; +import { Calendar } from "@/case"; +import { DynamicDateTimeSelect } from "../dynamicdatetime/dynamicdatetime.timeselect"; + +@shortcut() +export class StaticDateTimePaneCard extends Widget { + static xtype = "bi.static_date_time_pane_card"; + + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-date-time-pane", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + selectedTime: null, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.today = getDate(); + this._year = this.today.getFullYear(); + this._month = this.today.getMonth() + 1; + + this.selectedTime = o.selectedTime || { + year: this._year, + month: this._month, + }; + + this.datePicker = createWidget({ + type: DatePicker.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + }); + this.datePicker.on(DatePicker.EVENT_CHANGE, () => { + const value = this.datePicker.getValue(); + const monthDay = getMonthDays(getDate(value.year, value.month - 1, 1)); + let day = this.selectedTime.day || 0; + if (day > monthDay) { + day = monthDay; + } + this.selectedTime = extend(this.selectedTime, { + year: value.year, + month: value.month, + }); + day !== 0 && (this.selectedTime.day = day); + this.calendar.setSelect(Calendar.getPageByDateJSON(this.selectedTime)); + this.calendar.setValue(this.selectedTime); + day !== 0 && this.fireEvent(DateCalendarPopup.EVENT_CHANGE); + }); + + this.datePicker.on(DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, () => { + this.fireEvent(StaticDateTimePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }); + + this.calendar = createWidget({ + direction: "custom", + // logic: { + // dynamic: false + // }, + type: Navigation.xtype, + tab: this.datePicker, + cardCreator: bind(this._createNav, this), + }); + this.calendar.on(Navigation.EVENT_CHANGE, () => { + this.selectedTime = extend(this.calendar.getValue(), this.timeSelect.getValue()); + this.calendar.empty(); + this.setValue(this.selectedTime); + this.fireEvent(DateCalendarPopup.EVENT_CHANGE); + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + hgap: 10, + items: [ + { + el: this.datePicker, + height: 40, + }, + this.calendar, + { + el: { + type: DynamicDateTimeSelect.xtype, + cls: "bi-split-top", + ref: _ref => { + this.timeSelect = _ref; + }, + listeners: [ + { + eventName: DynamicDateTimeSelect.EVENT_CONFIRM, + action: () => { + this.selectedTime = extend(this.calendar.getValue(), this.timeSelect.getValue()); + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }, + height: 40, + } + ], + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Layout.xtype, + cls: "bi-split-top", + }, + height: 1, + top: 40, + left: 0, + right: 0, + } + ], + }); + this.setValue(o.selectedTime); + } + + _createNav(v) { + const date = Calendar.getDateJSONByPage(v); + const calendar = createWidget({ + type: Calendar.xtype, + logic: { + dynamic: false, + }, + min: this.options.min, + max: this.options.max, + year: date.year, + month: date.month, + day: this.selectedTime.day, + }); + + return calendar; + } + + _getNewCurrentDate() { + const today = getDate(); + + return { + year: today.getFullYear(), + month: today.getMonth() + 1, + }; + } + + _setCalenderValue(date) { + this.calendar.setSelect(Calendar.getPageByDateJSON(date)); + this.calendar.setValue(date); + this.selectedTime = extend({}, this.timeSelect.getValue(), date); + } + + _setDatePicker(timeOb) { + if (isNull(timeOb) || isNull(timeOb.year) || isNull(timeOb.month)) { + this.datePicker.setValue(this._getNewCurrentDate()); + } else { + this.datePicker.setValue(timeOb); + } + } + + _setCalendar(timeOb) { + if (isNull(timeOb) || isNull(timeOb.day)) { + this.calendar.empty(); + this._setCalenderValue(this._getNewCurrentDate()); + } else { + this._setCalenderValue(timeOb); + } + } + + _checkMin() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMinDate(o.min); + }); + } + + _checkMax() { + const o = this.options; + each(this.calendar.getAllCard(), (idx, calendar) => { + calendar.setMaxDate(o.max); + }); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + this.datePicker.setMinDate(minDate); + this._checkMin(); + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + this.datePicker.setMaxDate(maxDate); + this._checkMax(); + } + } + + setValue(timeOb) { + timeOb = timeOb || {}; + this._setDatePicker(timeOb); + this._setCalendar(timeOb); + this.timeSelect.setValue({ + hour: timeOb.hour, + minute: timeOb.minute, + second: timeOb.second, + }); + } + + getValue() { + return this.selectedTime; + } +} diff --git a/packages/fineui/src/widget/datetimepane/datetimepane.js b/packages/fineui/src/widget/datetimepane/datetimepane.js new file mode 100644 index 000000000..6faa2f4e1 --- /dev/null +++ b/packages/fineui/src/widget/datetimepane/datetimepane.js @@ -0,0 +1,262 @@ +import { + VTapeLayout, + CenterLayout, + shortcut, + Widget, + createItems, + i18nText, + isNull, + isEmptyObject, + isEmptyString, + isNotEmptyObject, + getDate +} from "@/core"; +import { LinearSegment } from "@/case"; +import { Tab, TextButton, ButtonGroup } from "@/base"; +import { StaticDateTimePaneCard } from "./card.static.datetimepane"; +import { DynamicDateCard, DynamicDateCombo, DynamicDateHelper } from "../dynamicdate"; +import { DynamicDatePane } from "../datepane"; + +@shortcut() +export class DynamicDateTimePane extends Widget { + static xtype = "bi.dynamic_date_time_pane"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + static Static = 1; + static Dynamic = 2; + + props = { + baseCls: "bi-dynamic-date-pane", + minDate: "1900-01-01", + maxDate: "2099-12-31", + supportDynamic: true, + }; + + render() { + const o = this.options; + + return { + type: VTapeLayout.xtype, + items: [ + { + el: { + type: LinearSegment.xtype, + invisible: !o.supportDynamic, + cls: "bi-split-bottom", + height: 30, + items: createItems( + [ + { + text: i18nText("BI-Multi_Date_YMD"), + value: DynamicDateTimePane.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicDateTimePane.Dynamic, + } + ], + { + textAlign: "center", + } + ), + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: () => { + const value = this.switcher.getValue()[0]; + let date; + this.dateTab.setSelect(value); + switch (value) { + case DynamicDateTimePane.Static: + date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + break; + case DynamicDateTimePane.Dynamic: + this.dynamicPane.setValue({ + year: 0, + }); + break; + default: + break; + } + this.fireEvent(DynamicDateTimePane.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.switcher = _ref; + }, + }, + height: o.supportDynamic ? 30 : 0, + }, + { + type: Tab.xtype, + ref: _ref => { + this.dateTab = _ref; + }, + showIndex: DynamicDateTimePane.Static, + cardCreator: v => { + switch (v) { + case DynamicDateTimePane.Static: + return { + type: StaticDateTimePaneCard.xtype, + min: o.minDate, + max: o.maxDate, + behaviors: o.behaviors, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent(DynamicDateTimePane.EVENT_CHANGE); + }, + }, + { + eventName: "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW", + action: () => { + this.fireEvent(DynamicDateTimePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + } + ], + ref: _ref => { + this.ymd = _ref; + }, + }; + case DynamicDateTimePane.Dynamic: + default: + return { + type: VTapeLayout.xtype, + items: [ + { + type: DynamicDateCard.xtype, + min: o.minDate, + max: o.maxDate, + ref: _ref => { + this.dynamicPane = _ref; + }, + }, + { + el: { + type: CenterLayout.xtype, + items: [ + { + type: TextButton.xtype, + cls: "bi-high-light bi-border-top", + shadow: true, + text: i18nText("BI-Basic_Clear"), + textHeight: 23, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.setValue(); + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-border-left bi-high-light bi-border-top", + textHeight: 23, + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent( + DynamicDatePane.EVENT_CHANGE + ); + } else { + this.fireEvent(DynamicDatePane.EVENT_CHANGE); + } + }, + } + ], + } + ], + }, + height: 24, + } + ], + }; + } + }, + } + ], + }; + } + + created() { + this.setValue(this.options.value); + } + + _checkValueValid(value) { + return isNull(value) || isEmptyObject(value) || isEmptyString(value); + } + + _checkValue(v) { + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: + default: + return true; + } + } + + setMinDate(minDate) { + if (this.options.minDate !== minDate) { + this.options.minDate = minDate; + this.ymd.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.maxDate !== maxDate) { + this.options.maxDate = maxDate; + this.ymd.setMaxDate(maxDate); + } + } + + setValue(v) { + v = v || {}; + const type = v.type || DynamicDateTimePane.Static; + const value = v.value || v; + this.switcher.setValue(type); + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateTimePane.Dynamic: + this.dynamicPane.setValue(value); + break; + case DynamicDateTimePane.Static: + default: + if (this._checkValueValid(value)) { + const date = getDate(); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + }); + } else { + this.ymd.setValue(value); + } + break; + } + } + + getValue() { + return { + type: this.dateTab.getSelect(), + value: this.dateTab.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/datetimepane/index.js b/packages/fineui/src/widget/datetimepane/index.js new file mode 100644 index 000000000..f70ff91e9 --- /dev/null +++ b/packages/fineui/src/widget/datetimepane/index.js @@ -0,0 +1,2 @@ +export { StaticDateTimePaneCard } from "./card.static.datetimepane"; +export { DynamicDateTimePane } from "./datetimepane"; diff --git a/src/widget/downlist/__test__/downlist.test.js b/packages/fineui/src/widget/downlist/__test__/downlist.test.js similarity index 100% rename from src/widget/downlist/__test__/downlist.test.js rename to packages/fineui/src/widget/downlist/__test__/downlist.test.js diff --git a/packages/fineui/src/widget/downlist/combo.downlist.js b/packages/fineui/src/widget/downlist/combo.downlist.js new file mode 100644 index 000000000..4b8a9294b --- /dev/null +++ b/packages/fineui/src/widget/downlist/combo.downlist.js @@ -0,0 +1,147 @@ +import { shortcut, Widget, extend, createWidget, cloneDeep, some, isArray, each } from "@/core"; +import { DownListPopup } from "./popup.downlist"; +import { Combo } from "@/base"; +import { IconTrigger } from "@/case"; + +function transformItems(items) { + if (!items) return items; + let result = cloneDeep(items); + const isComplexItmes = some(items, (_, item) => isArray(item)); + // 传一维数组,帮转二维 + if (!isComplexItmes) { + result = [result]; + } + // 帮转 el + each(result, (_, arr) => { + each(arr, (_, item) => { + if (item.children && !item.el) { + item.el = { + text: item.text, + icon: item.icon, + cls: item.cls, + iconCls1: item.iconCls1, + value: item.value, + }; + } + }); + }); + + return result; +} + +@shortcut() +export class DownListCombo extends Widget { + static xtype = "bi.down_list_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-down-list-combo", + height: 24, + items: [], + adjustLength: 0, + direction: "bottom", + trigger: "click", + container: null, + stopPropagation: false, + el: {}, + popup: {}, + minWidth: 140, + maxHeight: 1000, + destroyWhenHide: false, + isDefaultInit: true, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.downlistcombo = createWidget({ + element: this, + type: Combo.xtype, + trigger: o.trigger, + isNeedAdjustWidth: false, + isDefaultInit: o.isDefaultInit, + container: o.container, + adjustLength: o.adjustLength, + direction: o.direction, + belowMouse: o.belowMouse, + stopPropagation: o.stopPropagation, + destroyWhenHide: o.destroyWhenHide, + el: { + type: IconTrigger.xtype, + extraCls: o.iconCls, + width: o.width, + height: o.height, + ...o.el, + }, + popup: { + el: { + type: DownListPopup.xtype, + ref: _ref => { + this.popupView = _ref; + }, + items: transformItems(o.items), + chooseType: o.chooseType, + value: o.value, + listeners: [ + { + eventName: DownListPopup.EVENT_CHANGE, + action: value => { + this.fireEvent(DownListCombo.EVENT_CHANGE, value); + this.downlistcombo.hideView(); + }, + }, + { + eventName: DownListPopup.EVENT_SON_VALUE_CHANGE, + action: (value, fatherValue) => { + this.fireEvent(DownListCombo.EVENT_SON_VALUE_CHANGE, value, fatherValue); + this.downlistcombo.hideView(); + }, + } + ], + }, + stopPropagation: o.stopPropagation, + maxHeight: o.maxHeight, + minWidth: o.minWidth, + ...o.popup, + }, + }); + + this.downlistcombo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(DownListCombo.EVENT_BEFORE_POPUPVIEW); + }); + } + + hideView() { + this.downlistcombo.hideView(); + } + + showView(e) { + this.downlistcombo.showView(e); + } + + populate(items) { + this.popupView.populate(items); + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + adjustWidth() { + this.downlistcombo.adjustWidth(); + } + + adjustHeight() { + this.downlistcombo.adjustHeight(); + } +} diff --git a/packages/fineui/src/widget/downlist/group.downlist.js b/packages/fineui/src/widget/downlist/group.downlist.js new file mode 100644 index 000000000..ee1109938 --- /dev/null +++ b/packages/fineui/src/widget/downlist/group.downlist.js @@ -0,0 +1,56 @@ +import { ButtonTree } from "@/base"; +import { VerticalLayout, shortcut, Widget, extend, createWidget, Controller, Events } from "@/core"; + +@shortcut() +export class DownListGroup extends Widget { + static xtype = "bi.down_list_group"; + + constants = { iconCls: "check-mark-ha-font" }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-down-list-group", + items: [ + { + el: {}, + } + ], + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.downlistgroup = createWidget({ + element: this, + type: ButtonTree.xtype, + items: o.items, + chooseType: 0, // 0单选,1多选 + layouts: [ + { + type: VerticalLayout.xtype, + hgap: 0, + vgap: 0, + } + ], + value: o.value, + }); + this.downlistgroup.on(Controller.EVENT_CHANGE, (type, ...args) => { + this.fireEvent(Controller.EVENT_CHANGE, type, ...args); + if (type === Events.CLICK) { + this.fireEvent(DownListGroup.EVENT_CHANGE, type, ...args); + } + }); + } + + getValue() { + return this.downlistgroup.getValue(); + } + + setValue(v) { + this.downlistgroup.setValue(v); + } +} diff --git a/packages/fineui/src/widget/downlist/index.js b/packages/fineui/src/widget/downlist/index.js new file mode 100644 index 000000000..f27a18682 --- /dev/null +++ b/packages/fineui/src/widget/downlist/index.js @@ -0,0 +1,5 @@ +export { DownListGroup } from "./group.downlist"; +export { DownListItem } from "./item.downlist"; +export { DownListGroupItem } from "./item.downlistgroup"; +export { DownListPopup } from "./popup.downlist"; +export { DownListCombo } from "./combo.downlist"; diff --git a/packages/fineui/src/widget/downlist/item.downlist.js b/packages/fineui/src/widget/downlist/item.downlist.js new file mode 100644 index 000000000..8a222f980 --- /dev/null +++ b/packages/fineui/src/widget/downlist/item.downlist.js @@ -0,0 +1,121 @@ +import { Label, Icon, BasicButton } from "@/base"; +import { CenterAdaptLayout, shortcut, extend, createWidget, isPlainObject, LogicFactory, Direction, SIZE_CONSANTS } from "@/core"; + +@shortcut() +export class DownListItem extends BasicButton { + static xtype = "bi.down_list_item"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-down-list-item bi-list-item-active", + cls: "", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + logic: { + dynamic: true, + }, + selected: false, + iconHeight: null, + iconWidth: null, + textHgap: 0, + textVgap: 0, + textLgap: 0, + textRgap: 0, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + cls: "list-item-text", + textAlign: "left", + hgap: o.textHgap, + vgap: o.textVgap, + lgap: o.textLgap, + rgap: o.textRgap, + text: o.text, + value: o.value, + keyword: o.keyword, + height: o.height, + }); + + const icon = isPlainObject(o.icon) + ? o.icon + : { + type: Icon.xtype, + width: o.iconWidth, + height: o.iconHeight, + }; + + this.icon = createWidget({ + type: CenterAdaptLayout.xtype, + width: 36, + height: o.height, + items: [ + { + el: icon, + } + ], + }); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(Direction.Left), + extend(o.logic, { + items: LogicFactory.createLogicItemsByDirection(Direction.Left, this.icon, this.text), + }) + ) + ) + ); + } + + setValue() { + if (!this.isReadOnly()) { + this.text.setValue(...arguments); + } + } + + getValue() { + return this.text.getValue(); + } + + setText() { + this.text.setText(...arguments); + } + + getText() { + return this.text.getText(); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(DownListItem.EVENT_CHANGE, this.getValue(), this); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } +} diff --git a/packages/fineui/src/widget/downlist/item.downlistgroup.js b/packages/fineui/src/widget/downlist/item.downlistgroup.js new file mode 100644 index 000000000..8bc1d6094 --- /dev/null +++ b/packages/fineui/src/widget/downlist/item.downlistgroup.js @@ -0,0 +1,142 @@ +import { Label, IconButton, BasicButton } from "@/base"; +import { + CenterAdaptLayout, + HorizontalFillLayout, + shortcut, + extend, + createWidget, + isNotNull, + isArray, + any, + contains, + isPlainObject, + first, + BlankSplitChar +} from "@/core"; + +@shortcut() +export class DownListGroupItem extends BasicButton { + static xtype = "bi.down_list_group_item"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-down-list-group-item`, + logic: { + dynamic: false, + }, + // invalid: true, + iconCls1: "dot-e-font", + icon: "", + iconCls2: "pull-right-e-font", + }); + } + + render() { + const o = this.options; + this.text = createWidget({ + type: Label.xtype, + cls: "list-group-item-text", + textAlign: "left", + text: o.text, + value: o.value, + height: o.height, + }); + + if (isPlainObject(o.icon)) { + this.icon1 = createWidget({ + width: 36, + height: o.height, + type: CenterAdaptLayout.xtype, + items: [o.icon], + }); + } else { + this.icon1 = createWidget({ + type: IconButton.xtype, + cls: o.iconCls1, + width: 36, + height: o.height, + iconHeight: o.iconHeight, + iconWidth: 36, + disableSelected: true, + selected: this._digest(o.value), + }); + } + + this.icon2 = createWidget({ + type: IconButton.xtype, + cls: o.iconCls2, + width: 24, + forceNotSelected: true, + }); + + this.element.hover( + () => { + if (this.isEnabled()) { + this.hover(); + } + }, + () => { + if (this.isEnabled()) { + this.dishover(); + } + } + ); + + return { + type: HorizontalFillLayout.xtype, + columnSize: [36, "fill", 24], + items: [this.icon1, this.text, this.icon2], + }; + } + + _getLevel() { + const child = first(this.options.childValues); + + return isNotNull(child) ? `${child}`.split(BlankSplitChar).length : 0; + } + + _digest(v) { + const o = this.options; + v = isArray(v) ? v : [v]; + const level = this._getLevel(); + + return any(v, (idx, value) => + contains(o.childValues, `${value}`.split(BlankSplitChar).slice(0, level).join(BlankSplitChar)) + ); + } + + hover() { + super.hover(...arguments); + this.icon1.element.addClass("hover"); + this.icon2.element.addClass("hover"); + } + + dishover() { + super.dishover(...arguments); + this.icon1.element.removeClass("hover"); + this.icon2.element.removeClass("hover"); + } + + doClick() { + super.doClick(...arguments); + if (this.isValid()) { + this.fireEvent(DownListGroupItem.EVENT_CHANGE, this.getValue()); + } + } + + doRedMark() { + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + setValue(v) { + this.icon1.setSelected && this.icon1.setSelected(this._digest(v)); + } +} diff --git a/packages/fineui/src/widget/downlist/popup.downlist.js b/packages/fineui/src/widget/downlist/popup.downlist.js new file mode 100644 index 000000000..b598ea65d --- /dev/null +++ b/packages/fineui/src/widget/downlist/popup.downlist.js @@ -0,0 +1,332 @@ +import { ButtonTree, Pane } from "@/base"; +import { + VerticalLayout, + Layout, + shortcut, + extend, + createWidget, + createItems, + isNotNull, + contains, + each, + isEmpty, + map, + isNotEmptyString, + isNotEmptyArray, + some, + deepClone, + SIZE_CONSANTS, + BlankSplitChar +} from "@/core"; +import { DownListGroup } from "./group.downlist"; + +@shortcut() +export class DownListPopup extends Pane { + static xtype = "bi.down_list_popup"; + + constants = { + nextIcon: "pull-right-e-font", + height: 24, + iconHeight: 12, + iconWidth: 12, + hgap: 0, + vgap: 0, + border: 1, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-down-list-popup", + items: [], + chooseType: Selection.Multi, + }); + } + + _init() { + super._init(...arguments); + this.singleValues = []; + this.childValueMap = {}; + this.fatherValueMap = {}; + this.items = []; + const o = this.options, + children = this._createPopupItems(o.items); + this.popup = createWidget({ + type: ButtonTree.xtype, + items: createItems( + children, + {}, + { + adjustLength: -2, + } + ), + layouts: [ + { + type: VerticalLayout.xtype, + hgap: this.constants.hgap, + vgap: this.constants.vgap, + } + ], + value: this._digest(o.value), + chooseType: o.chooseType, + }); + + this.popup.on(ButtonTree.EVENT_CHANGE, (value, object) => { + let changedValue = value; + if (isNotNull(this.childValueMap[value])) { + changedValue = this.childValueMap[value]; + this.fireEvent(DownListPopup.EVENT_SON_VALUE_CHANGE, changedValue, this.fatherValueMap[value]); + } else { + this.fireEvent(DownListPopup.EVENT_CHANGE, changedValue, object); + } + + if (!contains(this.singleValues, changedValue)) { + const item = this.getValue(); + const result = []; + each(item, (i, valueObject) => { + if (valueObject.value !== changedValue) { + result.push(valueObject); + } + }); + this.setValue(result); + } + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.popup], + vgap: 5, + }); + } + + _createPopupItems(items) { + const result = []; + // 不能修改populate进来的item的引用 + each(items, (i, it) => { + const item_done = { + type: DownListGroup.xtype, + items: [], + }; + + const storeItem = []; + + each(it, (i, sourceItem) => { + const item = extend({}, sourceItem); + if (isNotEmptyArray(sourceItem.children) && !isEmpty(sourceItem.el)) { + item.type = "bi.combo_group"; + // popup未初始化返回的是options中的value, 在经过buttontree的getValue concat之后,无法区分值来自options + // 还是item自身, 这边控制defaultInit为true来避免这个问题 + item.isDefaultInit = true; + item.cls = "down-list-group"; + item.trigger = "hover"; + item.isNeedAdjustWidth = false; + item.el = sourceItem.el; + item.el.title = sourceItem.el.title || sourceItem.el.text; + item.el.type = "bi.down_list_group_item"; + item.el.logic = { + dynamic: true, + }; + item.el.height = sourceItem.el.height || SIZE_CONSANTS.LIST_ITEM_HEIGHT; + item.el.iconCls2 = this.constants.nextIcon; + item.popup = { + lgap: 1, + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + innerVgap: 5, + maxHeight: 378, + }; + this._createChildren(item, sourceItem); + } else { + item.type = sourceItem.type || "bi.down_list_item"; + item.title = sourceItem.title || sourceItem.text; + item.textRgap = 10; + item.isNeedAdjustWidth = false; + item.logic = { + dynamic: true, + }; + } + const el_done = {}; + el_done.el = item; + item_done.items.push(el_done); + storeItem.push(item); + }); + if (this._isGroup(item_done.items)) { + each(item_done.items, (i, item) => { + this.singleValues.push(item.el.value); + }); + } + + result.push(item_done); + this.items.push(storeItem); + if (this._needSpliter(i, items.length)) { + const spliter_container = createWidget({ + type: VerticalLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "bi-down-list-spliter bi-split-top cursor-pointer", + height: 0, + }, + } + ], + cls: "bi-down-list-spliter-container cursor-pointer", + vgap: 5, + hgap: 12, + }); + result.push(spliter_container); + } + }); + + return result; + } + + _createChildren(targetItem, sourceItem) { + targetItem.el.childValues = []; + targetItem.items = targetItem.children = []; + each(sourceItem.children, (i, child) => { + const item = extend({}, child); + const fatherValue = deepClone(targetItem.el.value); + const childValue = deepClone(item.value); + this.singleValues.push(item.value); + item.type = item.type || "bi.down_list_item"; + item.extraCls = " child-down-list-item"; + item.title = item.title || item.text; + item.textRgap = 10; + item.isNeedAdjustWidth = false; + item.logic = { + dynamic: true, + }; + item.father = fatherValue; + item.childValue = item.value; + this.fatherValueMap[this._createChildValue(fatherValue, childValue)] = fatherValue; + this.childValueMap[this._createChildValue(fatherValue, childValue)] = childValue; + item.value = this._createChildValue(fatherValue, childValue); + targetItem.el.childValues.push(item.value); + targetItem.items.push(item); + }); + } + + _isGroup(i) { + return i.length > 1; + } + + _needSpliter(i, itemLength) { + return i < itemLength - 1; + } + + _createChildValue(fatherValue, childValue) { + return fatherValue + BlankSplitChar + childValue; + } + + _digest(valueItem) { + const valueArray = []; + each(valueItem, (i, item) => { + let value; + if (isNotNull(item.childValue)) { + value = this._createChildValue(item.value, item.childValue); + } else { + value = item.value; + } + valueArray.push(value); + }); + + return valueArray; + } + + _checkValues(values) { + const value = []; + each(this.items, (idx, itemGroup) => { + each(itemGroup, (id, item) => { + if (isNotNull(item.children)) { + const childValues = map(item.children, "value"); + const v = joinValue(childValues, values[idx]); + if (isNotEmptyString(v)) { + value.push(v); + } + } else { + if (item.value === values[idx][0]) { + value.push(values[idx][0]); + } + } + }); + }); + + return value; + + function joinValue(sources, targets) { + let value = ""; + some(sources, (idx, s) => + some(targets, (id, t) => { + if (s === t) { + value = s; + + return true; + } + }) + ); + + return value; + } + } + + populate(items) { + super.populate(...arguments); + this.items = []; + this.childValueMap = {}; + this.fatherValueMap = {}; + this.singleValues = []; + const children = this._createPopupItems(items); + const popupItem = createItems( + children, + {}, + { + adjustLength: -2, + } + ); + this.popup.populate(popupItem); + } + + setValue(valueItem) { + this.popup.setValue(this._digest(valueItem)); + } + + _getValue() { + const v = []; + each(this.popup.getAllButtons(), (i, item) => { + i % 2 === 0 && v.push(item.getValue()); + }); + + return v; + } + + getValue() { + const result = []; + const values = this._checkValues(this._getValue()); + each(values, (i, value) => { + const valueItem = {}; + if (isNotNull(this.childValueMap[value])) { + const fartherValue = this.fatherValueMap[value]; + valueItem.childValue = this.childValueMap[value]; + valueItem.value = fartherValue; + } else { + valueItem.value = value; + } + result.push(valueItem); + }); + + return result; + } +} diff --git a/src/widget/dynamicdate/__test__/dynamicdate.test.js b/packages/fineui/src/widget/dynamicdate/__test__/dynamicdate.test.js similarity index 100% rename from src/widget/dynamicdate/__test__/dynamicdate.test.js rename to packages/fineui/src/widget/dynamicdate/__test__/dynamicdate.test.js diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.caculate.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.caculate.js new file mode 100644 index 000000000..245471cfd --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.caculate.js @@ -0,0 +1,158 @@ +import { + isNotNull, + parseInt, + getDate, + i18nText, + size, + getOffsetQuarter, + getOffsetMonth, + getOffsetDate, + getLastDateOfMonth, + getWeekStartDate, + getWeekEndDate, + getQuarterStartDate, + getQuarterEndDate, + print +} from "@/core"; +import { DynamicDateCard } from "./dynamicdate.card"; + +export const DynamicDateHelper = { + getCalculation(obj) { + const date = getDate(); + + return this.getCalculationByDate(date, obj); + }, + + getDescription(obj) { + let value = ""; + let endText = ""; + if (isNotNull(obj.year)) { + if (parseInt(obj.year) !== 0) { + value += + Math.abs(obj.year) + + i18nText("BI-Basic_Year") + + (obj.year < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Year"), obj.position); + } + if (isNotNull(obj.quarter)) { + if (parseInt(obj.quarter) !== 0) { + value += + Math.abs(obj.quarter) + + i18nText("BI-Basic_Single_Quarter") + + (obj.quarter < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Single_Quarter"), obj.position); + } + if (isNotNull(obj.month)) { + if (parseInt(obj.month) !== 0) { + value += + Math.abs(obj.month) + + i18nText("BI-Basic_Month") + + (obj.month < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Month"), obj.position); + } + if (isNotNull(obj.week)) { + if (parseInt(obj.week) !== 0) { + value += + Math.abs(obj.week) + + i18nText("BI-Basic_Week") + + (obj.week < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Week"), obj.position); + } + if (isNotNull(obj.day)) { + if (parseInt(obj.day) !== 0) { + value += + Math.abs(obj.day) + + i18nText("BI-Basic_Day") + + (obj.day < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = size(obj) === 1 ? getPositionText(i18nText("BI-Basic_Month"), obj.position) : ""; + } + if (isNotNull(obj.workDay) && parseInt(obj.workDay) !== 0) { + value += + Math.abs(obj.workDay) + + i18nText("BI-Basic_Work_Day") + + (obj.workDay < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + + return value + endText; + + function getPositionText(baseText, position) { + switch (position) { + case DynamicDateCard.OFFSET.BEGIN: + return baseText + i18nText("BI-Basic_Begin_Start"); + case DynamicDateCard.OFFSET.END: + return baseText + i18nText("BI-Basic_End_Stop"); + case DynamicDateCard.OFFSET.CURRENT: + default: + return i18nText("BI-Basic_Current_Day"); + } + } + }, + + getCalculationByDate(date, obj) { + if (isNotNull(obj.year)) { + date = getDate(date.getFullYear() + parseInt(obj.year), date.getMonth(), date.getDate()); + } + if (isNotNull(obj.quarter)) { + date = getOffsetQuarter(date, parseInt(obj.quarter)); + } + if (isNotNull(obj.month)) { + date = getOffsetMonth(date, parseInt(obj.month)); + } + if (isNotNull(obj.week)) { + date = getOffsetDate(date, parseInt(obj.week) * 7); + } + if (isNotNull(obj.day)) { + date = getOffsetDate(date, parseInt(obj.day)); + } + if (isNotNull(obj.workDay)) { + // 配置了节假日就按照节假日计算工作日偏移,否则按正常的天去算 + if (isNotNull(BI.holidays)) { + const count = Math.abs(obj.workDay); + for (let i = 0; i < count; i++) { + date = getOffsetDate(date, obj.workDay < 0 ? -1 : 1); + if (isNotNull(BI.holidays[print(date, "%Y-%X-%d")])) { + i--; + } + } + } else { + date = getOffsetDate(date, parseInt(obj.workDay)); + } + } + if (isNotNull(obj.position) && obj.position !== DynamicDateCard.OFFSET.CURRENT) { + date = this.getBeginDate(date, obj); + } + + return getDate(date.getFullYear(), date.getMonth(), date.getDate()); + }, + + getBeginDate(date, obj) { + if (isNotNull(obj.day)) { + return obj.position === DynamicDateCard.OFFSET.BEGIN + ? getDate(date.getFullYear(), date.getMonth(), 1) + : getDate(date.getFullYear(), date.getMonth(), getLastDateOfMonth(date).getDate()); + } + if (isNotNull(obj.week)) { + return obj.position === DynamicDateCard.OFFSET.BEGIN ? getWeekStartDate(date) : getWeekEndDate(date); + } + if (isNotNull(obj.month)) { + return obj.position === DynamicDateCard.OFFSET.BEGIN + ? getDate(date.getFullYear(), date.getMonth(), 1) + : getDate(date.getFullYear(), date.getMonth(), getLastDateOfMonth(date).getDate()); + } + if (isNotNull(obj.quarter)) { + return obj.position === DynamicDateCard.OFFSET.BEGIN ? getQuarterStartDate(date) : getQuarterEndDate(date); + } + if (isNotNull(obj.year)) { + return obj.position === DynamicDateCard.OFFSET.BEGIN + ? getDate(date.getFullYear(), 0, 1) + : getDate(date.getFullYear(), 11, 31); + } + + return date; + }, +}; diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.card.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.card.js new file mode 100644 index 000000000..9ea322d12 --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.card.js @@ -0,0 +1,514 @@ +import { + VerticalLayout, + FloatLeftLayout, + VerticalAdaptLayout, + shortcut, + Widget, + i18nText, + createItems, + each, + isNotNull, + map, + has, + bind, + last, + extend, + checkDateVoid, + isNull, + isNotEmptyString, + parseDateTime, + any, + SIZE_CONSANTS +} from "@/core"; +import { Label, ButtonGroup, Bubbles } from "@/base"; +import { MultiSelectItem, TextValueCombo } from "@/case"; +import { DynamicDateParamItem } from "./dynamicdate.param.item"; +import { DynamicDateHelper } from "./dynamicdate.caculate"; + +@shortcut() +export class DynamicDateCard extends Widget { + static xtype = "bi.dynamic_date_card"; + + static TYPE = { + YEAR: 1, + QUARTER: 2, + MONTH: 3, + WEEK: 4, + DAY: 5, + WORK_DAY: 6, + }; + static OFFSET = { + CURRENT: 1, + BEGIN: 2, + END: 3, + }; + + props = { + baseCls: "bi-dynamic-date-card", + }; + + render() { + this.position = DynamicDateCard.OFFSET.CURRENT; + + return { + type: VerticalLayout.xtype, + items: [ + { + el: { + type: Label.xtype, + text: i18nText("BI-Multi_Date_Relative_Current_Time"), + textAlign: "left", + lgap: 10, + }, + tgap: 10, + bgap: 5, + }, + { + type: ButtonGroup.xtype, + ref: _ref => { + this.checkgroup = _ref; + }, + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + lgap: 4, + value: [DynamicDateCard.TYPE.YEAR], + items: createItems( + [ + { + text: i18nText("BI-Basic_Year"), + value: DynamicDateCard.TYPE.YEAR, + }, + { + text: i18nText("BI-Basic_Single_Quarter"), + value: DynamicDateCard.TYPE.QUARTER, + }, + { + text: i18nText("BI-Basic_Month"), + value: DynamicDateCard.TYPE.MONTH, + }, + { + text: i18nText("BI-Basic_Week"), + value: DynamicDateCard.TYPE.WEEK, + }, + { + text: i18nText("BI-Basic_Day"), + value: DynamicDateCard.TYPE.DAY, + } + ], + { + type: MultiSelectItem.xtype, + logic: { + dynamic: true, + }, + iconWrapperWidth: 26, + } + ), + layouts: [ + { + type: FloatLeftLayout.xtype, + rgap: 4, + } + ], + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: () => { + const value = this.checkgroup.getValue(); + if (value.length !== 0) { + this.workDayBox.setSelected(false); + } + + const plainValue = {}; + each(this.resultPane.getAllButtons(), (idx, button) => { + const value = button.getValue(); + if (isNotNull(value.dateType)) { + plainValue[value.dateType] = { + value: value.value, + offset: value.offset, + }; + } + }); + this.resultPane.populate( + this._getParamJson( + map(this.checkgroup.getValue(), (idx, v) => { + const obj = { + dateType: v, + }; + if (has(plainValue, v)) { + obj.value = plainValue[v].value; + obj.offset = plainValue[v].offset; + } + + return obj; + }) + ) + ); + this.position = DynamicDateCard.OFFSET.CURRENT; + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }, + { + type: VerticalAdaptLayout.xtype, + lgap: 2, + items: [ + { + el: { + type: MultiSelectItem.xtype, + iconWrapperWidth: 26, + ref: _ref => { + this.workDayBox = _ref; + }, + logic: { + dynamic: true, + }, + text: i18nText("BI-Basic_Work_Day"), + value: DynamicDateCard.TYPE.WORK_DAY, + listeners: [ + { + eventName: MultiSelectItem.EVENT_CHANGE, + action: () => { + if (this.workDayBox.isSelected()) { + this.checkgroup.setValue(); + } + this.resultPane.populate( + this.workDayBox.isSelected() + ? this._getParamJson([ + { + dateType: DynamicDateCard.TYPE.WORK_DAY, + } + ]) + : [] + ); + this.position = DynamicDateCard.OFFSET.CURRENT; + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }, + } + ], + ref: _ref => { + this.workDay = _ref; + }, + }, + { + type: ButtonGroup.xtype, + items: this._getParamJson([ + { + dateType: DynamicDateCard.TYPE.YEAR, + } + ]), + ref: _ref => { + this.resultPane = _ref; + }, + layouts: [ + { + type: VerticalLayout.xtype, + bgap: 10, + hgap: 10, + } + ], + } + ], + }; + } + + _getParamJson(values, positionValue) { + const items = map(values, (idx, value) => { + return { + el: { + type: DynamicDateParamItem.xtype, + validationChecker: bind(this._checkDate, this), + dateType: value.dateType, + value: value.value, + offset: value.offset, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action() { + Bubbles.hide("dynamic-date-error"); + }, + } + ], + }, + tgap: idx === 0 ? 5 : 0, + }; + }); + + if (values.length === 1 && values[0].dateType === DynamicDateCard.TYPE.DAY) { + const comboItems = this._getText(DynamicDateCard.TYPE.MONTH); + comboItems[0].text = i18nText("BI-Basic_Empty"); + items.push({ + type: TextValueCombo.xtype, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + items: comboItems, + container: null, + value: positionValue || DynamicDateCard.OFFSET.CURRENT, + ref: _ref => { + this.textValueCombo = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.position = this.textValueCombo.getValue()[0]; + this.textValueCombo.setValue(this.position); + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }); + } else { + if ( + values.length !== 0 && + last(values).dateType !== DynamicDateCard.TYPE.DAY && + last(values).dateType !== DynamicDateCard.TYPE.WORK_DAY + ) { + items.push({ + type: TextValueCombo.xtype, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + container: null, + items: this._getText(last(values).dateType), + value: positionValue || DynamicDateCard.OFFSET.CURRENT, + ref: _ref => { + this.textValueCombo = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.position = this.textValueCombo.getValue()[0]; + this.textValueCombo.setValue(this.position); + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }); + } + } + + return items; + } + + _checkDate(obj) { + const o = this.options; + const date = DynamicDateHelper.getCalculation(extend(this._getValue(), this._digestDateTypeValue(obj))); + + return !checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; + } + + _getText(lastValue) { + switch (lastValue) { + case DynamicDateCard.TYPE.YEAR: + return [ + { + text: i18nText("BI-Basic_Current_Day"), + value: DynamicDateCard.OFFSET.CURRENT, + }, + { + text: i18nText("BI-Basic_Year_Begin"), + value: DynamicDateCard.OFFSET.BEGIN, + }, + { + text: i18nText("BI-Basic_Year_End"), + value: DynamicDateCard.OFFSET.END, + } + ]; + case DynamicDateCard.TYPE.QUARTER: + return [ + { + text: i18nText("BI-Basic_Current_Day"), + value: DynamicDateCard.OFFSET.CURRENT, + }, + { + text: i18nText("BI-Basic_Quarter_Begin"), + value: DynamicDateCard.OFFSET.BEGIN, + }, + { + text: i18nText("BI-Basic_Quarter_End"), + value: DynamicDateCard.OFFSET.END, + } + ]; + case DynamicDateCard.TYPE.MONTH: + return [ + { + text: i18nText("BI-Basic_Current_Day"), + value: DynamicDateCard.OFFSET.CURRENT, + }, + { + text: i18nText("BI-Basic_Month_Begin"), + value: DynamicDateCard.OFFSET.BEGIN, + }, + { + text: i18nText("BI-Basic_Month_End"), + value: DynamicDateCard.OFFSET.END, + } + ]; + case DynamicDateCard.TYPE.WEEK: + default: + return [ + { + text: i18nText("BI-Basic_Current_Day"), + value: DynamicDateCard.OFFSET.CURRENT, + }, + { + text: i18nText("BI-Basic_Week_Begin"), + value: DynamicDateCard.OFFSET.BEGIN, + }, + { + text: i18nText("BI-Basic_Week_End"), + value: DynamicDateCard.OFFSET.END, + } + ]; + } + } + + _createValue(type, v) { + return { + dateType: type, + value: Math.abs(v), + offset: v > 0 ? 1 : 0, + }; + } + + _digestDateTypeValue(value) { + const valueMap = {}; + switch (value.dateType) { + case DynamicDateCard.TYPE.YEAR: + valueMap.year = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.QUARTER: + valueMap.quarter = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.MONTH: + valueMap.month = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.WEEK: + valueMap.week = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.DAY: + valueMap.day = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.WORK_DAY: + valueMap.workDay = value.offset === 0 ? -value.value : +value.value; + break; + default: + break; + } + if (isNull(value.dateType)) { + valueMap.position = this.position || DynamicDateCard.OFFSET.CURRENT; + } + + return valueMap; + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + v = v || {}; + this.position = v.position || DynamicDateCard.OFFSET.CURRENT; + const values = []; + const valuesItems = []; + if (isNotNull(v.year)) { + values.push(DynamicDateCard.TYPE.YEAR); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.YEAR, v.year)); + } + if (isNotNull(v.quarter)) { + values.push(DynamicDateCard.TYPE.QUARTER); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.QUARTER, v.quarter)); + } + if (isNotNull(v.month)) { + values.push(DynamicDateCard.TYPE.MONTH); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.MONTH, v.month)); + } + if (isNotNull(v.week)) { + values.push(DynamicDateCard.TYPE.WEEK); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.WEEK, v.week)); + } + if (isNotNull(v.day)) { + values.push(DynamicDateCard.TYPE.DAY); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.DAY, v.day)); + } + if (isNotNull(v.workDay)) { + values.push(DynamicDateCard.TYPE.WORK_DAY); + valuesItems.push(this._createValue(DynamicDateCard.TYPE.WORK_DAY, v.workDay)); + } + this.checkgroup.setValue(values); + this.workDayBox.setSelected(isNotNull(v.workDay)); + this.resultPane.populate(this._getParamJson(valuesItems, v.position)); + } + + _getValue() { + const valueMap = {}; + const selectValues = this.checkgroup.getValue(); + const buttons = this.resultPane.getAllButtons(); + if (selectValues.length !== 0) { + each(buttons, (idx, button) => { + const value = button.getValue(); + extend(valueMap, this._digestDateTypeValue(value)); + }); + } + if (this.workDayBox.isSelected()) { + const value = buttons[0].getValue(); + valueMap.workDay = value.offset === 0 ? -value.value : +value.value; + } + + return valueMap; + } + + _getErrorText() { + const o = this.options; + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText( + "BI-Basic_Date_Range_Error", + start.getFullYear(), + start.getMonth() + 1, + start.getDate(), + end.getFullYear(), + end.getMonth() + 1, + end.getDate() + ); + } + + getValue() { + return this.checkValidation() ? this._getValue() : {}; + } + + getInputValue() { + return this._getValue(); + } + + checkValidation(show) { + const buttons = this.resultPane.getAllButtons(); + let errorText; + let invalid = any(buttons, (idx, button) => button.checkValidation && !button.checkValidation()); + if (invalid) { + errorText = i18nText("BI-Please_Input_Natural_Number"); + } else { + invalid = !this._checkDate(this._getValue()); + errorText = this._getErrorText(); + } + invalid && show && Bubbles.show("dynamic-date-error", errorText, this.resultPane); + + return !invalid; + } +} diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.combo.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.combo.js new file mode 100644 index 000000000..684776f8c --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.combo.js @@ -0,0 +1,372 @@ +import { + AbsoluteLayout, + HorizontalFillLayout, + shortcut, + getDate, + toPix, + isEqual, + isNotEmptyString, + isEmptyString, + isNotNull, + isNotEmptyObject, + checkDateVoid +} from "@/core"; +import { Combo, IconButton, Single } from "@/base"; +import { DynamicDateTrigger } from "./dynamicdate.trigger"; +import { DynamicDatePopup } from "./dynamicdate.popup"; + +@shortcut() +export class DynamicDateCombo extends Single { + static xtype = "bi.dynamic_date_combo"; + + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + static Static = 1; + static Dynamic = 2; + + constants = { + popupHeight: 259, + popupWidth: 270, + comboAdjustHeight: 1, + border: 1, + iconWidth: 24, + }; + + props = { + baseCls: "bi-dynamic-date-combo", + height: 24, + minDate: "1900-01-01", + maxDate: "2099-12-31", + format: "", + allowEdit: true, + supportDynamic: true, + attributes: { + tabIndex: -1, + }, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + }; + + _init() { + super._init(...arguments); + } + + render() { + const opts = this.options; + this.storeTriggerValue = ""; + const date = getDate(); + this.storeValue = opts.value; + const border = opts.simple ? 1 : 2; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + cls: `${opts.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + container: opts.container, + ref: _ref => { + this.combo = _ref; + }, + toggle: false, + isNeedAdjustHeight: opts.isNeedAdjustHeight, + isNeedAdjustWidth: opts.isNeedAdjustWidth, + destroyWhenHide: true, + el: { + type: HorizontalFillLayout.xtype, + columnSize: [this.constants.iconWidth, "fill"], + height: toPix(opts.height, border), + items: [ + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-change-h-font", + width: toPix(opts.height, border), + height: toPix(opts.height, border), + ref: _ref => { + this.changeIcon = _ref; + }, + }, + }, + { + type: DynamicDateTrigger.xtype, + simple: opts.simple, + min: opts.minDate, + max: opts.maxDate, + format: opts.format, + allowEdit: opts.allowEdit, + watermark: opts.watermark, + iconWidth: toPix(opts.height, border), + height: toPix(opts.height, border), + value: opts.value, + ref: _ref => { + this.trigger = _ref; + }, + listeners: [ + { + eventName: DynamicDateTrigger.EVENT_KEY_DOWN, + action: (...args) => { + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } + this.fireEvent(DynamicDateCombo.EVENT_KEY_DOWN, ...args); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_STOP, + action: () => { + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + }, + }, + { + eventName: DynamicDateTrigger.EVENT_FOCUS, + action: () => { + this.storeTriggerValue = this.trigger.getKey(); + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + this.fireEvent(DynamicDateCombo.EVENT_FOCUS); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_BLUR, + action: () => { + this.fireEvent(DynamicDateCombo.EVENT_BLUR); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_ERROR, + action: () => { + this.storeValue = { + type: DynamicDateCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1, + }, + }; + this.combo.element.addClass("error"); + this.fireEvent(DynamicDateCombo.EVENT_ERROR); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_VALID, + action: () => { + this.storeValue = this.trigger.getValue(); + this.combo.element.removeClass("error"); + this.fireEvent(DynamicDateCombo.EVENT_VALID); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateCombo.EVENT_CHANGE); + }, + }, + { + eventName: DynamicDateTrigger.EVENT_CONFIRM, + action: () => { + const dateStore = this.storeTriggerValue; + const dateObj = this.trigger.getKey(); + if (this.combo.isViewVisible() || isEqual(dateObj, dateStore)) { + return; + } + if (isNotEmptyString(dateObj) && !isEqual(dateObj, dateStore)) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.trigger.getValue()); + } else if (isEmptyString(dateObj)) { + this.storeValue = null; + this.trigger.setValue(); + } + this._checkDynamicValue(this.storeValue); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + } + ], + } + ], + }, + adjustLength: this.constants.comboAdjustHeight, + popup: { + el: { + type: DynamicDatePopup.xtype, + width: opts.isNeedAdjustWidth ? opts.width : undefined, + supportDynamic: opts.supportDynamic, + behaviors: opts.behaviors, + min: opts.minDate, + max: opts.maxDate, + ref: _ref => { + this.popup = _ref; + }, + listeners: [ + { + eventName: DynamicDatePopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicDatePopup.BUTTON_lABEL_EVENT_CHANGE, + action: () => { + const date = getDate(); + this.setValue({ + type: DynamicDateCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }, + }); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicDatePopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + const value = this.popup.getValue(); + if (this._checkValue(value)) { + this.setValue(value); + } + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicDatePopup.EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicDatePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, + action: () => { + this.fireEvent(DynamicDateCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + } + ], + }, + }, + // // DEC-4250 和复选下拉一样,点击triggerBtn不默认收起 + // hideChecker: function (e) { + // return self.triggerBtn.element.find(e.target).length === 0; + // }, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.popup.setMinDate(opts.minDate); + this.popup.setMaxDate(opts.maxDate); + this.popup.setValue(this.storeValue); + this.fireEvent(DynamicDateCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }, + top: 0, + left: 0, + right: 0, + bottom: 0, + } + ], + }; + } + + created() { + this._checkDynamicValue(this.storeValue); + } + + _checkDynamicValue(v) { + let type = null; + if (isNotNull(v)) { + type = v.type; + } + switch (type) { + case DynamicDateCombo.Dynamic: + this.changeIcon.setVisible(true); + // this.comboWrapper.attr("items")[0].width = o.height - this.options.simple ? 1 : 2; + // this.comboWrapper.resize(); + break; + default: + // this.comboWrapper.attr("items")[0].width = 0; + // this.comboWrapper.resize(); + this.changeIcon.setVisible(false); + break; + } + } + + _checkValue(v) { + const o = this.options; + let value; + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: + value = v.value || {}; + + return !checkDateVoid(value.year, value.month, value.day, o.minDate, o.maxDate)[0]; + default: + return true; + } + } + + _defaultState() {} + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.trigger.setMinDate(minDate); + this.popup && this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.trigger.setMaxDate(maxDate); + this.popup && this.popup.setMaxDate(maxDate); + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + this._checkDynamicValue(v); + } + + getValue() { + return this.storeValue; + } + + getKey() { + return this.trigger.getKey(); + } + + hidePopupView() { + this.combo.hideView(); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.param.item.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.param.item.js new file mode 100644 index 000000000..26dd9f22c --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.param.item.js @@ -0,0 +1,150 @@ +import { HTapeLayout, shortcut, Widget, toPix, isNaturalNumber, i18nText, SIZE_CONSANTS } from "@/core"; +import { SignEditor, TextValueCombo } from "@/case"; +import { Label } from "@/base"; +import { DynamicDateCard } from "./dynamicdate.card"; + +@shortcut() +export class DynamicDateParamItem extends Widget { + static xtype = "bi.dynamic_date_param_item"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_INPUT_CHANGE = "EVENT_INPUT_CHANGE"; + + props() { + return { + baseCls: "bi-dynamic-date-param-item", + dateType: DynamicDateCard.TYPE.YEAR, + validationChecker() { + return true; + }, + value: 0, + offset: 0, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }; + } + + render() { + const o = this.options; + + return { + type: HTapeLayout.xtype, + items: [ + { + el: { + type: SignEditor.xtype, + cls: "bi-border bi-focus-shadow bi-border-radius", + height: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 2), + validationChecker(v) { + return isNaturalNumber(v); + }, + value: o.value, + ref: _ref => { + this.editor = _ref; + }, + errorText() { + return i18nText("BI-Please_Input_Natural_Number"); + }, + allowBlank: false, + listeners: [ + { + eventName: SignEditor.EVENT_CONFIRM, + action: () => { + this.fireEvent(DynamicDateParamItem.EVENT_CHANGE); + }, + }, + { + eventName: SignEditor.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateParamItem.EVENT_INPUT_CHANGE); + }, + } + ], + }, + width: 60, + }, + { + el: { + type: Label.xtype, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + text: this._getText(), + }, + width: o.dateType === DynamicDateCard.TYPE.WORK_DAY ? 60 : 20, + }, + { + type: TextValueCombo.xtype, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + items: [ + { + text: i18nText("BI-Basic_Front"), + value: 0, + }, + { + text: i18nText("BI-Basic_Behind"), + value: 1, + } + ], + ref: _ref => { + this.offsetCombo = _ref; + }, + container: null, + value: o.offset, + listeners: [ + { + eventName: TextValueCombo.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateParamItem.EVENT_CHANGE); + }, + } + ], + } + ], + }; + } + + _getText() { + let text = ""; + switch (this.options.dateType) { + case DynamicDateCard.TYPE.YEAR: + text = i18nText("BI-Basic_Year"); + break; + case DynamicDateCard.TYPE.QUARTER: + text = i18nText("BI-Basic_Single_Quarter"); + break; + case DynamicDateCard.TYPE.MONTH: + text = i18nText("BI-Basic_Month"); + break; + case DynamicDateCard.TYPE.WEEK: + text = i18nText("BI-Basic_Week"); + break; + case DynamicDateCard.TYPE.DAY: + text = i18nText("BI-Basic_Day"); + break; + case DynamicDateCard.TYPE.WORK_DAY: + default: + text = i18nText("BI-Basic_Work_Day"); + break; + } + + return text; + } + + checkValidation() { + return isNaturalNumber(this.editor.getValue()); + } + + setValue(v) { + v = v || {}; + v.value = v.value || 0; + v.offset = v.offset || 0; + this.editor.setValue(v.value); + this.offsetCombo.setValue(v.offset); + } + + getValue() { + return { + dateType: this.options.dateType, + value: this.editor.getValue(), + offset: this.offsetCombo.getValue()[0], + }; + } +} diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.popup.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.popup.js new file mode 100644 index 000000000..907303d1e --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.popup.js @@ -0,0 +1,316 @@ +import { + VerticalLayout, + GridLayout, + shortcut, + Widget, + createWidget, + i18nText, + toPix, + createItems, + isNull, + isEmptyObject, + isEmptyString, + getDate, + checkDateVoid, + print, + SIZE_CONSANTS +} from "@/core"; +import { TextButton, Tab } from "@/base"; +import { LinearSegment } from "@/case"; +import { DynamicDateCard } from "./dynamicdate.card"; +import { DateCalendarPopup } from "../date/calendar"; +import { DynamicDateCombo } from "./dynamicdate.combo"; +import { DynamicDateHelper } from "./dynamicdate.caculate"; + +@shortcut() +export class DynamicDatePopup extends Widget { + static xtype = "bi.dynamic_date_popup"; + + constants = { + tabHeight: 40, + }; + + props = { + baseCls: "bi-dynamic-date-popup", + width: 272, + supportDynamic: true, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _init() { + super._init(...arguments); + const opts = this.options; + this.storeValue = { + type: DynamicDateCombo.Static, + }; + createWidget({ + element: this, + type: VerticalLayout.xtype, + items: [ + { + el: this._getTabJson(), + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + shadow: true, + text: i18nText("BI-Basic_Clear"), + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDatePopup.BUTTON_CLEAR_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + shadow: true, + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + text: i18nText("BI-Multi_Date_Today"), + disabled: this._checkTodayValid(), + ref: _ref => { + this.todayButton = _ref; + }, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDatePopup.BUTTON_lABEL_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent(DynamicDatePopup.BUTTON_OK_EVENT_CHANGE); + } else { + this.fireEvent(DynamicDatePopup.BUTTON_OK_EVENT_CHANGE); + } + }, + } + ], + } + ] + ], + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }, + } + ], + }); + this.setValue(opts.value); + } + + _getTabJson() { + const o = this.options; + + return { + type: Tab.xtype, + logic: { + dynamic: true, + }, + ref: _ref => { + this.dateTab = _ref; + }, + tab: { + type: LinearSegment.xtype, + invisible: !o.supportDynamic, + cls: "bi-split-bottom", + height: this.constants.tabHeight, + items: createItems( + [ + { + text: i18nText("BI-Multi_Date_YMD"), + value: DynamicDateCombo.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicDateCombo.Dynamic, + } + ], + { + textAlign: "center", + } + ), + }, + cardCreator: v => { + switch (v) { + case DynamicDateCombo.Dynamic: + return { + type: DynamicDateCard.xtype, + cls: "dynamic-date-pane", + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._setInnerValue(this.year, v); + }, + } + ], + min: this.options.min, + max: this.options.max, + ref: _ref => { + this.dynamicPane = _ref; + }, + }; + case DynamicDateCombo.Static: + default: + return { + type: DateCalendarPopup.xtype, + behaviors: o.behaviors, + min: this.options.min, + max: this.options.max, + listeners: [ + { + eventName: DateCalendarPopup.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDatePopup.EVENT_CHANGE); + }, + }, + { + eventName: DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, + action: () => { + this.fireEvent(DynamicDatePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + } + ], + ref: _ref => { + this.ymd = _ref; + }, + }; + } + }, + listeners: [ + { + eventName: Tab.EVENT_CHANGE, + action: () => { + const v = this.dateTab.getSelect(); + let date; + switch (v) { + case DynamicDateCombo.Static: + date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + this._setInnerValue(); + break; + case DynamicDateCombo.Dynamic: + default: + if (this.storeValue && this.storeValue.type === DynamicDateCombo.Dynamic) { + this.dynamicPane.setValue(this.storeValue.value); + } else { + this.dynamicPane.setValue({ + year: 0, + }); + } + this._setInnerValue(); + break; + } + }, + } + ], + }; + } + + _setInnerValue() { + if (this.dateTab.getSelect() === DynamicDateCombo.Static) { + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + this.todayButton.setEnable(!this._checkTodayValid()); + } else { + let date = DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); + date = print(date, "%Y-%X-%d"); + this.todayButton.setValue(date); + this.todayButton.setEnable(false); + } + } + + _checkValueValid(value) { + return isNull(value) || isEmptyObject(value) || isEmptyString(value); + } + + _checkTodayValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.ymd && this.ymd.setMinDate(minDate); + this.dynamicPane && this.dynamicPane.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.ymd && this.ymd.setMaxDate(maxDate); + this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); + } + } + + setValue(v) { + this.storeValue = v; + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + this._setInnerValue(); + break; + case DynamicDateCombo.Static: + default: + if (this._checkValueValid(value)) { + const date = getDate(); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + } else { + this.ymd.setValue(value); + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + } + this.todayButton.setEnable(!this._checkTodayValid()); + break; + } + } + + getValue() { + return { + type: this.dateTab.getSelect(), + value: this.dateTab.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/dynamicdate/dynamicdate.trigger.js b/packages/fineui/src/widget/dynamicdate/dynamicdate.trigger.js new file mode 100644 index 000000000..7cef929b4 --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/dynamicdate.trigger.js @@ -0,0 +1,402 @@ +import { SignEditor } from "@/case"; +import { + HTapeLayout, + AbsoluteLayout, + shortcut, + i18nText, + createWidget, + isKey, + checkDateLegal, + parseDateTime, + bind, + isNotNull, + isNotEmptyString, + isEqual, + isEmptyObject, + getDate, + isEmptyString, + isNull, + each, + checkDateVoid, + print +} from "@/core"; +import { IconButton, Text, Trigger } from "@/base"; +import { DynamicDateCombo } from "./dynamicdate.combo"; +import { DynamicDateHelper } from "./dynamicdate.caculate"; + +@shortcut() +export class DynamicDateTrigger extends Trigger { + static xtype = "bi.dynamic_date_trigger"; + + _const = { + hgap: 4, + vgap: 2, + yearLength: 4, + yearMonthLength: 6, + yearFullMonthLength: 7, + compareFormat: "%Y-%X-%d", + iconWidth: 24, + }; + + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + + props() { + return { + extraCls: "bi-date-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + iconWidth: 24, + format: "", // 显示的日期格式化方式 + allowEdit: true, // 是否允许编辑 + watermark: i18nText("BI-Basic_Unrestricted"), + }; + } + + _init() { + super._init(...arguments); + const o = this.options, + c = this._const; + this.storeTriggerValue = ""; + this.editor = createWidget({ + type: SignEditor.xtype, + simple: o.simple, + height: o.height, + validationChecker: v => { + const formatStr = this._getStandardDateStr(v); + const date = formatStr.match(/\d+/g); + !isKey(o.format) && this._autoAppend(v, date); + + return ( + this._dateCheck(formatStr) && + checkDateLegal(formatStr) && + this._checkVoid({ + year: date[0] | 0, + month: date[1] | 0, + day: date[2] | 0, + }) + ); + }, + quitChecker() { + return false; + }, + hgap: c.hgap, + vgap: c.vgap, + allowBlank: true, + watermark: o.watermark, + errorText: v => { + let str = ""; + if (!isKey(o.format)) { + if (!this._dateCheck(v)) { + str = this.editor.isEditing() + ? i18nText("BI-Date_Trigger_Error_Text") + : i18nText("BI-Year_Trigger_Invalid_Text"); + } else { + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + str = i18nText( + "BI-Basic_Date_Range_Error", + start.getFullYear(), + start.getMonth() + 1, + start.getDate(), + end.getFullYear(), + end.getMonth() + 1, + end.getDate() + ); + } + } + + return str; + }, + title: bind(this._getTitle, this), + }); + this.editor.on(SignEditor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(DynamicDateTrigger.EVENT_KEY_DOWN, ...args); + }); + this.editor.on(SignEditor.EVENT_FOCUS, () => { + this.storeTriggerValue = this.getKey(); + this.fireEvent(DynamicDateTrigger.EVENT_FOCUS); + }); + this.editor.on(SignEditor.EVENT_BLUR, () => { + this.fireEvent(DynamicDateTrigger.EVENT_BLUR); + }); + this.editor.on(SignEditor.EVENT_STOP, () => { + this.fireEvent(DynamicDateTrigger.EVENT_STOP); + }); + this.editor.on(SignEditor.EVENT_VALID, () => { + this.fireEvent(DynamicDateTrigger.EVENT_VALID); + }); + this.editor.on(SignEditor.EVENT_ERROR, () => { + this.fireEvent(DynamicDateTrigger.EVENT_ERROR); + }); + this.editor.on(SignEditor.EVENT_CONFIRM, () => { + const value = this.editor.getValue(); + if (isNotNull(value)) { + this.editor.setState(value); + } + + if (isNotEmptyString(value) && !isEqual(this.storeTriggerValue, this.getKey())) { + const formatStr = this._getStandardDateStr(value); + const date = formatStr.match(/\d+/g); + this.storeValue = { + type: DynamicDateCombo.Static, + value: { + year: date[0] | 0, + month: date[1] | 0, + day: date[2] | 0, + }, + }; + } + this.fireEvent(DynamicDateTrigger.EVENT_CONFIRM); + }); + this.editor.on(SignEditor.EVENT_SPACE, () => { + if (this.editor.isValid()) { + this.editor.blur(); + } + }); + this.editor.on(SignEditor.EVENT_START, () => { + this.fireEvent(DynamicDateTrigger.EVENT_START); + }); + this.editor.on(SignEditor.EVENT_CHANGE, () => { + this.fireEvent(DynamicDateTrigger.EVENT_CHANGE); + }); + createWidget({ + type: HTapeLayout.xtype, + element: this, + columnSize: ["", this._const.iconWidth], + items: [ + { + el: this.editor, + }, + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-font", + width: this._const.iconWidth, + }, + width: this._const.iconWidth, + } + ], + }); + !o.allowEdit && + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Text.xtype, + title: bind(this._getTitle, this), + }, + left: 0, + right: o.iconWidth, + top: 0, + bottom: 0, + } + ], + }); + this.setValue(o.value); + } + + _getTitle() { + const storeValue = this.storeValue || {}; + if (isEmptyObject(storeValue)) { + return this.options.watermark; + } + const type = storeValue.type || DynamicDateCombo.Static; + const value = storeValue.value; + let text, date, dateStr; + switch (type) { + case DynamicDateCombo.Dynamic: + text = this._getText(value); + date = getDate(); + date = DynamicDateHelper.getCalculation(value); + dateStr = print(date, this._getFormatString()); + + return isEmptyString(text) ? dateStr : `${text}:${dateStr}`; + case DynamicDateCombo.Static: + default: + if (isNull(value) || isNull(value.day)) { + return ""; + } + + return print(getDate(value.year, value.month - 1, value.day), this._getFormatString()); + } + } + + _getStandardDateStr(v) { + const c = this._const; + let result = [0, 1, 2]; + const formatArray = this._getFormatString().match(/%./g); + each(formatArray, (idx, v) => { + switch (v) { + case "%Y": + case "%y": + result[0] = idx; + break; + case "%X": + case "%x": + result[1] = idx; + break; + case "%d": + case "%e": + default: + result[2] = idx; + break; + } + }); + // 这边不能直接用\d+去切日期, 因为format格式可能是20190607这样的没有分割符的 = = + // 先看一下是否是合法的, 如果合法就变成标准格式的走原来的流程, 不合法不关心 + const date = parseDateTime(v, this._getFormatString()); + if (print(date, this._getFormatString()) === v) { + v = print(date, c.compareFormat); + result = [0, 1, 2]; + } + const dateArray = v.match(/\d+/g); + const newArray = []; + each(dateArray, idx => { + newArray[idx] = dateArray[result[idx]]; + }); + // 这边之所以不直接返回join结果是因为年的格式可能只有2位,所以需要format一下 + if (newArray.length === result.length && newArray[0].length === 2) { + return print(parseDateTime(newArray.join("-"), c.compareFormat), c.compareFormat); + } + + // 这边format成-20-也没关系, 反正都是不合法的 + return newArray.join("-"); + } + + _getFormatString() { + return this.options.format || this._const.compareFormat; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || + print(parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || + print(parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || + print(parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date + ); + } + + _checkVoid(obj) { + return !checkDateVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0]; + } + + _autoAppend(v, dateObj) { + const splitMonth = v.split("-")[1]; + if (isNotNull(dateObj) && checkDateLegal(v)) { + switch (v.length) { + case this._const.yearLength: + if (this._yearCheck(v)) { + this.editor.setValue(`${v}-`); + } + break; + case this._const.yearMonthLength: + case this._const.yearFullMonthLength: + if ((isNotNull(splitMonth) && splitMonth.length === 2) || this._monthCheck(v)) { + this.editor.setValue(`${v}-`); + } + break; + default: + } + } + } + + _yearCheck(v) { + const date = print(parseDateTime(v, this._getFormatString()), this._const.compareFormat); + + return print(parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; + } + + _monthCheck(v) { + const date = parseDateTime(v, this._getFormatString()); + const dateStr = print(date, this._const.compareFormat); + + return ( + date.getMonth() >= 0 && + (print(parseDateTime(v, "%Y-%X"), "%Y-%X") === v || print(parseDateTime(v, "%Y-%x"), "%Y-%x") === v) && + dateStr >= this.options.min && + dateStr <= this.options.max + ); + } + + _setInnerValue(date) { + const dateStr = print(date, this._getFormatString()); + this.editor.setState(dateStr); + this.editor.setValue(dateStr); + } + + _getText(obj) { + return DynamicDateHelper.getDescription(obj); + } + + setValue(v) { + let type, value, text; + let date = getDate(); + this.storeValue = v; + if (isNotNull(v)) { + type = v.type || DynamicDateCombo.Static; + value = v.value || v; + } + switch (type) { + case DynamicDateCombo.Dynamic: + text = this._getText(value); + date = DynamicDateHelper.getCalculation(value); + this._setInnerValue(date, text); + break; + case DynamicDateCombo.Static: + default: + if (isNull(value) || isNull(value.day)) { + this.editor.setState(""); + this.editor.setValue(""); + } else { + const dateStr = print(getDate(value.year, value.month - 1, value.day), this._getFormatString()); + this.editor.setState(dateStr); + this.editor.setValue(dateStr); + } + break; + } + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.storeValue; + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/dynamicdate/index.js b/packages/fineui/src/widget/dynamicdate/index.js new file mode 100644 index 000000000..5e3f3bf89 --- /dev/null +++ b/packages/fineui/src/widget/dynamicdate/index.js @@ -0,0 +1,6 @@ +export { DynamicDateHelper } from "./dynamicdate.caculate"; +export { DynamicDateCard } from "./dynamicdate.card"; +export { DynamicDateCombo } from "./dynamicdate.combo"; +export { DynamicDateParamItem } from "./dynamicdate.param.item"; +export { DynamicDatePopup } from "./dynamicdate.popup"; +export { DynamicDateTrigger } from "./dynamicdate.trigger"; diff --git a/src/widget/dynamicdatetime/__test__/dynamicdatetime.test.js b/packages/fineui/src/widget/dynamicdatetime/__test__/dynamicdatetime.test.js similarity index 100% rename from src/widget/dynamicdatetime/__test__/dynamicdatetime.test.js rename to packages/fineui/src/widget/dynamicdatetime/__test__/dynamicdatetime.test.js diff --git a/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.combo.js b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.combo.js new file mode 100644 index 000000000..97f916acb --- /dev/null +++ b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.combo.js @@ -0,0 +1,392 @@ +import { + AbsoluteLayout, + HorizontalFillLayout, + shortcut, + getDate, + toPix, + isEqual, + isNotEmptyString, + isEmptyString, + isNotNull, + isNotEmptyObject, + checkDateVoid +} from "@/core"; +import { Combo, IconButton, Single } from "@/base"; +import { DynamicDateTimeTrigger } from "./dynamicdatetime.trigger"; +import { DynamicDateTimePopup } from "./dynamicdatetime.popup"; +import { DynamicDateCombo } from "../dynamicdate"; + +@shortcut() +export class DynamicDateTimeCombo extends Single { + static xtype = "bi.dynamic_date_time_combo"; + + static Static = 1; + static Dynamic = 2; + + constants = { + popupHeight: 259, + popupWidth: 270, + comboAdjustHeight: 1, + border: 1, + iconWidth: 24 + }; + + props = () => { + const date = getDate(); + return { + baseCls: "bi-dynamic-date--time-combo", + height: 24, + minDate: "1900-01-01", + maxDate: "2099-12-31", + format: "", + allowEdit: true, + supportDynamic: true, + attributes: { + tabIndex: -1 + }, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + value: { + type: DynamicDateTimeCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1 + } + } + }; + }; + + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _init() { + super._init(...arguments); + } + + render() { + const opts = this.options; + this.storeTriggerValue = ""; + const date = getDate(); + this.storeValue = opts.value; + const border = opts.simple ? 1 : 2; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + cls: `${opts.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + destroyWhenHide: true, + container: opts.container, + ref: _ref => { + this.combo = _ref; + }, + toggle: false, + isNeedAdjustHeight: opts.isNeedAdjustHeight, + isNeedAdjustWidth: opts.isNeedAdjustWidth, + el: { + type: HorizontalFillLayout.xtype, + columnSize: [this.constants.iconWidth, "fill"], + height: toPix(opts.height, border), + items: [ + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-change-h-font", + width: this.constants.iconWidth, + height: toPix(opts.height, border), + ref: _ref => { + this.changeIcon = _ref; + } + } + }, + { + type: DynamicDateTimeTrigger.xtype, + simple: opts.simple, + min: opts.minDate, + max: opts.maxDate, + allowEdit: opts.allowEdit, + watermark: opts.watermark, + format: opts.format, + iconWidth: this.constants.iconWidth, + height: toPix(opts.height, border), + value: opts.value, + ref: _ref => { + this.trigger = _ref; + }, + listeners: [ + { + eventName: DynamicDateTimeTrigger.EVENT_KEY_DOWN, + action: (...args) => { + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } + this.fireEvent(DynamicDateTimeCombo.EVENT_KEY_DOWN, ...args); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_STOP, + action: () => { + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_TRIGGER_CLICK, + action: () => { + this.combo.toggle(); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_FOCUS, + action: () => { + this.storeTriggerValue = this.trigger.getKey(); + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + this.fireEvent(DynamicDateTimeCombo.EVENT_FOCUS); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_BLUR, + action: () => { + this.fireEvent(DynamicDateTimeCombo.EVENT_BLUR); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_ERROR, + action: () => { + this.storeValue = { + type: DynamicDateTimeCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1 + } + }; + this.combo.element.addClass("error"); + this.fireEvent(DynamicDateTimeCombo.EVENT_ERROR); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_VALID, + action: () => { + this.storeValue = this.trigger.getValue(); + this.combo.element.removeClass("error"); + this.fireEvent(DynamicDateTimeCombo.EVENT_VALID); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateTimeCombo.EVENT_CHANGE); + } + }, + { + eventName: DynamicDateTimeTrigger.EVENT_CONFIRM, + action: () => { + const dateStore = this.storeTriggerValue; + const dateObj = this.trigger.getKey(); + if (this.combo.isViewVisible() || isEqual(dateObj, dateStore)) { + return; + } + if (isNotEmptyString(dateObj) && !isEqual(dateObj, dateStore)) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.trigger.getValue()); + } else if (isEmptyString(dateObj)) { + this.storeValue = null; + this.trigger.setValue(); + } + this._checkDynamicValue(this.storeValue); + this.fireEvent(DynamicDateTimeCombo.EVENT_CONFIRM); + } + } + ] + } + ] + }, + adjustLength: this.constants.comboAdjustHeight, + popup: { + el: { + type: DynamicDateTimePopup.xtype, + width: opts.isNeedAdjustWidth ? opts.width : undefined, + supportDynamic: opts.supportDynamic, + behaviors: opts.behaviors, + min: opts.minDate, + max: opts.maxDate, + ref: _ref => { + this.popup = _ref; + }, + listeners: [ + { + eventName: DynamicDateTimePopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.combo.hideView(); + this.fireEvent(DynamicDateTimeCombo.EVENT_CONFIRM); + } + }, + { + eventName: DynamicDateTimePopup.BUTTON_lABEL_EVENT_CHANGE, + action: () => { + const date = getDate(); + this.setValue({ + type: DynamicDateTimeCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + hour: 0, + minute: 0, + second: 0 + } + }); + this.combo.hideView(); + this.fireEvent(DynamicDateTimeCombo.EVENT_CONFIRM); + } + }, + { + eventName: DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + const value = this.popup.getValue(); + if (this._checkValue(value)) { + this.setValue(value); + } + this.combo.hideView(); + this.fireEvent(DynamicDateTimeCombo.EVENT_CONFIRM); + } + }, + { + eventName: DynamicDateTimePopup.EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicDateTimeCombo.EVENT_CONFIRM); + } + }, + { + eventName: DynamicDateTimePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, + action: () => { + this.fireEvent(DynamicDateTimeCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + } + } + ] + } + }, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.popup.setMinDate(opts.minDate); + this.popup.setMaxDate(opts.maxDate); + this.popup.setValue(this.storeValue); + this.fireEvent(DynamicDateTimeCombo.EVENT_BEFORE_POPUPVIEW); + } + } + ] + // // DEC-4250 和复选下拉一样,点击不收起 + // hideChecker: function (e) { + // return self.triggerBtn.element.find(e.target).length === 0; + // } + }, + top: 0, + left: 0, + right: 0, + bottom: 0 + } + ] + }; + } + + created() { + this._checkDynamicValue(this.storeValue); + } + + _checkDynamicValue(v) { + let type = null; + if (isNotNull(v)) { + type = v.type; + } + switch (type) { + case DynamicDateTimeCombo.Dynamic: + this.changeIcon.setVisible(true); + // this.comboWrapper.attr("items")[0].width = o.height - (this.options.simple ? 1 : 2); + // this.comboWrapper.resize(); + break; + default: + // this.comboWrapper.attr("items")[0].width = 0; + // this.comboWrapper.resize(); + this.changeIcon.setVisible(false); + break; + } + } + + _checkValue(v) { + const o = this.options; + const value = v.value || {}; + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: + return !checkDateVoid(value.year, value.month, value.day, o.minDate, o.maxDate)[0]; + default: + return true; + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.trigger.setMinDate(minDate); + this.popup && this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.trigger.setMaxDate(maxDate); + this.popup && this.popup.setMaxDate(maxDate); + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + this._checkDynamicValue(v); + } + + getValue() { + return this.storeValue; + } + + getKey() { + return this.trigger.getKey(); + } + + hidePopupView() { + this.combo.hideView(); + } + + isValid() { + return this.trigger.isValid(); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.popup.js b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.popup.js new file mode 100644 index 000000000..6668ca462 --- /dev/null +++ b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.popup.js @@ -0,0 +1,336 @@ +import { + VerticalLayout, + GridLayout, + shortcut, + Widget, + createWidget, + toPix, + i18nText, + createItems, + print, + isNull, + isEmptyObject, + isEmptyString, + getDate, + checkDateVoid, + extend, + SIZE_CONSANTS +} from "@/core"; +import { TextButton, Tab } from "@/base"; +import { LinearSegment } from "@/case"; +import { DynamicDateCard, DynamicDateCombo, DynamicDateHelper } from "../dynamicdate"; +import { DateCalendarPopup } from "../date/calendar"; +import { DynamicDateTimeSelect } from "./dynamicdatetime.timeselect"; +import { DynamicDateTimeCombo } from "./dynamicdatetime.combo"; + +@shortcut() +export class DynamicDateTimePopup extends Widget { + static xtype = "bi.dynamic_date_time_popup"; + + constants = { + tabHeight: 40, + buttonHeight: 24, + }; + + props = { + baseCls: "bi-dynamic-date-time-popup", + width: 272, + supportDynamic: true, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _init() { + super._init(...arguments); + const opts = this.options; + this.storeValue = { + type: DynamicDateCombo.Static, + }; + createWidget({ + element: this, + type: VerticalLayout.xtype, + items: [ + { + el: this._getTabJson(), + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_Clear"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateTimePopup.BUTTON_CLEAR_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Multi_Date_Today"), + disabled: this._checkTodayValid(), + ref: _ref => { + this.todayButton = _ref; + }, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicDateTimePopup.BUTTON_lABEL_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent(DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE); + } else { + this.fireEvent(DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE); + } + }, + } + ], + } + ] + ], + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }, + } + ], + }); + this.setValue(opts.value); + } + + _getTabJson() { + const o = this.options; + + return { + type: Tab.xtype, + logic: { + dynamic: true, + }, + ref: _ref => { + this.dateTab = _ref; + }, + tab: { + type: LinearSegment.xtype, + invisible: !o.supportDynamic, + cls: "bi-split-bottom", + height: this.constants.tabHeight, + items: createItems( + [ + { + text: i18nText("BI-Multi_Date_YMD"), + value: DynamicDateCombo.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicDateCombo.Dynamic, + } + ], + { + textAlign: "center", + } + ), + }, + cardCreator: v => { + switch (v) { + case DynamicDateCombo.Dynamic: + return { + type: DynamicDateCard.xtype, + cls: "dynamic-date-pane", + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._setInnerValue(this.year, v); + }, + } + ], + ref: _ref => { + this.dynamicPane = _ref; + }, + min: this.options.min, + max: this.options.max, + }; + case DynamicDateCombo.Static: + default: + return { + type: VerticalLayout.xtype, + items: [ + { + type: DateCalendarPopup.xtype, + behaviors: o.behaviors, + min: this.options.min, + max: this.options.max, + ref: _ref => { + this.ymd = _ref; + }, + listeners: [ + { + eventName: DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, + action: () => { + this.fireEvent(DynamicDateTimePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + } + ], + }, + { + el: { + type: DynamicDateTimeSelect.xtype, + cls: "bi-split-top", + ref: _ref => { + this.timeSelect = _ref; + }, + height: 40, + }, + } + ], + }; + } + }, + listeners: [ + { + eventName: Tab.EVENT_CHANGE, + action: () => { + const v = this.dateTab.getSelect(); + const date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + switch (v) { + case DynamicDateCombo.Static: + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + this.timeSelect.setValue(); + this._setInnerValue(); + break; + case DynamicDateCombo.Dynamic: + default: + if (this.storeValue && this.storeValue.type === DynamicDateCombo.Dynamic) { + this.dynamicPane.setValue(this.storeValue.value); + } else { + this.dynamicPane.setValue({ + year: 0, + }); + } + this._setInnerValue(); + break; + } + }, + } + ], + }; + } + + _setInnerValue() { + if (this.dateTab.getSelect() === DynamicDateCombo.Static) { + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + this.todayButton.setEnable(!this._checkTodayValid()); + } else { + let date = DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); + date = print(date, "%Y-%X-%d"); + this.todayButton.setValue(date); + this.todayButton.setEnable(false); + } + } + + _checkValueValid(value) { + return isNull(value) || isEmptyObject(value) || isEmptyString(value); + } + + _checkTodayValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.ymd.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.ymd.setMaxDate(maxDate); + } + } + + setValue(v) { + this.storeValue = v; + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + this._setInnerValue(); + break; + case DynamicDateCombo.Static: + default: + if (this._checkValueValid(value)) { + const date = getDate(); + this.ymd.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }); + this.timeSelect.setValue(); + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + } else { + this.ymd.setValue(value); + this.timeSelect.setValue({ + hour: value.hour, + minute: value.minute, + second: value.second, + }); + this.todayButton.setValue(i18nText("BI-Multi_Date_Today")); + } + this.todayButton.setEnable(!this._checkTodayValid()); + break; + } + } + + getValue() { + const type = this.dateTab.getSelect(); + + return { + type, + value: + type === DynamicDateTimeCombo.Static + ? extend(this.ymd.getValue(), this.timeSelect.getValue()) + : this.dynamicPane.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js new file mode 100644 index 000000000..45355275b --- /dev/null +++ b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js @@ -0,0 +1,260 @@ +import { + CenterAdaptLayout, + VerticalAdaptLayout, + shortcut, + Widget, + isNaturalNumber, + parseInt, + isNumeric, + i18nText, + isNull, + isEmptyString, + SIZE_CONSANTS +} from "@/core"; +import { NumberEditor } from "../numbereditor/number.editor"; +import { Label } from "@/base"; +import { SignEditor } from "@/case"; + +@shortcut() +export class DynamicDateTimeSelect extends Widget { + static xtype = "bi.dynamic_date_time_select"; + + static HOUR = 1; + static MINUTE = 2; + static SECOND = 3; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + props () { + return { + baseCls: "bi-date-time-select", + editorHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }; + } + + render() { + const { editorHeight } = this.options; + + return { + type: CenterAdaptLayout.xtype, + items: [ + { + type: VerticalAdaptLayout.xtype, + items: [ + { + el: { + type: NumberEditor.xtype, + ref: _ref => { + this.hour = _ref; + }, + validationChecker(v) { + return isNaturalNumber(v) && parseInt(v) < 24; + }, + errorText(v) { + if (isNumeric(v)) { + return i18nText("BI-Basic_Input_From_To_Number", "\"00-23\""); + } + + return i18nText("BI-Numerical_Interval_Input_Data"); + }, + listeners: [ + { + eventName: SignEditor.EVENT_CONFIRM, + action: () => { + const value = this.hour.getValue(); + this._checkHour(value); + this.hour.setValue(this._formatValueToDoubleDigit(value)); + this.fireEvent(DynamicDateTimeSelect.EVENT_CONFIRM); + }, + }, + { + eventName: SignEditor.EVENT_CHANGE, + action: () => { + const value = this._autoSwitch( + this.hour.getValue(), + DynamicDateTimeSelect.HOUR + ); + this.hour.setValue(value); + }, + } + ], + width: 60, + height: editorHeight, + }, + }, + { + type: Label.xtype, + text: ":", + width: 20, + }, + { + type: NumberEditor.xtype, + ref: _ref => { + this.minute = _ref; + }, + validationChecker(v) { + return isNaturalNumber(v) && parseInt(v) < 60; + }, + errorText(v) { + if (isNumeric(v)) { + return i18nText("BI-Basic_Input_From_To_Number", "\"00-59\""); + } + + return i18nText("BI-Numerical_Interval_Input_Data"); + }, + listeners: [ + { + eventName: SignEditor.EVENT_CONFIRM, + action: () => { + const value = this.minute.getValue(); + this._checkMinute(value); + this.minute.setValue( + this._formatValueToDoubleDigit(value), + DynamicDateTimeSelect.MINUTE + ); + this.fireEvent(DynamicDateTimeSelect.EVENT_CONFIRM); + }, + }, + { + eventName: SignEditor.EVENT_CHANGE, + action: () => { + const value = this._autoSwitch(this.minute.getValue(), DynamicDateTimeSelect.MINUTE); + this.minute.setValue(value); + }, + } + ], + width: 60, + height: editorHeight, + }, + { + type: Label.xtype, + text: ":", + width: 20, + }, + { + type: NumberEditor.xtype, + ref: _ref => { + this.second = _ref; + }, + validationChecker(v) { + return isNaturalNumber(v) && parseInt(v) < 60; + }, + errorText(v) { + if (isNumeric(v)) { + return i18nText("BI-Basic_Input_From_To_Number", "\"00-59\""); + } + + return i18nText("BI-Numerical_Interval_Input_Data"); + }, + listeners: [ + { + eventName: SignEditor.EVENT_CONFIRM, + action: () => { + const value = this.second.getValue(); + this._checkSecond(value); + this.second.setValue(this._formatValueToDoubleDigit(value)); + this.fireEvent(DynamicDateTimeSelect.EVENT_CONFIRM); + }, + } + ], + width: 60, + height: editorHeight, + } + ], + } + ], + }; + } + + _checkBorder(v) { + v = v || {}; + this._checkHour(v.hour); + this._checkMinute(v.minute); + this._checkSecond(v.second); + } + + _checkHour(value) { + this.hour.setDownEnable(parseInt(value) > 0); + this.hour.setUpEnable(parseInt(value) < 23); + } + + _checkMinute(value) { + this.minute.setDownEnable(parseInt(value) > 0); + this.minute.setUpEnable(parseInt(value) < 59); + } + + _checkSecond(value) { + this.second.setDownEnable(parseInt(value) > 0); + this.second.setUpEnable(parseInt(value) < 59); + } + + _autoSwitch(v, type) { + let limit = 0; + let value = `${v}`; + switch (type) { + case DynamicDateTimeSelect.HOUR: + limit = 2; + break; + case DynamicDateTimeSelect.MINUTE: + limit = 5; + break; + default: + break; + } + if (value.length === 1 && parseInt(value) > limit) { + value = `0${value}`; + } + if (value.length === 2) { + switch (type) { + case DynamicDateTimeSelect.HOUR: + this.hour.isEditing() && this.minute.focus(); + break; + case DynamicDateTimeSelect.MINUTE: + this.minute.isEditing() && this.second.focus(); + break; + case DynamicDateTimeSelect.SECOND: + default: + break; + } + } + + return value; + } + + _formatValueToDoubleDigit(v) { + if (isNull(v) || isEmptyString(v)) { + v = 0; + } + let value = parseInt(v); + if (value < 10) { + value = `0${value}`; + } + + return value; + } + + _assertValue(v) { + v = v || {}; + v.hour = this._formatValueToDoubleDigit(v.hour) || "00"; + v.minute = this._formatValueToDoubleDigit(v.minute) || "00"; + v.second = this._formatValueToDoubleDigit(v.second) || "00"; + + return v; + } + + getValue() { + return { + hour: parseInt(this.hour.getValue()), + minute: parseInt(this.minute.getValue()), + second: parseInt(this.second.getValue()), + }; + } + + setValue(v) { + v = this._assertValue(v); + this.hour.setValue(v.hour); + this.minute.setValue(v.minute); + this.second.setValue(v.second); + this._checkBorder(v); + } +} diff --git a/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.trigger.js b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.trigger.js new file mode 100644 index 000000000..d0badcfe7 --- /dev/null +++ b/packages/fineui/src/widget/dynamicdatetime/dynamicdatetime.trigger.js @@ -0,0 +1,512 @@ +import { SignEditor } from "@/case"; +import { + HTapeLayout, + AbsoluteLayout, + shortcut, + i18nText, + createWidget, + isKey, + checkDateLegal, + parseDateTime, + bind, + isNotNull, + isNotEmptyString, + isEqual, + isEmptyObject, + isEmptyString, + isNull, + getDate, + each, + isNumeric, + checkDateVoid, + parseInt, + size, + print +} from "@/core"; +import { IconButton, Text, Trigger } from "@/base"; +import { DynamicDateCombo, DynamicDateCard, DynamicDateHelper } from "../dynamicdate"; + +@shortcut() +export class DynamicDateTimeTrigger extends Trigger { + static xtype = "bi.dynamic_date_time_trigger"; + + _const = { + hgap: 4, + vgap: 2, + yearLength: 4, + yearMonthLength: 6, + yearFullMonthLength: 7, + compareFormat: "%Y-%X-%d %H:%M:%S", + iconWidth: 24, + }; + + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + + props() { + return { + extraCls: "bi-date-time-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + iconWidth: 24, + format: "", // 显示的日期格式化方式 + allowEdit: true, // 是否允许编辑 + watermark: i18nText("BI-Basic_Unrestricted"), + }; + } + + _init() { + super._init(...arguments); + const o = this.options, + c = this._const; + this.storeTriggerValue = ""; + this.editor = createWidget({ + type: SignEditor.xtype, + simple: o.simple, + height: o.height, + validationChecker: v => { + const formatStr = this._getStandardDateStr(v); + const date = formatStr.match(/\d+/g); + !isKey(o.format) && this._autoAppend(v, date); + + return ( + this._dateCheck(formatStr) && + checkDateLegal(formatStr) && + this._checkVoid({ + year: date[0] | 0, + month: date[1] | 0, + day: date[2] | 0, + }) + ); + }, + quitChecker() { + return false; + }, + hgap: c.hgap, + vgap: c.vgap, + allowBlank: true, + watermark: o.watermark, + errorText: v => { + let str = ""; + if (!isKey(o.format)) { + if (!this._dateCheck(v)) { + str = this.editor.isEditing() + ? i18nText("BI-Date_Trigger_Error_Text") + : i18nText("BI-Year_Trigger_Invalid_Text"); + } else { + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + str = i18nText( + "BI-Basic_Date_Range_Error", + start.getFullYear(), + start.getMonth() + 1, + start.getDate(), + end.getFullYear(), + end.getMonth() + 1, + end.getDate() + ); + } + } + + return str; + }, + title: bind(this._getTitle, this), + }); + this.editor.on(SignEditor.EVENT_KEY_DOWN, (...args) => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_KEY_DOWN, ...args); + }); + this.editor.on(SignEditor.EVENT_FOCUS, () => { + this.storeTriggerValue = this.getKey(); + this.fireEvent(DynamicDateTimeTrigger.EVENT_FOCUS); + }); + this.editor.on(SignEditor.EVENT_BLUR, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_BLUR); + }); + this.editor.on(SignEditor.EVENT_STOP, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_STOP); + }); + this.editor.on(SignEditor.EVENT_VALID, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_VALID); + }); + this.editor.on(SignEditor.EVENT_ERROR, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_ERROR); + }); + this.editor.on(SignEditor.EVENT_CONFIRM, () => { + const value = this.editor.getValue(); + if (isNotNull(value)) { + this.editor.setState(value); + } + + if (isNotEmptyString(value) && !isEqual(this.storeTriggerValue, this.getKey())) { + const formatStr = this._getStandardDateStr(value); + const date = formatStr.match(/\d+/g); + this.storeValue = { + type: DynamicDateCombo.Static, + value: { + year: date[0] | 0, + month: date[1] | 0, + day: date[2] | 0, + hour: date[3] | 0, + minute: date[4] | 0, + second: date[5] | 0, + }, + }; + } + this.fireEvent(DynamicDateTimeTrigger.EVENT_CONFIRM); + }); + this.editor.on(SignEditor.EVENT_START, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_START); + }); + this.editor.on(SignEditor.EVENT_CHANGE, () => { + this.fireEvent(DynamicDateTimeTrigger.EVENT_CHANGE); + }); + createWidget({ + type: HTapeLayout.xtype, + element: this, + columnSize: ["", this._const.iconWidth], + items: [ + { + el: this.editor, + }, + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-font", + }, + width: o.iconWidth, + } + ], + }); + + !o.allowEdit && + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Text.xtype, + title: bind(this._getTitle, this), + }, + left: 0, + right: o.iconWidth, + top: 0, + bottom: 0, + } + ], + }); + this.setValue(o.value); + } + + _getTitle() { + const o = this.options; + const storeValue = this.storeValue || {}; + if (isEmptyObject(storeValue)) { + return o.watermark; + } + const type = storeValue.type || DynamicDateCombo.Static; + const value = storeValue.value; + const text = this._getText(value); + const date = DynamicDateHelper.getCalculation(value); + const dateStr = print(date, this._getFormatString()); + + switch (type) { + case DynamicDateCombo.Dynamic: + return isEmptyString(text) ? dateStr : `${text}:${dateStr}`; + case DynamicDateCombo.Static: + default: + if (isNull(value) || isNull(value.day)) { + return ""; + } + + return print( + getDate( + value.year, + value.month - 1, + value.day, + value.hour || 0, + value.minute || 0, + value.second || 0 + ), + this._getFormatString() + ); + } + } + + _getStandardDateStr(v) { + const c = this._const; + let result = []; + let hasSecond = false; + const formatArray = this._getFormatString().match(/%./g); + each(formatArray, (idx, v) => { + switch (v) { + case "%Y": + case "%y": + result[0] = idx; + break; + case "%X": + case "%x": + result[1] = idx; + break; + case "%d": + case "%e": + result[2] = idx; + break; + case "%S": + hasSecond = true; + break; + default: + break; + } + }); + // 这边不能直接用\d+去切日期, 因为format格式可能是20190607这样的没有分割符的 = = + // 先看一下是否是合法的, 如果合法就变成标准格式的走原来的流程, 不合法不关心 + const date = parseDateTime(v, this._getFormatString()); + if (print(date, this._getFormatString()) === v) { + v = print(date, c.compareFormat); + result = [0, 1, 2]; + } + const dateArray = v.match(/\d+/g) || []; + const newArray = []; + // 处理乱序的年月日 + each(dateArray.slice(0, 3), idx => { + newArray[idx] = dateArray[result[idx]]; + }); + // 拼接时分秒和pm + const suffixArray = dateArray.slice(3); + // 时分秒补0 + each(suffixArray, (idx, v) => { + isNumeric(v) && v.length === 1 && (suffixArray[idx] = `0${v}`); + }); + // hh:mm + if (suffixArray.length === 2 && !hasSecond) { + suffixArray.push("00"); + } + const suffixString = suffixArray.join(":"); + let dateString = newArray.slice(0, 3).join("-"); + if (isNotEmptyString(suffixString)) { + dateString += ` ${suffixString}`; + } + + return dateString; + } + + _getFormatString() { + return this.options.format || this._const.compareFormat; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%x-%d %H:%M:%S"), "%Y-%x-%d %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%x-%e %H:%M:%S"), "%Y-%x-%e %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%X-%e %H:%M:%S"), "%Y-%X-%e %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || + print(parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || + print(parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || + print(parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date + ); + } + + _checkVoid(obj) { + return !checkDateVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0]; + } + + _autoAppend(v, dateObj) { + if (isNotNull(dateObj) && checkDateLegal(v)) { + const splitMonth = v.split("-")[1]; + switch (v.length) { + case this._const.yearLength: + if (this._yearCheck(v)) { + this.editor.setValue(`${v}-`); + } + break; + case this._const.yearMonthLength: + case this._const.yearFullMonthLength: + if ((isNotNull(splitMonth) && splitMonth.length === 2) || this._monthCheck(v)) { + this.editor.setValue(`${v}-`); + } + break; + default: + } + } + } + + _yearCheck(v) { + const date = print(parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); + + return print(parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; + } + + _monthCheck(v) { + const date = parseDateTime(v, "%Y-%X-%d"); + const dateStr = print(date, "%Y-%X-%d"); + + return ( + date.getMonth() > 0 && + (print(parseDateTime(v, "%Y-%X"), "%Y-%X") === v || print(parseDateTime(v, "%Y-%x"), "%Y-%x") === v) && + dateStr >= this.options.min && + dateStr <= this.options.max + ); + } + + _setInnerValue(date) { + const dateStr = print(date, this._getFormatString()); + this.editor.setState(dateStr); + this.editor.setValue(dateStr); + } + + _getText(obj) { + let value = ""; + let endText = ""; + if (isNotNull(obj.year)) { + if (parseInt(obj.year) !== 0) { + value += + Math.abs(obj.year) + + i18nText("BI-Basic_Year") + + (obj.year < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Year"), obj.position); + } + if (isNotNull(obj.quarter)) { + if (parseInt(obj.quarter) !== 0) { + value += + Math.abs(obj.quarter) + + i18nText("BI-Basic_Single_Quarter") + + (obj.quarter < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Single_Quarter"), obj.position); + } + if (isNotNull(obj.month)) { + if (parseInt(obj.month) !== 0) { + value += + Math.abs(obj.month) + + i18nText("BI-Basic_Month") + + (obj.month < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Month"), obj.position); + } + if (isNotNull(obj.week)) { + if (parseInt(obj.week) !== 0) { + value += + Math.abs(obj.week) + + i18nText("BI-Basic_Week") + + (obj.week < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = getPositionText(i18nText("BI-Basic_Week"), obj.position); + } + if (isNotNull(obj.day)) { + if (parseInt(obj.day) !== 0) { + value += + Math.abs(obj.day) + + i18nText("BI-Basic_Day") + + (obj.day < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + endText = size(obj) === 1 ? getPositionText(i18nText("BI-Basic_Month"), obj.position) : ""; + } + if (isNotNull(obj.workDay) && parseInt(obj.workDay) !== 0) { + value += + Math.abs(obj.workDay) + + i18nText("BI-Basic_Work_Day") + + (obj.workDay < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + + return value + endText; + + function getPositionText(baseText, position) { + switch (position) { + case DynamicDateCard.OFFSET.BEGIN: + return baseText + i18nText("BI-Basic_Begin_Start"); + case DynamicDateCard.OFFSET.END: + return baseText + i18nText("BI-Basic_End_Stop"); + case DynamicDateCard.OFFSET.CURRENT: + default: + return i18nText("BI-Basic_Current_Day"); + } + } + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + let type, value; + let date = getDate(); + this.storeValue = v; + if (isNotNull(v)) { + type = v.type || DynamicDateCombo.Static; + value = v.value || v; + } + + switch (type) { + case DynamicDateCombo.Dynamic: + const text = this._getText(value); + date = DynamicDateHelper.getCalculation(value); + this._setInnerValue(date, text); + break; + case DynamicDateCombo.Static: + default: + if (isNull(value) || isNull(value.day)) { + this.editor.setState(""); + this.editor.setValue(""); + } else { + const dateStr = print( + getDate( + value.year, + value.month - 1, + value.day, + value.hour || 0, + value.minute || 0, + value.second || 0 + ), + this._getFormatString() + ); + this.editor.setState(dateStr); + this.editor.setValue(dateStr); + } + break; + } + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.storeValue; + } + + isValid() { + return this.editor.isValid(); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/dynamicdatetime/index.js b/packages/fineui/src/widget/dynamicdatetime/index.js new file mode 100644 index 000000000..2d289174f --- /dev/null +++ b/packages/fineui/src/widget/dynamicdatetime/index.js @@ -0,0 +1,4 @@ +export { DynamicDateTimeSelect } from "./dynamicdatetime.timeselect"; +export { DynamicDateTimeCombo } from "./dynamicdatetime.combo"; +export { DynamicDateTimePopup } from "./dynamicdatetime.popup"; +export { DynamicDateTimeTrigger } from "./dynamicdatetime.trigger"; diff --git a/src/widget/editor/__test__/editor.search.test.js b/packages/fineui/src/widget/editor/__test__/editor.search.test.js similarity index 100% rename from src/widget/editor/__test__/editor.search.test.js rename to packages/fineui/src/widget/editor/__test__/editor.search.test.js diff --git a/src/widget/editor/__test__/editor.text.test.js b/packages/fineui/src/widget/editor/__test__/editor.text.test.js similarity index 100% rename from src/widget/editor/__test__/editor.text.test.js rename to packages/fineui/src/widget/editor/__test__/editor.text.test.js diff --git a/packages/fineui/src/widget/editor/editor.search.js b/packages/fineui/src/widget/editor/editor.search.js new file mode 100644 index 000000000..00909258f --- /dev/null +++ b/packages/fineui/src/widget/editor/editor.search.js @@ -0,0 +1,237 @@ +import { + shortcut, + Widget, + extend, + i18nText, + emptyFn, + createWidget, + toPix, + isKey, + Controller, + Events, + HTapeLayout, + isEndWithBlank +} from "@/core"; +import { IconButton, Editor, IconLabel } from "@/base"; + +@shortcut() +export class SearchEditor extends Widget { + static xtype = "bi.search_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_BACKSPACE = "EVENT_BACKSPACE"; + static EVENT_CLEAR = "EVENT_CLEAR"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_REMOVE = "EVENT_REMOVE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `bi-search-editor bi-focus-shadow ${ + config.simple ? "bi-border-bottom" : "bi-border bi-border-radius" + }`, + height: 24, + errorText: "", + watermark: i18nText("BI-Basic_Search"), + validationChecker: emptyFn, + quitChecker: emptyFn, + value: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget(o.el, { + type: Editor.xtype, + simple: o.simple, + height: toPix(o.height, o.simple ? 1 : 2), + watermark: o.watermark, + allowBlank: true, + hgap: 1, + errorText: o.errorText, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + value: o.value, + autoTrim: o.autoTrim, + }); + this.clear = createWidget({ + type: IconButton.xtype, + stopEvent: true, + cls: "close-font", + invisible: !isKey(o.value), + }); + this.clear.on(IconButton.EVENT_CHANGE, () => { + this.setValue(""); + this.fireEvent(Controller.EVENT_CHANGE, Events.STOPEDIT, this.getValue()); + // 从有内容到无内容的清空也是一次change + this.fireEvent(SearchEditor.EVENT_CHANGE); + this.fireEvent(SearchEditor.EVENT_CLEAR); + }); + createWidget({ + element: this, + height: toPix(o.height, o.simple ? 1 : 2), + type: HTapeLayout.xtype, + items: [ + { + el: { + type: IconLabel.xtype, + cls: "search-font", + }, + width: 24, + }, + { + el: this.editor, + }, + { + el: this.clear, + width: 24, + } + ], + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.editor.on(Editor.EVENT_FOCUS, () => { + this.fireEvent(SearchEditor.EVENT_FOCUS); + }); + this.editor.on(Editor.EVENT_BLUR, () => { + this.fireEvent(SearchEditor.EVENT_BLUR); + }); + this.editor.on(Editor.EVENT_CLICK, () => { + this.fireEvent(SearchEditor.EVENT_CLICK); + }); + this.editor.on(Editor.EVENT_CHANGE, () => { + this._checkClear(); + this.fireEvent(SearchEditor.EVENT_CHANGE); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, v => { + this.fireEvent(SearchEditor.EVENT_KEY_DOWN, v); + }); + this.editor.on(Editor.EVENT_SPACE, () => { + this.fireEvent(SearchEditor.EVENT_SPACE); + }); + this.editor.on(Editor.EVENT_BACKSPACE, () => { + this.fireEvent(SearchEditor.EVENT_BACKSPACE); + }); + + this.editor.on(Editor.EVENT_VALID, () => { + this.fireEvent(SearchEditor.EVENT_VALID); + }); + this.editor.on(Editor.EVENT_ERROR, () => { + this.fireEvent(SearchEditor.EVENT_ERROR); + }); + this.editor.on(Editor.EVENT_ENTER, () => { + this.fireEvent(SearchEditor.EVENT_ENTER); + }); + this.editor.on(Editor.EVENT_RESTRICT, () => { + this.fireEvent(SearchEditor.EVENT_RESTRICT); + }); + this.editor.on(Editor.EVENT_EMPTY, () => { + this._checkClear(); + this.fireEvent(SearchEditor.EVENT_EMPTY); + }); + this.editor.on(Editor.EVENT_REMOVE, () => { + this.fireEvent(SearchEditor.EVENT_REMOVE); + }); + this.editor.on(Editor.EVENT_CONFIRM, () => { + this.fireEvent(SearchEditor.EVENT_CONFIRM); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, () => { + this.fireEvent(SearchEditor.EVENT_CHANGE_CONFIRM); + }); + this.editor.on(Editor.EVENT_START, () => { + this.fireEvent(SearchEditor.EVENT_START); + }); + this.editor.on(Editor.EVENT_PAUSE, () => { + this.fireEvent(SearchEditor.EVENT_PAUSE); + }); + this.editor.on(Editor.EVENT_STOP, () => { + this.fireEvent(SearchEditor.EVENT_STOP); + }); + } + + _checkClear() { + if (!this.getValue()) { + this.clear.invisible(); + } else { + this.clear.visible(); + } + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + getValue() { + if (this.isValid()) { + return this.editor.getValue(); + } + } + + getKeywords() { + const val = this.editor.getLastChangedValue(); + const keywords = val.match(/[\S]+/g); + if (isEndWithBlank(val)) { + return keywords.concat([" "]); + } + + return keywords; + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(v) { + this.editor.setValue(v); + if (isKey(v)) { + this.clear.visible(); + } + } + + isEditing() { + return this.editor.isEditing(); + } + + isValid() { + return this.editor.isValid(); + } + + showClearIcon() { + this.clear.visible(); + } + + hideClearIcon() { + this.clear.invisible(); + } +} diff --git a/packages/fineui/src/widget/editor/editor.search.small.js b/packages/fineui/src/widget/editor/editor.search.small.js new file mode 100644 index 000000000..90e44de8d --- /dev/null +++ b/packages/fineui/src/widget/editor/editor.search.small.js @@ -0,0 +1,20 @@ +import { shortcut, extend } from "@/core"; +import { SearchEditor } from "./editor.search"; + +@shortcut() +export class SmallSearchEditor extends SearchEditor { + static xtype = "bi.small_search_editor"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-small-search-editor`, + height: 20, + }); + } + + _init() { + super._init(...arguments); + } +} diff --git a/packages/fineui/src/widget/editor/editor.text.js b/packages/fineui/src/widget/editor/editor.text.js new file mode 100644 index 000000000..ba87a3a5a --- /dev/null +++ b/packages/fineui/src/widget/editor/editor.text.js @@ -0,0 +1,169 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, toPix, Controller } from "@/core"; +import { Editor } from "@/base"; + +@shortcut() +export class TextEditor extends Widget { + static xtype = "bi.text_editor"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_CLICK = "EVENT_CLICK"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_SPACE = "EVENT_SPACE"; + static EVENT_BACKSPACE = "EVENT_BACKSPACE"; + static EVENT_START = "EVENT_START"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_ENTER = "EVENT_ENTER"; + static EVENT_RESTRICT = "EVENT_RESTRICT"; + static EVENT_REMOVE = "EVENT_REMOVE"; + static EVENT_EMPTY = "EVENT_EMPTY"; + + _defaultConfig(config) { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: `bi-text-editor bi-focus-shadow ${config.simple ? "bi-border-bottom" : "bi-border"}`, + hgap: 4, + vgap: 2, + lgap: 0, + rgap: 0, + tgap: 0, + bgap: 0, + validationChecker: emptyFn, + quitChecker: emptyFn, + allowBlank: false, + watermark: "", + errorText: "", + height: 24, + }); + } + + render() { + const o = this.options; + const border = o.simple ? 1 : 2; + this.editor = createWidget({ + type: Editor.xtype, + element: this, + width: toPix(o.width, border), + height: toPix(o.height, border), + simple: o.simple, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + value: o.value, + title: o.title, + tipType: o.tipType, + validationChecker: o.validationChecker, + quitChecker: o.quitChecker, + allowBlank: o.allowBlank, + watermark: o.watermark, + errorText: o.errorText, + inputType: o.inputType, + autocomplete: o.autocomplete, + autoTrim: o.autoTrim, + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + + this.editor.on(Editor.EVENT_FOCUS, () => { + this.fireEvent(TextEditor.EVENT_FOCUS); + }); + this.editor.on(Editor.EVENT_BLUR, () => { + this.fireEvent(TextEditor.EVENT_BLUR); + }); + this.editor.on(Editor.EVENT_CLICK, () => { + this.fireEvent(TextEditor.EVENT_CLICK); + }); + this.editor.on(Editor.EVENT_CHANGE, () => { + this.fireEvent(TextEditor.EVENT_CHANGE); + }); + this.editor.on(Editor.EVENT_KEY_DOWN, v => { + this.fireEvent(TextEditor.EVENT_KEY_DOWN); + }); + this.editor.on(Editor.EVENT_SPACE, v => { + this.fireEvent(TextEditor.EVENT_SPACE); + }); + this.editor.on(Editor.EVENT_BACKSPACE, v => { + this.fireEvent(TextEditor.EVENT_BACKSPACE); + }); + + this.editor.on(Editor.EVENT_VALID, () => { + this.element.removeClass("error"); + this.fireEvent(TextEditor.EVENT_VALID); + }); + this.editor.on(Editor.EVENT_CONFIRM, () => { + this.fireEvent(TextEditor.EVENT_CONFIRM); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, () => { + this.fireEvent(TextEditor.EVENT_CHANGE_CONFIRM); + }); + this.editor.on(Editor.EVENT_REMOVE, v => { + this.fireEvent(TextEditor.EVENT_REMOVE); + }); + this.editor.on(Editor.EVENT_START, () => { + this.fireEvent(TextEditor.EVENT_START); + }); + this.editor.on(Editor.EVENT_PAUSE, () => { + this.fireEvent(TextEditor.EVENT_PAUSE); + }); + this.editor.on(Editor.EVENT_STOP, () => { + this.fireEvent(TextEditor.EVENT_STOP); + }); + this.editor.on(Editor.EVENT_ERROR, (...args) => { + this.element.addClass("error"); + this.fireEvent(TextEditor.EVENT_ERROR, ...args); + }); + this.editor.on(Editor.EVENT_ENTER, () => { + this.fireEvent(TextEditor.EVENT_ENTER); + }); + this.editor.on(Editor.EVENT_RESTRICT, () => { + this.fireEvent(TextEditor.EVENT_RESTRICT); + }); + this.editor.on(Editor.EVENT_EMPTY, () => { + this.fireEvent(TextEditor.EVENT_EMPTY); + }); + } + + setWaterMark(v) { + this.options.watermark = v; + this.editor.setWaterMark(v); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isValid() { + return this.editor.isValid(); + } + + setValue(v) { + this.editor.setValue(v); + } + + getValue() { + return this.editor.getValue(); + } +} diff --git a/packages/fineui/src/widget/editor/editor.text.small.js b/packages/fineui/src/widget/editor/editor.text.small.js new file mode 100644 index 000000000..5f574fe0f --- /dev/null +++ b/packages/fineui/src/widget/editor/editor.text.small.js @@ -0,0 +1,20 @@ +import { shortcut, extend } from "@/core"; +import { TextEditor } from "./editor.text"; + +@shortcut() +export class SmallTextEditor extends TextEditor { + static xtype = "bi.small_text_editor"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-small-text-editor`, + height: 20, + }); + } + + _init() { + super._init(...arguments); + } +} diff --git a/packages/fineui/src/widget/editor/index.js b/packages/fineui/src/widget/editor/index.js new file mode 100644 index 000000000..f5b7bed83 --- /dev/null +++ b/packages/fineui/src/widget/editor/index.js @@ -0,0 +1,4 @@ +export { SearchEditor } from "./editor.search"; +export { SmallSearchEditor } from "./editor.search.small"; +export { TextEditor } from "./editor.text"; +export { SmallTextEditor } from "./editor.text.small"; diff --git a/packages/fineui/src/widget/index.js b/packages/fineui/src/widget/index.js new file mode 100644 index 000000000..b378d16ad --- /dev/null +++ b/packages/fineui/src/widget/index.js @@ -0,0 +1,40 @@ +export { Collapse } from "./collapse/collapse"; +export { SelectTreeExpander } from "./selecttree/selecttree.expander"; +export { SelectTreeCombo } from "./selecttree/selecttree.combo"; +export { SingleTreeCombo } from "./singletree/singletree.combo"; +export { MultiTreeCombo } from "./multitree/multi.tree.combo"; +export { MultiTreeInsertCombo } from "./multitree/multi.tree.insert.combo"; +export { MultiTreeListCombo } from "./multitree/multi.tree.list.combo"; +export { NumberEditor } from "./numbereditor/number.editor"; +export { NumberInterval } from "./numberinterval/numberinterval"; +export { YearMonthInterval } from "./yearmonthinterval/yearmonthinterval"; +export { YearQuarterInterval } from "./yearquarterinterval/yearquarterinterval"; +export { YearInterval } from "./yearinterval/yearinterval"; + +export * from "./date/calendar"; +export * from "./dynamicdate"; +export * from "./datepane"; +export * from "./datetime"; +export * from "./datetimepane"; +export * from "./dynamicdatetime"; +export * from "./time"; +export * from "./timeinterval"; +export * from "./editor"; +export * from "./yearmonth"; +export * from "./multiselect"; +export * from "./multiselectlist"; +export * from "./downlist"; +export * from "./singleslider"; +export * from "./intervalslider"; +export * from "./year"; +export * from "./multilayersingletree"; +export * from "./multilayerselecttree"; +export * from "./searchmultitextvaluecombo"; +export * from "./singleselect"; +export * from "./multilayerdownlist"; +export * from "./yearquarter"; +export * from "./textvaluedownlistcombo"; +export * from "./searchmultitextvaluecombo"; +export * from "./multiselecttree/multiselecttree"; +export * from "./selecttree/selecttree.popup"; +export * from "./singletree/singletree.popup"; diff --git a/src/widget/intervalslider/__test__/accuratecalculation.test.js b/packages/fineui/src/widget/intervalslider/__test__/accuratecalculation.test.js similarity index 100% rename from src/widget/intervalslider/__test__/accuratecalculation.test.js rename to packages/fineui/src/widget/intervalslider/__test__/accuratecalculation.test.js diff --git a/src/widget/intervalslider/__test__/intervalslider.test.js b/packages/fineui/src/widget/intervalslider/__test__/intervalslider.test.js similarity index 100% rename from src/widget/intervalslider/__test__/intervalslider.test.js rename to packages/fineui/src/widget/intervalslider/__test__/intervalslider.test.js diff --git a/packages/fineui/src/widget/intervalslider/index.js b/packages/fineui/src/widget/intervalslider/index.js new file mode 100644 index 000000000..cee9fd741 --- /dev/null +++ b/packages/fineui/src/widget/intervalslider/index.js @@ -0,0 +1,2 @@ +export { AccurateCalculationModel } from "./model.accuratecalculation"; +export { IntervalSlider } from "./intervalslider"; diff --git a/packages/fineui/src/widget/intervalslider/intervalslider.js b/packages/fineui/src/widget/intervalslider/intervalslider.js new file mode 100644 index 000000000..894ef7a2c --- /dev/null +++ b/packages/fineui/src/widget/intervalslider/intervalslider.js @@ -0,0 +1,614 @@ +import { + VerticalFillLayout, + HorizontalLayout, + shortcut, + createWidget, + toPix, + parseFloat, + Layout, + AbsoluteLayout, + clamp, + VerticalLayout, + isEmptyString, + isNumeric, + isNull, + isInteger, + i18nText, + size, + parseInt, + isNotEmptyString, + MouseMoveTracker +} from "@/core"; +import { Single, Editor } from "@/base"; +import { AccurateCalculationModel } from "./model.accuratecalculation"; +import { SignTextEditor, SliderIconButton } from "../singleslider"; + +@shortcut() +export class IntervalSlider extends Single { + static xtype = "bi.interval_slider"; + _constant = { + EDITOR_WIDTH: 58, + EDITOR_R_GAP: 60, + EDITOR_HEIGHT: 20, + SLIDER_WIDTH_HALF: 15, + SLIDER_WIDTH: 30, + SLIDER_HEIGHT: 30, + TRACK_HEIGHT: 24, + }; + props = { + baseCls: "bi-interval-slider bi-slider-track", + digit: false, + unit: "", + min: 0, + max: 100, + value: { min: "", max: "" }, + lAlign: "center", + rAlign: "center", + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + beforeMount() { + const { value, min, max } = this.options; + this._setMinAndMax({ + min, + max, + }); + this.setValue(value); + this.populate(); + } + + render() { + const c = this._constant; + this.enable = false; + this.valueOne = ""; + this.valueTwo = ""; + const { unit, lAlign, rAlign, editorWidth } = this.options; + + this.calculation = new AccurateCalculationModel(); + this.grayTrack = createWidget({ + type: Layout.xtype, + cls: "gray-track", + height: 6, + }); + this.blueTrack = createWidget({ + type: Layout.xtype, + cls: "blue-track bi-high-light-background", + height: 6, + }); + this.track = this._createTrackWrapper(); + + this.labelOne = createWidget({ + type: SignTextEditor.xtype, + cls: "slider-editor-button", + text: unit, + allowBlank: false, + textAlign: lAlign, + width: BI.isNull(editorWidth) ? BI.toPix(c.EDITOR_WIDTH, 2) : BI.toPix(editorWidth, 2), + height: toPix(c.EDITOR_HEIGHT, 2), + validationChecker: v => this._checkValidation(v), + }); + this.labelOne.element.hover( + () => { + this.labelOne.element.removeClass("bi-border").addClass("bi-border"); + }, + () => { + this.labelOne.element.removeClass("bi-border"); + } + ); + this.labelOne.on(Editor.EVENT_CONFIRM, () => { + const oldValueOne = this.valueOne; + const v = parseFloat(this.labelOne.getValue()); + this.valueOne = v; + const percent = this._getPercentByValue(v); + const significantPercent = parseFloat(percent.toFixed(1)); // 分成1000份 + this._setSliderOnePosition(significantPercent); + this._setBlueTrack(); + this._checkLabelPosition(oldValueOne, this.valueTwo, this.valueOne, this.valueTwo); + this.fireEvent(IntervalSlider.EVENT_CHANGE); + }); + + this.labelTwo = createWidget({ + type: SignTextEditor.xtype, + cls: "slider-editor-button", + text: unit, + allowBlank: false, + textAlign: rAlign, + width: BI.isNull(editorWidth) ? BI.toPix(c.EDITOR_WIDTH, 2) : BI.toPix(editorWidth, 2), + height: toPix(c.EDITOR_HEIGHT, 2), + validationChecker: v => this._checkValidation(v), + }); + this.labelTwo.element.hover( + () => { + this.labelTwo.element.removeClass("bi-border").addClass("bi-border"); + }, + () => { + this.labelTwo.element.removeClass("bi-border"); + } + ); + this.labelTwo.on(Editor.EVENT_CONFIRM, () => { + const oldValueTwo = this.valueTwo; + const v = parseFloat(this.labelTwo.getValue()); + this.valueTwo = v; + const percent = this._getPercentByValue(v); + const significantPercent = parseFloat(percent.toFixed(1)); + this._setSliderTwoPosition(significantPercent); + this._setBlueTrack(); + this._checkLabelPosition(this.valueOne, oldValueTwo, this.valueOne, this.valueTwo); + this.fireEvent(IntervalSlider.EVENT_CHANGE); + }); + + this.sliderOne = createWidget({ + type: SliderIconButton.xtype, + }); + this.sliderTwo = createWidget({ + type: SliderIconButton.xtype, + }); + this._draggable(this.sliderOne, true); + this._draggable(this.sliderTwo, false); + this._setVisible(false); + + return { + type: VerticalFillLayout.xtype, + rowSize: [30, 30], + items: [ + this._createLabelWrapper(), + { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: HorizontalLayout.xtype, + horizontalAlign: "stretch", + verticalAlign: "middle", + columnSize: ["fill"], + items: [ + { + el: this.track, + } + ], + hgap: 10, + }, + inset: 0, + }, + this._createSliderWrapper() + ], + } + ], + }; + } + + _rePosBySizeAfterMove(size, isLeft) { + const o = this.options; + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); + let v = this._getValueByPercent(significantPercent); + v = this._assertValue(v); + v = o.digit === false ? v : v.toFixed(o.digit); + const oldValueOne = this.valueOne, + oldValueTwo = this.valueTwo; + if (isLeft) { + this._setSliderOnePosition(significantPercent); + this.labelOne.setValue(v); + this.valueOne = v; + this._checkLabelPosition(oldValueOne, oldValueTwo, v, this.valueTwo); + } else { + this._setSliderTwoPosition(significantPercent); + this.labelTwo.setValue(v); + this.valueTwo = v; + this._checkLabelPosition(oldValueOne, oldValueTwo, this.valueOne, v); + } + this._setBlueTrack(); + } + + _rePosBySizeAfterStop(size, isLeft) { + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); + isLeft ? this._setSliderOnePosition(significantPercent) : this._setSliderTwoPosition(significantPercent); + } + + _draggable(widget, isLeft) { + let startDrag = false; + let size = 0, + offset = 0, + defaultSize = 0; + const mouseMoveTracker = new MouseMoveTracker( + deltaX => { + if (mouseMoveTracker.isDragging()) { + startDrag = true; + offset += deltaX; + size = optimizeSize(defaultSize + offset); + widget.element.addClass("dragging"); + this._rePosBySizeAfterMove(size, isLeft); + } + }, + () => { + if (startDrag === true) { + size = optimizeSize(size); + this._rePosBySizeAfterStop(size, isLeft); + size = 0; + offset = 0; + defaultSize = size; + startDrag = false; + } + widget.element.removeClass("dragging"); + mouseMoveTracker.releaseMouseMoves(); + this.fireEvent(IntervalSlider.EVENT_CHANGE); + }, + window + ); + widget.element.on("mousedown", function (event) { + if (!widget.isEnabled()) { + return; + } + defaultSize = this.offsetLeft; + optimizeSize(defaultSize); + mouseMoveTracker.captureMouseMoves(event); + }); + + const optimizeSize = s => clamp(s, 0, this._getGrayTrackLength()); + } + + _createLabelWrapper() { + const c = this._constant; + + return { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.labelOne, + top: 0, + left: 0, + }, + { + el: this.labelTwo, + top: 0, + right: 0, + }, + ], + }, + ], + height: c.SLIDER_HEIGHT, + }, + top: 0, + left: 0, + width: "100%", + }; + } + + _createSliderWrapper() { + return { + el: { + type: HorizontalLayout.xtype, + horizontalAlign: "stretch", + verticalAlign: "middle", + items: [ + { + type: AbsoluteLayout.xtype, + height: 12, + width: "fill", + items: [ + { + el: this.sliderOne, + top: 0, + bottom: 0, + left: 0, + }, + { + el: this.sliderTwo, + top: 0, + bottom: 0, + left: "100%", + } + ], + } + ], + hgap: 10, + }, + inset: 0, + }; + } + + _createTrackWrapper() { + return createWidget({ + type: HorizontalLayout.xtype, + cls: "track-wrapper", + horizontalAlign: "stretch", + verticalAlign: "middle", + columnSize: ["fill"], + scrollx: false, + items: [ + { + type: AbsoluteLayout.xtype, + height: 6, + items: [ + { + el: this.grayTrack, + top: 0, + left: 0, + bottom: 0, + width: "100%", + }, + { + el: this.blueTrack, + top: 0, + left: 0, + bottom: 0, + width: "0%", + } + ], + } + ], + }); + } + + _checkValidation(v) { + const o = this.options; + let valid = false; + // 像90.这样的既不属于整数又不属于小数,是不合法的值 + let dotText = `${v}`.split(".")[1]; + // eslint-disable-next-line no-empty + if (isEmptyString(dotText)) { + } else { + if (isNumeric(v) && !(isNull(v) || v < this.min || v > this.max)) { + // 虽然规定了所填写的小数位数,但是我们认为所有的整数都是满足设置的小数位数的 + // 100等价于100.0 100.00 100.000 + if (o.digit === false || isInteger(v)) { + valid = true; + } else { + dotText = dotText || ""; + valid = dotText.length === o.digit; + } + } + } + + return valid; + } + + _checkOverlap() { + const labelOneLeft = this.labelOne.element[0].offsetLeft; + const labelTwoLeft = this.labelTwo.element[0].offsetLeft; + if (labelOneLeft <= labelTwoLeft) { + if (labelTwoLeft - labelOneLeft < 90) { + this.labelTwo.element.css({ top: 40 }); + } else { + this.labelTwo.element.css({ top: 0 }); + } + } else { + if (labelOneLeft - labelTwoLeft < 90) { + this.labelTwo.element.css({ top: 40 }); + } else { + this.labelTwo.element.css({ top: 0 }); + } + } + } + + _checkLabelPosition(oldValueOne, oldValueTwo, valueOne, valueTwo, isLeft) { + oldValueOne = parseFloat(oldValueOne); + oldValueTwo = parseFloat(oldValueTwo); + valueOne = parseFloat(valueOne); + valueTwo = parseFloat(valueTwo); + if ( + (oldValueOne <= oldValueTwo && valueOne > valueTwo) || + (oldValueOne >= oldValueTwo && valueOne < valueTwo) + ) { + const isSliderOneLeft = parseFloat(this.labelOne.getValue()) < parseFloat(this.labelTwo.getValue()); + this._resetLabelPosition(!isSliderOneLeft); + } + } + + _resetLabelPosition(needReverse) { + const { lAlign, rAlign } = this.options; + this.labelOne.element.css({ + left: needReverse ? "unset" : "0%", + right: needReverse ? "0%" : "unset", + }); + this.labelOne.element.children()[0] && (this.labelOne.element.children()[0].style.textAlign = needReverse ? rAlign : lAlign); + this.labelTwo.element.css({ + left: needReverse ? "0%" : "unset", + right: needReverse ? "unset" : "0%", + }); + this.labelTwo.element.children()[0] && (this.labelTwo.element.children()[0].style.textAlign = needReverse ? lAlign : rAlign); + } + + _setSliderOnePosition(percent) { + this.sliderOne.element.css({ left: `${percent}%` }); + } + + _setSliderTwoPosition(percent) { + this.sliderTwo.element.css({ left: `${percent}%` }); + } + + _setBlueTrackLeft(percent) { + this.blueTrack.element.css({ left: `${percent}%` }); + } + + _setBlueTrackWidth(percent) { + this.blueTrack.element.css({ width: `${percent}%` }); + } + + _setBlueTrack() { + const percentOne = this._getPercentByValue(this.labelOne.getValue()); + const percentTwo = this._getPercentByValue(this.labelTwo.getValue()); + if (percentOne <= percentTwo) { + this._setBlueTrackLeft(percentOne); + this._setBlueTrackWidth(percentTwo - percentOne); + } else { + this._setBlueTrackLeft(percentTwo); + this._setBlueTrackWidth(percentOne - percentTwo); + } + } + + _setAllPosition(one, two) { + this._setSliderOnePosition(one); + this._setSliderTwoPosition(two); + this._setBlueTrack(); + } + + _setVisible(visible) { + this.sliderOne.setVisible(visible); + this.sliderTwo.setVisible(visible); + this.labelOne.setVisible(visible); + this.labelTwo.setVisible(visible); + } + + _setErrorText() { + const errorText = i18nText("BI-Basic_Please_Enter_Number_Between", this.min, this.max); + this.labelOne.setErrorText(errorText); + this.labelTwo.setErrorText(errorText); + } + + _getGrayTrackLength() { + return this.grayTrack.element[0].scrollWidth; + } + + _getValueByPercent(percent) { + // return (((max-min)*percent)/100+min) + if (percent === 0) { + return this.min; + } + if (percent === 100) { + return this.max; + } + const sub = this.calculation.accurateSubtraction(this.max, this.min); + const mul = this.calculation.accurateMultiplication(sub, percent); + const div = this.calculation.accurateDivisionTenExponent(mul, 2); + if (this.precision < 0) { + const value = parseFloat(this.calculation.accurateAddition(div, this.min)); + const reduceValue = Math.round(this.calculation.accurateDivisionTenExponent(value, -this.precision)); + + return this.calculation.accurateMultiplication(reduceValue, Math.pow(10, -this.precision)); + } + + return parseFloat(this.calculation.accurateAddition(div, this.min).toFixed(this.precision)); + } + + _getPercentByValue(v) { + return ((v - this.min) * 100) / (this.max - this.min); + } + + _getPrecision() { + // 计算每一份值的精度(最大值和最小值的差值保留4为有效数字后的精度) + // 如果差值的整数位数大于4,toPrecision(4)得到的是科学计数法123456 => 1.235e+5 + // 返回非负值: 保留的小数位数 + // 返回负值: 保留的10^n精度中的n + const sub = this.calculation.accurateSubtraction(this.max, this.min); + const pre = sub.toPrecision(4); + // 科学计数法 + const eIndex = pre.indexOf("e"); + let arr = []; + if (eIndex > -1) { + arr = pre.split("e"); + const decimalPartLength = size(arr[0].split(".")[1]); + const sciencePartLength = parseInt(arr[1].substring(1)); + + return decimalPartLength - sciencePartLength; + } + arr = pre.split("."); + + return arr.length > 1 ? arr[1].length : 0; + } + + _assertValue(value) { + if (value <= this.min) { + return this.min; + } + if (value >= this.max) { + return this.max; + } + + return value; + } + + _setEnable(b) { + super._setEnable.apply(this, [b]); + if (b) { + this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); + } else { + this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); + } + } + + getValue() { + if (this.valueOne <= this.valueTwo) { + return { min: this.valueOne, max: this.valueTwo }; + } + + return { min: this.valueTwo, max: this.valueOne }; + } + + _setMinAndMax(v) { + const minNumber = parseFloat(v.min); + const maxNumber = parseFloat(v.max); + if (!isNaN(minNumber) && !isNaN(maxNumber) && maxNumber >= minNumber) { + this.min = minNumber; + this.max = maxNumber; + this.valueOne = minNumber; + this.valueTwo = maxNumber; + this.precision = this._getPrecision(); + } + } + + setMinAndMax(v) { + this._setMinAndMax(v); + this.setEnable(v.min <= v.max); + } + + setValue(v) { + const o = this.options; + let valueOne = parseFloat(v.min); + let valueTwo = parseFloat(v.max); + valueOne = o.digit === false ? valueOne : parseFloat(valueOne.toFixed(o.digit)); + valueTwo = o.digit === false ? valueTwo : parseFloat(valueTwo.toFixed(o.digit)); + if (!isNaN(valueOne) && !isNaN(valueTwo)) { + if (this._checkValidation(valueOne)) { + this.valueOne = this.valueOne <= this.valueTwo ? valueOne : valueTwo; + } + if (this._checkValidation(valueTwo)) { + this.valueTwo = this.valueOne <= this.valueTwo ? valueTwo : valueOne; + } + if (valueOne < this.min) { + this.valueOne = this.min; + } + if (valueTwo > this.max) { + this.valueTwo = this.max; + } + } + } + + reset() { + this._setVisible(false); + this.enable = false; + this.valueOne = ""; + this.valueTwo = ""; + this.min = NaN; + this.max = NaN; + this._setBlueTrackWidth(0); + } + + populate() { + const o = this.options; + if (!isNaN(this.min) && !isNaN(this.max)) { + this.enable = true; + this._setVisible(true); + this._setErrorText(); + if ( + (isNumeric(this.valueOne) || isNotEmptyString(this.valueOne)) && + (isNumeric(this.valueTwo) || isNotEmptyString(this.valueTwo)) + ) { + this.labelOne.setValue(o.digit === false ? this.valueOne : parseFloat(this.valueOne).toFixed(o.digit)); + this.labelTwo.setValue(o.digit === false ? this.valueTwo : parseFloat(this.valueTwo).toFixed(o.digit)); + this._setAllPosition(this._getPercentByValue(this.valueOne), this._getPercentByValue(this.valueTwo)); + } else { + this.labelOne.setValue(this.min); + this.labelTwo.setValue(this.max); + this._setAllPosition(0, 100); + } + this._resetLabelPosition(this.valueOne > this.valueTwo); + } + } +} diff --git a/packages/fineui/src/widget/intervalslider/model.accuratecalculation.js b/packages/fineui/src/widget/intervalslider/model.accuratecalculation.js new file mode 100644 index 000000000..3d423faa5 --- /dev/null +++ b/packages/fineui/src/widget/intervalslider/model.accuratecalculation.js @@ -0,0 +1,259 @@ +import { Widget, extend, parseInt, parseFloat } from "@/core"; + +export class AccurateCalculationModel extends Widget { + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "", + }); + } + + _init() { + super._init(...arguments); + } + + _getMagnitude(n) { + let magnitude = "1"; + for (let i = 0; i < n; i++) { + magnitude += "0"; + } + + return parseInt(magnitude); + } + + _formatDecimal(stringNumber1, stringNumber2) { + if (stringNumber1.numDecimalLength === stringNumber2.numDecimalLength) { + return; + } + let magnitudeDiff = stringNumber1.numDecimalLength - stringNumber2.numDecimalLength; + let needAddZero; + if (magnitudeDiff > 0) { + needAddZero = stringNumber2; + } else { + needAddZero = stringNumber1; + magnitudeDiff = 0 - magnitudeDiff; + } + for (let i = 0; i < magnitudeDiff; i++) { + if (needAddZero.numDecimal === "0" && i === 0) { + continue; + } + needAddZero.numDecimal += "0"; + } + } + + _stringNumberFactory(num) { + const strNum = num.toString(); + const numStrArray = strNum.split("."); + const numInteger = numStrArray[0]; + let numDecimal; + let numDecimalLength; + if (numStrArray.length === 1) { + numDecimal = "0"; + numDecimalLength = 0; + } else { + numDecimal = numStrArray[1]; + numDecimalLength = numStrArray[1].length; + } + + return { + numInteger, + numDecimal, + numDecimalLength, + }; + } + + _accurateSubtraction(num1, num2) { + // num1-num2 && num1>num2 + const stringNumber1 = this._stringNumberFactory(num1); + const stringNumber2 = this._stringNumberFactory(num2); + // 整数部分计算 + let integerResult = parseInt(stringNumber1.numInteger) - parseInt(stringNumber2.numInteger); + // 小数部分 + this._formatDecimal(stringNumber1, stringNumber2); + const decimalMaxLength = getDecimalMaxLength(stringNumber1, stringNumber2); + + let decimalResultTemp; + let decimalResult; + + if (parseInt(stringNumber1.numDecimal) >= parseInt(stringNumber2.numDecimal)) { + decimalResultTemp = (parseInt(stringNumber1.numDecimal) - parseInt(stringNumber2.numDecimal)).toString(); + decimalResult = addZero(decimalResultTemp, decimalMaxLength); + } else { + // 否则借位 + integerResult--; + const borrow = this._getMagnitude(decimalMaxLength); + decimalResultTemp = ( + borrow + + parseInt(stringNumber1.numDecimal) - + parseInt(stringNumber2.numDecimal) + ).toString(); + decimalResult = addZero(decimalResultTemp, decimalMaxLength); + } + const result = `${integerResult}.${decimalResult}`; + + return parseFloat(result); + + function getDecimalMaxLength(num1, num2) { + if (num1.numDecimal.length >= num2.numDecimal.length) { + return num1.numDecimal.length; + } + + return num2.numDecimal.length; + } + + function addZero(resultTemp, length) { + const diff = length - resultTemp.length; + for (let i = 0; i < diff; i++) { + resultTemp = `0${resultTemp}`; + } + + return resultTemp; + } + } + + _accurateAddition(num1, num2) { + // 加法结合律 + const stringNumber1 = this._stringNumberFactory(num1); + const stringNumber2 = this._stringNumberFactory(num2); + // 整数部分计算 + let integerResult = parseInt(stringNumber1.numInteger) + parseInt(stringNumber2.numInteger); + // 小数部分 + this._formatDecimal(stringNumber1, stringNumber2); + + let decimalResult = (parseInt(stringNumber1.numDecimal) + parseInt(stringNumber2.numDecimal)).toString(); + + if (decimalResult !== "0") { + if (decimalResult.length <= stringNumber1.numDecimal.length) { + decimalResult = addZero(decimalResult, stringNumber1.numDecimal.length); + } else { + integerResult++; // 进一 + decimalResult = decimalResult.slice(1); + } + } + const result = `${integerResult}.${decimalResult}`; + + return parseFloat(result); + + function addZero(resultTemp, length) { + const diff = length - resultTemp.length; + for (let i = 0; i < diff; i++) { + resultTemp = `0${resultTemp}`; + } + + return resultTemp; + } + } + + _accurateMultiplication(num1, num2) { + // 乘法分配律 + const stringNumber1 = this._stringNumberFactory(num1); + const stringNumber2 = this._stringNumberFactory(num2); + // 整数部分计算 + const integerResult = parseInt(stringNumber1.numInteger) * parseInt(stringNumber2.numInteger); + // num1的小数和num2的整数 + const dec1Int2 = this._accurateDivisionTenExponent( + parseInt(stringNumber1.numDecimal) * parseInt(stringNumber2.numInteger), + stringNumber1.numDecimalLength + ); + // num1的整数和num2的小数 + const int1dec2 = this._accurateDivisionTenExponent( + parseInt(stringNumber1.numInteger) * parseInt(stringNumber2.numDecimal), + stringNumber2.numDecimalLength + ); + // 小数*小数 + const dec1dec2 = this._accurateDivisionTenExponent( + parseInt(stringNumber1.numDecimal) * parseInt(stringNumber2.numDecimal), + stringNumber1.numDecimalLength + stringNumber2.numDecimalLength + ); + + return this._accurateAddition( + this._accurateAddition(this._accurateAddition(integerResult, dec1Int2), int1dec2), + dec1dec2 + ); + } + + _accurateDivisionTenExponent(num, n) { + // num/10^n && n>0 + const stringNumber = this._stringNumberFactory(num); + let integerResult, partDecimalResult; + if (stringNumber.numInteger.length > n) { + integerResult = stringNumber.numInteger.slice(0, stringNumber.numInteger.length - n); + partDecimalResult = stringNumber.numInteger.slice(-n); + } else { + integerResult = "0"; + partDecimalResult = addZero(stringNumber.numInteger, n); + } + const result = `${integerResult}.${partDecimalResult}${stringNumber.numDecimal}`; + + return parseFloat(result); + + function addZero(resultTemp, length) { + const diff = length - resultTemp.length; + for (let i = 0; i < diff; i++) { + resultTemp = `0${resultTemp}`; + } + + return resultTemp; + } + } + + accurateSubtraction(num1, num2) { + if (num1 >= 0 && num2 >= 0) { + if (num1 >= num2) { + return this._accurateSubtraction(num1, num2); + } + + return -this._accurateSubtraction(num2, num1); + } + if (num1 >= 0 && num2 < 0) { + return this._accurateAddition(num1, -num2); + } + if (num1 < 0 && num2 >= 0) { + return -this._accurateAddition(-num1, num2); + } + if (num1 < 0 && num2 < 0) { + if (num1 >= num2) { + return this._accurateSubtraction(-num2, -num1); + } + + return this._accurateSubtraction(-num1, -num2); + } + } + + accurateAddition(num1, num2) { + if (num1 >= 0 && num2 >= 0) { + return this._accurateAddition(num1, num2); + } + if (num1 >= 0 && num2 < 0) { + return this.accurateSubtraction(num1, -num2); + } + if (num1 < 0 && num2 >= 0) { + return this.accurateSubtraction(num2, -num1); + } + if (num1 < 0 && num2 < 0) { + return -this._accurateAddition(-num1, -num2); + } + } + + accurateMultiplication(num1, num2) { + if (num1 >= 0 && num2 >= 0) { + return this._accurateMultiplication(num1, num2); + } + if (num1 >= 0 && num2 < 0) { + return -this._accurateMultiplication(num1, -num2); + } + if (num1 < 0 && num2 >= 0) { + return -this._accurateMultiplication(-num1, num2); + } + if (num1 < 0 && num2 < 0) { + return this._accurateMultiplication(-num1, -num2); + } + } + + accurateDivisionTenExponent(num1, n) { + if (num1 >= 0) { + return this._accurateDivisionTenExponent(num1, n); + } + + return -this._accurateDivisionTenExponent(-num1, n); + } +} diff --git a/src/widget/multilayerdownlist/__test__/downlist.test.js b/packages/fineui/src/widget/multilayerdownlist/__test__/downlist.test.js similarity index 100% rename from src/widget/multilayerdownlist/__test__/downlist.test.js rename to packages/fineui/src/widget/multilayerdownlist/__test__/downlist.test.js diff --git a/packages/fineui/src/widget/multilayerdownlist/combo.downlist.js b/packages/fineui/src/widget/multilayerdownlist/combo.downlist.js new file mode 100644 index 000000000..c8824e46c --- /dev/null +++ b/packages/fineui/src/widget/multilayerdownlist/combo.downlist.js @@ -0,0 +1,94 @@ +import { MultiLayerDownListPopup } from "./popup.downlist"; +import { shortcut, Widget, extend, createWidget } from "@/core"; +import { Combo } from "@/base"; +import { IconTrigger } from "@/case"; + +@shortcut() +export class MultiLayerDownListCombo extends Widget { + static xtype = "bi.multi_layer_down_list_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-down-list-combo", + height: 24, + items: [], + adjustLength: 0, + direction: "bottom", + trigger: "click", + container: null, + stopPropagation: false, + el: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.popupview = createWidget({ + type: MultiLayerDownListPopup.xtype, + items: o.items, + chooseType: o.chooseType, + value: o.value, + }); + + this.popupview.on(MultiLayerDownListPopup.EVENT_CHANGE, value => { + this.fireEvent(MultiLayerDownListCombo.EVENT_CHANGE, value); + this.downlistcombo.hideView(); + }); + + this.popupview.on(MultiLayerDownListPopup.EVENT_SON_VALUE_CHANGE, (value, fatherValue) => { + this.fireEvent(MultiLayerDownListCombo.EVENT_SON_VALUE_CHANGE, value, fatherValue); + this.downlistcombo.hideView(); + }); + + this.downlistcombo = createWidget({ + element: this, + type: Combo.xtype, + trigger: o.trigger, + isNeedAdjustWidth: false, + container: o.container, + adjustLength: o.adjustLength, + direction: o.direction, + stopPropagation: o.stopPropagation, + el: createWidget(o.el, { + type: IconTrigger.xtype, + extraCls: o.iconCls ? o.iconCls : "pull-down-font", + width: o.width, + height: o.height, + }), + popup: { + el: this.popupview, + stopPropagation: o.stopPropagation, + maxHeight: 1000, + }, + }); + + this.downlistcombo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(MultiLayerDownListCombo.EVENT_BEFORE_POPUPVIEW); + }); + } + + hideView() { + this.downlistcombo.hideView(); + } + + showView(e) { + this.downlistcombo.showView(e); + } + + populate(items) { + this.popupview.populate(items); + } + + setValue(v) { + this.popupview.setValue(v); + } + + getValue() { + return this.popupview.getValue(); + } +} diff --git a/packages/fineui/src/widget/multilayerdownlist/index.js b/packages/fineui/src/widget/multilayerdownlist/index.js new file mode 100644 index 000000000..e73818700 --- /dev/null +++ b/packages/fineui/src/widget/multilayerdownlist/index.js @@ -0,0 +1,2 @@ +export { MultiLayerDownListCombo } from "./combo.downlist"; +export { MultiLayerDownListPopup } from "./popup.downlist"; diff --git a/packages/fineui/src/widget/multilayerdownlist/popup.downlist.js b/packages/fineui/src/widget/multilayerdownlist/popup.downlist.js new file mode 100644 index 000000000..a55504ec0 --- /dev/null +++ b/packages/fineui/src/widget/multilayerdownlist/popup.downlist.js @@ -0,0 +1,375 @@ +import { + shortcut, + extend, + Selection, + createWidget, + createItems, + isNotNull, + contains, + each, + VerticalLayout, + isNotEmptyArray, + isEmpty, + Layout, + deepClone, + isArray, + isNotEmptyString, + some, + concat, + BlankSplitChar, + SIZE_CONSANTS +} from "@/core"; +import { Pane, ButtonTree, ComboGroup } from "@/base"; +import { DownListGroup, DownListGroupItem, DownListItem } from "../downlist"; + +@shortcut() +export class MultiLayerDownListPopup extends Pane { + static xtype = "bi.multi_layer_down_list_popup"; + + constants = { + nextIcon: "pull-right-e-font", + height: 25, + iconHeight: 12, + iconWidth: 12, + hgap: 0, + vgap: 0, + border: 1, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: "bi-down-list-popup", + items: [], + chooseType: Selection.Multi, + }); + } + + _init() { + super._init(...arguments); + this.singleValues = []; + this.childValueMap = {}; + this.fatherValueMap = {}; + this.items = []; + const self = this, + o = this.options, + children = this._createPopupItems(o.items); + this.popup = createWidget({ + type: ButtonTree.xtype, + items: createItems( + children, + {}, + { + adjustLength: -2, + } + ), + layouts: [ + { + type: VerticalLayout.xtype, + hgap: this.constants.hgap, + vgap: this.constants.vgap, + } + ], + value: this._digest(o.value), + chooseType: o.chooseType, + }); + + this.popup.on(ButtonTree.EVENT_CHANGE, (value, object) => { + let changedValue = value; + if (isNotNull(self.childValueMap[value])) { + changedValue = self.childValueMap[value]; + const fatherValue = self.fatherValueMap[value]; + const fatherArrayValue = `${fatherValue}`.split(BlankSplitChar); + self.fireEvent( + MultiLayerDownListPopup.EVENT_SON_VALUE_CHANGE, + changedValue, + fatherArrayValue.length > 1 ? fatherArrayValue : fatherValue + ); + } else { + self.fireEvent(MultiLayerDownListPopup.EVENT_CHANGE, changedValue, object); + } + + if (!contains(self.singleValues, changedValue)) { + const item = self.getValue(); + const result = []; + each(item, (i, valueObject) => { + if (valueObject.value != changedValue) { + result.push(valueObject); + } + }); + self.setValue(result); + } + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.popup], + vgap: 5, + }); + } + + _createPopupItems(items) { + const self = this, + result = []; + each(items, (i, it) => { + const item_done = { + type: DownListGroup.xtype, + items: [], + }; + const storeItem = []; + + each(it, (i, sourceItem) => { + const item = extend({}, sourceItem); + if (isNotEmptyArray(sourceItem.children) && !isEmpty(sourceItem.el)) { + item.type = ComboGroup.xtype; + item.cls = "down-list-group"; + item.trigger = "hover"; + item.isNeedAdjustWidth = false; + item.el = sourceItem.el; + item.el.title = sourceItem.el.title || sourceItem.el.text; + item.el.type = DownListGroupItem.xtype; + item.el.logic = { + dynamic: true, + }; + item.el.height = sourceItem.el.height || SIZE_CONSANTS.LIST_ITEM_HEIGHT; + item.el.iconCls2 = self.constants.nextIcon; + item.popup = { + lgap: 1, + el: { + type: ButtonTree.xtype, + chooseType: 0, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + innerVgap: 5, + maxHeight: 378, + }; + self._createChildren(item, sourceItem); + } else { + item.type = sourceItem.type || DownListItem.xtype; + item.title = sourceItem.title || sourceItem.text; + item.textRgap = 10; + item.isNeedAdjustWidth = false; + item.logic = { + dynamic: true, + }; + } + const el_done = {}; + el_done.el = item; + item_done.items.push(el_done); + storeItem.push(item); + }); + if (self._isGroup(item_done.items)) { + each(item_done.items, (i, item) => { + self.singleValues.push(item.el.value); + }); + } + + result.push(item_done); + self.items.push(storeItem); + if (self._needSpliter(i, items.length)) { + const spliter_container = createWidget({ + type: VerticalLayout.xtype, + items: [ + { + el: { + type: Layout.xtype, + cls: "bi-down-list-spliter bi-border-top cursor-pointer", + height: 0, + }, + } + ], + cls: "bi-down-list-spliter-container cursor-pointer", + vgap: 5, + hgap: 12, + }); + result.push(spliter_container); + } + }); + + return result; + } + + _createChildren(targetItem, sourceItem) { + const self = this; + this._formatEL(targetItem).el.childValues = []; + targetItem.items = targetItem.children = []; + each(sourceItem.children, (i, child) => { + const item = child.el ? extend({}, child.el, { children: child.children }) : extend({}, child); + const fatherValue = deepClone(self._formatEL(targetItem).el.value); + const childValue = deepClone(item.value); + self.singleValues.push(item.value); + item.type = item.type || DownListItem.xtype; + item.extraCls = " child-down-list-item"; + item.title = item.title || item.text; + item.textRgap = 10; + item.isNeedAdjustWidth = false; + item.logic = { + dynamic: true, + }; + item.father = fatherValue; + self.fatherValueMap[self._createChildValue(fatherValue, childValue)] = fatherValue; + self.childValueMap[self._createChildValue(fatherValue, childValue)] = childValue; + item.value = self._createChildValue(fatherValue, childValue); + self._formatEL(targetItem).el.childValues.push(item.value); + if (isNotEmptyArray(child.children)) { + item.type = DownListGroupItem.xtype; + item.iconCls2 = self.constants.nextIcon; + item.height = child.height || SIZE_CONSANTS.LIST_ITEM_HEIGHT; + self._createChildren(item, child); + } + targetItem.items.push(item); + }); + } + + _formatEL(obj) { + if (obj && obj.el) { + return obj; + } + + return { + el: obj, + }; + } + + _isGroup(i) { + return i.length > 1; + } + + _needSpliter(i, itemLength) { + return i < itemLength - 1; + } + + _createChildValue(fatherValue, childValue) { + let fValue = fatherValue; + if (isArray(fatherValue)) { + fValue = fatherValue.join(BlankSplitChar); + } + + return fValue + BlankSplitChar + childValue; + } + + _digest(valueItem) { + const self = this; + const valueArray = []; + each(valueItem, (i, item) => { + let value; + if (isNotNull(item.childValue)) { + value = self._createChildValue(item.value, item.childValue); + } else { + value = item.value; + } + valueArray.push(value); + }); + + return valueArray; + } + + _checkValues(values) { + const value = []; + each(this.items, (idx, itemGroup) => { + each(itemGroup, (id, item) => { + if (isNotNull(item.children)) { + const childValues = getChildrenValue(item); + const v = joinValue(childValues, values[idx]); + if (isNotEmptyString(v)) { + value.push(v); + } + } else { + if (item.value === values[idx][0]) { + value.push(values[idx][0]); + } + } + }); + }); + + return value; + + function joinValue(sources, targets) { + let value = ""; + some(sources, (idx, s) => + some(targets, (id, t) => { + if (s === t) { + value = s; + + return true; + } + }) + ); + + return value; + } + + function getChildrenValue(item) { + let children = []; + if (isNotNull(item.children)) { + each(item.children, (idx, child) => { + children = concat(children, getChildrenValue(child)); + }); + } else { + children.push(item.value); + } + + return children; + } + } + + populate(items) { + super.populate(...arguments); + const self = this; + self.childValueMap = {}; + self.fatherValueMap = {}; + self.singleValues = []; + this.items = []; + const children = self._createPopupItems(items); + const popupItem = createItems( + children, + {}, + { + adjustLength: -2, + } + ); + self.popup.populate(popupItem); + } + + setValue(valueItem) { + this.popup.setValue(this._digest(valueItem)); + } + + _getValue() { + const v = []; + each(this.popup.getAllButtons(), (i, item) => { + i % 2 === 0 && v.push(item.getValue()); + }); + + return v; + } + + getValue() { + const self = this, + result = []; + const values = this._checkValues(this._getValue()); + each(values, (i, value) => { + const valueItem = {}; + if (isNotNull(self.childValueMap[value])) { + const fartherValue = self.fatherValueMap[value]; + valueItem.childValue = self.childValueMap[value]; + const fatherArrayValue = `${fartherValue}`.split(BlankSplitChar); + valueItem.value = fatherArrayValue.length > 1 ? fatherArrayValue : fartherValue; + } else { + valueItem.value = value; + } + result.push(valueItem); + }); + + return result; + } +} diff --git a/packages/fineui/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js b/packages/fineui/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js new file mode 100644 index 000000000..70d1d00a9 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js @@ -0,0 +1,136 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2019/9/18 + */ + +describe("multilayer_select_tree", () => { + const items = [ + { id: -1, pId: -2, value: "根目录", text: "根目录" }, + { id: 1, pId: -1, value: "第一级目录1", text: "第一级目录1" }, + { id: 11, pId: 1, value: "第二级文件1", text: "第二级文件1" }, + { id: 12, pId: 1, value: "第二级目录2", text: "第二级目录2" }, + { id: 121, pId: 12, value: "第三级目录1", text: "第三级目录1" }, + { id: 122, pId: 12, value: "第三级文件1", text: "第三级文件1" }, + { id: 1211, pId: 121, value: "第四级目录1", text: "第四级目录1" }, + { + id: 12111, + pId: 1211, + value: "第五级文件1", + text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + }, + { id: 2, pId: -1, value: "第一级目录2", text: "第一级目录2" }, + { id: 21, pId: 2, value: "第二级目录3", text: "第二级目录3" }, + { id: 22, pId: 2, value: "第二级文件2", text: "第二级文件2" }, + { id: 211, pId: 21, value: "第三级目录2", text: "第三级目录2" }, + { id: 212, pId: 21, value: "第三级文件2", text: "第三级文件2" }, + { id: 2111, pId: 211, value: "第四级文件1", text: "第四级文件1" } + ]; + + /** + * test_author_windy + **/ + it("defaultValue_allowEdit", () => { + const tree = BI.Test.createWidget({ + type: "bi.multilayer_select_tree_combo", + width: 300, + height: 24, + allowEdit: true, + items: BI.deepClone(items), + value: "第一级目录2", + }); + expect(tree.getValue()).to.equal("第一级目录2"); + tree.destroy(); + }); + + /** + * test_author_windy + **/ + it("defaultValue_not_allowEdit", () => { + const tree = BI.Test.createWidget({ + type: "bi.multilayer_select_tree_combo", + width: 300, + height: 24, + items: BI.deepClone(items), + value: "第一级目录2", + }); + expect(tree.getValue()).to.equal("第一级目录2"); + tree.destroy(); + }); + + /** + * test_author_windy + **/ + it("点选选值", done => { + const tree = BI.Test.createWidget({ + type: "bi.multilayer_select_tree_combo", + width: 300, + height: 24, + allowEdit: true, + items: BI.deepClone(items), + value: "第一级目录2", + }); + tree.element.find(".bi-multi-layer-select-tree-trigger").click(); + BI.nextTick(() => { + tree.element.find(".bi-select-tree-plus-group-node").click(); + expect(tree.getValue()[0]).to.equal("根目录"); + tree.destroy(); + done(); + }); + }); + + /** + * test_author_windy + **/ + it("搜索选值", done => { + const tree = BI.Test.createWidget({ + type: "bi.multilayer_select_tree_combo", + width: 300, + height: 24, + allowEdit: true, + items: BI.deepClone(items), + }); + BI.nextTick(() => { + tree.element.find(".bi-multi-layer-select-tree-trigger .tip-text-style").click(); + // 这边为啥要加呢,因为input的setValue中有nextTick + BI.nextTick(() => { + BI.Test.triggerKeyDown(tree.element.find(".bi-multi-layer-select-tree-trigger .bi-input"), "2", 50, () => { + BI.nextTick(() => { + tree.element.find(".bi-select-tree-mid-plus-group-node").click(); + expect(tree.getValue()[0]).to.equal("第一级目录2"); + tree.destroy(); + done(); + }); + }); + }); + }); + }); + + /** + * test_author_windy + **/ + it("新增值", done => { + const tree = BI.Test.createWidget({ + type: "bi.multilayer_select_tree_combo", + width: 300, + height: 24, + allowEdit: true, + allowInsertValue: true, + items: BI.deepClone(items), + }); + BI.nextTick(() => { + tree.element.find(".bi-multi-layer-select-tree-trigger .tip-text-style").click(); + // 这边为啥要加呢,因为input的setValue中有nextTick + BI.nextTick(() => { + BI.Test.triggerKeyDown(tree.element.find(".bi-multi-layer-select-tree-trigger .bi-input"), "z", 50, () => { + BI.nextTick(() => { + tree.element.find(".bi-text-button:contains(+点击新增\"z\")").click(); + expect(tree.getValue()[0]).to.equal("z"); + tree.destroy(); + done(); + }); + }); + }); + }); + }); +}); diff --git a/packages/fineui/src/widget/multilayerselecttree/index.js b/packages/fineui/src/widget/multilayerselecttree/index.js new file mode 100644 index 000000000..5876ea944 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/index.js @@ -0,0 +1,3 @@ +export { MultiLayerSelectTreeCombo } from "./multilayerselecttree.combo"; +export { MultiLayerSelectLevelTree } from "./multilayerselecttree.leveltree"; +export { MultiLayerSelectTreePopup } from "./multilayerselecttree.popup"; \ No newline at end of file diff --git a/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.combo.js b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.combo.js new file mode 100644 index 000000000..f12c54d55 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.combo.js @@ -0,0 +1,326 @@ +import { shortcut, Widget, extend, emptyFn, isKey, toPix, AbsoluteLayout, nextTick, isArray } from "@/core"; +import { SingleTreeTrigger } from "../singletree/singletree.trigger"; +import { MultiLayerSelectTreePopup } from "./multilayerselecttree.popup"; +import { Combo } from "@/base"; +import { MultiLayerSelectTreeTrigger } from "./multilayerselecttree.trigger"; +import { TriggerIconButton } from "@/case"; + +@shortcut() +export class MultiLayerSelectTreeCombo extends Widget { + static xtype = "bi.multilayer_select_tree_combo"; + + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-select-tree-combo", + isDefaultInit: false, + height: 24, + text: "", + defaultText: "", + itemsCreator: emptyFn, + items: [], + allowEdit: false, + allowSearchValue: false, + allowInsertValue: false, + isNeedAdjustWidth: true, + status: "", // "error","warning" + }); + } + + render() { + const self = this, + o = this.options; + + const cls = + (o.simple ? "bi-border-bottom " : "bi-border bi-border-radius ") + + (isKey(o.status) ? `status-${o.status}` : ""); + + const baseConfig = this._getBaseConfig(); + + if (o.allowEdit) { + return { + type: AbsoluteLayout.xtype, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + cls, + items: [ + { + el: extend(baseConfig, this._getSearchConfig()), + top: 0, + bottom: 0, + right: 0, + left: 0, + }, + { + el: self._getTriggerIconButton(), + top: 0, + bottom: 0, + right: 0, + } + ], + }; + } + + return extend( + baseConfig, + { + el: { + type: SingleTreeTrigger.xtype, + ref(_ref) { + self.textTrigger = _ref; + }, + text: o.text, + defaultText: o.defaultText, + height: toPix(o.height, 2), + items: o.items, + value: o.value, + tipType: o.tipType, + warningTitle: o.warningTitle, + valueFormatter: o.valueFormatter, + }, + }, + { cls } + ); + } + + _getBaseConfig() { + const self = this, + o = this.options; + + return { + type: Combo.xtype, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + container: o.container, + destroyWhenHide: o.destroyWhenHide, + adjustLength: 2, + ref(_ref) { + self.combo = _ref; + }, + popup: { + el: { + type: MultiLayerSelectTreePopup.xtype, + isDefaultInit: o.isDefaultInit, + itemsCreator: o.itemsCreator, + items: o.items, + ref(_ref) { + self.trigger && self.trigger.getSearcher().setAdapter(_ref); + }, + listeners: [ + { + eventName: MultiLayerSelectTreePopup.EVENT_CHANGE, + action() { + self.setValue(this.getValue()); + self.combo.hideView(); + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_CHANGE); + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); + }, + } + ], + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + }); + }, + }, + value: o.value, + maxHeight: 400, + maxWidth: o.isNeedAdjustWidth ? "auto" : 500, + minHeight: 240, + }, + isNeedAdjustWidth: o.isNeedAdjustWidth, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }; + } + + _getSearchConfig() { + const self = this, + o = this.options; + + return { + el: { + type: MultiLayerSelectTreeTrigger.xtype, + container: o.container, + allowInsertValue: o.allowInsertValue, + allowSearchValue: o.allowSearchValue, + allowEdit: o.allowEdit, + cls: "multilayer-select-tree-trigger", + ref(_ref) { + self.trigger = _ref; + }, + items: o.items, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + watermark: o.watermark, + height: toPix(o.height, 2), + text: o.text, + defaultText: o.defaultText, + value: o.value, + tipType: o.tipType, + warningTitle: o.warningTitle, + title: o.title, + listeners: [ + { + eventName: MultiLayerSelectTreeTrigger.EVENT_CHANGE, + action() { + self.setValue(this.getValue()); + self.combo.hideView(); + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_CHANGE); + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); + }, + }, + { + eventName: MultiLayerSelectTreeTrigger.EVENT_FOCUS, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiLayerSelectTreeTrigger.EVENT_BLUR, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiLayerSelectTreeTrigger.EVENT_SEARCHING, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiLayerSelectTreeTrigger.EVENT_STOP, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_STOP); + }, + }, + { + eventName: MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM, + action() { + const value = self.trigger.getSearcher().getKeyword(); + self.combo.setValue([value]); + self.combo.hideView(); + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_CHANGE); + }, + } + ], + }, + toggle: !o.allowEdit, + hideChecker(e) { + // 新增传配置container后对应hideChecker的修改 + // IE11下,popover(position: fixed)下放置下拉控件(position: fixed), 滚动的时候会异常卡顿 + // 通过container参数将popup放置于popover之外解决此问题, 其他下拉控件由于元素少或者有分页,所以 + // 卡顿不明显, 先在此做尝试, 并在FineUI特殊处理待解决文档中标记跟踪 + return o.container && + self.trigger.getSearcher().isSearching() && + self.trigger.getSearcher().getView().element.find(e.target).length > 0 + ? false + : self.triggerBtn?.element.find(e.target).length === 0; + }, + listeners: [ + { + eventName: Combo.EVENT_AFTER_HIDEVIEW, + action() { + self.trigger.stopEditing(); + }, + }, + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action() { + self.fireEvent(MultiLayerSelectTreeCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }; + } + + _getTriggerIconButton() { + const self = this, + o = this.options; + + return { + type: TriggerIconButton.xtype, + cls: "bi-trigger trigger-icon-button", + ref(_ref) { + self.triggerBtn = _ref; + }, + width: toPix(o.height, 2), + height: toPix(o.height, 2), + listeners: [ + { + eventName: TriggerIconButton.EVENT_CHANGE, + action() { + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }, + } + ], + }; + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + getSearcher() { + return this.trigger ? this.trigger.getSearcher() : this.textTrigger.getTextor(); + } + + clear() { + // do some work + } + + setStatus(status) { + if (isKey(this.options.status)) { + this.element.removeClass(`status-${this.options.status}`); + } + this.element.addClass(`status-${status}`); + this.options.status = status; + } + + setTipType(v) { + this.trigger ? this.trigger.setTipType(v) : this.textTrigger.setTipType(v); + } + + populate(items) { + this.combo.populate(items); + } + + focus() { + this.trigger ? this.trigger.focus() : this.textTrigger.focus(); + } + + blur() { + this.trigger ? this.trigger.blur() : this.textTrigger.blur(); + } + + showView() { + this.combo.showView(); + } + + setWaterMark(v) { + this.trigger ? this.trigger.setWaterMark(v) : this.textTrigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js new file mode 100644 index 000000000..f21c07112 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js @@ -0,0 +1,111 @@ +import { + shortcut, + Widget, + i18nText, + emptyFn, + createWidget, + Controller, + VerticalLayout, + isEmptyArray, + isArray +} from "@/core"; +import { MultiLayerSelectLevelTree } from "./multilayerselecttree.leveltree"; +import { TextButton } from "@/base"; + +@shortcut() +export class MultiLayerSelectTreeInsertSearchPane extends Widget { + static xtype = "bi.multilayer_select_tree_insert_search_pane"; + + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props() { + return { + baseCls: "bi-multilayer-select-tree-popup", + tipText: i18nText("BI-No_Selected_Item"), + isDefaultInit: false, + itemsCreator: emptyFn, + items: [], + value: "", + }; + } + + render() { + const self = this, + o = this.options; + this.tree = createWidget({ + type: MultiLayerSelectLevelTree.xtype, + isDefaultInit: o.isDefaultInit, + items: o.items, + itemsCreator: + o.itemsCreator === emptyFn + ? emptyFn + : function (op, callback) { + o.itemsCreator(op, res => { + callback(res); + self.setKeyword(o.keywordGetter()); + }); + }, + keywordGetter: o.keywordGetter, + value: o.value, + scrollable: null, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }, + }, + { + eventName: MultiLayerSelectLevelTree.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSelectTreeInsertSearchPane.EVENT_CHANGE); + }, + } + ], + }); + + return { + type: VerticalLayout.xtype, + scrolly: false, + scrollable: true, + vgap: 5, + items: [ + { + type: TextButton.xtype, + invisible: true, + text: i18nText("BI-Basic_Click_To_Add_Text", ""), + height: 24, + cls: "bi-high-light", + hgap: 5, + ref(_ref) { + self.addNotMatchTip = _ref; + }, + handler() { + self.fireEvent(MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM, o.keywordGetter()); + }, + }, + this.tree + ], + }; + } + + setKeyword(keyword) { + const showTip = isEmptyArray(this.tree.getAllLeaves()); + this.addNotMatchTip.setVisible(showTip); + showTip && this.addNotMatchTip.setText(i18nText("BI-Basic_Click_To_Add_Text", keyword)); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + this.tree.populate(items); + } +} diff --git a/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js new file mode 100644 index 000000000..99751ce09 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js @@ -0,0 +1,204 @@ +import { + shortcut, + extend, + emptyFn, + each, + isKey, + UUID, + isNotEmptyArray, + defaults, + createWidget, + Tree, + nextTick, + Selection, + Controller, + Events, + VerticalLayout, + AdaptiveLayout, + isNull, + isArray, + SIZE_CONSANTS +} from "@/core"; +import { Pane, CustomTree, Loader, ButtonTree } from "@/base"; +import { BasicTreeNode, BasicTreeItem, TreeExpander } from "@/case"; + +@shortcut() +export class MultiLayerSelectLevelTree extends Pane { + static xtype = "bi.multilayer_select_level_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-select-level-tree", + isDefaultInit: false, + items: [], + itemsCreator: emptyFn, + keywordGetter: emptyFn, + value: "", + scrollable: true, + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + + this.storeValue = o.value; + + this.initTree(this.options.items); + + this.check(); + } + + _formatItems(nodes, layer, pNode) { + const self = this, + o = this.options; + const keyword = o.keywordGetter(); + each(nodes, (i, node) => { + const extend = { + isFirstNode: i === 0, + isLastNode: i === nodes.length - 1, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }; + node.layer = layer; + if (!isKey(node.id)) { + node.id = UUID(); + } + node.keyword = node.keyword || keyword; + extend.pNode = pNode; + if (node.isParent === true || node.parent === true || isNotEmptyArray(node.children)) { + extend.type = BasicTreeNode.xtype; + extend.selectable = true; + defaults(node, extend); + self._formatItems(node.children, layer + 1, node); + } else { + extend.type = BasicTreeItem.xtype; + defaults(node, extend); + } + }); + + return nodes; + } + + _assertId(sNodes) { + each(sNodes, (i, node) => { + node.id = node.id || UUID(); + }); + } + + initTree(nodes) { + const self = this, + o = this.options; + let hasNext = false; + this.empty(); + this._assertId(nodes); + this.tree = createWidget({ + type: CustomTree.xtype, + cls: "tree-view display-table", + expander: { + type: TreeExpander.xtype, + selectable: true, + isDefaultInit: o.isDefaultInit, + el: {}, + popup: { + type: CustomTree.xtype, + }, + }, + + items: this._formatItems(Tree.transformToTreeFormat(nodes), 0), + itemsCreator(op, callback) { + op.times === 1 && + !op.node && + nextTick(() => { + self.loading(); + }); + o.itemsCreator(op, ob => { + hasNext = ob.hasNext; + op.times === 1 && !op.node && self._populate(ob.items); + callback( + self._formatItems( + Tree.transformToTreeFormat(ob.items), + op.node ? op.node.layer + 1 : 0, + op.node + ) + ); + self.setValue(self.storeValue); + op.times === 1 && + !op.node && + nextTick(() => { + self.loaded(); + }); + }); + }, + value: o.value, + + el: { + type: Loader.xtype, + isDefaultInit: o.itemsCreator !== emptyFn, + el: { + type: ButtonTree.xtype, + chooseType: o.chooseType === Selection.None ? Selection.None : Selection.Default, // 不使用buttontree内部getValue逻辑 + behaviors: o.behaviors, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + hasNext() { + return hasNext; + }, + }, + }); + this.tree.on(Controller.EVENT_CHANGE, function (type, value) { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + if (type === Events.CLICK) { + self.setValue(value); + self.fireEvent(MultiLayerSelectLevelTree.EVENT_CHANGE, arguments); + } + }); + + createWidget({ + type: AdaptiveLayout.xtype, + element: this, + scrollable: o.scrollable, + items: [this.tree], + }); + } + + _populate() { + super.populate(...arguments); + } + + populate(nodes) { + this._populate(nodes); + isNull(nodes) + ? this.tree.populate() + : this.tree.populate(this._formatItems(Tree.transformToTreeFormat(nodes), 0)); + } + + setValue(v) { + // getValue依赖于storeValue, 那么不选的时候就不要更新storeValue了 + if (this.options.chooseType !== Selection.None) { + this.storeValue = v; + this.tree.setValue(v); + } + } + + getValue() { + return isArray(this.storeValue) ? this.storeValue : isNull(this.storeValue) ? [] : [this.storeValue]; + } + + getAllLeaves() { + return this.tree.getAllLeaves(); + } + + getNodeById(id) { + return this.tree.getNodeById(id); + } + + getNodeByValue(id) { + return this.tree.getNodeByValue(id); + } +} diff --git a/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.popup.js b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.popup.js new file mode 100644 index 000000000..d881277ee --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.popup.js @@ -0,0 +1,75 @@ +import { shortcut, Widget, extend, i18nText, emptyFn, createWidget, Controller, VerticalLayout, isArray, pixFormat } from "@/core"; +import { MultiLayerSelectLevelTree } from "./multilayerselecttree.leveltree"; + +@shortcut() +export class MultiLayerSelectTreePopup extends Widget { + static xtype = "bi.multilayer_select_tree_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-select-tree-popup", + tipText: i18nText("BI-No_Selected_Item"), + isDefaultInit: false, + itemsCreator: emptyFn, + items: [], + value: "", + onLoaded: emptyFn, + minHeight: 240, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.tree = createWidget({ + type: MultiLayerSelectLevelTree.xtype, + isDefaultInit: o.isDefaultInit, + items: o.items, + itemsCreator: o.itemsCreator, + keywordGetter: o.keywordGetter, + value: o.value, + scrollable: null, + onLoaded() { + self.tree.check(); + o.onLoaded(); + }, + }); + + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + scrollable: true, + element: this, + vgap: 5, + items: [this.tree], + }); + + this.tree.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.tree.on(MultiLayerSelectLevelTree.EVENT_CHANGE, () => { + self.fireEvent(MultiLayerSelectTreePopup.EVENT_CHANGE); + }); + + this.tree.css("min-height", pixFormat(o.minHeight - 10)); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + this.tree.populate(items); + } +} diff --git a/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.trigger.js b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.trigger.js new file mode 100644 index 000000000..14805eb12 --- /dev/null +++ b/packages/fineui/src/widget/multilayerselecttree/multilayerselecttree.trigger.js @@ -0,0 +1,280 @@ +import { + shortcut, + emptyFn, + i18nText, + isNotNull, + isKey, + HorizontalFillLayout, + Tree, + deepClone, + Func, + concat, + isNotEmptyArray, + each, + uniqBy, + map, + isFunction, + find +} from "@/core"; +import { Trigger, Searcher } from "@/base"; +import { StateEditor, DefaultTextEditor } from "@/case"; +import { MultiLayerSelectTreeInsertSearchPane } from "./multilayerselecttree.insert.search.pane"; +import { MultiLayerSelectTreePopup } from "./multilayerselecttree.popup"; + +@shortcut() +export class MultiLayerSelectTreeTrigger extends Trigger { + static xtype = "bi.multilayer_select_tree_trigger"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_START = "EVENT_START"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + + props() { + return { + extraCls: "bi-multi-layer-select-tree-trigger", + height: 24, + itemsCreator: emptyFn, + watermark: i18nText("BI-Basic_Search"), + allowSearchValue: false, + title: () => this._getShowText(), + }; + } + + render() { + const self = this, + o = this.options; + if (o.itemsCreator === emptyFn) { + this._initData(); + } + + return { + type: HorizontalFillLayout.xtype, + items: [ + { + el: { + type: Searcher.xtype, + ref() { + self.searcher = this; + }, + masker: isNotNull(o.container) + ? { + offset: {}, + container: o.container, + } + : { + offset: {}, + }, + isAutoSearch: false, + el: { + type: DefaultTextEditor.xtype, + ref() { + self.editor = this; + }, + defaultText: o.defaultText, + text: isKey(o.value) ? this._digest(o.value) : o.text, + value: o.value, + height: o.height, + tipText: "", + watermark: o.watermark, + listeners: [ + { + eventName: StateEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiLayerSelectTreeTrigger.EVENT_FOCUS); + }, + }, + { + eventName: StateEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiLayerSelectTreeTrigger.EVENT_BLUR); + }, + }, + { + eventName: StateEditor.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSelectTreeTrigger.EVENT_SEARCHING); + }, + } + ], + }, + popup: { + type: o.allowInsertValue + ? MultiLayerSelectTreeInsertSearchPane.xtype + : MultiLayerSelectTreePopup.xtype, + itemsCreator: + o.itemsCreator === emptyFn + ? emptyFn + : function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + keywordGetter() { + return self.editor.getValue(); + }, + cls: "bi-card", + listeners: [ + { + eventName: MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM, + action() { + self.options.text = self.getSearcher().getKeyword(); + self.fireEvent(MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM); + }, + } + ], + ref(_ref) { + self.popup = _ref; + }, + }, + onSearch(obj, callback) { + const keyword = obj.keyword; + if (o.itemsCreator === emptyFn) { + callback(self._getSearchItems(keyword)); + o.allowInsertValue && self.popup.setKeyword(keyword); + } else { + callback(); + } + }, + listeners: [ + { + eventName: Searcher.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSelectTreeTrigger.EVENT_CHANGE); + }, + } + ], + }, + width: "fill", + rgap: 24, + } + ], + }; + } + + _initData() { + const o = this.options; + this.tree = new Tree(); + this.nodes = Tree.treeFormat(deepClone(o.items)); + this.tree.initTree(this.nodes); + } + + _getSearchItems(keyword) { + const self = this, + o = this.options; + // 把数组搜索换成用BI.tree搜索节点, 搜到了就不再往下搜索 + const items = []; + this.tree.traverse(node => { + const find = Func.getSearchResult( + self.tree.isRoot(node) ? [] : concat([node.text], o.allowSearchValue ? [node.value] : []), + keyword + ); + if (find.find.length > 0 || find.match.length > 0) { + items.push(node); + + return true; + } + }); + + return this._fillTreeStructure4Search(items, "id"); + } + + _createJson(node, open) { + return { + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + isParent: isNotEmptyArray(node.children), + open, + }; + } + + _getChildren(node) { + const self = this; + node.children = node.children || []; + let nodes = []; + each(node.children, (idx, child) => { + const children = self._getChildren(child); + nodes = nodes.concat(children); + }); + + return node.children.concat(nodes); + } + + _fillTreeStructure4Search(leaves) { + const self = this; + let result = []; + const queue = []; + each(leaves, (idx, node) => { + queue.push({ pId: node.pId }); + result.push(node); + result = result.concat(self._getChildren(node)); + }); + queue.reverse(); + while (isNotEmptyArray(queue)) { + const node = queue.pop(); + const pNode = this.tree.search(this.tree.getRoot(), node.pId, "id"); + if (pNode != null) { + pNode.open = true; + queue.push({ pId: pNode.pId }); + result.push(pNode); + } + } + + return uniqBy( + map(result, (idx, node) => self._createJson(node, node.open)), + "id" + ); + } + + _digest(v) { + const o = this.options; + if (isFunction(o.valueFormatter)) { + return o.valueFormatter(v); + } + + const result = find(o.items, (i, item) => item.value === v); + + return isNotNull(result) ? result.text : o.text ?? v; + } + + _getShowText() { + return this.editor.getText(); + } + + stopEditing() { + this.searcher.stopSearch(); + } + + getSearcher() { + return this.searcher; + } + + populate(items) { + this.options.items = items; + this._initData(items); + } + + setValue(v) { + this.editor.setState(this._digest(v[0])); + } + + getValue() { + return this.searcher.getValue(); + } + + focus() { + this.searcher.focus(); + } + + blur() { + this.searcher.blur(); + } + + setWaterMark(v) { + this.searcher.setWaterMark(v); + } +} diff --git a/src/widget/multilayersingletree/__test__/multilayersingletree.combo.test.js b/packages/fineui/src/widget/multilayersingletree/__test__/multilayersingletree.combo.test.js similarity index 100% rename from src/widget/multilayersingletree/__test__/multilayersingletree.combo.test.js rename to packages/fineui/src/widget/multilayersingletree/__test__/multilayersingletree.combo.test.js diff --git a/packages/fineui/src/widget/multilayersingletree/index.js b/packages/fineui/src/widget/multilayersingletree/index.js new file mode 100644 index 000000000..d0f9e5497 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/index.js @@ -0,0 +1,5 @@ +export { MultiLayerSingleTreeCombo } from "./multilayersingletree.combo"; +export { MultiLayerSingleTreeInsertSearchPane } from "./multilayersingletree.insert.search.pane"; +export { MultiLayerSingleLevelTree } from "./multilayersingletree.leveltree"; +export { MultiLayerSingleTreePopup } from "./multilayersingletree.popup"; +export { MultiLayerSingleTreeTrigger } from "./multilayersingletree.trigger"; diff --git a/packages/fineui/src/widget/multilayersingletree/multilayersingletree.combo.js b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.combo.js new file mode 100644 index 000000000..ea0695257 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.combo.js @@ -0,0 +1,317 @@ +import { shortcut, Widget, extend, emptyFn, isKey, toPix, AbsoluteLayout, nextTick, isArray } from "@/core"; +import { SingleTreeTrigger } from "../singletree/singletree.trigger"; +import { MultiLayerSingleTreePopup } from "./multilayersingletree.popup"; +import { Combo } from "@/base"; +import { MultiLayerSingleTreeTrigger } from "./multilayersingletree.trigger"; +import { TriggerIconButton } from "@/case"; + +@shortcut() +export class MultiLayerSingleTreeCombo extends Widget { + static xtype = "bi.multilayer_single_tree_combo"; + + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-single-tree-combo", + isDefaultInit: false, + height: 24, + text: "", + defaultText: "", + itemsCreator: emptyFn, + items: [], + allowEdit: false, + allowSearchValue: false, + allowInsertValue: false, + isNeedAdjustWidth: true, + }); + } + + render() { + const self = this, + o = this.options; + + const cls = + (o.simple ? "bi-border-bottom bi-focus-shadow " : "bi-border bi-border-radius bi-focus-shadow ") + + (isKey(o.status) ? `status-${o.status}` : ""); + + const baseConfig = this._getBaseConfig(); + + if (o.allowEdit) { + return { + type: AbsoluteLayout.xtype, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + cls, + items: [ + { + el: extend(baseConfig, this._getSearchConfig()), + top: 0, + bottom: 0, + right: 0, + left: 0, + }, + { + el: self._getTriggerIconButton(), + top: 0, + bottom: 0, + right: 0, + } + ], + }; + } + + return extend( + baseConfig, + { + width: toPix(o.width, 2), + height: toPix(o.height, 2), + el: { + type: SingleTreeTrigger.xtype, + ref(_ref) { + self.textTrigger = _ref; + }, + text: o.text, + defaultText: o.defaultText, + height: toPix(o.height, 2), + items: o.items, + value: o.value, + tipType: o.tipType, + warningTitle: o.warningTitle, + valueFormatter: o.valueFormatter, + }, + }, + { cls } + ); + } + + _getBaseConfig() { + const self = this, + o = this.options; + + return { + type: Combo.xtype, + container: o.container, + destroyWhenHide: o.destroyWhenHide, + adjustLength: 2, + ref(_ref) { + self.combo = _ref; + }, + popup: { + el: { + type: MultiLayerSingleTreePopup.xtype, + isDefaultInit: o.isDefaultInit, + itemsCreator: o.itemsCreator, + items: o.items, + ref(_ref) { + self.trigger && self.trigger.getSearcher().setAdapter(_ref); + }, + listeners: [ + { + eventName: MultiLayerSingleTreePopup.EVENT_CHANGE, + action() { + self.setValue(this.getValue()); + self.combo.hideView(); + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_CHANGE); + }, + } + ], + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + }); + }, + }, + value: o.value, + maxHeight: 400, + maxWidth: o.isNeedAdjustWidth ? "auto" : 500, + minHeight: 240, + }, + isNeedAdjustWidth: o.isNeedAdjustWidth, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }; + } + + _getSearchConfig() { + const self = this, + o = this.options; + + return { + el: { + type: MultiLayerSingleTreeTrigger.xtype, + container: o.container, + allowInsertValue: o.allowInsertValue, + allowSearchValue: o.allowSearchValue, + cls: "multilayer-single-tree-trigger", + ref(_ref) { + self.trigger = _ref; + }, + watermark: o.watermark, + items: o.items, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + height: toPix(o.height, 2), + text: o.text, + defaultText: o.defaultText, + value: o.value, + tipType: o.tipType, + warningTitle: o.warningTitle, + title: o.title, + listeners: [ + { + eventName: MultiLayerSingleTreeTrigger.EVENT_CHANGE, + action() { + self.setValue(this.getValue()); + self.combo.hideView(); + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_CHANGE); + }, + }, + { + eventName: MultiLayerSingleTreeTrigger.EVENT_FOCUS, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_FOCUS); + }, + }, + { + eventName: MultiLayerSingleTreeTrigger.EVENT_BLUR, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_BLUR); + }, + }, + { + eventName: MultiLayerSingleTreeTrigger.EVENT_SEARCHING, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_SEARCHING); + }, + }, + { + eventName: MultiLayerSingleTreeTrigger.EVENT_STOP, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_STOP); + }, + }, + { + eventName: MultiLayerSingleTreeTrigger.EVENT_ADD_ITEM, + action() { + const value = self.trigger.getSearcher().getKeyword(); + self.combo.setValue([value]); + self.combo.hideView(); + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_CHANGE); + }, + } + ], + }, + toggle: !o.allowEdit, + hideChecker(e) { + // 新增传配置container后对应hideChecker的修改 + // IE11下,popover(position: fixed)下放置下拉控件(position: fixed), 滚动的时候会异常卡顿 + // 通过container参数将popup放置于popover之外解决此问题, 其他下拉控件由于元素少或者有分页,所以 + // 卡顿不明显, 先在此做尝试, 并在FineUI特殊处理待解决文档中标记跟踪 + return o.container && + self.trigger.getSearcher().isSearching() && + self.trigger.getSearcher().getView().element.find(e.target).length > 0 + ? false + : self.triggerBtn?.element.find(e.target).length === 0; + }, + listeners: [ + { + eventName: Combo.EVENT_AFTER_HIDEVIEW, + action() { + self.trigger.stopEditing(); + }, + }, + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action() { + self.fireEvent(MultiLayerSingleTreeCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }; + } + + _getTriggerIconButton() { + const self = this, + o = this.options; + + return { + type: TriggerIconButton.xtype, + cls: "bi-trigger trigger-icon-button", + ref(_ref) { + self.triggerBtn = _ref; + }, + width: toPix(o.height, 2), + height: toPix(o.height, 2), + listeners: [ + { + eventName: TriggerIconButton.EVENT_CHANGE, + action() { + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }, + } + ], + }; + } + + getSearcher() { + return this.trigger ? this.trigger.getSearcher() : this.textTrigger.getTextor(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.combo.setValue(v); + } + + getValue() { + return this.combo.getValue(); + } + + setStatus(status) { + if (isKey(this.options.status)) { + this.element.removeClass(`status-${this.options.status}`); + } + this.element.addClass(`status-${status}`); + this.options.status = status; + } + + setTipType(v) { + this.trigger ? this.trigger.setTipType(v) : this.textTrigger.setTipType(v); + } + + populate(items) { + this.combo.populate(items); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + showView() { + this.combo.showView(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js new file mode 100644 index 000000000..e00b66ea7 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js @@ -0,0 +1,111 @@ +import { + shortcut, + Widget, + i18nText, + emptyFn, + createWidget, + Controller, + VerticalLayout, + isEmptyArray, + isArray +} from "@/core"; +import { TextButton } from "@/base"; +import { MultiLayerSingleLevelTree } from "./multilayersingletree.leveltree"; + +@shortcut() +export class MultiLayerSingleTreeInsertSearchPane extends Widget { + static xtype = "bi.multilayer_single_tree_insert_search_pane"; + + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + props() { + return { + baseCls: "bi-multilayer-single-tree-popup", + tipText: i18nText("BI-No_Selected_Item"), + isDefaultInit: false, + itemsCreator: emptyFn, + items: [], + value: "", + }; + } + + render() { + const self = this, + o = this.options; + this.tree = createWidget({ + type: MultiLayerSingleLevelTree.xtype, + isDefaultInit: o.isDefaultInit, + items: o.items, + itemsCreator: + o.itemsCreator === emptyFn + ? emptyFn + : function (op, callback) { + o.itemsCreator(op, res => { + callback(res); + self.setKeyword(o.keywordGetter()); + }); + }, + keywordGetter: o.keywordGetter, + value: o.value, + scrollable: null, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }, + }, + { + eventName: MultiLayerSingleLevelTree.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSingleTreeInsertSearchPane.EVENT_CHANGE); + }, + } + ], + }); + + return { + type: VerticalLayout.xtype, + scrolly: false, + scrollable: true, + vgap: 5, + items: [ + { + type: TextButton.xtype, + invisible: true, + text: i18nText("BI-Basic_Click_To_Add_Text", ""), + height: 24, + cls: "bi-high-light", + hgap: 5, + ref(_ref) { + self.addNotMatchTip = _ref; + }, + handler() { + self.fireEvent(MultiLayerSingleTreeInsertSearchPane.EVENT_ADD_ITEM, o.keywordGetter()); + }, + }, + this.tree + ], + }; + } + + setKeyword(keyword) { + const showTip = isEmptyArray(this.tree.getAllLeaves()); + this.addNotMatchTip.setVisible(showTip); + showTip && this.addNotMatchTip.setText(i18nText("BI-Basic_Click_To_Add_Text", keyword)); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + this.tree.populate(items); + } +} diff --git a/packages/fineui/src/widget/multilayersingletree/multilayersingletree.leveltree.js b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.leveltree.js new file mode 100644 index 000000000..d0073fdf2 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.leveltree.js @@ -0,0 +1,203 @@ +import { + shortcut, + extend, + emptyFn, + Selection, + each, + isKey, + UUID, + isNotEmptyArray, + defaults, + createWidget, + Tree, + nextTick, + Controller, + Events, + VerticalLayout, + AdaptiveLayout, + isNull, + isArray, + SIZE_CONSANTS +} from "@/core"; +import { Pane, CustomTree, Loader, ButtonTree } from "@/base"; +import { BasicTreeNode, BasicTreeItem, TreeExpander } from "@/case"; + +@shortcut() +export class MultiLayerSingleLevelTree extends Pane { + static xtype = "bi.multilayer_single_level_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-single-level-tree", + isDefaultInit: false, + items: [], + itemsCreator: emptyFn, + keywordGetter: emptyFn, + chooseType: Selection.Single, + scrollable: true, + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + + this.storeValue = o.value; + + this.initTree(this.options.items); + + this.check(); + } + + _formatItems(nodes, layer, pNode) { + const self = this, + o = this.options; + const keyword = o.keywordGetter(); + each(nodes, (i, node) => { + const extend = { + isFirstNode: i === 0, + isLastNode: i === nodes.length - 1, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }; + node.layer = layer; + if (!isKey(node.id)) { + node.id = UUID(); + } + node.keyword = node.keyword || keyword; + extend.pNode = pNode; + if (node.isParent === true || node.parent === true || isNotEmptyArray(node.children)) { + extend.type = BasicTreeNode.xtype; + extend.selectable = false; + defaults(node, extend); + self._formatItems(node.children, layer + 1, node); + } else { + extend.type = BasicTreeItem.xtype; + defaults(node, extend); + } + }); + + return nodes; + } + + _assertId(sNodes) { + each(sNodes, (i, node) => { + node.id = node.id || UUID(); + }); + } + + initTree(nodes) { + const self = this, + o = this.options; + let hasNext = false; + this.empty(); + this._assertId(nodes); + this.tree = createWidget({ + type: CustomTree.xtype, + cls: "tree-view display-table", + expander: { + type: TreeExpander.xtype, + isDefaultInit: o.isDefaultInit, + el: {}, + popup: { + type: CustomTree.xtype, + }, + }, + + items: this._formatItems(Tree.transformToTreeFormat(nodes), 0), + value: o.value, + itemsCreator(op, callback) { + op.times === 1 && + !op.node && + nextTick(() => { + self.loading(); + }); + o.itemsCreator(op, ob => { + hasNext = ob.hasNext; + op.times === 1 && !op.node && self._populate(ob.items); + callback( + self._formatItems( + Tree.transformToTreeFormat(ob.items), + op.node ? op.node.layer + 1 : 0, + op.node + ) + ); + self.setValue(self.storeValue); + op.times === 1 && + !op.node && + nextTick(() => { + self.loaded(); + }); + }); + }, + + el: { + type: Loader.xtype, + isDefaultInit: o.itemsCreator !== emptyFn, + el: { + type: ButtonTree.xtype, + chooseType: o.chooseType === Selection.None ? Selection.None : Selection.Default, // 不使用buttontree内部getValue逻辑 + behaviors: o.behaviors, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + hasNext() { + return hasNext; + }, + }, + }); + this.tree.on(Controller.EVENT_CHANGE, function (type, v) { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + if (type === Events.CLICK) { + self.setValue(v); + self.fireEvent(MultiLayerSingleLevelTree.EVENT_CHANGE, v); + } + }); + + createWidget({ + type: AdaptiveLayout.xtype, + element: this, + scrollable: o.scrollable, + items: [this.tree], + }); + } + + _populate() { + super.populate(...arguments); + } + + populate(nodes) { + this._populate(nodes); + isNull(nodes) + ? this.tree.populate() + : this.tree.populate(this._formatItems(Tree.transformToTreeFormat(nodes), 0)); + } + + setValue(v) { + // getValue依赖于storeValue, 那么不选的时候就不要更新storeValue了 + if (this.options.chooseType !== Selection.None) { + this.storeValue = v; + this.tree.setValue(v); + } + } + + getValue() { + return isArray(this.storeValue) ? this.storeValue : isNull(this.storeValue) ? [] : [this.storeValue]; + } + + getAllLeaves() { + return this.tree.getAllLeaves(); + } + + getNodeById(id) { + return this.tree.getNodeById(id); + } + + getNodeByValue(id) { + return this.tree.getNodeByValue(id); + } +} diff --git a/packages/fineui/src/widget/multilayersingletree/multilayersingletree.popup.js b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.popup.js new file mode 100644 index 000000000..990fb2a71 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.popup.js @@ -0,0 +1,74 @@ +import { shortcut, Widget, extend, i18nText, emptyFn, createWidget, Controller, VerticalLayout, isArray, pixFormat } from "@/core"; +import { MultiLayerSingleLevelTree } from "./multilayersingletree.leveltree"; + +@shortcut() +export class MultiLayerSingleTreePopup extends Widget { + static xtype = "bi.multilayer_single_tree_popup"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multilayer-singletree-popup", + tipText: i18nText("BI-No_Selected_Item"), + isDefaultInit: false, + itemsCreator: emptyFn, + items: [], + onLoaded: emptyFn, + minHeight: 240, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.tree = createWidget({ + type: MultiLayerSingleLevelTree.xtype, + isDefaultInit: o.isDefaultInit, + items: o.items, + itemsCreator: o.itemsCreator, + keywordGetter: o.keywordGetter, + value: o.value, + scrollable: null, + onLoaded() { + self.tree.check(); + o.onLoaded(); + }, + }); + + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + scrollable: true, + element: this, + vgap: 5, + items: [this.tree], + }); + + this.tree.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.tree.on(MultiLayerSingleLevelTree.EVENT_CHANGE, () => { + self.fireEvent(MultiLayerSingleTreePopup.EVENT_CHANGE); + }); + + this.tree.css("min-height", pixFormat(o.minHeight - 10)); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + this.tree.populate(items); + } +} diff --git a/packages/fineui/src/widget/multilayersingletree/multilayersingletree.trigger.js b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.trigger.js new file mode 100644 index 000000000..c06846692 --- /dev/null +++ b/packages/fineui/src/widget/multilayersingletree/multilayersingletree.trigger.js @@ -0,0 +1,281 @@ +import { + shortcut, + emptyFn, + i18nText, + isNotNull, + isKey, + HorizontalFillLayout, + Tree, + deepClone, + Func, + concat, + isNotEmptyArray, + each, + uniqBy, + map, + isFunction, + find +} from "@/core"; +import { Trigger, Searcher } from "@/base"; +import { StateEditor, DefaultTextEditor } from "@/case"; +import { MultiLayerSingleTreeInsertSearchPane } from "./multilayersingletree.insert.search.pane"; +import { MultiLayerSingleTreePopup } from "./multilayersingletree.popup"; + +@shortcut() +export class MultiLayerSingleTreeTrigger extends Trigger { + static xtype = "bi.multilayer_single_tree_trigger"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_START = "EVENT_START"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + + props() { + return { + extraCls: "bi-multi-layer-single-tree-trigger", + height: 24, + itemsCreator: emptyFn, + watermark: i18nText("BI-Basic_Search"), + allowSearchValue: false, + title: () => this._getShowText(), + }; + } + + render() { + const self = this, + o = this.options; + if (o.itemsCreator === emptyFn) { + this._initData(); + } + + return { + type: HorizontalFillLayout.xtype, + items: [ + { + el: { + type: Searcher.xtype, + ref() { + self.searcher = this; + }, + masker: isNotNull(o.container) + ? { + offset: {}, + container: o.container, + } + : { + offset: {}, + }, + isAutoSearch: false, + el: { + type: DefaultTextEditor.xtype, + ref() { + self.editor = this; + }, + defaultText: o.defaultText, + text: isKey(o.value) ? this._digest(o.value) : o.text, + value: o.value, + height: o.height, + tipText: "", + watermark: o.watermark, + listeners: [ + { + eventName: StateEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiLayerSingleTreeTrigger.EVENT_FOCUS); + }, + }, + { + eventName: StateEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiLayerSingleTreeTrigger.EVENT_BLUR); + }, + }, + { + eventName: StateEditor.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSingleTreeTrigger.EVENT_SEARCHING); + }, + } + ], + }, + popup: { + type: o.allowInsertValue + ? MultiLayerSingleTreeInsertSearchPane.xtype + : MultiLayerSingleTreePopup.xtype, + itemsCreator: + o.itemsCreator === emptyFn + ? emptyFn + : function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + keywordGetter() { + return self.editor.getValue(); + }, + cls: "bi-card", + listeners: [ + { + eventName: MultiLayerSingleTreeInsertSearchPane.EVENT_ADD_ITEM, + action() { + self.options.text = self.getSearcher().getKeyword(); + self.fireEvent(MultiLayerSingleTreeTrigger.EVENT_ADD_ITEM); + }, + } + ], + ref(_ref) { + self.popup = _ref; + }, + }, + onSearch(obj, callback) { + const keyword = obj.keyword; + if (o.itemsCreator === emptyFn) { + callback(self._getSearchItems(keyword)); + o.allowInsertValue && self.popup.setKeyword(keyword); + } else { + callback(); + } + }, + listeners: [ + { + eventName: Searcher.EVENT_CHANGE, + action() { + self.fireEvent(MultiLayerSingleTreeTrigger.EVENT_CHANGE); + }, + } + ], + }, + width: "fill", + rgap: 24, + } + ], + }; + } + + _initData() { + const o = this.options; + this.tree = new Tree(); + this.nodes = Tree.treeFormat(deepClone(o.items)); + this.tree.initTree(this.nodes); + } + + _getSearchItems(keyword) { + const self = this, + o = this.options; + // 把数组搜索换成用BI.tree搜索节点, 搜到了就不再往下搜索 + const items = []; + this.tree.traverse(node => { + const find = Func.getSearchResult( + self.tree.isRoot(node) ? [] : concat([node.text], o.allowSearchValue ? [node.value] : []), + keyword + ); + if (find.find.length > 0 || find.match.length > 0) { + items.push(node); + + return true; + } + }); + + return this._fillTreeStructure4Search(items, "id"); + } + + _createJson(node, open) { + return { + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + isParent: isNotEmptyArray(node.children), + open, + }; + } + + _getChildren(node) { + const self = this; + node.children = node.children || []; + let nodes = []; + each(node.children, (idx, child) => { + const children = self._getChildren(child); + nodes = nodes.concat(children); + }); + + return node.children.concat(nodes); + } + + _fillTreeStructure4Search(leaves) { + const self = this; + let result = []; + const queue = []; + each(leaves, (idx, node) => { + queue.push({ pId: node.pId }); + result.push(node); + result = result.concat(self._getChildren(node)); + }); + queue.reverse(); + while (isNotEmptyArray(queue)) { + const node = queue.pop(); + const pNode = this.tree.search(this.tree.getRoot(), node.pId, "id"); + if (pNode != null) { + pNode.open = true; + queue.push({ pId: pNode.pId }); + result.push(pNode); + } + } + + return uniqBy( + map(result, (idx, node) => self._createJson(node, node.open)), + "id" + ); + } + + _digest(v) { + const o = this.options; + + if (isFunction(o.valueFormatter)) { + return o.valueFormatter(v); + } + + const result = find(o.items, (i, item) => item.value === v); + + return isNotNull(result) ? result.text : o.text ?? v; + } + + _getShowText() { + return this.editor.getText(); + } + + stopEditing() { + this.searcher.stopSearch(); + } + + getSearcher() { + return this.searcher; + } + + populate(items) { + this.options.items = items; + this._initData(); + } + + setValue(v) { + this.editor.setState(this._digest(v[0])); + } + + getValue() { + return this.searcher.getValue(); + } + + focus() { + this.searcher.focus(); + } + + blur() { + this.searcher.blur(); + } + + setWaterMark(v) { + this.searcher.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js b/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js new file mode 100644 index 000000000..904452922 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js @@ -0,0 +1,309 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2019/9/18 + */ + +describe("multi_select_no_bar_series", () => { + let _getItemsByTimes, _itemsCreator, itemSelectorGetter, searchItemSelectorGetter, _hasNextByTimes, items; + before(() => { + _getItemsByTimes = function (items, times) { + const res = []; + for (let i = (times - 1) * 100; items[i] && i < times * 100; i++) { + res.push(items[i]); + } + + return res; + }; + + _hasNextByTimes = function (items, times) { + return times * 100 < items.length; + }; + + _itemsCreator = function (options, callback) { + let items = BI.map(BI.makeArray(100, null), (idx, v) => { + return { + text: idx, + value: idx, + title: idx, + }; + }); + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + BI.each(keywords, (i, kw) => { + const search = BI.Func.getSearchResult(items, kw); + items = search.match.concat(search.find); + }); + if (options.selectedValues) {// 过滤 + const filter = BI.makeObject(options.selectedValues, true); + items = BI.filter(items, (i, ob) => !filter[ob.value]); + } + if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items, + }); + + return; + } + if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: items.length }); + + return; + } + callback({ + items: _getItemsByTimes(items, options.times), + hasNext: _hasNextByTimes(items, options.times), + }); + }; + + itemSelectorGetter = function (array) { + return BI.map(array, (idx, num) => `.bi-multi-select-popup-view .bi-loader .bi-button-group .bi-multi-select-item:nth-child(${num})`); + }; + + searchItemSelectorGetter = function (array) { + return BI.map(array, (idx, num) => `.bi-multi-select-search-pane .bi-loader .bi-button-group .bi-multi-select-item:nth-child(${num})`); + }; + }); + + /** + * test_author_windy + **/ + it("setValue", () => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + widget.setValue([1, 2]); + expect(widget.getValue()).to.deep.equal([1, 2]); + widget.destroy(); + }); + + /** + * test_author_windy + **/ + it("getValue", () => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + value: [1, 2, 3], + }); + expect(widget.getValue()).to.deep.equal([1, 2, 3]); + widget.destroy(); + }); + + /** + * test_author_windy + **/ + it("点选选值", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + widget.element.find(".bi-multi-select-trigger").click(); + // 为什么要delay 300呢,因为按钮有debounce + BI.delay(() => { + // 点选1、2、3 + BI.each(itemSelectorGetter([1, 2, 3]), (idx, selector) => { + widget.element.find(selector).click(); + }); + // 取消勾选1、2 + BI.delay(() => { + BI.each(itemSelectorGetter([1, 2]), (idx, selector) => { + widget.element.find(selector).click(); + }); + expect(widget.getValue()).to.deep.equal([2]); + widget.destroy(); + done(); + }, 300); + }, 300); + }); + + /** + * test_author_windy + **/ + it("搜索选值", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + BI.nextTick(() => { + widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); + // 这边为啥要加呢,因为input的setValue中有nextTick + BI.nextTick(() => { + BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "2", 50, () => { + BI.nextTick(() => { + BI.each(searchItemSelectorGetter([1, 2]), (idx, selector) => { + widget.element.find(selector).click(); + }); + expect(widget.getValue()).to.deep.equal([2, 12]); + widget.destroy(); + done(); + }); + }); + }); + }); + }); + + /** + * test_author_windy + **/ + it("查看已选", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_no_bar_combo", + width: 220, + itemsCreator(op, callback) { + callback({ + items, + hasNext: false, + }); + }, + value: [1, 2], + }); + BI.nextTick(() => { + widget.element.find(".bi-multi-select-check-selected-button").click(); + BI.delay(() => { + expect(widget.element.find(".display-list-item").length).to.equal(2); + widget.destroy(); + done(); + }, 300); + }); + }); + + /** + * test_author_windy + **/ + it("setValue", () => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + widget.setValue([1, 2]); + expect(widget.getValue()).to.deep.equal([1, 2]); + widget.destroy(); + }); + + /** + * test_author_windy + **/ + it("getValue", () => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + value: [1, 2, 3], + }); + expect(widget.getValue()).to.deep.equal([1, 2, 3]); + widget.destroy(); + }); + + + /** + * test_author_windy + **/ + it("点选选值1", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + widget.element.find(".bi-multi-select-trigger").click(); + // 为什么要delay 300呢,因为按钮有debounce + BI.delay(() => { + // 点选1、2、3 + BI.each(itemSelectorGetter([1, 2, 3]), (idx, selector) => { + widget.element.find(selector).click(); + }); + // 取消勾选1、2、3 + BI.delay(() => { + BI.each(itemSelectorGetter([1, 2]), (idx, selector) => { + widget.element.find(selector).click(); + }); + expect(widget.getValue()).to.deep.equal([2]); + widget.destroy(); + done(); + }, 300); + }, 300); + }); + + /** + * test_author_windy + **/ + it("搜索选值1", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + BI.nextTick(() => { + widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); + // 这边为啥要加呢,因为input的setValue中有nextTick + BI.nextTick(() => { + BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "2", 50, () => { + BI.nextTick(() => { + BI.each(searchItemSelectorGetter([1, 2]), (idx, selector) => { + widget.element.find(selector).click(); + }); + expect(widget.getValue()).to.deep.equal([2, 12]); + widget.destroy(); + done(); + }); + }); + }); + }); + }); + + /** + * test_author_windy + **/ + it("新增值1", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + }); + BI.nextTick(() => { + widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); + // 这边为啥要加呢,因为input的setValue中有nextTick + BI.nextTick(() => { + BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "z", 50, () => { + BI.nextTick(() => { + widget.element.find(".bi-text-button:contains(+点击新增\"z\")").click(); + expect(widget.getValue()).to.deep.equal(["z"]); + widget.destroy(); + done(); + }); + }); + }); + }); + }); + + /** + * test_author_windy + **/ + it("查看已选1", done => { + const widget = BI.Test.createWidget({ + type: "bi.multi_select_insert_no_bar_combo", + width: 220, + itemsCreator: _itemsCreator, + value: { + type: 1, + value: [1, 2], + }, + }); + BI.nextTick(() => { + widget.element.find(".bi-multi-select-check-selected-button").click(); + BI.delay(() => { + expect(widget.element.find(".display-list-item").length).to.equal(2); + widget.destroy(); + done(); + }, 300); + }); + }); +}); diff --git a/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.test.js b/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.test.js new file mode 100644 index 000000000..3e3f47411 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/__test__/multiselect.loader.test.js @@ -0,0 +1,5 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2019/9/18 + */ diff --git a/packages/fineui/src/widget/multiselect/__test__/multiselectcombo.test.js b/packages/fineui/src/widget/multiselect/__test__/multiselectcombo.test.js new file mode 100644 index 000000000..3e3f47411 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/__test__/multiselectcombo.test.js @@ -0,0 +1,5 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2019/9/18 + */ diff --git a/packages/fineui/src/widget/multiselect/__test__/multiselectinsert.combo.test.js b/packages/fineui/src/widget/multiselect/__test__/multiselectinsert.combo.test.js new file mode 100644 index 000000000..3e3f47411 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/__test__/multiselectinsert.combo.test.js @@ -0,0 +1,5 @@ +/** + * @author windy + * @version 2.0 + * Created by windy on 2019/9/18 + */ diff --git a/packages/fineui/src/widget/multiselect/check/multiselect.check.pane.js b/packages/fineui/src/widget/multiselect/check/multiselect.check.pane.js new file mode 100644 index 000000000..8563504be --- /dev/null +++ b/packages/fineui/src/widget/multiselect/check/multiselect.check.pane.js @@ -0,0 +1,123 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + map, + i18nText, + VerticalAdaptLayout, + VTapeLayout, + Selection +} from "@/core"; +import { TextButton, Label } from "@/base"; +import { DisplaySelectedList } from "./multiselect.display"; + +@shortcut() +export class MultiSelectCheckPane extends Widget { + static xtype = "bi.multi_select_check_pane"; + + constants = { height: 12, lgap: 10, tgap: 10, bgap: 5 }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-check-pane bi-background", + items: [], + itemsCreator: emptyFn, + valueFormatter: emptyFn, + onClickContinueSelect: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + + this.storeValue = opts.value || {}; + this.display = createWidget({ + type: DisplaySelectedList.xtype, + items: opts.items, + itemsCreator(op, callback) { + op = extend(op || {}, { + selectedValues: self.storeValue.value, + }); + if (self.storeValue.type === Selection.Multi) { + callback({ + items: map(self.storeValue.value, (i, v) => { + const txt = opts.valueFormatter(v) || v; + + return { + text: txt, + value: v, + title: txt, + }; + }), + }); + + return; + } + opts.itemsCreator(op, callback); + }, + }); + + this.continueSelect = createWidget({ + type: TextButton.xtype, + title: i18nText("BI-Continue_Select"), + text: i18nText("BI-Continue_Select"), + cls: "multi-select-check-selected bi-high-light", + }); + + this.continueSelect.on(TextButton.EVENT_CHANGE, () => { + opts.onClickContinueSelect(); + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + height: this.constants.height, + el: { + type: VerticalAdaptLayout.xtype, + columnSize: ["auto", "auto"], + cls: "multi-select-continue-select", + items: [ + { + el: { + type: Label.xtype, + title: i18nText("BI-Selected_Data"), + text: i18nText("BI-Selected_Data"), + }, + lgap: this.constants.lgap, + }, + { + el: this.continueSelect, + hgap: this.constants.lgap, + } + ], + }, + tgap: this.constants.tgap, + }, + { + height: "fill", + el: this.display, + tgap: this.constants.bgap, + } + ], + }); + } + + setValue(v) { + this.storeValue = v || {}; + } + + empty() { + this.display.empty(); + } + + populate() { + this.display.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/check/multiselect.display.js b/packages/fineui/src/widget/multiselect/check/multiselect.display.js new file mode 100644 index 000000000..3254e4898 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/check/multiselect.display.js @@ -0,0 +1,102 @@ +import { shortcut, extend, emptyFn, createWidget, VerticalLayout, createItems } from "@/core"; +import { Pane, ButtonGroup, Loader, IconTextItem } from "@/base"; +import { ListPane } from "@/case"; + +@shortcut() +export class DisplaySelectedList extends Pane { + static xtype = "bi.display_selected_list"; + + constants = { height: 24, lgap: 10 }; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-display-list", + itemsCreator: emptyFn, + items: [], + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + + this.hasNext = false; + let cacheItems = []; + + this.button_group = createWidget({ + type: ListPane.xtype, + element: this, + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + items: this._createItems(opts.items), + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + layouts: [ + { + type: VerticalLayout.xtype, + lgap: 10, + } + ], + }, + itemsCreator(options, callback) { + if (options.times === 1) { + cacheItems = []; + } + + if (cacheItems.length > 0) { + const renderedItems = cacheItems.slice(0, 100); + cacheItems = cacheItems.slice(100); + self.hasNext = cacheItems.length > 0; + callback(self._createItems(renderedItems)); + + return; + } + + opts.itemsCreator(options, ob => { + self.hasNext = !!ob.hasNext; + const firstItemsCount = 100 + (ob.items.length % 100); + if (ob.items.length > 100) { + cacheItems = ob.items.slice(firstItemsCount); + self.hasNext = firstItemsCount !== ob.items.length; + } + callback(self._createItems(ob.items.slice(0, firstItemsCount))); + }); + }, + hasNext() { + return self.hasNext; + }, + }); + } + + _createItems(items) { + return createItems(items, { + type: IconTextItem.xtype, + cls: "cursor-default check-font icon-size-12 display-list-item bi-tips", + once: true, + invalid: true, + selected: true, + height: this.constants.height, + logic: { + dynamic: true, + }, + }); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + if (arguments.length === 0) { + this.button_group.populate(); + } else { + this.button_group.populate(this._createItems(items)); + } + } +} diff --git a/packages/fineui/src/widget/multiselect/index.js b/packages/fineui/src/widget/multiselect/index.js new file mode 100644 index 000000000..9236080dd --- /dev/null +++ b/packages/fineui/src/widget/multiselect/index.js @@ -0,0 +1,11 @@ +export { MultiSelectSearchPane } from "./search/multiselect.search.pane"; +export { MultiSelectEditor } from "./trigger/editor.multiselect"; +export { MultiSelectTrigger } from "./multiselect.trigger"; +export { MultiSelectPopupView } from "./multiselect.popup.view"; +export { MultiSelectSearcher } from "./trigger/searcher.multiselect"; +export { MultiSelectCheckSelectedSwitcher } from "./trigger/switcher.checkselected"; +export { MultiSelectCombo } from "./multiselect.combo"; +export { MultiSelectNoBarCombo } from "./multiselect.combo.nobar"; +export { MultiSelectInsertCombo } from "./multiselect.insert.combo"; +export { MultiSelectInsertNoBarCombo } from "./multiselect.insert.combo.nobar"; +export { SelectPatchEditor } from "./trigger/editor/editor.patch"; diff --git a/packages/fineui/src/widget/multiselect/loader.js b/packages/fineui/src/widget/multiselect/loader.js new file mode 100644 index 000000000..f39c35ef7 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/loader.js @@ -0,0 +1,326 @@ +import { LoadingBar, ButtonGroup, Loader } from "@/base"; +import { + shortcut, + Widget, + extend, + emptyFn, + VerticalLayout, + createWidget, + Controller, + Events, + isEmpty, + nextTick, + bind, + isNumber, + isObject, + isFunction, + makeObject, + isArray, + each, + Element +} from "@/core"; + +@shortcut() +export class MultiSelectInnerLoader extends Widget { + static xtype = "bi.multi_select_inner_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-inner-loader", + + direction: "top", + isDefaultInit: true, // 是否默认初始化数据 + logic: { + dynamic: true, + scrolly: true, + }, + + // 下面是button_group的属性 + el: { + type: ButtonGroup.xtype, + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + + items: [], + itemsCreator: emptyFn, + onLoaded: emptyFn, + + // 下面是分页信息 + count: false, + prev: false, + next: {}, + hasPrev: emptyFn, + hasNext: emptyFn, + }); + } + + _nextLoad() { + const self = this, + o = this.options; + this.next.setLoading(); + if (this.cachItems && this.cachItems.length > 0) { + this.next.setLoaded(); + const items = this._composeItems(this.cachItems.slice(0, 100)); + this.addItems(items); + this.cachItems = this.cachItems.slice(100); + + return; + } + o.itemsCreator.apply(this, [ + { times: ++this.times }, + function() { + self.next.setLoaded(); + self.addItems(...arguments); + } + ]); + } + + render() { + const self = this, + o = this.options; + if (o.itemsCreator === false) { + o.next = false; + } + this.button_group = createWidget(o.el, { + type: ButtonGroup.xtype, + chooseType: 0, + items: o.items, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value: o.value, + }); + this.button_group.on(Controller.EVENT_CHANGE, function(type, value, obj) { + if (type === Events.CLICK) { + const node = self.cachGroup.getNodeByValue(value); + if (node) { + node.setSelected(obj.isSelected()); + } + } + self.fireEvent(Controller.EVENT_CHANGE, arguments); + if (type === Events.CLICK) { + self.fireEvent(Loader.EVENT_CHANGE, obj); + } + }); + + const renderEngine = Widget._renderEngine; + Widget.registerRenderEngine(Element.renderEngine); + this.cachGroup = createWidget(o.el, { + type: ButtonGroup.xtype, + root: true, + chooseType: 0, + items: o.items, + behaviors: {}, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + value: o.value, + }); + Widget.registerRenderEngine(renderEngine); + + if (o.next !== false) { + this.next = createWidget( + extend( + { + type: LoadingBar.xtype, + }, + o.next + ) + ); + this.next.on(Controller.EVENT_CHANGE, type => { + if (type === Events.CLICK) { + self._nextLoad(); + } + }); + } + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.button_group, this.next], + }); + + o.isDefaultInit && + isEmpty(o.items) && + nextTick( + bind(function() { + o.isDefaultInit && isEmpty(o.items) && this._populate(); + }, this) + ); + } + + hasNext() { + const o = this.options; + if (isNumber(o.count)) { + return this.count < o.count; + } + if (this.cachItems && this.cachItems.length > 0) { + return true; + } + + return !!o.hasNext.apply(this, [ + { + times: this.times, + count: this.count, + } + ]); + } + + addItems(items) { + this.count += items.length; + if (isObject(this.next)) { + if (this.hasNext()) { + this.options.items = this.options.items.concat(items); + this.next.setLoaded(); + } else { + this.next.setEnd(); + } + } + // cacheGroup渲染的是全量的,如果这次加载更多add的items是从cacheItems里面拿的,那不用再add了 + if (this.cachItems.length > 0) { + this.button_group.addItems(...arguments); + return; + } + const renderEngine = Widget._renderEngine; + Widget.registerRenderEngine(Element.renderEngine); + this.cachGroup.addItems(...arguments); + Widget.registerRenderEngine(renderEngine); + this.button_group.addItems(...arguments); + } + + _composeItems(items) { + const cacheValue = this.cachGroup.getValue(); + return items.map(item => { + return { + ...item, + selected: cacheValue.includes(item.value || item.id) + }; + }); + } + + _populate(items) { + const self = this, + o = this.options; + if (arguments.length === 0 && isFunction(o.itemsCreator)) { + o.itemsCreator.apply(this, [ + { times: 1 }, + function(items, keyword) { + if (arguments.length === 0) { + throw new Error("object already registered"); + } + self.populate(...arguments); + o.onLoaded(); + } + ]); + + return false; + } + this.options.items = (items || []).slice(0, 100 + ((items || []).length % 100)); + this.times = 1; + this.count = 0; + this.count += items.length; + + return true; + } + + populate(items, keyword) { + if (this._populate(...arguments)) { + this.cachItems = []; + const firstItemsCount = 100 + (items.length % 100); + if (items.length > firstItemsCount) { + this.cachItems = items.slice(firstItemsCount); + } + const renderEngine = Widget._renderEngine; + Widget.registerRenderEngine(Element.renderEngine); + this.cachGroup.populate.call(this.cachGroup, items, keyword); + Widget.registerRenderEngine(renderEngine); + this.button_group.populate.call(this.button_group, items.slice(0, firstItemsCount), keyword); + + // hasNext依赖的是cacheItems计算,所以从_populate挪到populate里面 + if (isObject(this.next)) { + if (this.hasNext()) { + this.next.setLoaded(); + } else { + this.next.invisible(); + } + } + } + } + + setNotSelectedValue() { + this.button_group.setNotSelectedValue(...arguments); + this.cachGroup.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.cachGroup.getNotSelectedValue(); + } + + setAllSelected(v) { + this.button_group.setAllSelected(v); + this.cachGroup.setAllSelected(v); + } + + setValue(value) { + const map = makeObject(isArray(value) ? value : [value]); + this.cachGroup.setValueMap.call(this.cachGroup, map); + this.button_group.setValueMap.call(this.button_group, map); + } + + getValue() { + return this.cachGroup.getValue(...arguments); + } + + getAllButtons() { + return this.cachGroup.getAllButtons(); + } + + getAllLeaves() { + return this.cachGroup.getAllLeaves(); + } + + getSelectedButtons() { + return this.button_group.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.button_group.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.button_group.getIndexByValue(value); + } + + getNodeById(id) { + return this.button_group.getNodeById(id); + } + + getNodeByValue(value) { + return this.button_group.getNodeByValue(value); + } + + empty() { + this.button_group.empty(); + this.cachGroup.empty(); + each([this.prev, this.next], (i, ob) => { + ob && ob.setVisible(false); + }); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.combo.js b/packages/fineui/src/widget/multiselect/multiselect.combo.js new file mode 100644 index 000000000..72d152bd5 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.combo.js @@ -0,0 +1,527 @@ +import { MultiSelectPopupView } from "./multiselect.popup.view"; +import { + shortcut, + extend, + emptyFn, + isKey, + remove, + deepClone, + createWidget, + toPix, + bind, + last, + initial, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + isNotNull, + makeObject, + map, + each, + Func, + concat, + values, + filter, + contains, + isNull, + SIZE_CONSANTS, + pushDistinct, + endWith, + BlankSplitChar +} from "@/core"; +import { Single, Combo } from "@/base"; +import { TriggerIconButton, MultiSelectBar } from "@/case"; +import { MultiSelectTrigger } from "./multiselect.trigger"; +import { MultiSelectCheckSelectedSwitcher } from "./trigger/switcher.checkselected"; + +@shortcut() +export class MultiSelectCombo extends Single { + static xtype = "bi.multi_select_combo"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static MultiSelectCombo = "MultiSelectCombo"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-combo", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + height: 24, + allowEdit: true, + }); + } + + _init() { + const self = this; + const o = this.options; + super._init(...arguments); + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + + function assertShowValue() { + if (isKey(self._startValue)) { + if (self.storeValue.type === Selection.All) { + remove(self.storeValue.value, self._startValue); + self.storeValue.assist = self.storeValue.assist || []; + pushDistinct(self.storeValue.assist, self._startValue); + } else { + pushDistinct(self.storeValue.value, self._startValue); + remove(self.storeValue.assist, self._startValue); + } + } + + self.trigger.getSearcher().setState(self.storeValue); + self.numberCounter.setButtonChecked(self.storeValue); + } + + this.storeValue = deepClone(o.value) || {}; + + this._assertValue(this.storeValue); + + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: MultiSelectTrigger.xtype, + allowEdit: o.allowEdit, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + defaultText: o.defaultText, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + itemHeight: o.itemHeight, + value: this.storeValue, + }); + + this.trigger.on(MultiSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiSelectCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, function() { + self._setStartValue(""); + this.getSearcher().setValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, () => { + self._setStartValue(""); + self.fireEvent(MultiSelectCombo.EVENT_STOP); + }); + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, keywords => { + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.combo.setValue(self.storeValue); + assertShowValue(); + self.combo.populate(); + self._setStartValue(""); + } else { + self.combo.setValue(self.storeValue); + assertShowValue(); + } + self._dataChange = true; + }); + } + self.fireEvent(MultiSelectCombo.EVENT_SEARCHING); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, function(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectCombo.EVENT_CLICK_ITEM); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectCombo.EVENT_CLICK_ITEM); + }); + } + self._dataChange = true; + }); + this.trigger.on(MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, () => { + // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) + // 只需要更新查看面板的selectedValue用以请求已选数据 + self.numberCounter.updateSelectedValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: !o.allowEdit, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiSelectPopupView.xtype, + ref() { + self.popup = this; + }, + listeners: [ + { + eventName: MultiSelectPopupView.EVENT_CHANGE, + action() { + self._dataChange = true; + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + }); + self.fireEvent(MultiSelectCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CONFIRM, + action() { + self._defaultState(); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CLEAR, + action() { + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + }, + value: o.value, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function() { + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(self.storeValue); + nextTick(() => { + self._populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + self._stopEditing(); + if (self.requesting === true) { + self.wants2Quit = true; + } else { + self._dataChange && self.fireEvent(MultiSelectCombo.EVENT_CONFIRM); + } + this.fireEvent(MultiSelectCombo.EVENT_AFTER_HIDEVIEW); + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + value: this.storeValue, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function() { + this.updateSelectedValue(self.storeValue); + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _itemsCreator4Trigger(op, callback) { + const self = this; + const o = this.options; + o.itemsCreator(op, function(res) { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + self.trigger.setValue(deepClone(self.getValue())); + } + callback.apply(self, arguments); + }); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this; + const o = this.options; + this._assertValue(this.storeValue); + this.requesting = true; + o.itemsCreator( + { + type: MultiSelectCombo.REQ_GET_ALL_DATA, + keywords, + }, + ob => { + const values = map(ob.items, "value"); + digest(values); + } + ); + + function digest(items) { + const selectedMap = self._makeMap(items); + each(keywords, (i, val) => { + if (isNotNull(selectedMap[val])) { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + } + }); + self._adjust(callback); + } + } + + _joinAll(res, callback) { + const tempMap = this._makeMap(this.storeValue.value); + const self = this; + const o = this.options; + this._assertValue(res); + this.requesting = true; + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKey() + ); + let change = false; + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(tempMap[v]); + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + this._adjust(callback); + + return; + } + o.itemsCreator( + { + type: MultiSelectCombo.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKey()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + remove(self.storeValue.assist, item); + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + self._adjust(callback); + } + ); + } + + _adjust(callback) { + const self = this; + adjust(); + callback(); + + function adjust() { + if (self.wants2Quit === true) { + self._dataChange && self.fireEvent(MultiSelectCombo.EVENT_CONFIRM); + self.wants2Quit = false; + } + self.requesting = false; + } + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + remove(self.storeValue.assist, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(map[v]); + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + self._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + _populate() { + this.combo.populate(...arguments); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.combo.setValue(this.storeValue); + this.numberCounter.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue); + } + + populate() { + this._populate(...arguments); + this.numberCounter.populateSwitcher(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.combo.nobar.js b/packages/fineui/src/widget/multiselect/multiselect.combo.nobar.js new file mode 100644 index 000000000..32d4dfde8 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.combo.nobar.js @@ -0,0 +1,557 @@ +import { + shortcut, + extend, + emptyFn, + isKey, + remove, + deepClone, + createWidget, + toPix, + bind, + last, + initial, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + isNotNull, + makeObject, + map, + each, + Func, + concat, + values, + filter, + contains, + isNull, + pushDistinct, + Selection, + SIZE_CONSANTS, + endWith, + BlankSplitChar +} from "@/core"; +import { Single, Combo } from "@/base"; +import { MultiSelectBar, TriggerIconButton } from "@/case"; +import { MultiSelectTrigger } from "./multiselect.trigger"; +import { MultiSelectCheckSelectedSwitcher } from "./trigger/switcher.checkselected"; +import { MultiSelectNoBarPopupView } from "@/widget/multiselect/multiselect.popup.view.nobar"; + +@shortcut() +export class MultiSelectNoBarCombo extends Single { + static xtype = "bi.multi_select_no_bar_combo"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-combo-no-bar", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + height: 24, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + + function assertShowValue() { + if (isKey(self._startValue)) { + if (self.storeValue.type === Selection.All) { + remove(self.storeValue.value, self._startValue); + self.storeValue.assist = self.storeValue.assist || []; + pushDistinct(self.storeValue.assist, self._startValue); + } else { + pushDistinct(self.storeValue.value, self._startValue); + remove(self.storeValue.assist, self._startValue); + } + } + self.trigger.getSearcher().setState(self.storeValue); + self.numberCounter.setButtonChecked(self.storeValue); + } + + this.storeValue = { + type: Selection.Multi, + value: deepClone(o.value) || [], + }; + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: MultiSelectTrigger.xtype, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + defaultText: o.defaultText, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + itemFormatter: o.itemFormatter, + itemHeight: o.itemHeight, + value: { + type: Selection.Multi, + value: o.value, + }, + }); + + this.trigger.on(MultiSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectNoBarCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiSelectNoBarCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, function() { + self._setStartValue(""); + this.getSearcher().setValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, () => { + self._setStartValue(""); + self.fireEvent(MultiSelectNoBarCombo.EVENT_STOP); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, keywords => { + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.combo.setValue(self.storeValue); + assertShowValue(); + self.combo.populate(); + self._setStartValue(""); + } else { + self.combo.setValue(self.storeValue); + assertShowValue(); + } + self._dataChange = true; + }); + } + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, function(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + }); + } + self._dataChange = true; + self.fireEvent(MultiSelectNoBarCombo.EVENT_CLICK_ITEM); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, () => { + // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) + // 只需要更新查看面板的selectedValue用以请求已选数据 + self.numberCounter.updateSelectedValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiSelectNoBarPopupView.xtype, + ref() { + self.popup = this; + }, + listeners: [ + { + eventName: MultiSelectNoBarPopupView.EVENT_CHANGE, + action() { + self._dataChange = true; + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + }); + self.fireEvent(MultiSelectNoBarCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectNoBarPopupView.EVENT_CLICK_CONFIRM, + action() { + self._defaultState(); + }, + }, + { + eventName: MultiSelectNoBarPopupView.EVENT_CLICK_CLEAR, + action() { + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + }, + value: { + type: Selection.Multi, + value: o.value, + }, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function() { + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(self.storeValue); + nextTick(() => { + self._populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + self._stopEditing(); + if (self.requesting === true) { + self.wants2Quit = true; + } else { + self._dataChange && self.fireEvent(MultiSelectNoBarCombo.EVENT_CONFIRM); + } + this.fireEvent(MultiSelectNoBarCombo.EVENT_AFTER_HIDEVIEW); + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + value: { + type: Selection.Multi, + value: o.value, + }, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function() { + this.updateSelectedValue(self.storeValue); + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _addItem(assertShowValue, matched) { + const self = this; + const keyword = this.trigger.getSearcher().getKeyword(); + this._join( + { + type: Selection.Multi, + value: [keyword], + }, + () => { + // 如果在不选的状态下直接把该值添加进来 + if (self.storeValue.type === Selection.Multi) { + pushDistinct(self.storeValue.value, keyword); + } + self.combo.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.populate(); + self._setStartValue(""); + self._dataChange = true; + } + ); + } + + _itemsCreator4Trigger(op, callback) { + const self = this, + o = this.options; + o.itemsCreator(op, function(res) { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + self.trigger.setValue(deepClone(self.storeValue)); + } + callback.apply(self, arguments); + }); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this, + o = this.options; + this._assertValue(this.storeValue); + this.requesting = true; + o.itemsCreator( + { + type: MultiSelectNoBarCombo.REQ_GET_ALL_DATA, + keywords, + }, + ob => { + const values = map(ob.items, "value"); + digest(values); + } + ); + + function digest(items) { + const selectedMap = self._makeMap(items); + each(keywords, (i, val) => { + if (isNotNull(selectedMap[val])) { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + } + }); + self._adjust(callback); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + this.requesting = true; + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKey() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(tempMap[v]); + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + this._adjust(callback); + + return; + } + o.itemsCreator( + { + type: MultiSelectNoBarCombo.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKey()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + remove(self.storeValue.assist, item); + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + self._adjust(callback); + } + ); + } + + _adjust(callback) { + const self = this; + adjust(); + callback(); + + function adjust() { + if (self.wants2Quit === true) { + self._dataChange && self.fireEvent(MultiSelectNoBarCombo.EVENT_CONFIRM); + self.wants2Quit = false; + } + self.requesting = false; + } + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + remove(self.storeValue.assist, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(map[v]); + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + self._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + _populate() { + this.combo.populate(...arguments); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue = { + type: Selection.Multi, + value: v || [], + }; + this.combo.setValue(this.storeValue); + this.numberCounter.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this._populate(...arguments); + this.numberCounter.populateSwitcher(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.insert.combo.js b/packages/fineui/src/widget/multiselect/multiselect.insert.combo.js new file mode 100644 index 000000000..9a047fbd0 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.insert.combo.js @@ -0,0 +1,544 @@ +import { MultiSelectInsertTrigger } from "./multiselect.insert.trigger"; +import { MultiSelectPopupView } from "./multiselect.popup.view"; +import { + shortcut, + extend, + emptyFn, + isKey, + remove, + deepClone, + createWidget, + toPix, + bind, + last, + initial, + i18nText, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + isNotNull, + makeObject, + each, + Func, + map, + concat, + values, + filter, + contains, + isNull, + endWith, + pushDistinct, + Selection, + SIZE_CONSANTS, + BlankSplitChar +} from "@/core"; +import { Single, Combo, Msg } from "@/base"; +import { MultiSelectBar, TriggerIconButton } from "@/case"; +import { MultiSelectCheckSelectedSwitcher } from "./trigger/switcher.checkselected"; + +@shortcut() +export class MultiSelectInsertCombo extends Single { + static xtype = "bi.multi_select_insert_combo"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-insert-combo", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + height: 24, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + allowEdit: true, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + + function assertShowValue() { + if (isKey(self._startValue)) { + if (self.storeValue.type === Selection.All) { + remove(self.storeValue.value, self._startValue); + self.storeValue.assist = self.storeValue.assist || []; + pushDistinct(self.storeValue.assist, self._startValue); + } else { + pushDistinct(self.storeValue.value, self._startValue); + remove(self.storeValue.assist, self._startValue); + } + } + self.trigger.getSearcher().setState(self.storeValue); + self.numberCounter.setButtonChecked(self.storeValue); + } + + this.storeValue = deepClone(o.value) || {}; + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: MultiSelectInsertTrigger.xtype, + allowEdit: o.allowEdit, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + watermark: o.watermark, + defaultText: o.defaultText, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + itemFormatter: o.itemFormatter, + itemHeight: o.itemHeight, + value: this.storeValue, + }); + + this.trigger.on(MultiSelectInsertTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectInsertCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiSelectInsertCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectInsertTrigger.EVENT_START, function() { + self._setStartValue(""); + this.getSearcher().setValue(self.storeValue); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_STOP, () => { + self._setStartValue(""); + self.fireEvent(MultiSelectInsertCombo.EVENT_STOP); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_PAUSE, function() { + self._addItem(assertShowValue, true); + self.fireEvent(MultiSelectInsertCombo.EVENT_ADD_ITEM, this.getSearcher().getKeyword()); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_SEARCHING, function(keywords) { + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.combo.setValue(self.storeValue); + assertShowValue(); + self.combo.populate(); + self._setStartValue(""); + } else { + self.combo.setValue(self.storeValue); + assertShowValue(); + } + self._dataChange = true; + }); + this.getSearcher().getKeywordsLength() > 2000 && + Msg.alert(i18nText("BI-Basic_Prompt"), i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); + } + self.fireEvent(MultiSelectInsertCombo.EVENT_SEARCHING); + }); + + this.trigger.on(MultiSelectInsertTrigger.EVENT_CHANGE, function(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertCombo.EVENT_CLICK_ITEM); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertCombo.EVENT_CLICK_ITEM); + }); + } + self._dataChange = true; + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, () => { + // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) + // 只需要更新查看面板的selectedValue用以请求已选数据 + self.numberCounter.updateSelectedValue(self.storeValue); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: !o.allowEdit, + el: this.trigger, + adjustLength: 1, + container: o.container, + popup: { + type: MultiSelectPopupView.xtype, + ref() { + self.popup = this; + }, + listeners: [ + { + eventName: MultiSelectPopupView.EVENT_CHANGE, + action() { + self._dataChange = true; + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + }); + self.fireEvent(MultiSelectInsertCombo.EVENT_CLICK_ITEM); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CONFIRM, + action() { + self._defaultState(); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CLEAR, + action() { + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + itemHeight: o.itemHeight, + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + }, + value: o.value, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function() { + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(self.storeValue); + nextTick(() => { + self._populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + self._stopEditing(); + if (self.requesting === true) { + self.wants2Quit = true; + } else { + self._dataChange && self.fireEvent(MultiSelectInsertCombo.EVENT_CONFIRM); + } + this.fireEvent(MultiSelectInsertCombo.EVENT_AFTER_HIDEVIEW); + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + value: o.value, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function() { + this.updateSelectedValue(self.storeValue); + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _itemsCreator4Trigger(op, callback) { + const self = this, + o = this.options; + o.itemsCreator(op, function(res) { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + self.trigger.setValue(deepClone(self.getValue())); + } + callback.apply(self, arguments); + }); + } + + _addItem(assertShowValue) { + const self = this; + const keyword = this.trigger.getSearcher().getKeyword(); + this._join( + { + type: Selection.Multi, + value: [keyword], + }, + () => { + // 如果在不选的状态下直接把该值添加进来 + if (self.storeValue.type === Selection.Multi) { + pushDistinct(self.storeValue.value, keyword); + } + self.combo.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.populate(); + self._setStartValue(""); + self._dataChange = true; + } + ); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this; + this._assertValue(this.storeValue); + this.requesting = true; + + digest(); + + function digest() { + each(keywords, (i, val) => { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + }); + self._adjust(callback); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + this.requesting = true; + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKey() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(tempMap[v]); + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + this._adjust(callback); + + return; + } + o.itemsCreator( + { + type: MultiSelectInsertCombo.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKey()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + remove(self.storeValue.assist, item); + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + self._adjust(callback); + } + ); + } + + _adjust(callback) { + const self = this; + adjust(); + callback(); + + function adjust() { + if (self.wants2Quit === true) { + self._dataChange && self.fireEvent(MultiSelectInsertCombo.EVENT_CONFIRM); + self.wants2Quit = false; + } + self.requesting = false; + } + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + // value更新的时候assist也需要更新 + remove(self.storeValue.assist, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(map[v]); + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + self._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + _populate() { + this.combo.populate(...arguments); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.combo.setValue(this.storeValue); + this.numberCounter.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue); + } + + populate() { + this._populate(...arguments); + this.numberCounter.populateSwitcher(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.insert.combo.nobar.js b/packages/fineui/src/widget/multiselect/multiselect.insert.combo.nobar.js new file mode 100644 index 000000000..03300f29c --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.insert.combo.nobar.js @@ -0,0 +1,535 @@ +import { + shortcut, + extend, + emptyFn, + isKey, + remove, + deepClone, + createWidget, + toPix, + bind, + last, + initial, + i18nText, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + isNotNull, + makeObject, + each, + Func, + map, + concat, + values, + filter, + contains, + isNull, + endWith, + pushDistinct, + Selection, + BlankSplitChar, + SIZE_CONSANTS +} from "@/core"; +import { Single, Combo, Msg } from "@/base"; +import { MultiSelectInsertTrigger } from "./multiselect.insert.trigger"; +import { MultiSelectBar, TriggerIconButton } from "@/case"; +import { MultiSelectCheckSelectedSwitcher } from "./trigger/switcher.checkselected"; +import { MultiSelectNoBarPopupView } from "./multiselect.popup.view.nobar"; + +@shortcut() +export class MultiSelectInsertNoBarCombo extends Single { + static xtype = "bi.multi_select_insert_no_bar_combo"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-insert-combo-no-bar", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + height: 24, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + + function assertShowValue() { + if (isKey(self._startValue)) { + if (self.storeValue.type === Selection.All) { + remove(self.storeValue.value, self._startValue); + self.storeValue.assist = self.storeValue.assist || []; + pushDistinct(self.storeValue.assist, self._startValue); + } else { + pushDistinct(self.storeValue.value, self._startValue); + remove(self.storeValue.assist, self._startValue); + } + } + self.trigger.getSearcher().setState(self.storeValue); + self.numberCounter.setButtonChecked(self.storeValue); + } + + this.storeValue = { + type: Selection.Multi, + value: deepClone(o.value) || [], + }; + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: MultiSelectInsertTrigger.xtype, + height: toPix(o.height, o.simple ? 1 : 2), + text: o.text, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + itemFormatter: o.itemFormatter, + itemHeight: o.itemHeight, + value: { + type: Selection.Multi, + value: o.value, + }, + }); + + this.trigger.on(MultiSelectInsertTrigger.EVENT_START, function() { + self._setStartValue(""); + this.getSearcher().setValue(self.storeValue); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_STOP, () => { + self._setStartValue(""); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_PAUSE, function() { + self._addItem(assertShowValue, true); + self.fireEvent(MultiSelectInsertNoBarCombo.EVENT_ADD_ITEM, this.getSearcher().getKeyword()); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_SEARCHING, function(keywords) { + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.combo.setValue(self.storeValue); + assertShowValue(); + self.combo.populate(); + self._setStartValue(""); + } else { + self.combo.setValue(self.storeValue); + assertShowValue(); + } + self._dataChange = true; + }); + this.getSearcher().getKeywordsLength() > 2000 && + Msg.alert(i18nText("BI-Basic_Prompt"), i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); + } + }); + + this.trigger.on(MultiSelectInsertTrigger.EVENT_CHANGE, function(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + }); + } + self._dataChange = true; + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, () => { + // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) + // 只需要更新查看面板的selectedValue用以请求已选数据 + self.numberCounter.updateSelectedValue(self.storeValue); + }); + this.trigger.on(MultiSelectInsertTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiSelectNoBarPopupView.xtype, + ref() { + self.popup = this; + }, + listeners: [ + { + eventName: MultiSelectNoBarPopupView.EVENT_CHANGE, + action() { + self._dataChange = true; + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + }); + }, + }, + { + eventName: MultiSelectNoBarPopupView.EVENT_CLICK_CONFIRM, + action() { + self._defaultState(); + }, + }, + { + eventName: MultiSelectNoBarPopupView.EVENT_CLICK_CLEAR, + action() { + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + }, + value: { + type: Selection.Multi, + value: o.value, + }, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function() { + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(self.storeValue); + nextTick(() => { + self._populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + self._stopEditing(); + if (self.requesting === true) { + self.wants2Quit = true; + } else { + self._dataChange && self.fireEvent(MultiSelectInsertNoBarCombo.EVENT_CONFIRM); + } + this.fireEvent(MultiSelectInsertNoBarCombo.EVENT_AFTER_HIDEVIEW); + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + adapter: () => { + return this.popup.getView(); + }, + valueFormatter: o.valueFormatter, + itemsCreator: bind(this._itemsCreator4Trigger, this), + value: { + type: Selection.Multi, + value: o.value, + }, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function() { + this.updateSelectedValue(self.storeValue); + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _itemsCreator4Trigger(op, callback) { + const self = this, + o = this.options; + o.itemsCreator(op, function(res) { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + self.trigger.setValue(deepClone(self.storeValue)); + } + callback.apply(self, arguments); + }); + } + + _addItem(assertShowValue) { + const self = this; + const keyword = this.trigger.getSearcher().getKeyword(); + this._join( + { + type: Selection.Multi, + value: [keyword], + }, + () => { + // 如果在不选的状态下直接把该值添加进来 + if (self.storeValue.type === Selection.Multi) { + pushDistinct(self.storeValue.value, keyword); + } + self.combo.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.populate(); + self._setStartValue(""); + self._dataChange = true; + } + ); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this; + this._assertValue(this.storeValue); + this.requesting = true; + + digest(); + + function digest() { + each(keywords, (i, val) => { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + }); + self._adjust(callback); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + this.requesting = true; + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKey() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(tempMap[v]); + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + this._adjust(callback); + + return; + } + o.itemsCreator( + { + type: MultiSelectInsertNoBarCombo.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKey()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + remove(self.storeValue.assist, item); + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + self._adjust(callback); + } + ); + } + + _adjust(callback) { + const self = this; + adjust(); + callback(); + + function adjust() { + if (self.wants2Quit === true) { + self._dataChange && self.fireEvent(MultiSelectInsertNoBarCombo.EVENT_CONFIRM); + self.wants2Quit = false; + } + self.requesting = false; + } + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + self.storeValue.value.push(v); + remove(self.storeValue.assist, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + self.storeValue.assist && self.storeValue.assist.push(map[v]); + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + self._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + _populate() { + this.combo.populate(...arguments); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue = { + type: Selection.Multi, + value: v || [], + }; + this.combo.setValue(this.storeValue); + this.numberCounter.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this._populate(...arguments); + this.numberCounter.populateSwitcher(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.insert.trigger.js b/packages/fineui/src/widget/multiselect/multiselect.insert.trigger.js new file mode 100644 index 000000000..b7be3abf6 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.insert.trigger.js @@ -0,0 +1,152 @@ +import { shortcut, extend, emptyFn, createWidget, Layout, HTapeLayout, AbsoluteLayout } from "@/core"; +import { Trigger, Text } from "@/base"; +import { MultiSelectInsertSearcher } from "./trigger/searcher.multiselect.insert"; + +@shortcut() +export class MultiSelectInsertTrigger extends Trigger { + static xtype = "bi.multi_select_insert_trigger"; + + constants = { height: 14, rgap: 4, lgap: 4 }; + + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-trigger", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + itemHeight: 24, + searcher: {}, + switcher: {}, + + adapter: null, + masker: {}, + allowEdit: true, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.searcher = createWidget(o.searcher, { + type: MultiSelectInsertSearcher.xtype, + height: o.height, + text: o.text, + defaultText: o.defaultText, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + itemHeight: o.itemHeight, + watermark: o.watermark, + popup: {}, + adapter: o.adapter, + masker: o.masker, + value: o.value, + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_START, () => { + self.fireEvent(MultiSelectInsertTrigger.EVENT_START); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_PAUSE, () => { + self.fireEvent(MultiSelectInsertTrigger.EVENT_PAUSE); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_SEARCHING, function () { + self.fireEvent(MultiSelectInsertTrigger.EVENT_SEARCHING, arguments); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_STOP, () => { + self.fireEvent(MultiSelectInsertTrigger.EVENT_STOP); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectInsertTrigger.EVENT_CHANGE, arguments); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_BLUR, () => { + self.fireEvent(MultiSelectInsertTrigger.EVENT_BLUR); + }); + this.searcher.on(MultiSelectInsertSearcher.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectInsertTrigger.EVENT_FOCUS); + }); + + this.wrapNumberCounter = createWidget({ + type: Layout.xtype, + }); + + this.wrapper = createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: this.searcher, + width: "fill", + }, + { + el: this.wrapNumberCounter, + width: 0, + }, + { + el: createWidget(), + width: 24, + } + ], + }); + + !o.allowEdit && + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Text.xtype, + title() { + return self.searcher.getState(); + }, + }, + left: 0, + right: 24, + top: 0, + bottom: 0, + } + ], + }); + } + + refreshPlaceHolderWidth(width) { + this.wrapper.attr("items")[1].width = width; + this.wrapper.resize(); + } + + getSearcher() { + return this.searcher; + } + + stopEditing() { + this.searcher.stopSearch(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setValue(ob) { + this.searcher.setValue(ob); + } + + getKey() { + return this.searcher.getKey(); + } + + getValue() { + return this.searcher.getValue(); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.loader.js b/packages/fineui/src/widget/multiselect/multiselect.loader.js new file mode 100644 index 000000000..ab234b3f9 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.loader.js @@ -0,0 +1,228 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + isKey, + map, + contains, + remove, + Controller, + delay, + isNotNull, + Selection, + Direction, + LogicFactory, + pushDistinct, + SIZE_CONSANTS +} from "@/core"; +import { SelectList, MultiSelectBar, MultiSelectItem } from "@/case"; +import { MultiSelectInnerLoader } from "./loader"; + +@shortcut() +export class MultiSelectLoader extends Widget { + static xtype = "bi.multi_select_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-loader", + logic: { + dynamic: true, + }, + el: { + height: 400, + }, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemFormatter: emptyFn, + onLoaded: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + isDefaultInit: false, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + let hasNext = false; + + this.storeValue = opts.value || {}; + this._assertValue(this.storeValue); + + this.button_group = createWidget({ + type: SelectList.xtype, + logic: opts.logic, + toolbar: { + type: MultiSelectBar.xtype, + cls: "bi-list-item-active", + height: this.options.itemHeight || SIZE_CONSANTS.LIST_ITEM_HEIGHT, + iconWrapperWidth: 36, + }, + el: extend( + { + onLoaded: opts.onLoaded, + el: { + type: MultiSelectInnerLoader.xtype, + isDefaultInit: opts.isDefaultInit, + }, + }, + opts.el + ), + itemsCreator(op, callback) { + const startValue = self._startValue; + self.storeValue && + (op = extend(op || {}, { + selectedValues: + isKey(startValue) && self.storeValue.type === Selection.Multi + ? self.storeValue.value.concat(startValue) + : self.storeValue.value, + })); + opts.itemsCreator(op, ob => { + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && self.storeValue) { + const json = map(self.storeValue.value, (i, v) => { + const txt = opts.valueFormatter(v) || v; + + return { + text: txt, + value: v, + title: txt, + selected: self.storeValue.type === Selection.Multi, + }; + }); + if (isKey(self._startValue) && !contains(self.storeValue.value, self._startValue)) { + const txt = opts.valueFormatter(startValue) || startValue; + json.unshift({ + text: txt, + value: startValue, + title: txt, + selected: true, + }); + } + firstItems = self._createItems(json); + } + callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); + if (op.times === 1 && self.storeValue) { + isKey(startValue) && + (self.storeValue.type === Selection.All + ? remove(self.storeValue.value, startValue) + : pushDistinct(self.storeValue.value, startValue)); + self.setValue(self.storeValue); + } + op.times === 1 && self._scrollToTop(); + }); + }, + hasNext() { + return hasNext; + }, + value: this.storeValue, + }); + + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(Direction.Top), + extend( + { + scrolly: true, + vgap: 5, + }, + opts.logic, + { + items: LogicFactory.createLogicItemsByDirection(Direction.Top, this.button_group), + } + ) + ) + ) + ); + this.button_group.on(Controller.EVENT_CHANGE, function() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.button_group.on(SelectList.EVENT_CHANGE, function() { + self.fireEvent(MultiSelectLoader.EVENT_CHANGE, arguments); + }); + } + + _createItems(items) { + const allSelected = this.isAllSelected(); + const itemFormatter = this.options.itemFormatter; + + return map(items, (i, item) => { + return { + type: MultiSelectItem.xtype, + logic: this.options.logic, + cls: "bi-list-item-active", + height: this.options.itemHeight || SIZE_CONSANTS.LIST_ITEM_HEIGHT, + selected: allSelected, + iconWrapperWidth: 36, + ...item, + ...itemFormatter(item), + }; + }); + } + + _scrollToTop() { + const self = this; + delay(() => { + self.button_group.element.scrollTop(0); + }, 30); + } + + isAllSelected() { + return this.button_group.isAllSelected(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + setStartValue(v) { + this._startValue = v; + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.button_group.setValue(this.storeValue); + } + + getValue() { + return this.button_group.getValue(); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(...args) { + const items = args[0]; + if (isNotNull(items)) { + args[0] = this._createItems(items); + } + this.button_group.populate(...args); + } + + resetHeight(h) { + this.button_group.resetHeight(h - 10); + } + + resetWidth(w) { + this.button_group.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.loader.nobar.js b/packages/fineui/src/widget/multiselect/multiselect.loader.nobar.js new file mode 100644 index 000000000..825a7f6ac --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.loader.nobar.js @@ -0,0 +1,220 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + isKey, + map, + contains, + remove, + Controller, + VerticalLayout, + delay, + isNotNull, + toPix, + Selection, + pushDistinct, + SIZE_CONSANTS, + LogicFactory, + Direction +} from "@/core"; +import { ButtonGroup, Loader } from "@/base"; +import { SelectList, ListPane, MultiSelectItem } from "@/case"; + +@shortcut() +export class MultiSelectNoBarLoader extends Widget { + static xtype = "bi.multi_select_no_bar_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-loader-no-bar", + logic: { + dynamic: true, + }, + el: { + height: 400, + }, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + onLoaded: emptyFn, + itemFormatter: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + let hasNext = false; + + this.storeValue = opts.value || {}; + this._assertValue(this.storeValue); + + this.button_group = createWidget( + extend( + { + type: ListPane.xtype, + onLoaded: opts.onLoaded, + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + itemsCreator(op, callback) { + const startValue = self._startValue; + self.storeValue && + (op = extend(op || {}, { + selectedValues: + isKey(startValue) && self.storeValue.type === Selection.Multi + ? self.storeValue.value.concat(startValue) + : self.storeValue.value, + })); + opts.itemsCreator(op, ob => { + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && self.storeValue) { + const json = map(self.storeValue.value, (i, v) => { + const txt = opts.valueFormatter(v) || v; + + return { + text: txt, + value: v, + title: txt, + selected: self.storeValue.type === Selection.Multi, + }; + }); + if (isKey(self._startValue) && !contains(self.storeValue.value, self._startValue)) { + const txt = opts.valueFormatter(startValue) || startValue; + json.unshift({ + text: txt, + value: startValue, + title: txt, + selected: true, + }); + } + firstItems = self._createItems(json); + } + callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); + if (op.times === 1 && self.storeValue) { + isKey(startValue) && + (self.storeValue.type === Selection.All + ? remove(self.storeValue.value, startValue) + : pushDistinct(self.storeValue.value, startValue)); + self.setValue(self.storeValue); + } + op.times === 1 && self._scrollToTop(); + }); + }, + hasNext() { + return hasNext; + }, + value: this.storeValue, + }, + opts.el + ) + ); + + createWidget(extend({ + element: this, + }, LogicFactory.createLogic(LogicFactory.createLogicTypeByDirection(Direction.Top), extend({ + scrolly: true, + vgap: 5, + }, opts.logic, { + items: LogicFactory.createLogicItemsByDirection(Direction.Top, this.button_group), + })))); + + this.button_group.on(Controller.EVENT_CHANGE, function() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.button_group.on(SelectList.EVENT_CHANGE, function() { + self.fireEvent(MultiSelectNoBarLoader.EVENT_CHANGE, arguments); + }); + } + + _createItems(items) { + return map(items, (index, item) => { + return { + type: MultiSelectItem.xtype, + cls: "bi-list-item-active", + logic: this.options.logic, + height: this.options.itemHeight || SIZE_CONSANTS.LIST_ITEM_HEIGHT, + iconWrapperWidth: 36, + ...item, + ...this.options.itemFormatter(item), + }; + }); + } + + _scrollToTop() { + const self = this; + delay(() => { + self.button_group.element.scrollTop(0); + }, 30); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + setStartValue(v) { + this._startValue = v; + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.button_group.setValue(this.storeValue.value); + } + + getValue() { + return { + type: Selection.Multi, + value: this.button_group.getValue(), + }; + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + if (isNotNull(items)) { + arguments[0] = this._createItems(items); + } + this.button_group.populate(...arguments); + } + + resetHeight(h) { + this.button_group.element.css({ "max-height": toPix(h) }); + } + + resetWidth() { + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.popup.view.js b/packages/fineui/src/widget/multiselect/multiselect.popup.view.js new file mode 100644 index 000000000..84e3faf58 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.popup.view.js @@ -0,0 +1,105 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, i18nText, SIZE_CONSANTS } from "@/core"; +import { MultiPopupView } from "@/case"; +import { MultiSelectLoader } from "./multiselect.loader"; + +@shortcut() +export class MultiSelectPopupView extends Widget { + static xtype = "bi.multi_select_popup_view"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-popup-view", + maxWidth: "auto", + minWidth: 135, + maxHeight: 400, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + onLoaded: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }); + } + + _init() { + super._init(...arguments); + const self = this, + opts = this.options; + + this.loader = createWidget({ + type: MultiSelectLoader.xtype, + itemsCreator: opts.itemsCreator, + itemHeight: opts.itemHeight, + valueFormatter: opts.valueFormatter, + itemFormatter: opts.itemFormatter, + onLoaded: opts.onLoaded, + value: opts.value, + }); + + this.popupView = createWidget({ + type: MultiPopupView.xtype, + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + element: this, + buttons: [i18nText("BI-Basic_Clears"), i18nText("BI-Basic_OK")], + el: this.loader, + value: opts.value, + }); + + this.popupView.on(MultiPopupView.EVENT_CHANGE, () => { + self.fireEvent(MultiSelectPopupView.EVENT_CHANGE); + }); + this.popupView.on(MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, index => { + switch (index) { + case 0: + self.fireEvent(MultiSelectPopupView.EVENT_CLICK_CLEAR); + break; + case 1: + self.fireEvent(MultiSelectPopupView.EVENT_CLICK_CONFIRM); + break; + default: + break; + } + }); + } + + isAllSelected() { + return this.loader.isAllSelected(); + } + + setStartValue(v) { + this.loader.setStartValue(v); + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + populate(items) { + this.popupView.populate(...arguments); + } + + resetHeight(h) { + this.popupView.resetHeight(h); + } + + resetWidth(w) { + this.popupView.resetWidth(w); + } + + setDirection(direction, position) { + this.popupView.setDirection(direction, position); + } + + getView() { + return this.popupView.getView(); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.popup.view.nobar.js b/packages/fineui/src/widget/multiselect/multiselect.popup.view.nobar.js new file mode 100644 index 000000000..728ccf50c --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.popup.view.nobar.js @@ -0,0 +1,100 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, i18nText, SIZE_CONSANTS } from "@/core"; +import { MultiPopupView } from "@/case"; +import { MultiSelectNoBarLoader } from "./multiselect.loader.nobar"; + +@shortcut() +export class MultiSelectNoBarPopupView extends Widget { + static xtype = "bi.multi_select_no_bar_popup_view"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-popup-view", + maxWidth: "auto", + minWidth: 135, + maxHeight: 400, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + onLoaded: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this, + opts = this.options; + + this.loader = createWidget({ + type: MultiSelectNoBarLoader.xtype, + itemsCreator: opts.itemsCreator, + itemHeight: opts.itemHeight, + valueFormatter: opts.valueFormatter, + itemFormatter: opts.itemFormatter, + onLoaded: opts.onLoaded, + value: opts.value, + }); + + this.popupView = createWidget({ + type: MultiPopupView.xtype, + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + element: this, + buttons: [i18nText("BI-Basic_Clears"), i18nText("BI-Basic_OK")], + el: this.loader, + value: opts.value, + }); + + this.popupView.on(MultiPopupView.EVENT_CHANGE, () => { + self.fireEvent(MultiSelectNoBarPopupView.EVENT_CHANGE); + }); + this.popupView.on(MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, index => { + switch (index) { + case 0: + self.fireEvent(MultiSelectNoBarPopupView.EVENT_CLICK_CLEAR); + break; + case 1: + self.fireEvent(MultiSelectNoBarPopupView.EVENT_CLICK_CONFIRM); + break; + default: + } + }); + } + + setStartValue(v) { + this.loader.setStartValue(v); + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + populate(items) { + this.popupView.populate(...arguments); + } + + resetHeight(h) { + this.popupView.resetHeight(h); + } + + resetWidth(w) { + this.popupView.resetWidth(w); + } + + setDirection(direction, position) { + this.popupView.setDirection(direction, position); + } + + getView() { + return this.popupView.getView(); + } +} diff --git a/packages/fineui/src/widget/multiselect/multiselect.trigger.js b/packages/fineui/src/widget/multiselect/multiselect.trigger.js new file mode 100644 index 000000000..d0666731d --- /dev/null +++ b/packages/fineui/src/widget/multiselect/multiselect.trigger.js @@ -0,0 +1,163 @@ +import { shortcut, extend, emptyFn, createWidget, isFunction, Layout, HTapeLayout, AbsoluteLayout } from "@/core"; +import { Trigger, Text } from "@/base"; +import { MultiSelectSearcher } from "./trigger/searcher.multiselect"; + +@shortcut() +export class MultiSelectTrigger extends Trigger { + static xtype = "bi.multi_select_trigger"; + + constants = { height: 14, rgap: 4, lgap: 4 }; + + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-trigger", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcher: {}, + switcher: {}, + + adapter: null, + masker: {}, + allowEdit: true, + itemHeight: 24, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.searcher = createWidget(o.searcher, { + type: MultiSelectSearcher.xtype, + height: o.height, + text: o.text, + defaultText: o.defaultText, + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + watermark: o.watermark, + popup: {}, + adapter: o.adapter, + masker: o.masker, + value: o.value, + }); + this.searcher.on(MultiSelectSearcher.EVENT_START, () => { + self.fireEvent(MultiSelectTrigger.EVENT_START); + }); + this.searcher.on(MultiSelectSearcher.EVENT_PAUSE, () => { + self.fireEvent(MultiSelectTrigger.EVENT_PAUSE); + }); + this.searcher.on(MultiSelectSearcher.EVENT_SEARCHING, function () { + self.fireEvent(MultiSelectTrigger.EVENT_SEARCHING, arguments); + }); + this.searcher.on(MultiSelectSearcher.EVENT_STOP, () => { + self.fireEvent(MultiSelectTrigger.EVENT_STOP); + }); + this.searcher.on(MultiSelectSearcher.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectTrigger.EVENT_CHANGE, arguments); + }); + this.searcher.on(MultiSelectSearcher.EVENT_BLUR, () => { + self.fireEvent(MultiSelectTrigger.EVENT_BLUR); + }); + this.searcher.on(MultiSelectSearcher.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectTrigger.EVENT_FOCUS); + }); + + this.wrapNumberCounter = createWidget({ + type: Layout.xtype, + }); + + this.wrapper = createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: this.searcher, + width: "fill", + rgap: 24, + } + ], + }); + + !o.allowEdit && + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Text.xtype, + title() { + /** 修正REPORT-73699引入,需要考虑到传递过来的值是方法的情况 */ + const state = self.searcher.getState(); + if (isFunction(state)) { + return state(); + } + + return state; + }, + }, + left: 0, + right: 24, + top: 0, + bottom: 0, + } + ], + }); + } + + refreshPlaceHolderWidth(width) { + this.wrapper.attr("items")[0].rgap = 24 + width; + this.wrapper.resize(); + } + + getSearcher() { + return this.searcher; + } + + stopEditing() { + this.searcher.stopSearch(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setValue(ob) { + this.searcher.setValue(ob); + } + + getKey() { + return this.searcher.getKey(); + } + + getValue() { + return this.searcher.getValue(); + } + + focus() { + this.searcher.focus(); + } + + blur() { + this.searcher.blur(); + } + + setWaterMark(v) { + this.searcher.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multiselect/search/multiselect.search.insert.pane.js b/packages/fineui/src/widget/multiselect/search/multiselect.search.insert.pane.js new file mode 100644 index 000000000..3d136e1b4 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/search/multiselect.search.insert.pane.js @@ -0,0 +1,101 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, i18nText, Controller, VerticalFillLayout, SIZE_CONSANTS } from "@/core"; +import { Label } from "@/base"; +import { MultiSelectSearchLoader } from "./multiselect.search.loader"; + +@shortcut() +export class MultiSelectSearchInsertPane extends Widget { + static xtype = "bi.multi_select_search_insert_pane"; + + constants = { height: 24, lgap: 10, tgap: 5 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-search-pane bi-card", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + keywordGetter: emptyFn, + allowSelectAll: true, + itemHeight: 24, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.addNotMatchTip = createWidget({ + type: Label.xtype, + text: i18nText("BI-Basic_Press_Enter_To_Add_Text", ""), + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + cls: "bi-keyword-red-mark", + hgap: 5, + }); + + this.loader = createWidget({ + type: MultiSelectSearchLoader.xtype, + keywordGetter: o.keywordGetter, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + itemsCreator(op, callback) { + o.itemsCreator.apply(self, [ + op, + function (res) { + callback(res); + self.setKeyword(o.keywordGetter()); + } + ]); + }, + itemHeight: o.itemHeight, + value: o.value, + allowSelectAll: o.allowSelectAll, + }); + this.loader.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.resizer = createWidget({ + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + element: this, + items: [ + { + el: this.addNotMatchTip, + }, + { + el: this.loader, + } + ], + }); + } + + setKeyword(keyword) { + this.addNotMatchTip.setText(i18nText("BI-Basic_Press_Enter_To_Add_Text", keyword)); + } + + isAllSelected() { + return this.loader.isAllSelected(); + } + + hasMatched() { + return false; + } + + setValue(v) { + this.loader.setValue(v); + } + + getValue() { + return this.loader.getValue(); + } + + empty() { + this.loader.empty(); + } + + populate(items) { + this.loader.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/search/multiselect.search.loader.js b/packages/fineui/src/widget/multiselect/search/multiselect.search.loader.js new file mode 100644 index 000000000..223d96b75 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/search/multiselect.search.loader.js @@ -0,0 +1,252 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + deepClone, + createWidget, + i18nText, + Controller, + VerticalLayout, + map, + isKey, + Func, + SIZE_CONSANTS +} from "@/core"; +import { ButtonGroup, Loader } from "@/base"; +import { SelectList, MultiSelectBar, MultiSelectItem, ListPane } from "@/case"; + +@shortcut() +export class MultiSelectSearchLoader extends Widget { + static xtype = "bi.multi_select_search_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-search-loader", + itemsCreator: emptyFn, + keywordGetter: emptyFn, + valueFormatter: emptyFn, + itemFormatter: emptyFn, + allowSelectAll: true, + itemHeight: 24, + }); + } + + _init() { + super._init(...arguments); + const self = this, + opts = this.options; + let hasNext = false; + this.storeValue = deepClone(opts.value); + this.button_group = createWidget(opts.allowSelectAll ? { + type: SelectList.xtype, + toolbar: { + type: MultiSelectBar.xtype, + cls: "bi-list-item-active", + iconWrapperWidth: 36, + }, + element: this, + logic: { + dynamic: false, + }, + value: opts.value, + el: { + tipText: i18nText("BI-No_Select"), + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + }, + itemsCreator(op, callback) { + self.storeValue && + (op = extend(op || {}, { + selectedValues: self.storeValue.value, + })); + opts.itemsCreator(op, ob => { + const keyword = (ob.keyword = opts.keywordGetter()); + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && self.storeValue) { + const json = self._filterValues(self.storeValue); + firstItems = self._createItems(json); + } + const context = { + tipText: ob.tipText, + }; + callback(firstItems.concat(self._createItems(ob.items)), keyword, context); + if (op.times === 1 && self.storeValue) { + self.setValue(self.storeValue); + } + }); + }, + hasNext() { + return hasNext; + }, + } : { + type: "bi.list_pane", + logic: { + dynamic: true, + innerVgap: 5, + rowSize: ["", "fill"], + verticalAlign: BI.VerticalAlign.Stretch, + }, + element: this, + el: { + chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, + behaviors: { + redmark () { + return true; + }, + }, + layouts: [ + { + type: "bi.vertical", + } + ], + }, + itemsCreator (op, callback) { + self.storeValue && (op = BI.extend(op || {}, { + selectedValues: self.storeValue.value, + })); + opts.itemsCreator(op, ob => { + const keyword = ob.keyword = opts.keywordGetter(); + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && self.storeValue) { + const json = self._filterValues(self.storeValue); + firstItems = self._createItems(json); + } + const context = { + tipText: ob.tipText, + }; + callback(firstItems.concat(self._createItems(ob.items)), keyword, context); + if (op.times === 1 && self.storeValue) { + self.setValue(self.storeValue); + } + }); + }, + value: opts.value, + height: "fill", + }); + this.button_group.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + const searchLoaderEventChangeName = opts.allowSelectAll ? SelectList.EVENT_CHANGE : ListPane.EVENT_CHANGE; + this.button_group.on(searchLoaderEventChangeName, function () { + self.fireEvent(MultiSelectSearchLoader.EVENT_CHANGE, arguments); + }); + } + + _createItems(items) { + const allSelected = this.isAllSelected(); + const itemFormatter = this.options.itemFormatter; + + return map(items, (index, item) => { + return { + type: MultiSelectItem.xtype, + logic: { + dynamic: false, + }, + height: this.options.itemHeight || SIZE_CONSANTS.LIST_ITEM_HEIGHT, + selected: allSelected, + cls: "bi-list-item-active", + iconWrapperWidth: 36, + ...item, + ...itemFormatter(item), + }; + }); + } + + isAllSelected() { + const o = this.options; + + return o.allowSelectAll ? this.button_group.isAllSelected() : false; + } + + _filterValues(src) { + const o = this.options; + const keyword = o.keywordGetter(); + let values = deepClone(src.value) || []; + const newValues = map(values, (i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }); + if (isKey(keyword)) { + const search = Func.getSearchResult(newValues, keyword); + values = search.match.concat(search.find); + } + + return map(values, (i, v) => { + return { + text: v.text, + title: v.text, + value: v.value, + selected: src.type === Selection.All, + ...o.itemFormatter(v), + }; + }); + } + + setValue(v) { + v || (v = {}); + const o = this.options; + // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 + this.storeValue = deepClone(v); + o.allowSelectAll ? (this.button_group.setValue(v)) : (this.button_group.setValue(v.value)); + } + + getValue() { + const o = this.options; + if (o.allowSelectAll) { + return this.button_group.getValue(); + } + + return { + type: ButtonGroup.CHOOSE_TYPE_MULTI, + value: this.button_group.getValue(), + assist: this.button_group.getNotSelectedValue(), + }; + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + this.button_group.populate(...arguments); + } + + resetHeight(h) { + this.button_group.resetHeight(h); + } + + resetWidth(w) { + this.button_group.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/multiselect/search/multiselect.search.pane.js b/packages/fineui/src/widget/multiselect/search/multiselect.search.pane.js new file mode 100644 index 000000000..1130a1243 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/search/multiselect.search.pane.js @@ -0,0 +1,83 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, Controller, AbsoluteLayout } from "@/core"; +import { MultiSelectSearchLoader } from "./multiselect.search.loader"; + +@shortcut() +export class MultiSelectSearchPane extends Widget { + static xtype = "bi.multi_select_search_pane"; + + constants = { height: 24, lgap: 10, tgap: 5 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-search-pane bi-card", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + keywordGetter: emptyFn, + itemHeight: 24, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.loader = createWidget({ + type: MultiSelectSearchLoader.xtype, + keywordGetter: o.keywordGetter, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + itemsCreator(op, callback) { + o.itemsCreator.apply(self, [ + op, + function (res) { + callback(res); + } + ]); + }, + itemHeight: o.itemHeight, + value: o.value, + }); + this.loader.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.resizer = createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.loader, + left: 0, + right: 0, + bottom: 0, + top: 0, + } + ], + }); + } + + isAllSelected() { + return this.loader.isAllSelected(); + } + + hasMatched() {} + + setValue(v) { + this.loader.setValue(v); + } + + getValue() { + return this.loader.getValue(); + } + + empty() { + this.loader.empty(); + } + + populate(items) { + this.loader.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/trigger/button.checkselected.js b/packages/fineui/src/widget/multiselect/trigger/button.checkselected.js new file mode 100644 index 000000000..02bfc1473 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/button.checkselected.js @@ -0,0 +1,120 @@ +import { + shortcut, + extend, + emptyFn, + createWidget, + Controller, + i18nText, + isNotNull, + isNotEmptyString, + nextTick, + Selection +} from "@/core"; +import { Single, TextButton } from "@/base"; +import { MultiSelectCombo } from "../multiselect.combo"; + +@shortcut() +export class MultiSelectCheckSelectedButton extends Single { + static xtype = "bi.multi_select_check_selected_button"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-check-selected-button", + itemsCreator: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.numberCounter = createWidget({ + type: TextButton.xtype, + element: this, + hgap: 4, + text: "0", + textAlign: "center", + textHeight: 16, + cls: "bi-high-light-background count-tip", + }); + this.numberCounter.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.numberCounter.on(TextButton.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); + }); + + this.numberCounter.element.hover( + () => { + self.numberCounter.setTag(self.numberCounter.getText()); + self.numberCounter.setText(i18nText("BI-Check_Selected")); + }, + () => { + self.numberCounter.setText(self.numberCounter.getTag()); + } + ); + this.setVisible(false); + if (isNotNull(o.value)) { + this.setValue(o.value); + } + } + + _populate(ob) { + const self = this, + o = this.options; + if (ob.type === Selection.All) { + o.itemsCreator( + { + type: MultiSelectCombo.REQ_GET_DATA_LENGTH, + }, + res => { + if (self.options.value.type !== Selection.All) { + return; + } + if (isNotEmptyString(res.count)) { + nextTick(() => { + self.numberCounter.setText(res.count); + self.setVisible(true); + }); + + return; + } + const length = res.count - ob.value.length; + nextTick(() => { + self.numberCounter.setText(length); + self.setVisible(length > 0); + }); + } + ); + + return; + } + nextTick(() => { + self.numberCounter.setText(ob.value.length); + self.setVisible(ob.value.length > 0); + }); + } + + _assertValue(ob) { + ob || (ob = {}); + ob.type || (ob.type = Selection.Multi); + ob.value || (ob.value = []); + + return ob; + } + + setValue(ob) { + ob = this._assertValue(ob); + this.options.value = ob; + this._populate(ob); + } + + populate() { + this._populate(this._assertValue(this.options.value)); + } + + getValue() {} +} diff --git a/packages/fineui/src/widget/multiselect/trigger/editor.multiselect.js b/packages/fineui/src/widget/multiselect/trigger/editor.multiselect.js new file mode 100644 index 000000000..3391c22a8 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/editor.multiselect.js @@ -0,0 +1,103 @@ +import { shortcut, Widget, extend, i18nText, createWidget, Controller, isEmptyString, isEmptyArray, BlankSplitChar } from "@/core"; +import { StateEditor } from "@/case"; +import { SelectPatchEditor } from "./editor/editor.patch"; + +@shortcut() +export class MultiSelectEditor extends Widget { + static xtype = "bi.multi_select_editor"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_PAUSE = "EVENT_PAUSE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-editor", + el: {}, + watermark: i18nText("BI-Basic_Search"), + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget(o.el, { + type: SelectPatchEditor.xtype, + element: this, + height: o.height, + watermark: o.watermark, + allowBlank: true, + value: o.value, + defaultText: o.defaultText, + text: o.text, + tipType: o.tipType, + warningTitle: o.warningTitle, + }); + + this.editor.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.editor.on(StateEditor.EVENT_FOCUS, () => { + self.fireEvent(MultiSelectEditor.EVENT_FOCUS); + }); + this.editor.on(StateEditor.EVENT_BLUR, () => { + self.fireEvent(MultiSelectEditor.EVENT_BLUR); + }); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setState(state) { + this.editor.setState(state); + } + + setValue(v) { + this.editor.setValue(v); + } + + setTipType(v) { + this.editor.setTipType(v); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.editor.getText(); + } + + getKeywords() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + if (/\u200b\s\u200b$/.test(val)) { + return keywords.concat([BlankSplitChar]); + } + + return keywords; + } + + getKeyword() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + + return isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multiselect/trigger/editor/editor.patch.js b/packages/fineui/src/widget/multiselect/trigger/editor/editor.patch.js new file mode 100644 index 000000000..d5f4c60f6 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/editor/editor.patch.js @@ -0,0 +1,239 @@ +import { + shortcut, + Widget, + debounce, + bind, + extend, + Controller, + contains, + isKey, + Events, + trim, + replaceAll, + KeyCode, + endWith, + BlankSplitChar +} from "@/core"; +import { Editor, TextAreaEditor } from "@/base"; +import { StateEditor } from "@/case"; + +@shortcut() +export class SelectPatchEditor extends Widget { + static xtype = "bi.select_patch_editor"; + + props = { baseCls: "bi-patch-select-editor", height: 24 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + render() { + const self = this, + o = this.options; + + const debounceInputChange = debounce(bind(this._dealChange, this), 300); + + return extend( + { + type: StateEditor.xtype, + ref(_ref) { + self.editor = _ref; + }, + hgap: o.hgap, + vgap: o.vgap, + lgap: o.lgap, + rgap: o.rgap, + tgap: o.tgap, + bgap: o.bgap, + height: o.height, + watermark: o.watermark, + allowBlank: true, + value: o.value, + defaultText: o.defaultText, + text: o.text, + tipType: o.tipType, + warningTitle: o.warningTitle, + el: { + type: TextAreaEditor.xtype, + scrolly: false, + validationChecker() { + return true; + }, + throttle: true, + }, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action(type, v) { + if (contains(v, "\n")) { + self._dealChange(type, v); + } else { + debounceInputChange(type, v); + } + }, + }, + { + eventName: Editor.EVENT_KEY_DOWN, + action(keyCode) { + if (keyCode === KeyCode.ENTER) { + self._clearSplitValue(); + } + }, + }, + { + eventName: Editor.EVENT_FOCUS, + action() { + self.fireEvent(SelectPatchEditor.EVENT_FOCUS, arguments); + }, + }, + { + eventName: Editor.EVENT_BLUR, + action() { + self._start = false; + self.fireEvent(SelectPatchEditor.EVENT_BLUR, arguments); + }, + } + ], + }, + o.el + ); + } + + _clearSplitValue() { + this.editor.setValue(""); + } + + _dealChange(type, v) { + let value = ""; + if (v !== this.editor.getValue()) { + return; + } + if (isKey(v)) { + value = this._formatText(v); + } + if (type === Events.CHANGE) { + this._setValue(value); + if (this._trimValue(value) !== "") { + if ( + !this._start || + !isKey(this._lastValue) || + (this._pause === true && this._trimValue(this._lastValue) !== this._trimValue(value)) + ) { + this._start = true; + this._pause = false; + this.fireEvent(Controller.EVENT_CHANGE, Events.STARTEDIT, this.getValue(), this); + } + } + if (this._trimValue(this._lastValue) !== this._trimValue(value)) { + this.fireEvent(Controller.EVENT_CHANGE, arguments); + } + if (endWith(value, BlankSplitChar)) { + this._pause = true; + this.fireEvent(Controller.EVENT_CHANGE, Events.PAUSE, "", this); + } + } + if (type === Events.EMPTY || type === Events.STOPEDIT) { + this.fireEvent(Controller.EVENT_CHANGE, Events.EMPTY); + } + this._lastValue = value; + } + + _trimValue(v) { + return trim(replaceAll(v || "", BlankSplitChar, "")); + } + + _formatText(v) { + return replaceAll(v || "", "\n", BlankSplitChar); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } + + doRedMark() { + this.editor.doRedMark(...arguments); + } + + unRedMark() { + this.editor.unRedMark(...arguments); + } + + doHighLight() { + this.editor.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + _setValue(v) { + this.editor.setValue(this._formatText(v)); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(v) { + this._setValue(v); + this._lastValue = this._trimValue(v); + } + + getValue() { + return trim(this.editor.getValue()); + } + + getState() { + return this.editor.getState(); + } + + setState(v) { + this.editor.setState(v); + } + + setTipType(v) { + this.editor.setTipType(v); + } + + getText() { + return this.editor.getText(); + } +} diff --git a/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.insert.js b/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.insert.js new file mode 100644 index 000000000..66249b148 --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.insert.js @@ -0,0 +1,220 @@ +import { shortcut, Widget, extend, emptyFn, i18nText, createWidget, isNotNull, isEmptyArray, size, each, BlankSplitChar, Selection } from "@/core"; +import { MultiSelectEditor } from "./editor.multiselect"; +import { Searcher } from "@/base"; +import { MultiSelectSearchInsertPane } from "../search/multiselect.search.insert.pane"; + +@shortcut() +export class MultiSelectInsertSearcher extends Widget { + static xtype = "bi.multi_select_insert_searcher"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-searcher", + itemsCreator: emptyFn, + itemHeight: 24, + el: {}, + popup: {}, + valueFormatter: emptyFn, + adapter: null, + masker: {}, + watermark: i18nText("BI-Basic_Search_And_Patch_Paste"), + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget(o.el, { + type: MultiSelectEditor.xtype, + watermark: o.watermark, + height: o.height, + text: o.text, + defaultText: o.defaultText, + listeners: [ + { + eventName: MultiSelectEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiSelectInsertSearcher.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiSelectInsertSearcher.EVENT_BLUR); + }, + } + ], + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + height: o.height, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + el: this.editor, + + popup: extend( + { + type: MultiSelectSearchInsertPane.xtype, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + keywordGetter() { + return self.editor.getKeyword(); + }, + itemsCreator(op, callback) { + const keyword = self.editor.getKeyword(); + op.keywords = [keyword]; + this.setKeyword(keyword); + o.itemsCreator(op, function () { + if (keyword === self.editor.getValue()) { + callback(...arguments); + } + }); + }, + itemHeight: o.itemHeight, + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + self.fireEvent(MultiSelectInsertSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + self.fireEvent(MultiSelectInsertSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + self.fireEvent(MultiSelectInsertSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectInsertSearcher.EVENT_CHANGE, arguments); + }); + this.searcher.on(Searcher.EVENT_SEARCHING, function () { + const keywords = this.getKeywords(); + self.fireEvent( + MultiSelectInsertSearcher.EVENT_SEARCHING, + keywords.length > 2000 ? keywords.slice(0, 2000).concat([BlankSplitChar]) : keywords.slice(0, 2000) + ); + }); + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + adjustView() { + this.searcher.adjustView(); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeywordsLength() { + const keywords = this.editor.getKeywords(); + + return keywords[keywords.length - 1] === BlankSplitChar ? keywords.length - 1 : keywords.length; + } + + getKeyword() { + let keywords = this.editor.getKeywords().slice(0, 2000); + if (keywords[keywords.length - 1] === BlankSplitChar) { + keywords = keywords.slice(0, keywords.length - 1); + } + + return isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setState(ob) { + let state; + const o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + if (ob.type === Selection.All) { + if (ob.value.length === 0) { + this.editor.setState(Selection.All); + } else if (size(ob.assist) <= 20) { + state = ""; + each(ob.assist, (i, v) => { + if (i === 0) { + state += `${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } else { + if (ob.value.length === 0) { + this.editor.setState(Selection.None); + } else if (size(ob.value) <= 20) { + state = ""; + each(ob.value, (i, v) => { + if (i === 0) { + state += `${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } + } + + getState() { + return this.editor.getState(); + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(items) { + this.searcher.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.js b/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.js new file mode 100644 index 000000000..710a17bbc --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/searcher.multiselect.js @@ -0,0 +1,216 @@ +import { shortcut, Widget, extend, emptyFn, i18nText, createWidget, isNotNull, size, each, Selection } from "@/core"; +import { MultiSelectEditor } from "./editor.multiselect"; +import { Searcher } from "@/base"; +import { MultiSelectSearchPane } from "../search/multiselect.search.pane"; + +@shortcut() +export class MultiSelectSearcher extends Widget { + static xtype = "bi.multi_select_searcher"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-searcher", + itemsCreator: emptyFn, + el: {}, + popup: {}, + valueFormatter: emptyFn, + adapter: null, + masker: {}, + defaultText: i18nText("BI-Basic_Please_Select"), + itemHeight: 24, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget(o.el, { + type: MultiSelectEditor.xtype, + height: o.height, + text: o.text, + defaultText: o.defaultText, + watermark: o.watermark, + listeners: [ + { + eventName: MultiSelectEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_BLUR); + }, + } + ], + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + height: o.height, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + el: this.editor, + popup: extend( + { + type: MultiSelectSearchPane.xtype, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + keywordGetter() { + return self.editor.getValue(); + }, + itemsCreator(op, callback) { + const keyword = self.editor.getValue(); + op.keywords = [keyword]; + o.itemsCreator(op, () => { + const keyword = self.editor.getValue(); + op.keywords = [keyword]; + o.itemsCreator(op, function () { + if (keyword === self.editor.getValue()) { + callback(...arguments); + } + }); + }); + }, + itemHeight: o.itemHeight, + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + self.fireEvent(MultiSelectSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + self.fireEvent(MultiSelectSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + self.fireEvent(MultiSelectSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectSearcher.EVENT_CHANGE, arguments); + }); + this.searcher.on(Searcher.EVENT_SEARCHING, function () { + const keywords = this.getKeywords(); + self.fireEvent(MultiSelectSearcher.EVENT_SEARCHING, keywords); + }); + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + adjustView() { + this.searcher.adjustView(); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeyword() { + return this.editor.getValue(); + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setState(ob) { + let state; + const o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + if (ob.type === Selection.All) { + if (ob.value.length === 0) { + this.editor.setState(Selection.All); + } else if (size(ob.assist) <= 20) { + state = ""; + each(ob.assist, (i, v) => { + if (i === 0) { + state += `${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } else { + if (ob.value.length === 0) { + this.editor.setState(Selection.None); + } else if (size(ob.value) <= 20) { + state = ""; + each(ob.value, (i, v) => { + if (i === 0) { + state += `${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${v === null ? "" : o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } + } + + getState() { + return this.editor.getState(); + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(items) { + this.searcher.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselect/trigger/switcher.checkselected.js b/packages/fineui/src/widget/multiselect/trigger/switcher.checkselected.js new file mode 100644 index 000000000..4d5bab1da --- /dev/null +++ b/packages/fineui/src/widget/multiselect/trigger/switcher.checkselected.js @@ -0,0 +1,113 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, Events, nextTick } from "@/core"; +import { Switcher } from "@/base"; +import { MultiSelectCheckSelectedButton } from "./button.checkselected"; +import { MultiSelectCheckPane } from "../check/multiselect.check.pane"; + +@shortcut() +export class MultiSelectCheckSelectedSwitcher extends Widget { + static xtype = "bi.multi_select_check_selected_switcher"; + + static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-check-selected-switcher", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + el: {}, + popup: {}, + adapter: null, + masker: {}, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.button = createWidget(o.el, { + type: MultiSelectCheckSelectedButton.xtype, + itemsCreator: o.itemsCreator, + value: o.value, + }); + this.button.on(Events.VIEW, function () { + self.fireEvent(Events.VIEW, arguments); + }); + this.switcher = createWidget({ + type: Switcher.xtype, + toggle: false, + element: this, + el: this.button, + popup: extend( + { + type: MultiSelectCheckPane.xtype, + valueFormatter: o.valueFormatter, + itemsCreator: o.itemsCreator, + onClickContinueSelect() { + self.switcher.hideView(); + }, + ref(_ref) { + self.checkPane = _ref; + }, + value: o.value, + }, + o.popup + ), + adapter: o.adapter, + masker: o.masker, + }); + this.switcher.on(Switcher.EVENT_TRIGGER_CHANGE, () => { + self.fireEvent(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE); + }); + this.switcher.on(Switcher.EVENT_BEFORE_POPUPVIEW, () => { + self.fireEvent(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW); + }); + this.switcher.on(Switcher.EVENT_AFTER_HIDEVIEW, () => { + self.fireEvent(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW); + }); + this.switcher.on(Switcher.EVENT_AFTER_POPUPVIEW, function () { + const me = this; + nextTick(() => { + me._populate(); + }); + }); + } + + adjustView() { + this.switcher.adjustView(); + } + + hideView() { + this.switcher.empty(); + this.switcher.hideView(); + } + + setAdapter(adapter) { + this.switcher.setAdapter(adapter); + } + + setValue(v) { + this.switcher.setValue(v); + } + + updateSelectedValue(v) { + this.checkPane.setValue(v); + } + + setButtonChecked(v) { + this.button.setValue(v); + } + + getValue() {} + + populate(items) { + this.switcher.populate.apply(this.switcher, arguments); + } + + populateSwitcher() { + this.button.populate.apply(this.button, arguments); + } +} diff --git a/src/widget/multiselectlist/__test__/multiselect.insert.nobar.test.js b/packages/fineui/src/widget/multiselectlist/__test__/multiselect.insert.nobar.test.js similarity index 100% rename from src/widget/multiselectlist/__test__/multiselect.insert.nobar.test.js rename to packages/fineui/src/widget/multiselectlist/__test__/multiselect.insert.nobar.test.js diff --git a/src/widget/multiselectlist/__test__/multiselectlist.insert.test.js b/packages/fineui/src/widget/multiselectlist/__test__/multiselectlist.insert.test.js similarity index 100% rename from src/widget/multiselectlist/__test__/multiselectlist.insert.test.js rename to packages/fineui/src/widget/multiselectlist/__test__/multiselectlist.insert.test.js diff --git a/packages/fineui/src/widget/multiselectlist/index.js b/packages/fineui/src/widget/multiselectlist/index.js new file mode 100644 index 000000000..416458b1f --- /dev/null +++ b/packages/fineui/src/widget/multiselectlist/index.js @@ -0,0 +1,3 @@ +export * from "./multiselectlist.insert"; +export * from "./multiselectlist.insert.nobar"; +export * from "./multiselectlist"; diff --git a/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.js b/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.js new file mode 100644 index 000000000..e0e4aac3b --- /dev/null +++ b/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.js @@ -0,0 +1,431 @@ +import { + shortcut, + extend, + emptyFn, + deepClone, + isKey, + Selection, + remove, + pushDistinct, + createWidget, + isNotEmptyString, + i18nText, + isEmptyArray, + last, + initial, + endWith, + AbsoluteLayout, + isEmptyString, + makeObject, + each, + Func, + map, + concat, + isNotNull, + values, + filter, + contains, + isNull, + VerticalFillLayout, + SIZE_CONSANTS, + BlankSplitChar +} from "@/core"; +import { Single, Searcher, Msg } from "@/base"; +import { MultiSelectBar } from "@/case"; +import { SelectPatchEditor } from "../multiselect/trigger/editor/editor.patch"; +import { MultiSelectLoader } from "../multiselect/multiselect.loader"; +import { MultiSelectSearchInsertPane } from "../multiselect/search/multiselect.search.insert.pane"; +import { SearchEditor } from "@/widget/editor/editor.search"; + +@shortcut() +export class MultiSelectInsertList extends Single { + static xtype = "bi.multi_select_insert_list"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-insert-list", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcherHeight: SIZE_CONSANTS.TRIGGER_HEIGHT, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + simple: false, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + this.storeValue = this._assertValue(deepClone(o.value) || {}); + + function assertShowValue() { + isKey(self._startValue) && + (self.storeValue.type === Selection.All + ? remove(self.storeValue.value, self._startValue) + : pushDistinct(self.storeValue.value, self._startValue)); + // self.trigger.setValue(self.storeValue); + } + + this.adapter = createWidget({ + type: MultiSelectLoader.xtype, + cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + logic: { + dynamic: false, + }, + // onLoaded: o.onLoaded, + el: {}, + isDefaultInit: true, + value: o.value, + }); + this.adapter.on(MultiSelectLoader.EVENT_CHANGE, function () { + self.storeValue = this.getValue(); + assertShowValue(); + self.fireEvent(MultiSelectInsertList.EVENT_CHANGE); + }); + + this.searcherPane = createWidget({ + type: MultiSelectSearchInsertPane.xtype, + cls: "bi-border-left bi-border-right bi-border-bottom", + valueFormatter: o.valueFormatter, + itemFormatter: o.itemFormatter, + keywordGetter() { + return self.trigger.getKeyword(); + }, + itemsCreator(op, callback) { + const keyword = self.trigger.getKeyword(); + if (isNotEmptyString(keyword)) { + op.keywords = [keyword]; + this.setKeyword(op.keywords[0]); + o.itemsCreator(op, callback); + } + }, + itemHeight: o.itemHeight, + }); + this.searcherPane.setVisible(false); + + this.trigger = createWidget({ + type: Searcher.xtype, + el: { + type: SelectPatchEditor.xtype, + el: { + type: SearchEditor.xtype, + watermark: i18nText("BI-Basic_Search_And_Patch_Paste"), + simple: o.simple, + }, + ref(ref) { + self.editor = ref; + }, + }, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + adapter: this.adapter, + popup: this.searcherPane, + masker: false, + listeners: [ + { + eventName: Searcher.EVENT_START, + action() { + self._showSearcherPane(); + self._setStartValue(""); + this.setValue(deepClone(self.storeValue)); + }, + }, + { + eventName: Searcher.EVENT_STOP, + action() { + self._showAdapter(); + self._setStartValue(""); + self.adapter.setValue(self.storeValue); + // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); + }, + }, + { + eventName: Searcher.EVENT_PAUSE, + action() { + let keywords = self._getKeywords(); + if (keywords[keywords.length - 1] === BlankSplitChar) { + keywords = keywords.slice(0, keywords.length - 1); + } + const keyword = isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; + self._join( + { + type: Selection.Multi, + value: [keyword], + }, + () => { + if (self.storeValue.type === Selection.Multi) { + pushDistinct(self.storeValue.value, keyword); + } + self._showAdapter(); + self.adapter.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(""); + self.fireEvent(MultiSelectInsertList.EVENT_CHANGE); + } + ); + self._showAdapter(); + }, + }, + { + eventName: Searcher.EVENT_SEARCHING, + action() { + let keywords = self._getKeywords(); + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.adapter.setValue(self.storeValue); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(""); + } else { + self.adapter.setValue(self.storeValue); + assertShowValue(); + } + self.fireEvent(MultiSelectInsertList.EVENT_CHANGE); + }); + self._getKeywordsLength() > 2000 && + Msg.alert( + i18nText("BI-Basic_Prompt"), + i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand") + ); + } + }, + }, + { + eventName: Searcher.EVENT_CHANGE, + action(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertList.EVENT_CHANGE); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertList.EVENT_CHANGE); + }); + } + }, + } + ], + value: o.value, + }); + + createWidget({ + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + element: this, + items: [ + { + el: this.trigger, + }, + { + el: this.adapter, + } + ], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.searcherPane, + top: o.searcherHeight || SIZE_CONSANTS.TRIGGER_HEIGHT, + bottom: 0, + left: 0, + right: 0, + } + ], + }); + } + + _getKeywords() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + if (/\u200b\s\u200b$/.test(val)) { + keywords = keywords.concat([BlankSplitChar]); + } + + return keywords.length > 2000 ? keywords.slice(0, 2000).concat([BlankSplitChar]) : keywords.slice(0, 2000); + } + + _getKeywordsLength() { + const val = this.editor.getValue(); + const keywords = val.split(/\u200b\s\u200b/); + + return keywords.length - 1; + } + + _showAdapter() { + this.adapter.setVisible(true); + this.searcherPane.setVisible(false); + } + + _showSearcherPane() { + this.searcherPane.setVisible(true); + this.adapter.setVisible(false); + } + + _defaultState() { + this.trigger.stopEditing(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + + return val; + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this; + this._assertValue(this.storeValue); + // 和复选下拉框同步,allData做缓存是会爆炸的 + + digest(); + + function digest() { + each(keywords, (i, val) => { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + }); + callback(); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKeyword() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + callback(); + + return; + } + o.itemsCreator( + { + type: MultiSelectInsertList.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKeyword()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + callback(); + } + ); + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + callback(); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.adapter.setStartValue(value); + } + + isAllSelected() { + return this.adapter.isAllSelected(); + } + + resize() { + // this.trigger.getCounter().adjustView(); + // this.trigger.adjustView(); + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.adapter.setValue(this.storeValue); + this.trigger.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue); + } + + populate() { + this.adapter.populate(...arguments); + this.trigger.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.nobar.js b/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.nobar.js new file mode 100644 index 000000000..1bca0a442 --- /dev/null +++ b/packages/fineui/src/widget/multiselectlist/multiselectlist.insert.nobar.js @@ -0,0 +1,435 @@ +import { + shortcut, + extend, + emptyFn, + Selection, + deepClone, + isKey, + remove, + pushDistinct, + createWidget, + isNotEmptyString, + i18nText, + isEmptyArray, + last, + initial, + endWith, + AbsoluteLayout, + isEmptyString, + makeObject, + each, + Func, + map, + concat, + isNotNull, + values, + filter, + contains, + isNull, + VTapeLayout, + BlankSplitChar, + SIZE_CONSANTS +} from "@/core"; +import { Single, Searcher, Msg } from "@/base"; +import { MultiSelectBar } from "@/case"; +import { SelectPatchEditor } from "../multiselect/trigger/editor/editor.patch"; +import { MultiSelectNoBarLoader } from "../multiselect/multiselect.loader.nobar"; +import { MultiSelectSearchInsertPane } from "../multiselect/search/multiselect.search.insert.pane"; +import { SearchEditor } from "../editor/editor.search"; + +@shortcut() +export class MultiSelectInsertNoBarList extends Single { + static xtype = "bi.multi_select_insert_no_bar_list"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-insert-list", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcherHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + this.storeValue = { + type: Selection.Multi, + value: deepClone(o.value) || [], + }; + + function assertShowValue() { + isKey(self._startValue) && + (self.storeValue.type === Selection.All + ? remove(self.storeValue.value, self._startValue) + : pushDistinct(self.storeValue.value, self._startValue)); + // self.trigger.setValue(self.storeValue); + } + + this.adapter = createWidget({ + type: MultiSelectNoBarLoader.xtype, + cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", + itemsCreator: o.itemsCreator, + itemHeight: o.itemHeight, + valueFormatter: o.valueFormatter, + logic: { + dynamic: false, + }, + // onLoaded: o.onLoaded, + el: {}, + value: { + type: Selection.Multi, + value: o.value || [], + }, + }); + this.adapter.on(MultiSelectNoBarLoader.EVENT_CHANGE, function () { + self.storeValue = this.getValue(); + assertShowValue(); + self.fireEvent(MultiSelectInsertNoBarList.EVENT_CHANGE); + }); + + this.searcherPane = createWidget({ + type: MultiSelectSearchInsertPane.xtype, + cls: "bi-border-left bi-border-right bi-border-bottom", + valueFormatter: o.valueFormatter, + keywordGetter() { + return self.trigger.getKeyword(); + }, + itemsCreator(op, callback) { + const keyword = self.trigger.getKeyword(); + if (isNotEmptyString(keyword)) { + op.keywords = [keyword]; + this.setKeyword(op.keywords[0]); + o.itemsCreator(op, callback); + } + }, + allowSelectAll: false, + }); + this.searcherPane.setVisible(false); + + this.trigger = createWidget({ + type: Searcher.xtype, + el: { + type: SelectPatchEditor.xtype, + el: { + type: SearchEditor.xtype, + watermark: i18nText("BI-Basic_Search_And_Patch_Paste"), + }, + ref(ref) { + self.editor = ref; + }, + height: o.searcherHeight, + }, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + adapter: this.adapter, + popup: this.searcherPane, + height: 200, + masker: false, + listeners: [ + { + eventName: Searcher.EVENT_START, + action() { + self._showSearcherPane(); + self._setStartValue(""); + this.setValue(deepClone(self.storeValue)); + }, + }, + { + eventName: Searcher.EVENT_STOP, + action() { + self._showAdapter(); + self._setStartValue(""); + self.adapter.setValue(self.storeValue); + // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); + }, + }, + { + eventName: Searcher.EVENT_PAUSE, + action() { + let keywords = self._getKeywords(); + if (keywords[keywords.length - 1] === BlankSplitChar) { + keywords = keywords.slice(0, keywords.length - 1); + } + const keyword = isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; + self._join( + { + type: Selection.Multi, + value: [keyword], + }, + () => { + if (self.storeValue.type === Selection.Multi) { + pushDistinct(self.storeValue.value, keyword); + } + self._showAdapter(); + self.adapter.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(""); + self.fireEvent(MultiSelectInsertNoBarList.EVENT_CHANGE); + } + ); + }, + }, + { + eventName: Searcher.EVENT_SEARCHING, + action() { + let keywords = self._getKeywords(); + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.adapter.setValue(self.storeValue); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(""); + } else { + self.adapter.setValue(self.storeValue); + assertShowValue(); + } + self.fireEvent(MultiSelectInsertNoBarList.EVENT_CHANGE); + }); + self._getKeywordsLength() > 2000 && + Msg.alert( + i18nText("BI-Basic_Prompt"), + i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand") + ); + } + }, + }, + { + eventName: Searcher.EVENT_CHANGE, + action(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertNoBarList.EVENT_CHANGE); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectInsertNoBarList.EVENT_CHANGE); + }); + } + }, + } + ], + value: { + type: Selection.Multi, + value: o.value || [], + }, + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + el: this.trigger, + height: o.searcherHeight, + }, + { + el: this.adapter, + height: "fill", + } + ], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.searcherPane, + top: o.searcherHeight, + bottom: 0, + left: 0, + right: 0, + } + ], + }); + } + + _getKeywords() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + if (/\u200b\s\u200b$/.test(val)) { + keywords = keywords.concat([BlankSplitChar]); + } + + return keywords.length > 2000 ? keywords.slice(0, 2000).concat([BlankSplitChar]) : keywords.slice(0, 2000); + } + + _getKeywordsLength() { + const val = this.editor.getValue(); + const keywords = val.split(/\u200b\s\u200b/); + + return keywords.length - 1; + } + + _showAdapter() { + this.adapter.setVisible(true); + this.searcherPane.setVisible(false); + } + + _showSearcherPane() { + this.searcherPane.setVisible(true); + this.adapter.setVisible(false); + } + + _defaultState() { + this.trigger.stopEditing(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this; + this._assertValue(this.storeValue); + // 和复选下拉框同步,allData做缓存是会爆炸的 + digest(); + + function digest(items) { + each(keywords, (i, val) => { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + }); + callback(); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKeyword() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + callback(); + + return; + } + o.itemsCreator( + { + type: MultiSelectInsertNoBarList.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKeyword()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + callback(); + } + ); + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + callback(); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.adapter.setStartValue(value); + } + + isAllSelected() { + return this.adapter.isAllSelected(); + } + + resize() { + // this.trigger.getCounter().adjustView(); + // this.trigger.adjustView(); + } + + setValue(v) { + this.storeValue = { + type: Selection.Multi, + value: v || [], + }; + this.adapter.setValue(this.storeValue); + this.trigger.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this.adapter.populate(...arguments); + this.trigger.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselectlist/multiselectlist.js b/packages/fineui/src/widget/multiselectlist/multiselectlist.js new file mode 100644 index 000000000..e4190fb0a --- /dev/null +++ b/packages/fineui/src/widget/multiselectlist/multiselectlist.js @@ -0,0 +1,437 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + deepClone, + isKey, + Selection, + remove, + pushDistinct, + createWidget, + isNotEmptyString, + last, + initial, + endWith, + AbsoluteLayout, + isEmptyString, + makeObject, + map, + each, + isNotNull, + Func, + concat, + values, + filter, + contains, + isNull, + VTapeLayout, + SIZE_CONSANTS, + BlankSplitChar +} from "@/core"; +import { Searcher } from "@/base"; +import { MultiSelectBar } from "@/case"; +import { MultiSelectLoader } from "../multiselect/multiselect.loader"; +import { MultiSelectSearchPane } from "../multiselect/search/multiselect.search.pane"; +import { SelectPatchEditor } from "../multiselect/trigger/editor/editor.patch"; +import { SearchEditor } from "../editor/editor.search"; + +@shortcut() +export class MultiSelectList extends Widget { + static xtype = "bi.multi_select_list"; + + static REQ_GET_DATA_LENGTH = "1"; + static REQ_GET_ALL_DATA = "-1"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-list", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcherHeight: 24, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + this.storeValue = this._assertValue(deepClone(o.value) || {}); + + function assertShowValue() { + isKey(self._startValue) && + (self.storeValue.type === Selection.All + ? remove(self.storeValue.value, self._startValue) + : pushDistinct(self.storeValue.value, self._startValue)); + // self.trigger.setValue(self.storeValue); + } + + this.adapter = createWidget({ + type: MultiSelectLoader.xtype, + cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + itemHeight: o.itemHeight, + logic: { + dynamic: false, + }, + value: o.value, + isDefaultInit: true, + // onLoaded: o.onLoaded, + el: {}, + }); + this.adapter.on(MultiSelectLoader.EVENT_CHANGE, function () { + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + self.fireEvent(MultiSelectList.EVENT_CHANGE); + }); + }); + + this.searcherPane = createWidget({ + type: MultiSelectSearchPane.xtype, + cls: "bi-border-left bi-border-right bi-border-bottom", + valueFormatter: o.valueFormatter, + keywordGetter() { + return self.trigger.getKeyword(); + }, + itemsCreator(op, callback) { + const keyword = self.trigger.getKeyword(); + if (isNotEmptyString(keyword)) { + op.keywords = [keyword]; + o.itemsCreator(op, callback); + } + }, + itemHeight: o.itemHeight, + }); + this.searcherPane.setVisible(false); + + this.trigger = createWidget({ + type: Searcher.xtype, + el: { + type: SelectPatchEditor.xtype, + el: { + type: SearchEditor.xtype, + }, + ref(ref) { + self.editor = ref; + }, + height: o.searcherHeight, + }, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + adapter: this.adapter, + popup: this.searcherPane, + height: 200, + masker: false, + listeners: [ + { + eventName: Searcher.EVENT_START, + action() { + self._showSearcherPane(); + self._setStartValue(""); + this.setValue(deepClone(self.storeValue)); + }, + }, + { + eventName: Searcher.EVENT_STOP, + action() { + self._showAdapter(); + self._setStartValue(""); + self.adapter.setValue(self.storeValue); + // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); + }, + }, + { + eventName: Searcher.EVENT_PAUSE, + action() { + self._showAdapter(); + self.fireEvent(MultiSelectList.EVENT_CHANGE); + }, + }, + { + eventName: Searcher.EVENT_SEARCHING, + action() { + let keywords = this.getKeyword(); + const lastKeyword = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + self._joinKeywords(keywords, () => { + if (endWith(lastKeyword, BlankSplitChar)) { + self.adapter.setValue(self.storeValue); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(""); + } else { + self.adapter.setValue(self.storeValue); + assertShowValue(); + } + self.fireEvent(MultiSelectList.EVENT_CHANGE); + }); + } + }, + }, + { + eventName: Searcher.EVENT_CHANGE, + action(value, obj) { + if (obj instanceof MultiSelectBar) { + self._joinAll(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectList.EVENT_CHANGE); + }); + } else { + self._join(this.getValue(), () => { + assertShowValue(); + self.fireEvent(MultiSelectList.EVENT_CHANGE); + }); + } + }, + } + ], + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + el: this.trigger, + height: o.searcherHeight, + }, + { + el: this.adapter, + height: "fill", + } + ], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.searcherPane, + top: o.searcherHeight, + bottom: 0, + left: 0, + right: 0, + } + ], + }); + } + + _getKeywords() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + if (/\u200b\s\u200b$/.test(val)) { + return keywords.concat([BlankSplitChar]); + } + + return keywords; + } + + _showAdapter() { + this.adapter.setVisible(true); + this.searcherPane.setVisible(false); + } + + _showSearcherPane() { + this.searcherPane.setVisible(true); + this.adapter.setVisible(false); + } + + _defaultState() { + this.trigger.stopEditing(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + + return val; + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const self = this, + o = this.options; + this._assertValue(this.storeValue); + // 和复选下拉框同步,allData做缓存是会爆炸的 + o.itemsCreator( + { + type: MultiSelectList.REQ_GET_ALL_DATA, + keywords, + }, + ob => { + const values = map(ob.items, "value"); + digest(values); + } + ); + + function digest(items) { + const selectedMap = self._makeMap(items); + each(keywords, (i, val) => { + if (isNotNull(selectedMap[val])) { + self.storeValue.type === Selection.Multi + ? pushDistinct(self.storeValue.value, val) + : remove(self.storeValue.value, val); + } + }); + self._adjust(callback); + } + } + + _joinAll(res, callback) { + const self = this, + o = this.options; + this._assertValue(res); + if (this.storeValue.type === res.type) { + const result = Func.getSearchResult( + map(this.storeValue.value, (_i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }), + this.trigger.getKeyword() + ); + let change = false; + const tempMap = this._makeMap(this.storeValue.value); + each(concat(result.match, result.find), (i, obj) => { + const v = obj.value; + if (isNotNull(tempMap[v])) { + change = true; + delete tempMap[v]; + } + }); + change && (this.storeValue.value = values(tempMap)); + this._adjust(callback); + + return; + } + o.itemsCreator( + { + type: MultiSelectList.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKeyword()], + selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)), + }, + ob => { + const items = map(ob.items, "value"); + const selectedMap = self._makeMap(self.storeValue.value); + const notSelectedMap = self._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + newItems.push(item); + } + }); + self.storeValue.value = newItems.concat(values(selectedMap)); + self._adjust(callback); + } + ); + } + + _adjust(callback) { + const self = this, + o = this.options; + if (!this._count) { + o.itemsCreator( + { + type: MultiSelectList.REQ_GET_DATA_LENGTH, + }, + res => { + self._count = res.count; + adjust(); + callback(); + } + ); + } else { + adjust(); + callback(); + } + + function adjust() { + if (self.storeValue.type === Selection.All && self.storeValue.value.length >= self._count) { + self.storeValue = { + type: Selection.Multi, + value: [], + }; + } else if (self.storeValue.type === Selection.Multi && self.storeValue.value.length >= self._count) { + self.storeValue = { + type: Selection.All, + value: [], + }; + } + } + } + + _join(res, callback) { + const self = this; + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + pushDistinct(self.storeValue.value, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + self._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.adapter.setStartValue(value); + } + + isAllSelected() { + return this.adapter.isAllSelected(); + } + + resize() {} + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.adapter.setValue(this.storeValue); + this.trigger.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue); + } + + populate() { + this.adapter.populate(...arguments); + this.trigger.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/multiselecttree/multiselecttree.js b/packages/fineui/src/widget/multiselecttree/multiselecttree.js new file mode 100644 index 000000000..1047a9601 --- /dev/null +++ b/packages/fineui/src/widget/multiselecttree/multiselecttree.js @@ -0,0 +1,190 @@ +import { MultiTreeSearchPane } from "../multitree/trigger/multi.tree.search.pane"; +import { VerticalFillLayout, shortcut, extend, emptyFn, createWidget, nextTick, AbsoluteLayout } from "@/core"; +import { Single, Searcher } from "@/base"; +import { MultiSelectTreePopup } from "./multiselecttree.popup"; + +@shortcut() +export class MultiSelectTree extends Single { + static xtype = "bi.multi_select_tree"; + + _constant = { EDITOR_HEIGHT: 24 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-tree", + itemsCreator: emptyFn, + simple: false, + searcherPaneIsSelectedAny: true, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.storeValue = { value: {} }; + + this.adapter = createWidget({ + type: MultiSelectTreePopup.xtype, + itemsCreator: o.itemsCreator, + showLine: o.showLine, + }); + this.adapter.on(MultiSelectTreePopup.EVENT_CHANGE, () => { + if (self.searcher.isSearching()) { + self.storeValue = { value: self.searcherPane.getValue() }; + } else { + self.storeValue = { value: self.adapter.getValue() }; + } + self.setSelectedValue(self.storeValue.value); + self.fireEvent(MultiSelectTree.EVENT_CHANGE); + }); + + // 搜索中的时候用的是parttree,同adapter中的synctree不一样 + this.searcherPane = createWidget({ + type: MultiTreeSearchPane.xtype, + cls: "bi-border-left bi-border-right bi-border-bottom", + isSelectedAny: o.searcherPaneIsSelectedAny, + keywordGetter() { + return self.searcher.getKeyword(); + }, + itemsCreator(op, callback) { + op.keyword = self.searcher.getKeyword(); + o.itemsCreator(op, callback); + }, + }); + this.searcherPane.setVisible(false); + + this.searcher = createWidget({ + type: Searcher.xtype, + simple: o.simple, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback({ + keyword: self.searcher.getKeyword(), + }); + }, + adapter: this.adapter, + popup: this.searcherPane, + masker: false, + listeners: [ + { + eventName: Searcher.EVENT_START, + action() { + self._showSearcherPane(); + // self.storeValue = {value: self.adapter.getValue()}; + // self.searcherPane.setSelectedValue(self.storeValue.value); + }, + }, + { + eventName: Searcher.EVENT_STOP, + action() { + self._showAdapter(); + // self.storeValue = {value: self.searcherPane.getValue()}; + // self.adapter.setSelectedValue(self.storeValue.value); + nextTick(() => { + self.adapter.populate(); + }); + }, + }, + { + eventName: Searcher.EVENT_CHANGE, + action() { + if (self.searcher.isSearching()) { + self.storeValue = { + value: self.searcherPane.getValue(), + }; + } else { + self.storeValue = { + value: self.adapter.getValue(), + }; + } + self.setSelectedValue(self.storeValue.value); + self.fireEvent(MultiSelectTree.EVENT_CHANGE); + }, + }, + { + eventName: Searcher.EVENT_PAUSE, + action() { + self._showAdapter(); + // BI-64732 pause 和stop一致, 都应该刷新adapter + nextTick(() => { + self.adapter.populate(); + }); + }, + } + ], + }); + + createWidget({ + type: VerticalFillLayout.xtype, + element: this, + items: [ + { + el: this.searcher, + height: "", + }, + { + el: this.adapter, + height: "fill", + } + ], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.searcherPane, + top: this._constant.EDITOR_HEIGHT, + bottom: 0, + left: 0, + right: 0, + } + ], + }); + } + + _showAdapter() { + this.adapter.setVisible(true); + this.searcherPane.setVisible(false); + } + + _showSearcherPane() { + this.searcherPane.setVisible(true); + this.adapter.setVisible(false); + } + + resize() {} + + setSelectedValue(v) { + this.storeValue.value = v || {}; + this.adapter.setSelectedValue(v); + this.searcherPane.setSelectedValue(v); + this.searcher.setValue({ + value: v || {}, + }); + } + + setValue(v) { + this.adapter.setValue(v); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + updateValue(v) { + this.adapter.updateValue(v); + } + + getValue() { + return this.storeValue.value; + } + + populate() { + this.adapter.populate(); + } +} diff --git a/packages/fineui/src/widget/multiselecttree/multiselecttree.popup.js b/packages/fineui/src/widget/multiselecttree/multiselecttree.popup.js new file mode 100644 index 000000000..3782d209b --- /dev/null +++ b/packages/fineui/src/widget/multiselecttree/multiselecttree.popup.js @@ -0,0 +1,62 @@ +import { shortcut, Widget, extend, emptyFn, createWidget } from "@/core"; +import { TreeView, AsyncTree } from "@/case"; + +@shortcut() +export class MultiSelectTreePopup extends Widget { + static xtype = "bi.multi_select_tree_popup"; + + static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-tree-popup bi-border-left bi-border-right bi-border-bottom", + itemsCreator: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.popup = createWidget({ + type: AsyncTree.xtype, + showLine: o.showLine, + element: this, + itemsCreator: o.itemsCreator, + }); + this.popup.on(TreeView.EVENT_AFTERINIT, () => { + self.fireEvent(MultiSelectTreePopup.EVENT_AFTER_INIT); + }); + this.popup.on(TreeView.EVENT_CHANGE, () => { + self.fireEvent(MultiSelectTreePopup.EVENT_CHANGE); + }); + } + + hasChecked() { + return this.popup.hasChecked(); + } + + getValue() { + return this.popup.getValue(); + } + + setValue(v) { + v || (v = {}); + this.popup.setValue(v); + } + + setSelectedValue(v) { + v || (v = {}); + this.popup.setSelectedValue(v); + } + + updateValue(v) { + this.popup.updateValue(v); + this.popup.refresh(); + } + + populate(config) { + this.popup.stroke(config); + } +} diff --git a/packages/fineui/src/widget/multitree/check/multi.tree.check.pane.js b/packages/fineui/src/widget/multitree/check/multi.tree.check.pane.js new file mode 100644 index 000000000..809d1dc67 --- /dev/null +++ b/packages/fineui/src/widget/multitree/check/multi.tree.check.pane.js @@ -0,0 +1,128 @@ +import { + shortcut, + extend, + emptyFn, + createWidget, + i18nText, + nextTick, + Events, + VerticalAdaptLayout, + VTapeLayout +} from "@/core"; +import { Pane, TextButton, Label } from "@/base"; +import { DisplayTree, TreeView } from "@/case"; + +@shortcut() +export class MultiTreeCheckPane extends Pane { + static xtype = "bi.multi_tree_check_pane"; + + constants = { height: 25, lgap: 10, tgap: 5 }; + + static EVENT_CONTINUE_CLICK = "EVENT_CONTINUE_CLICK"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-check-pane bi-background", + onClickContinueSelect: emptyFn, + el: { + type: DisplayTree.xtype, + }, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + + this.selectedValues = {}; + + const continueSelect = createWidget({ + type: TextButton.xtype, + title: i18nText("BI-Continue_Select"), + text: i18nText("BI-Continue_Select"), + cls: "bi-high-light", + }); + continueSelect.on(TextButton.EVENT_CHANGE, () => { + opts.onClickContinueSelect(); + nextTick(() => { + self.empty(); + }); + }); + + const backToPopup = createWidget({ + type: VerticalAdaptLayout.xtype, + columnSize: ["auto", "auto"], + cls: "multi-tree-continue-select", + items: [ + { + el: { + type: Label.xtype, + title: i18nText("BI-Selected_Data"), + text: i18nText("BI-Selected_Data"), + }, + lgap: this.constants.lgap, + tgap: this.constants.tgap, + }, + { + el: continueSelect, + hgap: this.constants.lgap, + tgap: this.constants.tgap, + } + ], + }); + + this.display = createWidget(opts.el, { + type: DisplayTree.xtype, + cls: "bi-multi-tree-display", + itemsCreator(op, callback) { + op.type = TreeView.REQ_TYPE_GET_SELECTED_DATA; + opts.itemsCreator(op, callback); + }, + value: (opts.value || {}).value, + }); + + this.display.on(Events.AFTERINIT, () => { + self.fireEvent(Events.AFTERINIT); + }); + + this.display.on(TreeView.EVENT_INIT, () => { + backToPopup.setVisible(false); + }); + + this.display.on(TreeView.EVENT_AFTERINIT, () => { + backToPopup.setVisible(true); + }); + + createWidget({ + type: VTapeLayout.xtype, + element: this, + items: [ + { + height: this.constants.height, + el: backToPopup, + }, + { + height: "fill", + el: this.display, + } + ], + }); + } + + empty() { + this.display.empty(); + } + + populate(configs) { + this.display.stroke(configs); + } + + setValue(v) { + v || (v = {}); + this.display.setSelectedValue(v.value); + } + + getValue() {} +} diff --git a/packages/fineui/src/widget/multitree/multi.tree.combo.js b/packages/fineui/src/widget/multitree/multi.tree.combo.js new file mode 100644 index 000000000..7d61b6e9d --- /dev/null +++ b/packages/fineui/src/widget/multitree/multi.tree.combo.js @@ -0,0 +1,446 @@ +import { + shortcut, + extend, + emptyFn, + createWidget, + toPix, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + deepClone, + Selection, + SIZE_CONSANTS +} from "@/core"; +import { Single, Combo } from "@/base"; +import { MultiTreeSearcher } from "./trigger/searcher.multi.tree"; +import { MultiTreePopup } from "./multi.tree.popup"; +import { MultiSelectTrigger } from "../multiselect/multiselect.trigger"; +import { TriggerIconButton } from "@/case"; +import { MultiSelectCheckSelectedSwitcher } from "../multiselect/trigger/switcher.checkselected"; +import { MultiTreeCheckSelectedButton } from "./trigger/multi.tree.button.checkselected"; +import { MultiTreeCheckPane } from "./check/multi.tree.check.pane"; + +@shortcut() +export class MultiTreeCombo extends Single { + static xtype = "bi.multi_tree_combo"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-combo", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + height: 24, + allowEdit: true, + isNeedAdjustWidth: true, + }); + } + + _init() { + const self = this, + o = this.options; + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + let clear; + let change; + super._init(...arguments); + let isInit = false; + let want2showCounter = false; + + this.storeValue = { value: o.value || {} }; + + this.trigger = createWidget({ + type: "bi.multi_select_trigger", + allowEdit: o.allowEdit, + height: toPix(o.height, o.simple ? 1 : 2), + valueFormatter: o.valueFormatter, + text: o.text, + defaultText: o.defaultText, + watermark: o.watermark, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + searcher: { + type: "bi.multi_tree_searcher", + itemsCreator: o.itemsCreator, + listeners: [ + { + eventName: MultiTreeSearcher.EVENT_CLICK_TREE_NODE, + action() { + self._dataChange = true; + }, + } + ], + }, + value: { value: o.value || {} }, + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: !o.allowEdit, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiTreePopup.xtype, + ref() { + self.popup = this; + self.trigger.setAdapter(this); + self.numberCounter.setAdapter(this); + }, + listeners: [ + { + eventName: MultiTreePopup.EVENT_AFTERINIT, + action() { + self.numberCounter.adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + }, + }, + { + eventName: MultiTreePopup.EVENT_CHANGE, + action() { + change = true; + const val = { + type: Selection.Multi, + value: this.hasChecked() ? this.getValue() : {}, + }; + self.trigger.getSearcher().setState(val); + self.numberCounter.setButtonChecked(val); + self.storeValue = { value: self.combo.getValue() }; + self.fireEvent( + MultiTreeCombo.EVENT_CLICK_ITEM, + self.combo.getValue() + ); + self._dataChange = true; + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CONFIRM, + action() { + self.combo.hideView(); + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CLEAR, + action() { + clear = true; + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + onLoaded() { + nextTick(() => { + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + maxWidth: o.isNeedAdjustWidth ? "auto" : 500, + }, + isNeedAdjustWidth: o.isNeedAdjustWidth, + value: { value: o.value || {} }, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + change = false; + clear = false; // 标识当前是否点击了清空 + + function isSearching() { + return self.trigger.getSearcher().isSearching(); + } + + function isPopupView() { + return self.combo.isViewVisible(); + } + + this.trigger.on(MultiSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiTreeCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiTreeCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, function () { + self.storeValue = { value: self.combo.getValue() }; + this.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = { value: this.getValue() }; + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + nextTick(() => { + if (isPopupView()) { + self.combo.populate(); + } + }); + self.fireEvent(MultiTreeCombo.EVENT_STOP); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, () => { + self.fireEvent(MultiTreeCombo.EVENT_SEARCHING); + }); + + function showCounter() { + if (isSearching()) { + self.storeValue = { value: self.trigger.getValue() }; + } else if (isPopupView()) { + self.storeValue = { value: self.combo.getValue() }; + } + self.trigger.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + } + + this.trigger.on(MultiSelectTrigger.EVENT_TRIGGER_CLICK, () => { + self.combo.toggle(); + }); + this.trigger.on(MultiSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, function () { + const checked = this.getSearcher().hasChecked(); + const val = { + type: Selection.Multi, + value: checked ? { 1: 1 } : {}, + }; + this.getSearcher().setState( + checked ? Selection.Multi : Selection.None + ); + self.numberCounter.setButtonChecked(val); + self.fireEvent( + MultiTreeCombo.EVENT_CLICK_ITEM, + self.combo.getValue() + ); + self._dataChange = true; + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + if (change === true) { + self.storeValue = { value: self.combo.getValue() }; + change = false; + } + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + self.populate(); + self.fireEvent(MultiTreeCombo.EVENT_BEFORE_POPUPVIEW); + }); + this.combo.on(Combo.EVENT_BEFORE_HIDEVIEW, () => { + if (isSearching()) { + self._stopEditing(); + self._dataChange && + self.fireEvent(MultiTreeCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self._stopEditing(); + self.storeValue = { value: self.combo.getValue() }; + if (clear === true) { + self.storeValue = { value: {} }; + } + self._dataChange && + self.fireEvent(MultiTreeCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + self.fireEvent(MultiTreeCombo.EVENT_AFTER_HIDEVIEW); + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: "bi.multi_select_check_selected_switcher", + el: { + // type: "bi.multi_tree_check_selected_button", + type: MultiTreeCheckSelectedButton.xtype, + }, + popup: { + // type: "bi.multi_tree_check_pane", + type: MultiTreeCheckPane.xtype, + }, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + value: { value: o.value || {} }, + }); + this.numberCounter.on( + MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, + () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + } + ); + this.numberCounter.on( + MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, + () => { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + } + ); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth( + b === true ? self.numberCounter.element.outerWidth() + 8 : 0 + ); + }); + }); + + this.numberCounter.on( + MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, + () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + } + ); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + bottom: 0, + } + ], + }); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue.value = v || {}; + this.combo.setValue({ + value: v || {}, + }); + this.numberCounter.setValue({ + value: v || {}, + }); + } + + getSearcher() { + return this.trigger.getSearcher(); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this.combo.populate(); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multitree/multi.tree.insert.combo.js b/packages/fineui/src/widget/multitree/multi.tree.insert.combo.js new file mode 100644 index 000000000..7b43365d3 --- /dev/null +++ b/packages/fineui/src/widget/multitree/multi.tree.insert.combo.js @@ -0,0 +1,430 @@ +import { MultiTreeSearcher } from "./trigger/searcher.multi.tree"; +import { MultiTreeSearchInsertPane } from "./trigger/multi.tree.search.insert.pane"; +import { MultiTreePopup } from "./multi.tree.popup"; +import { MultiTreeCheckSelectedButton } from "./trigger/multi.tree.button.checkselected"; +import { MultiTreeCheckPane } from "./check/multi.tree.check.pane"; +import { + shortcut, + extend, + emptyFn, + createWidget, + toPix, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + deepClone, + Selection, + SIZE_CONSANTS +} from "@/core"; +import { Single, Combo } from "@/base"; +import { MultiSelectTrigger } from "../multiselect/multiselect.trigger"; +import { TriggerIconButton } from "@/case"; +import { MultiSelectCheckSelectedSwitcher } from "../multiselect/trigger/switcher.checkselected"; + +@shortcut() +export class MultiTreeInsertCombo extends Single { + static xtype = "bi.multi_tree_insert_combo"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-insert-combo", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + height: 24, + allowEdit: true, + isNeedAdjustWidth: true, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + let isInit = false; + let want2showCounter = false; + + this.storeValue = { value: o.value || {} }; + + this.trigger = createWidget({ + type: MultiSelectTrigger.xtype, + allowEdit: o.allowEdit, + height: toPix(o.height, o.simple ? 1 : 2), + valueFormatter: o.valueFormatter, + text: o.text, + defaultText: o.defaultText, + watermark: o.watermark, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + searcher: { + type: MultiTreeSearcher.xtype, + + itemsCreator: o.itemsCreator, + popup: { + type: MultiTreeSearchInsertPane.xtype, + listeners: [ + { + eventName: MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action() { + self.storeValue.value[self.trigger.getSearcher().getKeyword()] = {}; + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + self._stopEditing(); + self._dataChange = true; + }, + }, + { + eventName: MultiTreeSearchInsertPane.EVENT_CLICK_TREE_NODE, + action() { + self._dataChange = true; + }, + } + ], + }, + }, + value: { value: o.value || {} }, + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: !o.allowEdit, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiTreePopup.xtype, + ref() { + self.popup = this; + self.trigger.setAdapter(this); + self.numberCounter.setAdapter(this); + }, + listeners: [ + { + eventName: MultiTreePopup.EVENT_AFTERINIT, + action() { + self.numberCounter.adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + }, + }, + { + eventName: MultiTreePopup.EVENT_CHANGE, + action() { + change = true; + const val = { + type: Selection.Multi, + value: this.hasChecked() ? this.getValue() : {}, + }; + self.trigger.getSearcher().setState(val); + self.numberCounter.setButtonChecked(val); + self.storeValue = { value: self.combo.getValue() }; + self.fireEvent(MultiTreeInsertCombo.EVENT_CLICK_ITEM, self.getValue()); + self._dataChange = true; + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CONFIRM, + action() { + self.combo.hideView(); + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CLEAR, + action() { + clear = true; + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + onLoaded() { + nextTick(() => { + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + maxWidth: o.isNeedAdjustWidth ? "auto" : 500, + }, + isNeedAdjustWidth: o.isNeedAdjustWidth, + value: { value: o.value || {} }, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + let change = false; + let clear = false; // 标识当前是否点击了清空 + + const isSearching = () => self.trigger.getSearcher().isSearching(); + + const isPopupView = () => self.combo.isViewVisible(); + + this.trigger.on(MultiSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiTreeInsertCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiTreeInsertCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, function () { + self.storeValue = { value: self.combo.getValue() }; + this.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = { value: this.getValue() }; + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + nextTick(() => { + if (isPopupView()) { + self.combo.populate(); + } + }); + self.fireEvent(MultiTreeInsertCombo.EVENT_STOP); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, () => { + self.fireEvent(MultiTreeInsertCombo.EVENT_SEARCHING); + }); + + function showCounter() { + if (isSearching()) { + self.storeValue = { value: self.trigger.getValue() }; + } else if (isPopupView()) { + self.storeValue = { value: self.combo.getValue() }; + } + self.trigger.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + } + + this.trigger.on(MultiSelectTrigger.EVENT_TRIGGER_CLICK, () => { + self.combo.toggle(); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, function () { + const checked = this.getSearcher().hasChecked(); + const val = { + type: Selection.Multi, + value: checked ? { 1: 1 } : {}, + }; + this.getSearcher().setState(checked ? Selection.Multi : Selection.None); + self.numberCounter.setButtonChecked(val); + self.fireEvent(MultiTreeInsertCombo.EVENT_CLICK_ITEM, self.combo.getValue()); + self._dataChange = true; + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + if (change === true) { + self.storeValue = { value: self.combo.getValue() }; + change = false; + } + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + self.populate(); + self.fireEvent(MultiTreeInsertCombo.EVENT_BEFORE_POPUPVIEW); + }); + this.combo.on(Combo.EVENT_BEFORE_HIDEVIEW, () => { + if (isSearching()) { + self._stopEditing(); + self._dataChange && self.fireEvent(MultiTreeInsertCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self._stopEditing(); + self.storeValue = { value: self.combo.getValue() }; + if (clear === true) { + self.storeValue = { value: {} }; + } + self._dataChange && self.fireEvent(MultiTreeInsertCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + el: { + type: MultiTreeCheckSelectedButton.xtype, + }, + popup: { + type: MultiTreeCheckPane.xtype, + }, + itemsCreator: o.itemsCreator, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + valueFormatter: o.valueFormatter, + value: o.value, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, () => { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _assertShowValue() { + this.trigger.getSearcher().setState(this.storeValue); + this.numberCounter.setButtonChecked(this.storeValue); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + getSearcher() { + return this.trigger.getSearcher(); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue.value = v || {}; + this.combo.setValue({ + value: v || {}, + }); + this.numberCounter.setValue({ + value: v || {}, + }); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this.combo.populate(); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multitree/multi.tree.list.combo.js b/packages/fineui/src/widget/multitree/multi.tree.list.combo.js new file mode 100644 index 000000000..d32f941ed --- /dev/null +++ b/packages/fineui/src/widget/multitree/multi.tree.list.combo.js @@ -0,0 +1,443 @@ +import { MultiListTreeSearcher } from "./trigger/searcher.list.multi.tree"; +import { MultiTreeCheckSelectedButton } from "./trigger/multi.tree.button.checkselected"; +import { MultiTreeCheckPane } from "./check/multi.tree.check.pane"; +import { + shortcut, + extend, + emptyFn, + createWidget, + toPix, + nextTick, + Events, + AbsoluteLayout, + VerticalAdaptLayout, + deepClone, + Selection, + SIZE_CONSANTS +} from "@/core"; +import { Single, Combo } from "@/base"; +import { MultiTreeSearchInsertPane } from "./trigger/multi.tree.search.insert.pane"; +import { MultiTreePopup } from "./multi.tree.popup"; +import { MultiSelectTrigger } from "../multiselect/multiselect.trigger"; +import { TriggerIconButton, ListPartTree, ListDisplayTree, ListAsyncTree } from "@/case"; +import { MultiSelectCheckSelectedSwitcher } from "../multiselect/trigger/switcher.checkselected"; + +@shortcut() +export class MultiTreeListCombo extends Single { + static xtype = "bi.multi_tree_list_combo"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + height: 24, + allowEdit: true, + allowInsertValue: true, + isNeedAdjustWidth: true, + text: "", + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + let isInit = false; + let want2showCounter = false; + + this.storeValue = { value: o.value || [] }; + + this.trigger = createWidget({ + type: MultiSelectTrigger.xtype, + allowEdit: o.allowEdit, + text: o.text, + defaultText: o.defaultText, + watermark: o.watermark, + height: toPix(o.height, o.simple ? 1 : 2), + valueFormatter: o.valueFormatter, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + searcher: { + type: MultiListTreeSearcher.xtype, + itemsCreator: o.itemsCreator, + popup: { + type: o.allowInsertValue ? "bi.multi_tree_search_insert_pane" : "bi.multi_tree_search_pane", + el: { + type: ListPartTree.xtype, + }, + listeners: [ + { + eventName: MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action() { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + self._stopEditing(); + self._dataChange = true; + }, + } + ], + }, + }, + switcher: { + el: { + type: MultiTreeCheckSelectedButton.xtype, + }, + popup: { + type: MultiTreeCheckPane.xtype, + el: { + type: ListDisplayTree.xtype, + }, + itemsCreator: o.itemsCreator, + }, + }, + value: this.storeValue, + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: !o.allowEdit, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: MultiTreePopup.xtype, + ref() { + self.popup = this; + self.trigger.setAdapter(this); + self.numberCounter.setAdapter(this); + }, + el: { + type: ListAsyncTree.xtype, + }, + listeners: [ + { + eventName: MultiTreePopup.EVENT_AFTERINIT, + action() { + self.numberCounter.adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + }, + }, + { + eventName: MultiTreePopup.EVENT_CHANGE, + action() { + change = true; + const val = { + type: Selection.Multi, + value: this.hasChecked() ? this.getValue() : [], + }; + self.trigger.getSearcher().setState(val); + self.numberCounter.setButtonChecked(val); + self.storeValue = { value: self.combo.getValue() }; + self.fireEvent(MultiTreeListCombo.EVENT_CLICK_ITEM, self.getValue()); + self._dataChange = true; + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CONFIRM, + action() { + self.combo.hideView(); + }, + }, + { + eventName: MultiTreePopup.EVENT_CLICK_CLEAR, + action() { + clear = true; + self._dataChange = true; + self.setValue(); + self._defaultState(); + }, + } + ], + itemsCreator: o.itemsCreator, + onLoaded() { + nextTick(() => { + self.numberCounter.adjustView(); + self.trigger.getSearcher().adjustView(); + }); + }, + maxWidth: o.isNeedAdjustWidth ? "auto" : 500, + }, + isNeedAdjustWidth: o.isNeedAdjustWidth, + value: this.storeValue, + hideChecker(e) { + return ( + triggerBtn.element.find(e.target).length === 0 && + self.numberCounter.element.find(e.target).length === 0 + ); + }, + }); + + let change = false; + let clear = false; // 标识当前是否点击了清空 + + const isSearching = () => self.trigger.getSearcher().isSearching(); + + const isPopupView = () => self.combo.isViewVisible(); + + this.trigger.on(MultiSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(MultiTreeListCombo.EVENT_FOCUS); + }); + this.trigger.on(MultiSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(MultiTreeListCombo.EVENT_BLUR); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, function () { + self.storeValue = { value: self.combo.getValue() }; + this.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = { value: this.getValue() }; + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + nextTick(() => { + if (isPopupView()) { + self.combo.populate(); + } + }); + self.fireEvent(MultiTreeListCombo.EVENT_STOP); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, () => { + self.fireEvent(MultiTreeListCombo.EVENT_SEARCHING); + }); + + function showCounter() { + if (isSearching()) { + self.storeValue = { value: self.trigger.getValue() }; + } else if (isPopupView()) { + self.storeValue = { value: self.combo.getValue() }; + } + self.trigger.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + } + + this.trigger.on(MultiSelectTrigger.EVENT_TRIGGER_CLICK, () => { + self.combo.toggle(); + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, function () { + const checked = this.getSearcher().hasChecked(); + const val = { + type: Selection.Multi, + value: checked ? { 1: 1 } : {}, + }; + this.getSearcher().setState(checked ? Selection.Multi : Selection.None); + self.numberCounter.setButtonChecked(val); + self.fireEvent(MultiTreeListCombo.EVENT_CLICK_ITEM, self.combo.getValue()); + self._dataChange = true; + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + if (change === true) { + self.storeValue = { value: self.combo.getValue() }; + change = false; + } + self.combo.setValue(self.storeValue); + self.numberCounter.setValue(self.storeValue); + self.populate(); + self.fireEvent(MultiTreeListCombo.EVENT_BEFORE_POPUPVIEW); + }); + this.combo.on(Combo.EVENT_BEFORE_HIDEVIEW, () => { + if (isSearching()) { + self.trigger.stopEditing(); + self._dataChange && self.fireEvent(MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self._stopEditing(); + self.storeValue = { value: self.combo.getValue() }; + if (clear === true) { + self.storeValue = { value: [] }; + } + self._dataChange && self.fireEvent(MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + self.numberCounter.hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + + this.numberCounter = createWidget({ + type: MultiSelectCheckSelectedSwitcher.xtype, + el: { + type: MultiTreeCheckSelectedButton.xtype, + }, + popup: { + type: MultiTreeCheckPane.xtype, + }, + itemsCreator: o.itemsCreator, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + valueFormatter: o.valueFormatter, + value: o.value, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, () => { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + self.trigger.refreshPlaceHolderWidth(b === true ? self.numberCounter.element.outerWidth() + 8 : 0); + }); + }); + + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, () => { + nextTick(() => { + // 收起时自动调整宽度 + self.trigger.refreshPlaceHolderWidth(0); + }); + }); + + this.trigger.element.click(e => { + if (self.trigger.element.find(e.target).length > 0) { + self.numberCounter.hideView(); + } + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: VerticalAdaptLayout.xtype, + items: [this.numberCounter], + }, + right: o.height, + top: 0, + height: o.height, + } + ], + }); + } + + _assertShowValue() { + this.trigger.getSearcher().setState(this.storeValue); + this.numberCounter.setButtonChecked(this.storeValue); + } + + _stopEditing() { + this.trigger.stopEditing(); + this.numberCounter.hideView(); + } + + _defaultState() { + this._stopEditing(); + this.combo.hideView(); + } + + showView() { + this.combo.showView(); + } + + hideView() { + this.combo.hideView(); + } + + getSearcher() { + return this.trigger.getSearcher(); + } + + setValue(v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [], + }); + this.numberCounter.setValue({ + value: v || [], + }); + } + + getValue() { + return deepClone(this.storeValue.value); + } + + populate() { + this.combo.populate(); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multitree/multi.tree.popup.js b/packages/fineui/src/widget/multitree/multi.tree.popup.js new file mode 100644 index 000000000..44c91a591 --- /dev/null +++ b/packages/fineui/src/widget/multitree/multi.tree.popup.js @@ -0,0 +1,108 @@ +import { shortcut, extend, emptyFn, createWidget, i18nText } from "@/core"; +import { Pane } from "@/base"; +import { AsyncTree, MultiPopupView, TreeView } from "@/case"; + +@shortcut() +export class MultiTreePopup extends Pane { + static xtype = "bi.multi_tree_popup_view"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + static EVENT_AFTERINIT = "EVENT_AFTERINIT"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-popup", + maxWidth: "auto", + minWidth: 140, + maxHeight: 400, + onLoaded: emptyFn, + el: { + type: AsyncTree.xtype, + }, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options, + v = opts.value; + + this.selectedValues = {}; + + this.tree = createWidget(opts.el, { + type: AsyncTree.xtype, + showLine: opts.showLine, + height: 400, + cls: "popup-view-tree", + itemsCreator: opts.itemsCreator, + onLoaded: opts.onLoaded, + value: v.value || {}, + }); + + this.popupView = createWidget({ + type: MultiPopupView.xtype, + element: this, + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + buttons: [i18nText("BI-Basic_Clears"), i18nText("BI-Basic_OK")], + el: this.tree, + }); + + this.popupView.on(MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, index => { + switch (index) { + case 0: + self.fireEvent(MultiTreePopup.EVENT_CLICK_CLEAR); + break; + case 1: + self.fireEvent(MultiTreePopup.EVENT_CLICK_CONFIRM); + break; + + default: + break; + } + }); + + this.tree.on(TreeView.EVENT_CHANGE, () => { + self.fireEvent(MultiTreePopup.EVENT_CHANGE); + }); + + this.tree.on(TreeView.EVENT_AFTERINIT, () => { + self.fireEvent(MultiTreePopup.EVENT_AFTERINIT); + }); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v || (v = {}); + this.tree.setSelectedValue(v.value); + } + + populate(config) { + this.tree.stroke(config); + } + + hasChecked() { + return this.tree.hasChecked(); + } + + setDirection(direction, position) { + this.popupView.setDirection(direction, position); + } + + resetHeight(h) { + this.popupView.resetHeight(h); + } + + resetWidth(w) { + this.popupView.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/multitree/trigger/multi.tree.button.checkselected.js b/packages/fineui/src/widget/multitree/trigger/multi.tree.button.checkselected.js new file mode 100644 index 000000000..3d7b13299 --- /dev/null +++ b/packages/fineui/src/widget/multitree/trigger/multi.tree.button.checkselected.js @@ -0,0 +1,69 @@ +import { HorizontalLayout, shortcut, extend, emptyFn, createWidget, i18nText, Controller, size } from "@/core"; +import { Single, TextButton, IconButton } from "@/base"; +import { MultiSelectCheckSelectedButton } from "../../multiselect/trigger/button.checkselected"; + +@shortcut() +export class MultiTreeCheckSelectedButton extends Single { + static xtype = "bi.multi_tree_check_selected_button"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-check-selected-button", + itemsCreator: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this; + this.indicator = createWidget({ + type: IconButton.xtype, + cls: "check-font trigger-check-selected icon-size-12", + width: 16, + height: 16, + stopPropagation: true, + }); + + this.checkSelected = createWidget({ + type: TextButton.xtype, + cls: "bi-high-light-background trigger-check-text", + invisible: true, + hgap: 4, + text: i18nText("BI-Check_Selected"), + textAlign: "center", + }); + this.checkSelected.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.checkSelected.on(TextButton.EVENT_CHANGE, function () { + self.fireEvent(MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); + }); + + createWidget({ + type: HorizontalLayout.xtype, + element: this, + items: [this.indicator, this.checkSelected], + }); + + this.element.hover( + () => { + self.indicator.setVisible(false); + self.checkSelected.setVisible(true); + }, + () => { + self.indicator.setVisible(true); + self.checkSelected.setVisible(false); + } + ); + this.setVisible(false); + } + + setValue(v) { + v || (v = {}); + const show = size(v.value) > 0; + this.setVisible(show); + } +} diff --git a/packages/fineui/src/widget/multitree/trigger/multi.tree.search.insert.pane.js b/packages/fineui/src/widget/multitree/trigger/multi.tree.search.insert.pane.js new file mode 100644 index 000000000..454e1daf9 --- /dev/null +++ b/packages/fineui/src/widget/multitree/trigger/multi.tree.search.insert.pane.js @@ -0,0 +1,128 @@ +import { shortcut, Widget, i18nText, extend, Controller, AbsoluteLayout, isEmptyArray } from "@/core"; +import { TreeView, PartTree } from "@/case"; +import { TextButton } from "@/base"; + +@shortcut() +export class MultiTreeSearchInsertPane extends Widget { + static xtype = "bi.multi_tree_search_insert_pane"; + + props = { + baseCls: "bi-multi-tree-search-insert-pane bi-card", + el: { type: PartTree.xtype }, + }; + + static CONSTANTS = { + height: 24, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + static EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; + static EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; + + render() { + const self = this, + opts = this.options; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: TextButton.xtype, + invisible: true, + ref(_ref) { + self.addTip = _ref; + }, + text: i18nText("BI-Basic_Click_To_Add_Text", ""), + height: MultiTreeSearchInsertPane.CONSTANTS.height, + cls: "bi-high-light", + handler() { + self.fireEvent(MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + }, + }, + top: 5, + left: 0, + right: 0, + }, + { + el: extend( + { + type: PartTree.xtype, + tipText: i18nText("BI-No_Select"), + itemsCreator(op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, res => { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref(_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }, + }, + { + eventName: TreeView.EVENT_CHANGE, + action() { + self.fireEvent(MultiTreeSearchInsertPane.EVENT_CHANGE); + }, + }, + { + eventName: PartTree.EVENT_CLICK_TREE_NODE, + action() { + self.fireEvent(MultiTreeSearchInsertPane.EVENT_CLICK_TREE_NODE); + }, + } + ], + }, + opts.el + ), + left: 0, + top: 0, + bottom: 0, + right: 0, + } + ], + }; + } + + setKeyword(keyword, nodes) { + const isAddTipVisible = isEmptyArray(nodes); + this.addTip.setVisible(isAddTipVisible); + this.partTree.setVisible(!isAddTipVisible); + isAddTipVisible && this.addTip.setText(i18nText("BI-Basic_Click_To_Add_Text", keyword)); + } + + hasChecked() { + return this.partTree.hasChecked(); + } + + setValue(v) { + this.setSelectedValue(v.value); + } + + setSelectedValue(v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + } + + getValue() { + return this.partTree.getValue(); + } + + empty() { + this.partTree.empty(); + } + + populate(op) { + this.partTree.stroke(...arguments); + } +} diff --git a/packages/fineui/src/widget/multitree/trigger/multi.tree.search.pane.js b/packages/fineui/src/widget/multitree/trigger/multi.tree.search.pane.js new file mode 100644 index 000000000..01bb92499 --- /dev/null +++ b/packages/fineui/src/widget/multitree/trigger/multi.tree.search.pane.js @@ -0,0 +1,86 @@ +import { shortcut, extend, i18nText, Controller } from "@/core"; +import { Pane } from "@/base"; +import { TreeView, PartTree } from "@/case"; + +@shortcut() +export class MultiTreeSearchPane extends Pane { + static xtype = "bi.multi_tree_search_pane"; + + props = { + baseCls: "bi-multi-tree-search-pane bi-card", + isSelectedAny: true, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + static EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; + + render() { + const self = this, + opts = this.options; + + return extend( + { + type: PartTree.xtype, + element: this, + tipText: i18nText("BI-No_Select"), + isSelectedAny: opts.isSelectedAny, + itemsCreator(op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action() { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }, + }, + { + eventName: TreeView.EVENT_CHANGE, + action() { + self.fireEvent(MultiTreeSearchPane.EVENT_CHANGE); + }, + }, + { + eventName: PartTree.EVENT_CLICK_TREE_NODE, + action() { + self.fireEvent(MultiTreeSearchPane.EVENT_CLICK_TREE_NODE); + }, + } + ], + ref(_ref) { + self.partTree = _ref; + }, + }, + opts.el + ); + } + + hasChecked() { + return this.partTree.hasChecked(); + } + + setValue(v) { + this.setSelectedValue(v.value); + } + + setSelectedValue(v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + } + + getValue() { + return this.partTree.getValue(); + } + + empty() { + this.partTree.empty(); + } + + populate(op) { + this.partTree.stroke(...arguments); + } +} diff --git a/packages/fineui/src/widget/multitree/trigger/searcher.list.multi.tree.js b/packages/fineui/src/widget/multitree/trigger/searcher.list.multi.tree.js new file mode 100644 index 000000000..d38fd3436 --- /dev/null +++ b/packages/fineui/src/widget/multitree/trigger/searcher.list.multi.tree.js @@ -0,0 +1,194 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, isNotNull, isNumber, size, each, last, Selection, isObject } from "@/core"; +import { MultiSelectEditor } from "../../multiselect/trigger/editor.multiselect"; +import { MultiSelectSearcher } from "../../multiselect/trigger/searcher.multiselect"; +import { Searcher } from "@/base"; +import { SimpleStateEditor } from "@/case"; +import { MultiTreeSearchPane } from "./multi.tree.search.pane"; + +@shortcut() +export class MultiListTreeSearcher extends Widget { + static xtype = "bi.multi_list_tree_searcher"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-list-tree-searcher", + itemsCreator: emptyFn, + valueFormatter(v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {}, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget({ + type: MultiSelectEditor.xtype, + height: o.height, + text: o.text, + defaultText: o.defaultText, + watermark: o.watermark, + el: { + type: SimpleStateEditor.xtype, + height: o.height, + }, + listeners: [ + { + eventName: MultiSelectEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_BLUR); + }, + } + ], + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback({ + keyword: self.editor.getValue(), + }); + }, + el: this.editor, + + popup: extend( + { + type: MultiTreeSearchPane.xtype, + keywordGetter() { + return self.editor.getValue(); + }, + itemsCreator(op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + self.fireEvent(MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + self.fireEvent(MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + self.fireEvent(MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, function () { + self.fireEvent(MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + adjustView() { + this.searcher.adjustView(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeyword() { + return this.editor.getValue(); + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setState(ob) { + const o = this.options; + ob || (ob = {}); + isObject(ob) && (ob.value || (ob.value = [])); + let count = 0; + if (isNumber(ob)) { + this.editor.setState(ob); + } else if (size(ob.value) === 0) { + this.editor.setState(Selection.None); + } else { + let text = ""; + each(ob.value, (idx, path) => { + const childValue = last(path); + text += path === "null" ? "" : `${o.valueFormatter(`${childValue}`) || childValue}; `; + count++; + }); + + if (count > 20) { + this.editor.setState(Selection.Multi); + } else { + this.editor.setState(text); + } + } + } + + getState() { + return this.editor.getState(); + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(items) { + this.searcher.populate(...arguments); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/multitree/trigger/searcher.multi.tree.js b/packages/fineui/src/widget/multitree/trigger/searcher.multi.tree.js new file mode 100644 index 000000000..518dff408 --- /dev/null +++ b/packages/fineui/src/widget/multitree/trigger/searcher.multi.tree.js @@ -0,0 +1,251 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + isNotNull, + isNumber, + size, + keys, + each, + isEmptyObject, + Func, + Selection, + isObject +} from "@/core"; +import { MultiSelectEditor } from "../../multiselect/trigger/editor.multiselect"; +import { MultiSelectSearcher } from "../../multiselect/trigger/searcher.multiselect"; +import { MultiTreeSearchPane } from "./multi.tree.search.pane"; +import { Searcher } from "@/base"; +import { SimpleStateEditor } from "@/case"; + +@shortcut() +export class MultiTreeSearcher extends Widget { + static xtype = "bi.multi_tree_searcher"; + + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: emptyFn, + valueFormatter(v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {}, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget({ + type: MultiSelectEditor.xtype, + watermark: o.watermark, + height: o.height, + el: { + type: SimpleStateEditor.xtype, + text: o.text, + defaultText: o.defaultText, + height: o.height, + }, + listeners: [ + { + eventName: MultiSelectEditor.EVENT_FOCUS, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_FOCUS); + }, + }, + { + eventName: MultiSelectEditor.EVENT_BLUR, + action() { + self.fireEvent(MultiSelectSearcher.EVENT_BLUR); + }, + } + ], + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback({ + keyword: self.editor.getValue(), + }); + }, + el: this.editor, + + popup: extend( + { + type: MultiTreeSearchPane.xtype, + keywordGetter() { + return self.editor.getValue(); + }, + itemsCreator(op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + listeners: [ + { + eventName: MultiTreeSearchPane.EVENT_CLICK_TREE_NODE, + action() { + self.fireEvent(MultiTreeSearcher.EVENT_CLICK_TREE_NODE, arguments); + }, + } + ], + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + self.fireEvent(MultiTreeSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + self.fireEvent(MultiTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + self.fireEvent(MultiTreeSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, function () { + self.fireEvent(MultiTreeSearcher.EVENT_CHANGE, arguments); + }); + this.searcher.on(Searcher.EVENT_SEARCHING, function () { + const keywords = this.getKeywords(); + self.fireEvent(MultiTreeSearcher.EVENT_SEARCHING, keywords); + }); + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + adjustView() { + this.searcher.adjustView(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeyword() { + return this.editor.getValue(); + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setState(ob) { + const o = this.options; + ob || (ob = {}); + isObject(ob) && (ob.value || (ob.value = {})); + let count = 0; + if (isNumber(ob)) { + this.editor.setState(ob); + } else if (size(ob.value) === 0) { + this.editor.setState(Selection.None); + } else { + let text = ""; + const value = ob.value; + const names = Func.getSortedResult(keys(value)); + each(names, (idx, name) => { + const childNodes = getChildrenNode(value[name]); + text += `${ + (name === "null" ? "" : o.valueFormatter(`${name}`) || name) + + (childNodes === "" ? (isEmptyObject(value[name]) ? "" : ":") : `:${childNodes}`) + }; `; + if (childNodes === "") { + count++; + } + }); + + if (count > 20) { + this.editor.setState(Selection.Multi); + } else { + this.editor.setState(text); + } + } + + function getChildrenNode(ob) { + let text = ""; + const _size = size(ob); + let index = 0; + + const names = Func.getSortedResult(keys(ob)); + each(names, (idx, name) => { + index++; + const childNodes = getChildrenNode(ob[name]); + text += + (name === "null" ? "" : o.valueFormatter(`${name}`) || name) + + (childNodes === "" ? "" : `:${childNodes}`) + + (index === _size ? "" : ","); + if (childNodes === "") { + count++; + } + }); + + return text; + } + } + + getState() { + return this.editor.getState(); + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(items) { + this.searcher.populate(...arguments); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/numbereditor/number.editor.js b/packages/fineui/src/widget/numbereditor/number.editor.js new file mode 100644 index 000000000..1adc95ce4 --- /dev/null +++ b/packages/fineui/src/widget/numbereditor/number.editor.js @@ -0,0 +1,228 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + toPix, + parseFloat, + HTapeLayout, + GridLayout, + isNumeric, + clamp, + MIN, + MAX, + KeyCode, + add +} from "@/core"; +import { SignEditor } from "@/case"; +import { TextEditor } from "../editor"; +import { IconButton } from "@/base"; + +@shortcut() +export class NumberEditor extends Widget { + static xtype = "bi.number_editor"; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(conf) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-number-editor bi-focus-shadow ${ + conf.simple ? "bi-border-bottom" : "bi-border bi-border-radius" + }`, + validationChecker: emptyFn, + valueFormatter(v) { + return v; + }, + valueParser(v) { + return v; + }, + value: 0, + allowBlank: false, + errorText: "", + step: 1, + min: MIN, + max: MAX, + watermark: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget({ + type: SignEditor.xtype, + height: toPix(o.height, 2), + simple: o.simple, + allowBlank: o.allowBlank, + watermark: o.watermark, + value: o.valueFormatter(o.value), + validationChecker: v => { + // 不设置validationChecker就自动检测 + const parsedValue = o.valueParser(v); + if (o.validationChecker === emptyFn && !this._checkValueInRange(parsedValue)) { + return false; + } + + return o.validationChecker(parsedValue); + }, + errorText: o.errorText, + listeners: [ + { + eventName: SignEditor.EVENT_QUICK_DOWN, + action: e => { + if ([KeyCode.UP, KeyCode.DOWN].includes(e.keyCode)) { + e.preventDefault(); + } + }, + }, + { + eventName: SignEditor.EVENT_KEY_DOWN, + action: keycode => { + if (keycode === KeyCode.UP) { + this._finetuning(o.step); + + return; + } + if (keycode === KeyCode.DOWN) { + this._finetuning(-o.step); + } + }, + } + ], + }); + this.editor.on(TextEditor.EVENT_CHANGE, () => { + // 大多数时候valueFormatter往往需要配合valueParser一起使用 + const value = this.editor.getValue(); + const parsedValue = o.valueParser(value); + this.editor.setValue(o.valueFormatter(parsedValue)); + this.fireEvent(NumberEditor.EVENT_CHANGE); + }); + this.editor.on(TextEditor.EVENT_ERROR, () => { + o.value = parseFloat(this.editor.getLastValidValue()); + this._checkAdjustDisabled(o.value); + this.element.addClass("error"); + }); + this.editor.on(TextEditor.EVENT_VALID, () => { + o.value = parseFloat(this.editor.getValue()); + this._checkAdjustDisabled(o.value); + this.element.removeClass("error"); + }); + this.editor.on(TextEditor.EVENT_CONFIRM, () => { + this.fireEvent(NumberEditor.EVENT_CONFIRM); + }); + this.topBtn = createWidget({ + type: IconButton.xtype, + forceNotSelected: true, + trigger: "lclick,", + debounce: false, + cls: `${ + o.simple ? "solid-triangle-top-font " : "add-up-font bi-border-left " + }top-button bi-list-item-active2 icon-size-12`, + }); + this.topBtn.on(IconButton.EVENT_CHANGE, () => { + this._finetuning(o.step); + this.fireEvent(NumberEditor.EVENT_CHANGE); + this.fireEvent(NumberEditor.EVENT_CONFIRM); + }); + this.bottomBtn = createWidget({ + type: IconButton.xtype, + trigger: "lclick,", + forceNotSelected: true, + debounce: false, + cls: `${ + o.simple ? "solid-triangle-bottom-font " : "minus-down-font bi-border-left " + }bottom-button bi-list-item-active2 icon-size-12`, + }); + this.bottomBtn.on(IconButton.EVENT_CHANGE, () => { + this._finetuning(-o.step); + this.fireEvent(NumberEditor.EVENT_CHANGE); + this.fireEvent(NumberEditor.EVENT_CONFIRM); + }); + createWidget({ + type: HTapeLayout.xtype, + height: toPix(o.height, 2), + element: this, + items: [ + this.editor, + { + el: { + type: GridLayout.xtype, + columns: 1, + rows: 2, + items: [ + { + column: 0, + row: 0, + el: this.topBtn, + }, + { + column: 0, + row: 1, + el: this.bottomBtn, + } + ], + }, + width: 23, + } + ], + }); + } + + focus() { + this.editor.focus(); + } + + isEditing() { + return this.editor.isEditing(); + } + + _checkValueInRange(v) { + const o = this.options; + + return !!(isNumeric(v) && parseFloat(v) >= o.min && parseFloat(v) <= o.max); + } + + _checkAdjustDisabled(v) { + if (this.options.validationChecker === emptyFn) { + this.bottomBtn.setEnable(parseFloat(v) > this.options.min); + this.topBtn.setEnable(parseFloat(v) < this.options.max); + } + } + + _finetuning(addValue) { + const { max, min } = this.options; + let v = parseFloat(this.getValue()); + v = add(v, addValue); + v = clamp(v, min, max); + this.setValue(v); + } + + setUpEnable(v) { + this.topBtn.setEnable(!!v); + } + + setDownEnable(v) { + this.bottomBtn.setEnable(!!v); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + getValue() { + return this.options.value; + } + + setValue(v) { + const o = this.options; + o.value = v; + this.editor.setValue(o.valueFormatter(v)); + this._checkAdjustDisabled(o.value); + } +} diff --git a/src/widget/numberinterval/__test__/numberinterval.test.js b/packages/fineui/src/widget/numberinterval/__test__/numberinterval.test.js similarity index 100% rename from src/widget/numberinterval/__test__/numberinterval.test.js rename to packages/fineui/src/widget/numberinterval/__test__/numberinterval.test.js diff --git a/packages/fineui/src/widget/numberinterval/numberinterval.js b/packages/fineui/src/widget/numberinterval/numberinterval.js new file mode 100644 index 000000000..89085cd75 --- /dev/null +++ b/packages/fineui/src/widget/numberinterval/numberinterval.js @@ -0,0 +1,630 @@ +import { + HorizontalFillLayout, + shortcut, + extend, + i18nText, + createWidget, + toPix, + isNumeric, + AbsoluteLayout, + isEmptyString, + isNotNull, + isNull, + isIE, + getIEVersion, +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { IconCombo } from "@/case"; +import { NumberIntervalSingleEidtor } from "./singleeditor/single.editor"; + +@shortcut() +export class NumberInterval extends Single { + static xtype = "bi.number_interval"; + + constants = { + typeError: "typeBubble", + numberError: "numberBubble", + signalError: "signalBubble", + editorWidth: 114, + columns: 5, + width: 24, + rows: 1, + numberErrorCls: "number-error", + border: 1, + less: 0, + less_equal: 1, + numTip: "", + adjustYOffset: 2, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: `bi-number-interval${isIE() && getIEVersion() < 10 ? " hack" : ""}`, + height: 24, + validation: "valid", + closeMin: true, + allowBlank: true, + watermark: i18nText("BI-Basic_Unrestricted"), + }); + } + + _init() { + const self = this, + c = this.constants, + o = this.options; + super._init(...arguments); + this.smallEditor = createWidget({ + type: NumberIntervalSingleEidtor.xtype, + height: toPix(o.height, o.simple ? 1 : 2), + watermark: o.watermark, + allowBlank: o.allowBlank, + value: o.min, + level: "warning", + tipType: "success", + title() { + return self.smallEditor && self.smallEditor.getValue(); + }, + quitChecker() { + return false; + }, + validationChecker(v) { + if (!isNumeric(v)) { + self.smallEditorBubbleType = c.typeError; + + return false; + } + + return true; + }, + cls: `number-interval-small-editor bi-focus-shadow ${ + o.simple ? "bi-border-bottom" : "bi-border bi-border-corner-left-radius" + }`, + }); + + this.smallTip = createWidget({ + type: Label.xtype, + text: o.numTip, + height: toPix(o.height, o.simple ? 1 : 2), + invisible: true, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this.smallEditor, + items: [ + { + el: this.smallTip, + top: 0, + right: 5, + }, + ], + }); + + this.bigEditor = createWidget({ + type: NumberIntervalSingleEidtor.xtype, + height: toPix(o.height, o.simple ? 1 : 2), + watermark: o.watermark, + allowBlank: o.allowBlank, + value: o.max, + title() { + return self.bigEditor && self.bigEditor.getValue(); + }, + quitChecker() { + return false; + }, + validationChecker(v) { + if (!isNumeric(v)) { + self.bigEditorBubbleType = c.typeError; + + return false; + } + + return true; + }, + cls: `number-interval-big-editor bi-focus-shadow${ + o.simple ? " bi-border-bottom" : " bi-border bi-border-corner-right-radius" + }`, + }); + + this.bigTip = createWidget({ + type: Label.xtype, + text: o.numTip, + height: toPix(o.height, o.simple ? 1 : 2), + invisible: true, + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this.bigEditor, + items: [ + { + el: this.bigTip, + top: 0, + right: 5, + }, + ], + }); + this.smallCombo = createWidget({ + type: IconCombo.xtype, + cls: `number-interval-small-combo${ + o.simple ? "" : " bi-border-top bi-border-bottom bi-border-right bi-border-corner-right-radius" + }`, + height: toPix(o.height, o.simple ? 0 : 2), + width: toPix(c.width, c.border), + items: [ + { + text: `(${i18nText("BI-Less_Than")})`, + iconCls: "less-font", + value: 0, + }, + { + text: `(${i18nText("BI-Less_And_Equal")})`, + value: 1, + iconCls: "less-equal-font", + }, + ], + }); + if (o.closeMin === true) { + this.smallCombo.setValue(1); + } else { + this.smallCombo.setValue(0); + } + this.bigCombo = createWidget({ + type: IconCombo.xtype, + cls: `number-interval-big-combo${ + o.simple ? "" : " bi-border-top bi-border-bottom bi-border-left bi-border-corner-left-radius" + }`, + height: toPix(o.height, o.simple ? 0 : 2), + width: toPix(c.width, c.border), + items: [ + { + text: `(${i18nText("BI-Less_Than")})`, + iconCls: "less-font", + value: 0, + }, + { + text: `(${i18nText("BI-Less_And_Equal")})`, + value: 1, + iconCls: "less-equal-font", + }, + ], + }); + if (o.closeMax === true) { + this.bigCombo.setValue(1); + } else { + this.bigCombo.setValue(0); + } + this.label = createWidget({ + type: Label.xtype, + text: i18nText("BI-Basic_Value"), + textHeight: o.height, + // width: toPix(o.width, o.simple ? 0 : c.border * 2), + hgap: 5, + height: o.height, + level: "warning", + tipType: "warning", + }); + this.left = createWidget({ + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + { + el: self.smallEditor, + }, + { + el: self.smallCombo, + }, + ], + }); + this.right = createWidget({ + type: HorizontalFillLayout.xtype, + columnSize: ["", "fill"], + items: [ + { + el: self.bigCombo, + }, + { + el: self.bigEditor, + // BI-23883 间距考虑边框 + // lgap: 1 + }, + ], + }); + + createWidget({ + element: self, + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: self.left, + }, + { + el: self.label, + }, + { + el: self.right, + }, + ], + }); + + // createWidget({ + // element: self, + // type: HorizontalAutoLayout.xtype, + // items: [ + // self.label + // ] + // }); + + // createWidget({ + // element: self, + // type: CenterLayout.xtype, + // hgap: 15, + // height: o.height, + // items: [ + // { + // type: AbsoluteLayout.xtype, + // items: [{ + // el: self.left, + // left: -15, + // right: 0, + // top: 0, + // bottom: 0 + // }] + // }, { + // type: AbsoluteLayout.xtype, + // items: [{ + // el: self.right, + // left: 0, + // right: -15, + // top: 0, + // bottom: 0 + // }] + // } + // ] + // }); + + self._setValidEvent(self.bigEditor, c.bigEditor); + self._setValidEvent(self.smallEditor, c.smallEditor); + self._setErrorEvent(self.bigEditor, c.bigEditor); + self._setErrorEvent(self.smallEditor, c.smallEditor); + self._setBlurEvent(self.bigEditor); + self._setBlurEvent(self.smallEditor); + self._setFocusEvent(self.bigEditor); + self._setFocusEvent(self.smallEditor); + self._setComboValueChangedEvent(self.bigCombo); + self._setComboValueChangedEvent(self.smallCombo); + self._setEditorValueChangedEvent(self.bigEditor); + self._setEditorValueChangedEvent(self.smallEditor); + + self._checkValidation(); + } + + _checkValidation() { + const self = this, + c = this.constants, + o = this.options; + self._setTitle(""); + Bubbles.hide(c.typeError); + Bubbles.hide(c.numberError); + Bubbles.hide(c.signalError); + if (!self.smallEditor.isValid() || !self.bigEditor.isValid()) { + self.element.removeClass("number-error"); + o.validation = "invalid"; + + return c.typeError; + } + if (isEmptyString(self.smallEditor.getValue()) || isEmptyString(self.bigEditor.getValue())) { + self.element.removeClass("number-error"); + o.validation = "valid"; + + return ""; + } + const smallValue = parseFloat(self.smallEditor.getValue()), + bigValue = parseFloat(self.bigEditor.getValue()), + bigComboValue = self.bigCombo.getValue(), + smallComboValue = self.smallCombo.getValue(); + if (bigComboValue[0] === c.less_equal && smallComboValue[0] === c.less_equal) { + if (smallValue > bigValue) { + self.element.addClass("number-error"); + o.validation = "invalid"; + + return c.numberError; + } + self.element.removeClass("number-error"); + o.validation = "valid"; + + return ""; + } + if (smallValue > bigValue) { + self.element.addClass("number-error"); + o.validation = "invalid"; + + return c.numberError; + } else if (smallValue === bigValue) { + self.element.addClass("number-error"); + o.validation = "invalid"; + + return c.signalError; + } + self.element.removeClass("number-error"); + o.validation = "valid"; + + return ""; + } + + _setTitle(v) { + this.label.setTitle(v); + } + + _setFocusEvent(w) { + const self = this, + c = this.constants; + w.on(NumberIntervalSingleEidtor.EVENT_FOCUS, () => { + self._setTitle(""); + switch (self._checkValidation()) { + case c.typeError: + Bubbles.show(c.typeError, i18nText("BI-Numerical_Interval_Input_Data"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + case c.numberError: + Bubbles.show(c.numberError, i18nText("BI-Numerical_Interval_Number_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + case c.signalError: + Bubbles.show(c.signalError, i18nText("BI-Numerical_Interval_Signal_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + default: + return; + } + }); + } + + _setBlurEvent(w) { + const c = this.constants, + self = this; + w.on(NumberIntervalSingleEidtor.EVENT_BLUR, () => { + Bubbles.hide(c.typeError); + Bubbles.hide(c.numberError); + Bubbles.hide(c.signalError); + switch (self._checkValidation()) { + case c.typeError: + self._setTitle(i18nText("BI-Numerical_Interval_Input_Data")); + break; + case c.numberError: + self._setTitle(i18nText("BI-Numerical_Interval_Number_Value")); + break; + case c.signalError: + self._setTitle(i18nText("BI-Numerical_Interval_Signal_Value")); + break; + default: + self._setTitle(""); + } + }); + } + + _setErrorEvent(w) { + const c = this.constants, + self = this; + w.on(NumberIntervalSingleEidtor.EVENT_ERROR, () => { + self._checkValidation(); + Bubbles.show(c.typeError, i18nText("BI-Numerical_Interval_Input_Data"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + self.fireEvent(NumberInterval.EVENT_ERROR); + }); + } + + _setValidEvent(w) { + const self = this, + c = this.constants; + w.on(NumberIntervalSingleEidtor.EVENT_VALID, () => { + switch (self._checkValidation()) { + case c.numberError: + Bubbles.show(c.numberError, i18nText("BI-Numerical_Interval_Number_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + self.fireEvent(NumberInterval.EVENT_ERROR); + break; + case c.signalError: + Bubbles.show(c.signalError, i18nText("BI-Numerical_Interval_Signal_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + self.fireEvent(NumberInterval.EVENT_ERROR); + break; + default: + self.fireEvent(NumberInterval.EVENT_VALID); + } + }); + } + + _setEditorValueChangedEvent(w) { + const self = this, + c = this.constants; + w.on(NumberIntervalSingleEidtor.EVENT_CHANGE, () => { + switch (self._checkValidation()) { + case c.typeError: + Bubbles.show(c.typeError, i18nText("BI-Numerical_Interval_Input_Data"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + case c.numberError: + Bubbles.show(c.numberError, i18nText("BI-Numerical_Interval_Number_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + case c.signalError: + Bubbles.show(c.signalError, i18nText("BI-Numerical_Interval_Signal_Value"), self, { + offsetStyle: "left", + adjustYOffset: c.adjustYOffset, + }); + break; + default: + break; + } + self.fireEvent(NumberInterval.EVENT_CHANGE); + }); + w.on(NumberIntervalSingleEidtor.EVENT_CONFIRM, () => { + self.fireEvent(NumberInterval.EVENT_CONFIRM); + }); + } + + _setComboValueChangedEvent(w) { + const self = this, + c = this.constants; + w.on(IconCombo.EVENT_CHANGE, () => { + switch (self._checkValidation()) { + case c.typeError: + self._setTitle(i18nText("BI-Numerical_Interval_Input_Data")); + self.fireEvent(NumberInterval.EVENT_ERROR); + break; + case c.numberError: + self._setTitle(i18nText("BI-Numerical_Interval_Number_Value")); + self.fireEvent(NumberInterval.EVENT_ERROR); + break; + case c.signalError: + self._setTitle(i18nText("BI-Numerical_Interval_Signal_Value")); + self.fireEvent(NumberInterval.EVENT_ERROR); + break; + default: + self.fireEvent(NumberInterval.EVENT_CHANGE); + self.fireEvent(NumberInterval.EVENT_CONFIRM); + self.fireEvent(NumberInterval.EVENT_VALID); + } + }); + } + + isStateValid() { + return this.options.validation === "valid"; + } + + setMinEnable(b) { + this.smallEditor.setEnable(b); + } + + setCloseMinEnable(b) { + this.smallCombo.setEnable(b); + } + + setMaxEnable(b) { + this.bigEditor.setEnable(b); + } + + setCloseMaxEnable(b) { + this.bigCombo.setEnable(b); + } + + showNumTip() { + this.smallTip.setVisible(true); + this.bigTip.setVisible(true); + } + + hideNumTip() { + this.smallTip.setVisible(false); + this.bigTip.setVisible(false); + } + + setNumTip(numTip) { + this.smallTip.setText(numTip); + this.bigTip.setText(numTip); + } + + getNumTip() { + return this.smallTip.getText(); + } + + setValue(data) { + data = data || {}; + const self = this; + let combo_value; + if (isNumeric(data.min) || isEmptyString(data.min)) { + self.smallEditor.setValue(data.min); + } + + if (!isNotNull(data.min)) { + self.smallEditor.setValue(""); + } + + if (isNumeric(data.max) || isEmptyString(data.max)) { + self.bigEditor.setValue(data.max); + } + + if (!isNotNull(data.max)) { + self.bigEditor.setValue(""); + } + + if (!isNull(data.closeMin)) { + if (data.closeMin === true) { + combo_value = 1; + } else { + combo_value = 0; + } + self.smallCombo.setValue(combo_value); + } + + if (!isNull(data.closeMax)) { + if (data.closeMax === true) { + combo_value = 1; + } else { + combo_value = 0; + } + self.bigCombo.setValue(combo_value); + } + + this._checkValidation(); + } + + getValue() { + const self = this, + value = {}, + minComboValue = self.smallCombo.getValue(), + maxComboValue = self.bigCombo.getValue(); + value.min = self.smallEditor.getValue(); + value.max = self.bigEditor.getValue(); + if (minComboValue[0] === 0) { + value.closeMin = false; + } else { + value.closeMin = true; + } + + if (maxComboValue[0] === 0) { + value.closeMax = false; + } else { + value.closeMax = true; + } + + return value; + } + + focusMinEditor() { + this.smallEditor.focus(); + } + + focusMaxEditor() { + this.bigEditor.focus(); + } + + destroyed() { + const c = this.constants; + Bubbles.remove(c.typeError); + Bubbles.remove(c.numberError); + Bubbles.remove(c.signalError); + } +} diff --git a/packages/fineui/src/widget/numberinterval/singleeditor/single.editor.js b/packages/fineui/src/widget/numberinterval/singleeditor/single.editor.js new file mode 100644 index 000000000..1e477b245 --- /dev/null +++ b/packages/fineui/src/widget/numberinterval/singleeditor/single.editor.js @@ -0,0 +1,105 @@ +import { shortcut, VerticalLayout } from "@/core"; +import { Single, Editor } from "@/base"; + +@shortcut() +export class NumberIntervalSingleEidtor extends Single { + static xtype = "bi.number_interval_single_editor"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + props = { + baseCls: "bi-number-interval-single-editor", + tipType: "success", + title: "", + }; + + render() { + const self = this, + o = this.options; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: Editor.xtype, + simple: o.simple, + ref(_ref) { + self.editor = _ref; + }, + height: o.height, + watermark: o.watermark, + allowBlank: o.allowBlank, + value: o.value, + quitChecker: o.quitChecker, + validationChecker: o.validationChecker, + listeners: [ + { + eventName: Editor.EVENT_ERROR, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_ERROR, arguments); + }, + }, + { + eventName: Editor.EVENT_FOCUS, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_FOCUS, arguments); + }, + }, + { + eventName: Editor.EVENT_BLUR, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_BLUR, arguments); + }, + }, + { + eventName: Editor.EVENT_VALID, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_VALID, arguments); + }, + }, + { + eventName: Editor.EVENT_CHANGE, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_CHANGE, arguments); + }, + }, + { + eventName: Editor.EVENT_CONFIRM, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_CONFIRM, arguments); + }, + }, + { + eventName: Editor.EVENT_CHANGE_CONFIRM, + action() { + self.fireEvent(NumberIntervalSingleEidtor.EVENT_CHANGE_CONFIRM, arguments); + }, + } + ], + } + ], + }; + } + + isValid() { + return this.editor.isValid(); + } + + getValue() { + return this.editor.getValue(); + } + + setValue(v) { + return this.editor.setValue(v); + } + + focus() { + this.editor.focus(); + } +} diff --git a/src/widget/searchmultitextvaluecombo/__test__/multitextvalue.combo.search.test.js b/packages/fineui/src/widget/searchmultitextvaluecombo/__test__/multitextvalue.combo.search.test.js similarity index 100% rename from src/widget/searchmultitextvaluecombo/__test__/multitextvalue.combo.search.test.js rename to packages/fineui/src/widget/searchmultitextvaluecombo/__test__/multitextvalue.combo.search.test.js diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/index.js b/packages/fineui/src/widget/searchmultitextvaluecombo/index.js new file mode 100644 index 000000000..24e5e4312 --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/index.js @@ -0,0 +1,5 @@ +export { SearchMultiTextValueCombo } from "./multitextvalue.combo.search"; +export { SearchMultiSelectPopupView } from "./multitextvalue.popup.view.search"; +export { SearchMultiSelectTrigger } from "./multitextvalue.combo.trigger.search"; +export { SearchMultiSelectLoader } from "./multitextvalue.loader.search"; +export { SearchMultiSelectSearcher } from "./trigger/searcher.multitextvalue"; diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js new file mode 100644 index 000000000..1b0919afa --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js @@ -0,0 +1,524 @@ +import { + shortcut, + extend, + isKey, + Selection, + remove, + pushDistinct, + deepClone, + createWidget, + toPix, + isNotNull, + last, + initial, + endWith, + bind, + nextTick, + AbsoluteLayout, + contains, + map, + makeObject, + each, + values, + isNull, + Func, + filter, + isNotEmptyArray, + isArray, + find, + BlankSplitChar, + SIZE_CONSANTS +} from "@/core"; +import { Single, Combo } from "@/base"; +import { MultiSelectBar, TriggerIconButton } from "@/case"; +import { MultiSelectTrigger } from "@/widget/multiselect/multiselect.trigger"; +import { MultiSelectPopupView } from "@/widget/multiselect/multiselect.popup.view"; +import { MultiSelectCombo } from "@/widget/multiselect/multiselect.combo"; +import { SearchMultiSelectTrigger } from "@/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search"; +import { SearchMultiSelectPopupView } from "@/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search"; + +@shortcut() +export class SearchMultiTextValueCombo extends Single { + static xtype = "bi.search_multi_text_value_combo"; + + static REQ_GET_DATA_LENGTH = 1; + static REQ_GET_ALL_DATA = -1; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-combo bi-search-multi-text-value-combo", + height: 24, + items: [], + }); + } + + _init() { + const o = this.options; + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button", + }); + super._init(...arguments); + const assertShowValue = () => { + isKey(this._startValue) && + (this.storeValue.type === Selection.All + ? remove(this.storeValue.value, this._startValue) + : pushDistinct(this.storeValue.value, this._startValue)); + this._updateAllValue(); + this._checkError(); + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }; + this.storeValue = deepClone(o.value || {}); + this._updateAllValue(); + + this._assertValue(this.storeValue); + this._checkError(); + + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: SearchMultiSelectTrigger.xtype, + text: o.text, + height: toPix(o.height, o.simple ? 1 : 2), + // adapter: this.popup, + masker: { + offset: { + left: 0, + top: 0, + right: 0, + bottom: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + }, + }, + allValueGetter: () => this.allValue, + valueFormatter: o.valueFormatter, + itemsCreator: (op, callback) => { + this._itemsCreator(op, (res, ...args) => { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + this.trigger.setValue(deepClone(this.getValue())); + } + + callback.apply(this, [res, ...args]); + }); + }, + value: this.storeValue, + warningTitle: o.warningTitle, + }); + + this.trigger.on(MultiSelectTrigger.EVENT_START, () => { + this._setStartValue(""); + this.trigger.getSearcher().setValue(this.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_STOP, () => { + this._setStartValue(""); + }); + this.trigger.on(MultiSelectTrigger.EVENT_SEARCHING, keywords => { + const _last = last(keywords); + keywords = initial(keywords || []); + if (keywords.length > 0) { + this._joinKeywords(keywords, () => { + if (endWith(_last, BlankSplitChar)) { + this.combo.setValue(this.storeValue); + assertShowValue(); + this.combo.populate(); + this._setStartValue(""); + } else { + this.combo.setValue(this.storeValue); + assertShowValue(); + } + this._dataChange = true; + }); + } + }); + + this.trigger.on(MultiSelectTrigger.EVENT_CHANGE, (value, obj) => { + if (obj instanceof MultiSelectBar) { + this._joinAll(this.getValue(), () => { + assertShowValue(); + }); + } else { + this._join(this.getValue(), () => { + assertShowValue(); + }); + } + this._dataChange = true; + }); + this.trigger.on(MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, () => { + this.trigger.getCounter().setValue(this.storeValue); + }); + this.trigger.on(MultiSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: SearchMultiSelectPopupView.xtype, + ref: _ref => { + this.popup = _ref; + this.trigger.setAdapter(_ref); + }, + listeners: [ + { + eventName: MultiSelectPopupView.EVENT_CHANGE, + action: () => { + this._dataChange = true; + this.storeValue = this.popup.getValue(); + this._adjust(() => { + assertShowValue(); + }); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CONFIRM, + action: () => { + this._defaultState(); + }, + }, + { + eventName: MultiSelectPopupView.EVENT_CLICK_CLEAR, + action: () => { + this._dataChange = true; + this.setValue(); + this._defaultState(); + }, + } + ], + itemsCreator: bind(this._itemsCreator, this), + valueFormatter: o.valueFormatter, + onLoaded: () => { + nextTick(() => { + this.combo.adjustWidth(); + this.combo.adjustHeight(); + this.trigger.getCounter().adjustView(); + this.trigger.getSearcher().adjustView(); + }); + }, + }, + value: o.value, + hideChecker: e => triggerBtn.element.find(e.target).length === 0, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + if (!this.combo.isViewVisible()) { + this._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(this.storeValue); + nextTick(() => { + this._populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + this.trigger.stopEditing(); + if (this.requesting === true) { + this.wants2Quit = true; + } else { + /** + * 在存在标红的情况,如果popover没有发生改变就确认需要同步trigger的值,否则对外value值和trigger样式不统一 + */ + assertShowValue(); + this._dataChange && this.fireEvent(SearchMultiTextValueCombo.EVENT_CONFIRM); + } + }); + + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + this.trigger.getCounter().hideView(); + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } else { + this.combo.showView(); + } + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + this._checkError(); + } + + _defaultState() { + this.trigger.stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) { + const o = this.options; + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + remove(val.value, (idx, value) => !contains(map(o.items, "value"), value)); + } + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const digest = items => { + const selectedMap = this._makeMap(items); + each(keywords, (i, val) => { + if (isNotNull(selectedMap[val])) { + this.storeValue.type === Selection.Multi + ? pushDistinct(this.storeValue.value, val) + : remove(this.storeValue.value, val); + } + }); + this._adjust(callback); + }; + + this._assertValue(this.storeValue); + this.requesting = true; + this._itemsCreator( + { + type: SearchMultiTextValueCombo.REQ_GET_ALL_DATA, + keywords, + }, + ob => { + const values = map(ob.items, "value"); + digest(values); + } + ); + } + + _joinAll(res, callback) { + this._assertValue(res); + this.requesting = true; + this._itemsCreator( + { + type: SearchMultiTextValueCombo.REQ_GET_ALL_DATA, + keywords: [this.trigger.getKey()], + }, + ob => { + const items = map(ob.items, "value"); + if (this.storeValue.type === res.type) { + let change = false; + const _map = this._makeMap(this.storeValue.value); + each(items, (i, v) => { + if (isNotNull(_map[v])) { + change = true; + this.storeValue.assist && this.storeValue.assist.push(_map[v]); + delete _map[v]; + } + }); + change && (this.storeValue.value = values(_map)); + this._adjust(callback); + + return; + } + const selectedMap = this._makeMap(this.storeValue.value); + const notSelectedMap = this._makeMap(res.value); + const newItems = []; + each(items, (i, item) => { + if (isNotNull(selectedMap[items[i]])) { + this.storeValue.assist && this.storeValue.assist.push(selectedMap[items[i]]); + delete selectedMap[items[i]]; + } + if (isNull(notSelectedMap[items[i]])) { + remove(this.storeValue.assist, item); + newItems.push(item); + } + }); + this.storeValue.value = newItems.concat(values(selectedMap)); + this._adjust(callback); + } + ); + } + + _adjust(callback) { + const adjust = () => { + if (this.storeValue.type === Selection.All && this.storeValue.value.length >= this._count) { + this.storeValue = { + type: Selection.Multi, + value: [], + }; + } else if (this.storeValue.type === Selection.Multi && this.storeValue.value.length >= this._count) { + this.storeValue = { + type: Selection.All, + value: [], + }; + } + this._updateAllValue(); + this._checkError(); + if (this.wants2Quit === true) { + this._dataChange && this.fireEvent(SearchMultiTextValueCombo.EVENT_CONFIRM); + this.wants2Quit = false; + } + this.requesting = false; + }; + if (!this._count) { + this._itemsCreator( + { + type: SearchMultiTextValueCombo.REQ_GET_DATA_LENGTH, + }, + res => { + this._count = res.count; + adjust(); + callback(); + } + ); + } else { + adjust(); + callback(); + } + } + + _join(res, callback) { + this._assertValue(res); + this._assertValue(this.storeValue); + if (this.storeValue.type === res.type) { + const map = this._makeMap(this.storeValue.value); + each(res.value, (i, v) => { + if (!map[v]) { + this.storeValue.value.push(v); + remove(this.storeValue.assist, v); + map[v] = v; + } + }); + let change = false; + each(res.assist, (i, v) => { + if (isNotNull(map[v])) { + change = true; + this.storeValue.assist && this.storeValue.assist.push(map[v]); + delete map[v]; + } + }); + change && (this.storeValue.value = values(map)); + this._adjust(callback); + + return; + } + this._joinAll(res, callback); + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + _getItemsByTimes(items, times) { + const res = []; + for (let i = (times - 1) * 100; items[i] && i < times * 100; i++) { + res.push(items[i]); + } + + return res; + } + + _hasNextByTimes(items, times) { + return times * 100 < items.length; + } + + _itemsCreator(options, callback) { + const o = this.options; + let items = o.items; + const keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + each(keywords, (i, kw) => { + const search = Func.getSearchResult(items, kw); + items = search.match.concat(search.find); + }); + if (options.selectedValues) { + // 过滤 + const _filter = makeObject(options.selectedValues, true); + items = filter(items, (i, ob) => !_filter[ob.value]); + } + if (options.type == MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items, + }); + + return; + } + if (options.type == MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({ count: items.length }); + + return; + } + callback({ + items: this._getItemsByTimes(items, options.times), + hasNext: this._hasNextByTimes(items, options.times), + }); + } + + _checkError() { + let v = this.storeValue.value || []; + if (isNotEmptyArray(v)) { + v = isArray(v) ? v : [v]; + const result = find(this.allValue, (idx, value) => !contains(v, value)); + if (isNull(result)) { + isNotNull(this.trigger) && this.trigger.setTipType("success"); + this.element.removeClass("combo-error"); + } else { + isNotNull(this.trigger) && this.trigger.setTipType("warning"); + this.element.addClass("combo-error"); + } + } else { + if (v.length === this.allValue.length) { + isNotNull(this.trigger) && this.trigger.setTipType("success"); + this.element.removeClass("combo-error"); + } else { + isNotNull(this.trigger) && this.trigger.setTipType("warning"); + this.element.addClass("combo-error"); + } + } + } + + _updateAllValue() { + this.storeValue = this.storeValue || {}; + this.allValue = deepClone(this.storeValue.value || []); + } + + setValue(v) { + this.storeValue = deepClone(v || {}); + this._updateAllValue(); + this._assertValue(this.storeValue); + this.combo.setValue(this.storeValue); + this._checkError(); + } + + getValue() { + return deepClone(this.storeValue); + } + + _populate() { + this._count = null; + this.combo.populate(); + } + + populate(items) { + this.options.items = items; + this._populate(); + } +} diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js new file mode 100644 index 000000000..1005412b7 --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js @@ -0,0 +1,171 @@ +import { + shortcut, + extend, + emptyFn, + createWidget, + Events, + nextTick, + HTapeLayout, + RightVerticalAdaptLayout +} from "@/core"; +import { Trigger } from "@/base"; +import { MultiSelectCheckSelectedSwitcher } from "@/widget/multiselect/trigger/switcher.checkselected"; +import { MultiSelectSearcher } from "@/widget/multiselect/trigger/searcher.multiselect"; +import { SearchMultiSelectSearcher } from "@/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue"; + +@shortcut() +export class SearchMultiSelectTrigger extends Trigger { + static xtype = "bi.search_multi_select_trigger"; + + constants = { height: 14, rgap: 4, lgap: 4 }; + + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-trigger", + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcher: {}, + switcher: {}, + + adapter: null, + masker: {}, + }); + } + + _init() { + super._init(...arguments); + + const o = this.options; + + this.searcher = createWidget(o.searcher, { + type: SearchMultiSelectSearcher.xtype, + height: o.height, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + allValueGetter: o.allValueGetter, + popup: {}, + adapter: o.adapter, + masker: o.masker, + value: o.value, + text: o.text, + tipType: o.tipType, + warningTitle: o.warningTitle, + }); + this.searcher.on(MultiSelectSearcher.EVENT_START, () => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_START); + }); + this.searcher.on(MultiSelectSearcher.EVENT_PAUSE, () => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_PAUSE); + }); + this.searcher.on(MultiSelectSearcher.EVENT_SEARCHING, (...args) => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_SEARCHING, ...args); + }); + this.searcher.on(MultiSelectSearcher.EVENT_STOP, () => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_STOP); + }); + this.searcher.on(MultiSelectSearcher.EVENT_CHANGE, (...args) => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_CHANGE, ...args); + }); + this.numberCounter = createWidget(o.switcher, { + type: MultiSelectCheckSelectedSwitcher.xtype, + valueFormatter: o.valueFormatter, + itemsCreator: o.itemsCreator, + adapter: o.adapter, + masker: o.masker, + value: o.value, + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, () => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_COUNTER_CLICK); + }); + this.numberCounter.on(MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, () => { + this.fireEvent(SearchMultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW); + }); + + const wrapNumberCounter = createWidget({ + type: RightVerticalAdaptLayout.xtype, + hgap: 4, + items: [ + { + el: this.numberCounter, + } + ], + }); + + const wrapper = createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: this.searcher, + width: "fill", + }, + { + el: wrapNumberCounter, + width: 0, + }, + { + el: createWidget(), + width: 24, + } + ], + }); + + this.numberCounter.on(Events.VIEW, b => { + nextTick(() => { + // 自动调整宽度 + wrapper.attr("items")[1].width = b === true ? this.numberCounter.element.outerWidth() + 8 : 0; + wrapper.resize(); + }); + }); + + this.element.click(e => { + if (this.element.find(e.target).length > 0) { + this.numberCounter.hideView(); + } + }); + } + + getCounter() { + return this.numberCounter; + } + + getSearcher() { + return this.searcher; + } + + stopEditing() { + this.searcher.stopSearch(); + this.numberCounter.hideView(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + this.numberCounter.setAdapter(adapter); + } + + setValue(ob) { + this.searcher.setValue(ob); + this.numberCounter.setValue(ob); + } + + setTipType(v) { + this.searcher.setTipType(v); + } + + getKey() { + return this.searcher.getKey(); + } + + getValue() { + return this.searcher.getValue(); + } +} diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js new file mode 100644 index 000000000..965208bac --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js @@ -0,0 +1,209 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + isKey, + Selection, + map, + contains, + remove, + pushDistinct, + Controller, + VerticalLayout, + createItems, + delay, + isNotNull, + SIZE_CONSANTS +} from "@/core"; +import { ButtonGroup, Loader } from "@/base"; +import { SelectList, MultiSelectBar, MultiSelectItem } from "@/case"; + +@shortcut() +export class SearchMultiSelectLoader extends Widget { + static xtype = "bi.search_multi_select_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-search-multi-select-loader", + logic: { + dynamic: true, + }, + el: { + height: 400, + }, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemHeight: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + onLoaded: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const opts = this.options; + let hasNext = false; + + this.storeValue = opts.value || {}; + this._assertValue(this.storeValue); + + this.button_group = createWidget({ + type: SelectList.xtype, + element: this, + logic: opts.logic, + toolbar: { + type: MultiSelectBar.xtype, + cls: "bi-list-item-active", + height: this.options.itemHeight, + iconWrapperWidth: 36, + }, + el: extend( + { + onLoaded: opts.onLoaded, + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + chooseType: ButtonGroup.CHOOSE_TYPE_MULTI, + behaviors: { + redmark: () => true, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + }, + opts.el + ), + itemsCreator: (op, callback) => { + const startValue = this._startValue; + this.storeValue && + (op = extend(op || {}, { + selectedValues: + isKey(startValue) && this.storeValue.type === Selection.Multi + ? this.storeValue.value.concat(startValue) + : this.storeValue.value, + })); + opts.itemsCreator(op, ob => { + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && this.storeValue) { + const json = map(this.storeValue.value, (i, v) => { + const txt = opts.valueFormatter(v) || v; + + return { + text: txt, + value: v, + title: txt, + selected: this.storeValue.type === Selection.Multi, + }; + }); + if (isKey(this._startValue) && !contains(this.storeValue.value, this._startValue)) { + const txt = opts.valueFormatter(startValue) || startValue; + json.unshift({ + text: txt, + value: startValue, + title: txt, + selected: true, + }); + } + firstItems = this._createItems(json); + } + + callback(firstItems.concat(this._createItems(ob.items)), ob.keyword || ""); + if (op.times === 1 && this.storeValue) { + isKey(startValue) && + (this.storeValue.type === Selection.All + ? remove(this.storeValue.value, startValue) + : pushDistinct(this.storeValue.value, startValue)); + this.setValue(this.storeValue); + } + op.times === 1 && this._scrollToTop(); + }); + }, + hasNext: () => hasNext, + value: this.storeValue, + }); + this.button_group.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.button_group.on(SelectList.EVENT_CHANGE, (...args) => { + this.fireEvent(SearchMultiSelectLoader.EVENT_CHANGE, ...args); + }); + } + + _createItems(items) { + return createItems(items, { + type: MultiSelectItem.xtype, + logic: this.options.logic, + cls: "bi-list-item-active", + height: this.options.itemHeight, + selected: this.isAllSelected(), + iconWrapperWidth: 36, + }); + } + + _scrollToTop() { + delay(() => { + this.button_group.element.scrollTop(0); + }, 30); + } + + isAllSelected() { + return this.button_group.isAllSelected(); + } + + _assertValue(val) { + val || (val = {}); + val.type || (val.type = Selection.Multi); + val.value || (val.value = []); + } + + setStartValue(v) { + this._startValue = v; + } + + setValue(v) { + this.storeValue = v || {}; + this._assertValue(this.storeValue); + this.button_group.setValue(this.storeValue); + } + + getValue() { + return this.button_group.getValue(); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + if (isNotNull(items)) { + arguments[0] = this._createItems(items); + } + this.button_group.populate(...arguments); + } + + resetHeight(h) { + this.button_group.resetHeight(h); + } + + resetWidth(w) { + this.button_group.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js new file mode 100644 index 000000000..9d6577f70 --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js @@ -0,0 +1,98 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, i18nText } from "@/core"; +import { MultiPopupView } from "@/case"; +import { SearchMultiSelectLoader } from "@/widget/searchmultitextvaluecombo/multitextvalue.loader.search"; + +@shortcut() +export class SearchMultiSelectPopupView extends Widget { + static xtype = "bi.search_multi_select_popup_view"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; + static EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-popup-view", + maxWidth: "auto", + minWidth: 135, + maxHeight: 400, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + onLoaded: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const opts = this.options; + + this.loader = createWidget({ + type: SearchMultiSelectLoader.xtype, + itemsCreator: opts.itemsCreator, + valueFormatter: opts.valueFormatter, + onLoaded: opts.onLoaded, + value: opts.value, + }); + + this.popupView = createWidget({ + type: MultiPopupView.xtype, + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + element: this, + buttons: [i18nText("BI-Basic_Clears"), i18nText("BI-Basic_OK")], + el: this.loader, + value: opts.value, + }); + + this.popupView.on(MultiPopupView.EVENT_CHANGE, () => { + this.fireEvent(SearchMultiSelectPopupView.EVENT_CHANGE); + }); + + this.popupView.on(MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, index => { + switch (index) { + case 0: + this.fireEvent(SearchMultiSelectPopupView.EVENT_CLICK_CLEAR); + break; + case 1: + this.fireEvent(SearchMultiSelectPopupView.EVENT_CLICK_CONFIRM); + break; + default: + break; + } + }); + } + + isAllSelected() { + return this.loader.isAllSelected(); + } + + setStartValue(v) { + this.loader.setStartValue(v); + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + populate(items) { + this.popupView.populate(...arguments); + } + + resetHeight(h) { + this.popupView.resetHeight(h); + } + + resetWidth(w) { + this.popupView.resetWidth(w); + } + + setDirection(direction, position) { + this.popupView.setDirection(direction, position); + } +} diff --git a/packages/fineui/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js b/packages/fineui/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js new file mode 100644 index 000000000..ff78e3646 --- /dev/null +++ b/packages/fineui/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js @@ -0,0 +1,180 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, isNotNull, Selection, size, each } from "@/core"; +import { Searcher } from "@/base"; +import { MultiSelectEditor } from "@/widget/multiselect/trigger/editor.multiselect"; +import { MultiSelectSearchPane } from "@/widget/multiselect/search/multiselect.search.pane"; + +@shortcut() +export class SearchMultiSelectSearcher extends Widget { + static xtype = "bi.search_multi_select_searcher"; + + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-multi-select-searcher", + itemsCreator: emptyFn, + el: {}, + popup: {}, + valueFormatter: emptyFn, + adapter: null, + masker: {}, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget(o.el, { + type: MultiSelectEditor.xtype, + height: o.height, + text: o.text, + tipType: o.tipType, + warningTitle: o.warningTitle, + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + height: o.height, + isAutoSearch: false, + isAutoSync: false, + onSearch: (op, callback) => { + callback(); + }, + el: this.editor, + + popup: extend( + { + type: MultiSelectSearchPane.xtype, + valueFormatter: o.valueFormatter, + keywordGetter: () => this.editor.getValue(), + itemsCreator: (op, callback) => { + const keyword = this.editor.getValue(); + op.keywords = [keyword]; + o.itemsCreator(op, callback); + }, + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + this.fireEvent(SearchMultiSelectSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + this.fireEvent(SearchMultiSelectSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + this.fireEvent(SearchMultiSelectSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, (...args) => { + this.fireEvent(SearchMultiSelectSearcher.EVENT_CHANGE, ...args); + }); + this.searcher.on(Searcher.EVENT_SEARCHING, () => { + const keywords = this.searcher.getKeywords(); + this.fireEvent(SearchMultiSelectSearcher.EVENT_SEARCHING, keywords); + }); + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + adjustView() { + this.searcher.adjustView(); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeyword() { + return this.editor.getValue(); + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setState(obj) { + let state; + const o = this.options; + const ob = {}; + ob.type = obj.type; + ob.value = o.allValueGetter() || []; + ob.assist = obj.assist; + if (ob.type === Selection.All) { + if (ob.value.length === 0) { + this.editor.setState(Selection.All); + } else if (size(ob.assist) <= 20) { + state = ""; + each(ob.assist, (i, v) => { + if (i === 0) { + state += `${o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } else { + if (ob.value.length === 0) { + this.editor.setState(Selection.None); + } else if (size(ob.value) <= 20) { + state = ""; + each(ob.value, (i, v) => { + if (i === 0) { + state += `${o.valueFormatter(`${v}`) || v}`; + } else { + state += `,${o.valueFormatter(`${v}`) || v}`; + } + }); + this.editor.setState(state); + } else { + this.editor.setState(Selection.Multi); + } + } + } + + setTipType(v) { + this.editor.setTipType(v); + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(...items) { + this.searcher.populate(items); + } +} diff --git a/src/widget/selecttree/__test__/selecttree.combo.test.js b/packages/fineui/src/widget/selecttree/__test__/selecttree.combo.test.js similarity index 100% rename from src/widget/selecttree/__test__/selecttree.combo.test.js rename to packages/fineui/src/widget/selecttree/__test__/selecttree.combo.test.js diff --git a/packages/fineui/src/widget/selecttree/selecttree.combo.js b/packages/fineui/src/widget/selecttree/selecttree.combo.js new file mode 100644 index 000000000..506025c22 --- /dev/null +++ b/packages/fineui/src/widget/selecttree/selecttree.combo.js @@ -0,0 +1,130 @@ +import { + shortcut, + Widget, + extend, + createWidget, + Controller, + contains, + isArray, + toPix, + isKey, + isEmptyArray, + isEmptyString, + find, + isNull +} from "@/core"; +import { Combo } from "@/base"; +import { SingleTreeTrigger } from "@/widget/singletree/singletree.trigger"; +import { SelectTreePopup } from "./selecttree.popup"; + +/** + * @class SelectTreeCombo + * @extends Widget + */ + +@shortcut() +export class SelectTreeCombo extends Widget { + static xtype = "bi.select_tree_combo"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-tree-combo bi-border bi-border-radius", + height: 24, + text: "", + items: [], + value: "", + allowClear: false, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + + this.trigger = createWidget({ + type: SingleTreeTrigger.xtype, + text: o.text, + height: toPix(o.height, 2), + items: o.items, + value: o.value, + allowClear: o.allowClear, + warningTitle: o.warningTitle, + }); + + this.trigger.on(SingleTreeTrigger.EVENT_CLEAR, () => { + this._clear(); + }); + + this.popup = createWidget({ + type: SelectTreePopup.xtype, + items: o.items, + value: o.value, + }); + + this.combo = createWidget({ + type: Combo.xtype, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + container: o.container, + element: this, + adjustLength: 2, + el: this.trigger, + popup: { + el: this.popup, + }, + }); + + this.combo.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.popup.on(SelectTreePopup.EVENT_CHANGE, () => { + self.setValue(self.popup.getValue()); + self.combo.hideView(); + }); + + if (isKey(o.value)) { + this._checkError(o.value); + } + } + + _checkError(v) { + if (isNull(v) || isEmptyArray(v) || isEmptyString(v)) { + this.trigger.options.tipType = "success"; + this.trigger.element.removeClass("error"); + this.element.removeClass("error"); + } else { + v = isArray(v) ? v : [v]; + const result = find(this.options.items, (idx, item) => contains(v, item.value)); + if (isNull(result)) { + this.trigger.setTipType("warning"); + this.element.removeClass("error").addClass("error"); + this.trigger.element.removeClass("error").addClass("error"); + } else { + this.trigger.setTipType("success"); + this.trigger.element.removeClass("error"); + this.element.removeClass("error"); + } + } + } + + _clear() { + this.setValue([]); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.trigger.setValue(v); + this.popup.setValue(v); + this._checkError(v); + } + + getValue() { + return this.popup.getValue(); + } + + populate(items) { + this.combo.populate(items); + } +} diff --git a/packages/fineui/src/widget/selecttree/selecttree.expander.js b/packages/fineui/src/widget/selecttree/selecttree.expander.js new file mode 100644 index 000000000..85b027110 --- /dev/null +++ b/packages/fineui/src/widget/selecttree/selecttree.expander.js @@ -0,0 +1,78 @@ +import { shortcut, Widget, extend, createWidget, Controller, Events, contains } from "@/core"; +import { Expander } from "@/base"; + +@shortcut() +export class SelectTreeExpander extends Widget { + static xtype = "bi.select_tree_expander"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-tree-expander", + trigger: "", + toggle: true, + direction: "bottom", + isDefaultInit: true, + el: {}, + popup: {}, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.trigger = createWidget(o.el); + this.trigger.on(Controller.EVENT_CHANGE, function (type) { + if (type === Events.CLICK) { + if (this.isSelected()) { + self.expander.setValue([]); + } + } + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.expander = createWidget({ + type: Expander.xtype, + element: this, + trigger: o.trigger, + toggle: o.toggle, + direction: o.direction, + isDefaultInit: o.isDefaultInit, + el: this.trigger, + popup: o.popup, + }); + this.expander.on(Controller.EVENT_CHANGE, function (type) { + if (type === Events.CLICK) { + self.trigger.setSelected(false); + } + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + } + + getAllLeaves() { + return this.expander.getAllLeaves(); + } + + setValue(v) { + if (contains(v, this.trigger.getValue())) { + this.trigger.setSelected(true); + this.expander.setValue([]); + } else { + this.trigger.setSelected(false); + this.expander.setValue(v); + } + } + + getValue() { + if (this.trigger.isSelected()) { + return [this.trigger.getValue()]; + } + + return this.expander.getValue(); + } + + populate(items) { + this.expander.populate(items); + } +} diff --git a/packages/fineui/src/widget/selecttree/selecttree.popup.js b/packages/fineui/src/widget/selecttree/selecttree.popup.js new file mode 100644 index 000000000..1356a995b --- /dev/null +++ b/packages/fineui/src/widget/selecttree/selecttree.popup.js @@ -0,0 +1,109 @@ +import { + shortcut, + extend, + i18nText, + each, + createWidget, + Controller, + isArray, + isNotEmptyArray, + UUID, + defaults, + Tree, + VerticalLayout, + SIZE_CONSANTS +} from "@/core"; +import { Pane } from "@/base"; +import { BasicTreeItem, BasicTreeNode, LevelTree, TreeExpander } from "@/case"; + +@shortcut() +export class SelectTreePopup extends Pane { + static xtype = "bi.select_level_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-level-tree", + tipText: i18nText("BI-No_Selected_Item"), + items: [], + value: "", + }); + } + + _formatItems(nodes, layer, pNode) { + const self = this; + each(nodes, (i, node) => { + const extend = { + layer, + isFirstNode: i === 0, + isLastNode: i === nodes.length - 1, + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + pNode, + }; + node.id = node.id || UUID(); + + if (node.isParent === true || node.parent === true || isNotEmptyArray(node.children)) { + extend.type = BasicTreeNode.xtype; + extend.selectable = true; + defaults(node, extend); + self._formatItems(node.children, layer + 1, node); + } else { + extend.type = BasicTreeItem.xtype; + defaults(node, extend); + } + }); + + return nodes; + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.tree = createWidget({ + type: LevelTree.xtype, + expander: { + type: TreeExpander.xtype, + // isDefaultInit: true, + selectable: true, + }, + items: this._formatItems(Tree.transformToTreeFormat(o.items), 0), + value: o.value, + chooseType: Selection.Single, + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + vgap: 5, + items: [this.tree], + }); + + this.tree.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.tree.on(LevelTree.EVENT_CHANGE, () => { + self.fireEvent(SelectTreePopup.EVENT_CHANGE); + }); + + this.check(); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + super.populate(...arguments); + this.tree.populate(this._formatItems(Tree.transformToTreeFormat(items))); + } +} diff --git a/src/widget/singleselect/__test__/singleselect.combo.test.js b/packages/fineui/src/widget/singleselect/__test__/singleselect.combo.test.js similarity index 100% rename from src/widget/singleselect/__test__/singleselect.combo.test.js rename to packages/fineui/src/widget/singleselect/__test__/singleselect.combo.test.js diff --git a/src/widget/singleselect/__test__/singleselect.insert.combo.test.js b/packages/fineui/src/widget/singleselect/__test__/singleselect.insert.combo.test.js similarity index 100% rename from src/widget/singleselect/__test__/singleselect.insert.combo.test.js rename to packages/fineui/src/widget/singleselect/__test__/singleselect.insert.combo.test.js diff --git a/packages/fineui/src/widget/singleselect/index.js b/packages/fineui/src/widget/singleselect/index.js new file mode 100644 index 000000000..7e3f4cd04 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/index.js @@ -0,0 +1,9 @@ +export { SingleSelectCombo } from "./singleselect.combo"; +export { SingleSelectInsertCombo } from "./singleselect.insert.combo"; +export { SingleSelectList } from "./singleselect.list"; +export { SingleSelectLoader } from "./singleselect.loader"; +export { SingleSelectPopupView } from "./singleselect.popup.view"; +export { SingleSelectTrigger } from "./singleselect.trigger"; +export { SingleSelectInsertList } from "./singleselectlist.insert"; +export * from "./trigger"; +export * from "./search"; diff --git a/packages/fineui/src/widget/singleselect/search/index.js b/packages/fineui/src/widget/singleselect/search/index.js new file mode 100644 index 000000000..70c02c573 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/search/index.js @@ -0,0 +1,3 @@ +export { SingleSelectSearchLoader } from "./singleselect.search.loader"; +export { SingleSelectSearchPane } from "./singleselect.search.pane"; +export { SingleSelectSearchInsertPane } from "./singleselect.search.pane.insert"; diff --git a/packages/fineui/src/widget/singleselect/search/singleselect.search.loader.js b/packages/fineui/src/widget/singleselect/search/singleselect.search.loader.js new file mode 100644 index 000000000..0eb7009a5 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/search/singleselect.search.loader.js @@ -0,0 +1,187 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + i18nText, + isUndefined, + Controller, + VerticalLayout, + map, + isArray, + isKey, + Func, + SIZE_CONSANTS +} from "@/core"; +import { ButtonGroup, Loader } from "@/base"; +import { SingleSelectList } from "../singleselect.list"; +import { SingleSelectItem, SingleSelectRadioItem } from "@/case"; + +@shortcut() +export class SingleSelectSearchLoader extends Widget { + static xtype = "bi.single_select_search_loader"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-search-loader", + allowNoSelect: false, + logic: { + dynamic: false, + }, + itemsCreator: emptyFn, + keywordGetter: emptyFn, + valueFormatter: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + let hasNext = false; + + this.button_group = createWidget({ + type: SingleSelectList.xtype, + allowNoSelect: opts.allowNoSelect, + element: this, + logic: { + dynamic: false, + }, + value: opts.value, + el: { + tipText: i18nText("BI-No_Select"), + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + }, + itemsCreator(op, callback) { + self.storeValue && + (op = extend(op || {}, { + selectedValues: [self.storeValue], + })); + opts.itemsCreator(op, ob => { + const keyword = (ob.keyword = opts.keywordGetter()); + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && !isUndefined(self.storeValue)) { + const json = self._filterValues(self.storeValue); + firstItems = self._createItems(json); + } + const context = { + tipText: ob.tipText, + }; + callback(firstItems.concat(self._createItems(ob.items)), keyword || "", context); + if (op.times === 1 && self.storeValue) { + self.setValue(self.storeValue); + } + }); + }, + hasNext() { + return hasNext; + }, + }); + this.button_group.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.button_group.on(SingleSelectList.EVENT_CHANGE, function () { + self.fireEvent(SingleSelectSearchLoader.EVENT_CHANGE, arguments); + }); + } + + _createItems(items) { + const o = this.options; + + return map(items, (i, item) => + extend( + { + type: o.allowNoSelect ? SingleSelectItem.xtype : SingleSelectRadioItem.xtype, + logic: o.logic, + cls: "bi-list-item-active", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + selected: false, + iconWrapperWidth: 26, + hgap: o.allowNoSelect ? 10 : 0, + title: item.title || item.text, + }, + item + ) + ); + } + + _filterValues(src) { + const o = this.options; + const keyword = o.keywordGetter(); + let values = src || []; + const newValues = map(isArray(values) ? values : [values], (i, v) => { + return { + text: o.valueFormatter(v) || v, + value: v, + }; + }); + if (isKey(keyword)) { + const search = Func.getSearchResult(newValues, keyword); + values = search.match.concat(search.find); + } + + return map(values, (i, v) => { + return { + text: v.text, + title: v.text, + value: v.value, + selected: false, + }; + }); + } + + setValue(v) { + // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 + this.storeValue = v; + this.button_group.setValue(v); + } + + getValue() { + return this.button_group.getValue(); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + this.button_group.populate(...arguments); + } + + resetHeight(h) { + this.button_group.resetHeight(h); + } + + resetWidth(w) { + this.button_group.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.insert.js b/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.insert.js new file mode 100644 index 000000000..e2940fff5 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.insert.js @@ -0,0 +1,106 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + i18nText, + Controller, + VerticalFillLayout, + VerticalLayout +} from "@/core"; +import { Label } from "@/base"; +import { SingleSelectSearchLoader } from "./singleselect.search.loader"; + +@shortcut() +export class SingleSelectSearchInsertPane extends Widget { + static xtype = "bi.single_select_search_insert_pane"; + + constants = { height: 25, lgap: 10, tgap: 5 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-search-pane-insert bi-card", + allowNoSelect: false, + itemsCreator: emptyFn, + valueFormatter: emptyFn, + keywordGetter: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.addNotMatchTip = createWidget({ + type: Label.xtype, + text: i18nText("BI-Basic_Press_Enter_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-keyword-red-mark", + hgap: 5, + }); + + this.loader = createWidget({ + type: SingleSelectSearchLoader.xtype, + allowNoSelect: o.allowNoSelect, + keywordGetter: o.keywordGetter, + valueFormatter: o.valueFormatter, + itemsCreator(op, callback) { + o.itemsCreator.apply(self, [ + op, + function (res) { + callback(res); + self.setKeyword(o.keywordGetter()); + } + ]); + }, + value: o.value, + }); + this.loader.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.resizer = createWidget({ + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + element: this, + items: [ + { + type: VerticalLayout.xtype, + items: [this.addNotMatchTip], + height: this.constants.height, + }, + { + el: this.loader, + } + ], + }); + } + + setKeyword(keyword) { + this.addNotMatchTip.setText(i18nText("BI-Basic_Press_Enter_To_Add_Text", keyword)); + } + + hasMatched() { + return false; + } + + setValue(v) { + this.loader.setValue(v); + } + + getValue() { + return this.loader.getValue(); + } + + empty() { + this.loader.empty(); + } + + populate(items) { + this.loader.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.js b/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.js new file mode 100644 index 000000000..8075c2917 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/search/singleselect.search.pane.js @@ -0,0 +1,105 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, i18nText, Controller, VerticalFillLayout } from "@/core"; +import { Label } from "@/base"; +import { SingleSelectSearchLoader } from "./singleselect.search.loader"; + +@shortcut() +export class SingleSelectSearchPane extends Widget { + static xtype = "bi.single_select_search_pane"; + + constants = { height: 25, lgap: 10, tgap: 5 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-search-pane bi-card", + allowNoSelect: false, + itemsCreator: emptyFn, + valueFormatter: emptyFn, + keywordGetter: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.tooltipClick = createWidget({ + type: Label.xtype, + invisible: true, + text: i18nText("BI-Click_Blank_To_Select"), + cls: "single-select-toolbar", + height: this.constants.height, + }); + + this.loader = createWidget({ + type: SingleSelectSearchLoader.xtype, + allowNoSelect: o.allowNoSelect, + keywordGetter: o.keywordGetter, + valueFormatter: o.valueFormatter, + itemsCreator(op, callback) { + o.itemsCreator.apply(self, [ + op, + function (res) { + callback(res); + self.setKeyword(o.keywordGetter()); + } + ]); + }, + value: o.value, + }); + this.loader.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.resizer = createWidget({ + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + element: this, + items: [ + { + el: this.tooltipClick, + }, + { + el: this.loader, + } + ], + }); + this.tooltipClick.setVisible(false); + } + + setKeyword(keyword) { + let btn; + const o = this.options; + const isVisible = + this.loader.getAllButtons().length > 0 && + (btn = this.loader.getAllButtons()[0]) && + keyword === (o.valueFormatter(btn.getValue()) || btn.getValue()); + if (isVisible !== this.tooltipClick.isVisible()) { + this.tooltipClick.setVisible(isVisible); + this.resizer.attr("items")[0].height = isVisible ? this.constants.height : 0; + this.resizer.resize(); + } + } + + hasMatched() { + return this.tooltipClick.isVisible(); + } + + setValue(v) { + this.loader.setValue(v); + } + + getValue() { + return this.loader.getValue(); + } + + empty() { + this.loader.empty(); + } + + populate(items) { + this.loader.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.combo.js b/packages/fineui/src/widget/singleselect/singleselect.combo.js new file mode 100644 index 000000000..a5369e4f7 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.combo.js @@ -0,0 +1,293 @@ +import { + shortcut, + extend, + emptyFn, + isKey, + createWidget, + toPix, + isNotNull, + nextTick, + AbsoluteLayout, + makeObject, + map, + each, + remove +} from "@/core"; +import { Single, Combo } from "@/base"; +import { SingleSelectTrigger } from "./singleselect.trigger"; +import { SingleSelectPopupView } from "./singleselect.popup.view"; +import { TriggerIconButton } from "@/case"; + +@shortcut() +export class SingleSelectCombo extends Single { + static xtype = "bi.single_select_combo"; + + static REQ_GET_DATA_LENGTH = 0; + static REQ_GET_ALL_DATA = -1; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-combo", + allowNoSelect: false, + itemsCreator: emptyFn, + itemWrapper: emptyFn, + valueFormatter: emptyFn, + height: 24, + allowEdit: true, + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + + const assertShowValue = () => { + isKey(this._startValue) && (this.storeValue = this._startValue); + this.trigger.getSearcher().setState(this.storeValue); + }; + this.storeValue = o.value; + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: SingleSelectTrigger.xtype, + height: toPix(o.height, o.simple ? 1 : 2), + // adapter: this.popup, + allowNoSelect: o.allowNoSelect, + allowEdit: o.allowEdit, + valueFormatter: o.valueFormatter, + itemsCreator: (op, callback) => { + o.itemsCreator(op, (...args) => { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + this.trigger.setValue(this.getValue()); + } + callback.apply(this, args); + }); + }, + text: o.text, + value: this.storeValue, + }); + + this.trigger.on(SingleSelectTrigger.EVENT_FOCUS, () => { + this.fireEvent(SingleSelectCombo.EVENT_FOCUS); + }); + this.trigger.on(SingleSelectTrigger.EVENT_BLUR, () => { + this.fireEvent(SingleSelectCombo.EVENT_BLUR); + }); + + this.trigger.on(SingleSelectTrigger.EVENT_START, () => { + this._setStartValue(); + this.trigger.getSearcher().setValue(this.storeValue); + }); + this.trigger.on(SingleSelectTrigger.EVENT_STOP, () => { + this._setStartValue(); + this.fireEvent(SingleSelectCombo.EVENT_STOP); + }); + this.trigger.on(SingleSelectTrigger.EVENT_SEARCHING, () => { + this._dataChange = true; + this.fireEvent(SingleSelectCombo.EVENT_SEARCHING); + }); + + this.trigger.on(SingleSelectTrigger.EVENT_CHANGE, (value, obj) => { + this.storeValue = this.trigger.getValue(); + assertShowValue(); + this._defaultState(); + this._dataChange = true; + }); + this.trigger.on(SingleSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + container: o.container, + toggle: false, + el: this.trigger, + adjustLength: 1, + popup: { + type: SingleSelectPopupView.xtype, + allowNoSelect: o.allowNoSelect, + ref: _ref => { + this.popup = _ref; + this.trigger.setAdapter(_ref); + }, + listeners: [ + { + eventName: SingleSelectPopupView.EVENT_CHANGE, + action: () => { + this._dataChange = true; + this.storeValue = this.popup.getValue(); + this._adjust(() => { + assertShowValue(); + this._defaultState(); + }); + this.fireEvent(SingleSelectCombo.EVENT_CLICK_ITEM); + }, + } + ], + itemsCreator: o.itemsCreator, + itemWrapper: o.itemWrapper, + valueFormatter: o.valueFormatter, + onLoaded: () => { + nextTick(() => { + this.combo.adjustWidth(); + this.combo.adjustHeight(); + this.trigger.getSearcher().adjustView(); + }); + }, + }, + hideChecker(e) { + return triggerBtn.element.find(e.target).length === 0; + }, + value: o.value, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + if (!this.combo.isViewVisible()) { + this._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(this.storeValue); + nextTick(() => { + this.populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + this.trigger.stopEditing(); + if (this.requesting === true) { + this.wants2Quit = true; + } else { + this._dataChange && this.fireEvent(SingleSelectCombo.EVENT_CONFIRM); + } + }); + + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "single-select-trigger-icon-button", + }); + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } else { + this.combo.showView(); + } + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + } + + _defaultState() { + this.trigger.stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) {} + + _makeMap(values) { + return makeObject(values || []); + } + + _joinKeywords(keywords, callback) { + const o = this.options; + this._assertValue(this.storeValue); + this.requesting = true; + o.itemsCreator( + { + type: SingleSelectCombo.REQ_GET_ALL_DATA, + keywords, + }, + ob => { + const values = map(ob.items, "value"); + digest(values); + } + ); + + const digest = items => { + const selectedMap = this._makeMap(items); + each(keywords, (i, val) => { + if (isNotNull(selectedMap[val])) { + remove(this.storeValue.value, val); + } + }); + this._adjust(callback); + }; + } + + _adjust(callback) { + const adjust = () => { + if (this.wants2Quit === true) { + this._dataChange && this.fireEvent(SingleSelectCombo.EVENT_CONFIRM); + this.wants2Quit = false; + } + this.requesting = false; + }; + + const o = this.options; + if (!this._count) { + o.itemsCreator( + { + type: SingleSelectCombo.REQ_GET_DATA_LENGTH, + }, + res => { + this._count = res.count; + adjust(); + callback(); + } + ); + } else { + adjust(); + callback(); + } + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + setValue(v) { + this.storeValue = v; + this._assertValue(this.storeValue); + this.combo.setValue(this.storeValue); + } + + getValue() { + return this.storeValue; + } + + populate() { + this._count = null; + this.combo.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.insert.combo.js b/packages/fineui/src/widget/singleselect/singleselect.insert.combo.js new file mode 100644 index 000000000..eb528ec7a --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.insert.combo.js @@ -0,0 +1,264 @@ +import { SingleSelectSearchInsertPane } from "./search"; +import { + shortcut, + extend, + emptyFn, + i18nText, + isKey, + createWidget, + toPix, + isNotNull, + nextTick, + AbsoluteLayout, + makeObject +} from "@/core"; +import { Single, Combo } from "@/base"; +import { SingleSelectTrigger } from "./singleselect.trigger"; +import { SingleSelectPopupView } from "./singleselect.popup.view"; +import { TriggerIconButton } from "@/case"; + +@shortcut() +export class SingleSelectInsertCombo extends Single { + static xtype = "bi.single_select_insert_combo"; + + static REQ_GET_DATA_LENGTH = 0; + static REQ_GET_ALL_DATA = -1; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-combo", + allowNoSelect: false, + itemsCreator: emptyFn, + itemWrapper: emptyFn, + valueFormatter: emptyFn, + height: 24, + allowEdit: true, + watermark: i18nText("BI-Basic_Search_And_Patch_Paste"), + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + const assertShowValue = () => { + isKey(this._startValue) && (this.storeValue = this._startValue); + this.trigger.getSearcher().setState(this.storeValue); + }; + this.storeValue = o.value; + // 标记正在请求数据 + this.requesting = false; + + this.trigger = createWidget({ + type: SingleSelectTrigger.xtype, + watermark: o.watermark, + height: toPix(o.height, o.simple ? 1 : 2), + allowNoSelect: o.allowNoSelect, + allowEdit: o.allowEdit, + // adapter: this.popup, + valueFormatter: o.valueFormatter, + itemsCreator(op, callback) { + o.itemsCreator(op, function (res) { + if (op.times === 1 && isNotNull(op.keywords)) { + // 预防trigger内部把当前的storeValue改掉 + self.trigger.setValue(self.getValue()); + } + callback.apply(self, arguments); + }); + }, + text: o.text, + value: this.storeValue, + searcher: { + popup: { + type: SingleSelectSearchInsertPane.xtype, + }, + }, + }); + + this.trigger.on(SingleSelectTrigger.EVENT_FOCUS, () => { + self.fireEvent(SingleSelectInsertCombo.EVENT_FOCUS); + }); + this.trigger.on(SingleSelectTrigger.EVENT_BLUR, () => { + self.fireEvent(SingleSelectInsertCombo.EVENT_BLUR); + }); + + this.trigger.on(SingleSelectTrigger.EVENT_START, function () { + self._setStartValue(); + this.getSearcher().setValue(self.storeValue); + }); + this.trigger.on(SingleSelectTrigger.EVENT_STOP, () => { + self._setStartValue(); + self.fireEvent(SingleSelectInsertCombo.EVENT_STOP); + }); + this.trigger.on(SingleSelectTrigger.EVENT_PAUSE, () => { + self.storeValue = self.trigger.getSearcher().getKeyword(); + assertShowValue(); + self._defaultState(); + }); + this.trigger.on(SingleSelectTrigger.EVENT_SEARCHING, () => { + self._dataChange = true; + self.fireEvent(SingleSelectInsertCombo.EVENT_SEARCHING); + }); + + this.trigger.on(SingleSelectTrigger.EVENT_CHANGE, function (value, obj) { + self.storeValue = this.getValue(); + assertShowValue(); + self._defaultState(); + self._dataChange = true; + }); + this.trigger.on(SingleSelectTrigger.EVENT_COUNTER_CLICK, () => { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.combo = createWidget({ + type: Combo.xtype, + cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", + container: o.container, + toggle: false, + el: this.trigger, + adjustLength: 1, + popup: { + type: SingleSelectPopupView.xtype, + allowNoSelect: o.allowNoSelect, + ref() { + self.popup = this; + self.trigger.setAdapter(this); + }, + listeners: [ + { + eventName: SingleSelectPopupView.EVENT_CHANGE, + action() { + self._dataChange = true; + self.storeValue = this.getValue(); + self._adjust(() => { + assertShowValue(); + self._defaultState(); + }); + self.fireEvent(SingleSelectInsertCombo.EVENT_CLICK_ITEM); + }, + } + ], + itemsCreator: o.itemsCreator, + itemWrapper: o.itemWrapper, + valueFormatter: o.valueFormatter, + onLoaded() { + nextTick(() => { + self.combo.adjustWidth(); + self.combo.adjustHeight(); + self.trigger.getSearcher().adjustView(); + }); + }, + }, + hideChecker(e) { + return triggerBtn.element.find(e.target).length === 0; + }, + value: o.value, + }); + + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (!this.isViewVisible()) { + self._dataChange = false; // 标记数据是否发生变化 + } + this.setValue(self.storeValue); + nextTick(() => { + self.populate(); + }); + }); + // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 + this.wants2Quit = false; + this.combo.on(Combo.EVENT_AFTER_HIDEVIEW, () => { + // important:关闭弹出时又可能没有退出编辑状态 + self.trigger.stopEditing(); + if (self.requesting === true) { + self.wants2Quit = true; + } else { + self._dataChange && self.fireEvent(SingleSelectInsertCombo.EVENT_CONFIRM); + } + }); + + const triggerBtn = createWidget({ + type: TriggerIconButton.xtype, + width: o.height, + height: o.height, + cls: "single-select-trigger-icon-button", + }); + triggerBtn.on(TriggerIconButton.EVENT_CHANGE, () => { + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + } + + _defaultState() { + this.trigger.stopEditing(); + this.combo.hideView(); + } + + _assertValue(val) {} + + _makeMap(values) { + return makeObject(values || []); + } + + _adjust(callback) { + const self = this; + adjust(); + callback(); + + function adjust() { + if (self.wants2Quit === true) { + self._dataChange && self.fireEvent(SingleSelectInsertCombo.EVENT_CONFIRM); + self.wants2Quit = false; + } + self.requesting = false; + } + } + + _setStartValue(value) { + this._startValue = value; + this.popup.setStartValue(value); + } + + setValue(v) { + this.storeValue = v; + this._assertValue(this.storeValue); + this.combo.setValue(this.storeValue); + } + + getValue() { + return this.storeValue; + } + + populate() { + this.combo.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.list.js b/packages/fineui/src/widget/singleselect/singleselect.list.js new file mode 100644 index 000000000..e29f6e976 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.list.js @@ -0,0 +1,183 @@ +import { shortcut, Widget, extend, emptyFn, createWidget, Controller, Events, i18nText, Direction, LogicFactory, pixFormat } from "@/core"; +import { ListPane, SingleSelectItem } from "@/case"; + +@shortcut() +export class SingleSelectList extends Widget { + static xtype = "bi.single_select_list"; + + _constants = { itemHeight: 24 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-select-list", + direction: Direction.Top, // toolbar的位置 + logic: { + dynamic: true, + }, + items: [], + itemsCreator: emptyFn, + hasNext: emptyFn, + onLoaded: emptyFn, + el: { + type: ListPane.xtype, + }, + allowNoSelect: false, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + + this.list = createWidget(o.el, { + type: ListPane.xtype, + items: o.items, + itemsCreator(op, callback) { + op.times === 1 && self.toolbar && self.toolbar.setVisible(false); + o.itemsCreator(op, function (items) { + callback.apply(self, arguments); + if (op.times === 1) { + self.toolbar && self.toolbar.setVisible(items && items.length > 0); + self.toolbar && self.toolbar.setEnable(items && items.length > 0); + } + }); + }, + onLoaded: o.onLoaded, + hasNext: o.hasNext, + value: o.value, + }); + + this.list.on(Controller.EVENT_CHANGE, function (type, value, obj) { + if (type === Events.CLICK) { + self.fireEvent(SingleSelectList.EVENT_CHANGE, value, obj); + } + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + createWidget( + extend( + { + element: this, + }, + LogicFactory.createLogic( + LogicFactory.createLogicTypeByDirection(o.direction), + extend( + { + scrolly: true, + }, + o.logic, + { + items: o.allowNoSelect + ? LogicFactory.createLogicItemsByDirection( + o.direction, + { + type: SingleSelectItem.xtype, + cls: "bi-list-item-active", + height: this._constants.itemHeight, + forceNotSelected: true, + text: i18nText("BI-Basic_No_Select"), + ref(_ref) { + self.toolbar = _ref; + }, + listeners: [ + { + eventName: Controller.EVENT_CHANGE, + action(type) { + if (type === Events.CLICK) { + self.list.setValue(); + self.fireEvent(SingleSelectList.EVENT_CHANGE); + } + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }, + } + ], + }, + this.list + ) + : LogicFactory.createLogicItemsByDirection(o.direction, this.list), + } + ) + ) + ) + ); + } + + hasPrev() { + return this.list.hasPrev(); + } + + hasNext() { + return this.list.hasNext(); + } + + prependItems(items) { + this.list.prependItems(...arguments); + } + + addItems(items) { + this.list.addItems(...arguments); + } + + setValue(v) { + this.list.setValue([v]); + } + + getValue() { + return this.list.getValue()[0]; + } + + empty() { + this.list.empty(); + } + + populate(items) { + this.list.populate(...arguments); + } + + resetHeight(h) { + this.list.resetHeight + ? this.list.resetHeight(h) + : this.list.element.css({ + "max-height": pixFormat(h - (this.options.allowNoSelect ? this._constants.itemHeight : 0)), + }); + } + + setNotSelectedValue() { + this.list.setNotSelectedValue(...arguments); + } + + getNotSelectedValue() { + return this.list.getNotSelectedValue(); + } + + getAllButtons() { + return this.list.getAllButtons(); + } + + getAllLeaves() { + return this.list.getAllLeaves(); + } + + getSelectedButtons() { + return this.list.getSelectedButtons(); + } + + getNotSelectedButtons() { + return this.list.getNotSelectedButtons(); + } + + getIndexByValue(value) { + return this.list.getIndexByValue(value); + } + + getNodeById(id) { + return this.list.getNodeById(id); + } + + getNodeByValue(value) { + return this.list.getNodeByValue(value); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.loader.js b/packages/fineui/src/widget/singleselect/singleselect.loader.js new file mode 100644 index 000000000..18589a815 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.loader.js @@ -0,0 +1,202 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + isUndefined, + map, + isKey, + Controller, + VerticalLayout, + delay, + SIZE_CONSANTS +} from "@/core"; +import { ButtonGroup, Loader } from "@/base"; +import { SingleSelectList } from "./singleselect.list"; +import { SingleSelectItem, SingleSelectRadioItem } from "@/case"; + +@shortcut() +export class SingleSelectLoader extends Widget { + static xtype = "bi.single_select_loader"; + + _constants = { itemVgap: 5 }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-loader", + logic: { + dynamic: true, + }, + el: { + height: 400, + }, + allowNoSelect: false, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemWrapper: emptyFn, + onLoaded: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + opts = this.options; + let hasNext = false; + this.storeValue = opts.value; + this.button_group = createWidget({ + type: SingleSelectList.xtype, + allowNoSelect: opts.allowNoSelect, + logic: opts.logic, + el: extend( + { + onLoaded: opts.onLoaded, + el: { + type: Loader.xtype, + isDefaultInit: false, + logic: { + dynamic: true, + scrolly: true, + }, + el: { + chooseType: ButtonGroup.CHOOSE_TYPE_SINGLE, + behaviors: { + redmark() { + return true; + }, + }, + layouts: [ + { + type: VerticalLayout.xtype, + } + ], + }, + }, + }, + opts.el + ), + itemsCreator(op, callback) { + const startValue = self._startValue; + !isUndefined(self.storeValue) && + (op = extend(op || {}, { + selectedValues: [self.storeValue], + })); + opts.itemsCreator(op, ob => { + hasNext = ob.hasNext; + let firstItems = []; + if (op.times === 1 && !isUndefined(self.storeValue)) { + const json = map([self.storeValue], (i, v) => { + const txt = opts.valueFormatter(v) || v; + + return ( + opts.itemWrapper({ + text: txt, + value: v, + title: txt, + selected: true, + }) || { + text: txt, + value: v, + title: txt, + selected: true, + } + ); + }); + firstItems = self._createItems(json); + } + callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); + if (op.times === 1 && self.storeValue) { + isKey(startValue) && (self.storeValue = startValue); + self.setValue(self.storeValue); + } + op.times === 1 && self._scrollToTop(); + }); + }, + hasNext() { + return hasNext; + }, + value: this.storeValue, + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + items: [this.button_group], + vgap: this._constants.itemVgap, + }); + + this.button_group.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.button_group.on(SingleSelectList.EVENT_CHANGE, function () { + self.fireEvent(SingleSelectLoader.EVENT_CHANGE, arguments); + }); + } + + _createItems(items) { + const o = this.options; + + return map(items, (i, item) => + extend( + { + type: o.allowNoSelect ? SingleSelectItem.xtype : SingleSelectRadioItem.xtype, + logic: o.logic, + cls: "bi-list-item-active", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + selected: false, + iconWrapperWidth: 26, + textHgap: o.allowNoSelect ? 10 : 0, + title: item.title || item.text, + }, + item + ) + ); + } + + _scrollToTop() { + const self = this; + delay(() => { + self.button_group.element.scrollTop(0); + }, 30); + } + + _assertValue(val) {} + + setStartValue(v) { + this._startValue = v; + } + + setValue(v) { + this.storeValue = v; + this._assertValue(this.storeValue); + this.button_group.setValue(this.storeValue); + } + + getValue() { + return this.button_group.getValue(); + } + + getAllButtons() { + return this.button_group.getAllButtons(); + } + + empty() { + this.button_group.empty(); + } + + populate(items) { + this.button_group.populate(...arguments); + } + + resetHeight(h) { + this.button_group.resetHeight(h - this._constants.itemVgap * 2); + } + + resetWidth(w) { + this.button_group.resetWidth(w); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.popup.view.js b/packages/fineui/src/widget/singleselect/singleselect.popup.view.js new file mode 100644 index 000000000..405ce363f --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.popup.view.js @@ -0,0 +1,83 @@ +import { SingleSelectLoader } from "./singleselect.loader"; +import { shortcut, Widget, extend, emptyFn, createWidget } from "@/core"; +import { MultiPopupView } from "@/case"; +import { PopupView } from "@/base"; + +@shortcut() +export class SingleSelectPopupView extends Widget { + static xtype = "bi.single_select_popup_view"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-popup-view", + allowNoSelect: false, + maxWidth: "auto", + minWidth: 135, + maxHeight: 400, + valueFormatter: emptyFn, + itemsCreator: emptyFn, + itemWrapper: emptyFn, + onLoaded: emptyFn, + }); + } + + _init() { + super._init(...arguments); + const opts = this.options; + + this.loader = createWidget({ + type: SingleSelectLoader.xtype, + allowNoSelect: opts.allowNoSelect, + itemsCreator: opts.itemsCreator, + itemWrapper: opts.itemWrapper, + valueFormatter: opts.valueFormatter, + onLoaded: opts.onLoaded, + value: opts.value, + }); + + this.popupView = createWidget({ + type: PopupView.xtype, + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + element: this, + el: this.loader, + value: opts.value, + }); + + this.popupView.on(MultiPopupView.EVENT_CHANGE, () => { + this.fireEvent(SingleSelectPopupView.EVENT_CHANGE); + }); + } + + setStartValue(v) { + this.loader.setStartValue(v); + } + + setValue(v) { + this.popupView.setValue(v); + } + + getValue() { + return this.popupView.getValue(); + } + + populate(items) { + this.popupView.populate(...arguments); + } + + resetHeight(h) { + this.popupView.resetHeight(h); + } + + resetWidth(w) { + this.popupView.resetWidth(w); + } + + setDirection(direction, position) { + this.popupView.setDirection(direction, position); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselect.trigger.js b/packages/fineui/src/widget/singleselect/singleselect.trigger.js new file mode 100644 index 000000000..02021774c --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselect.trigger.js @@ -0,0 +1,134 @@ +import { shortcut, extend, emptyFn, createWidget, HTapeLayout, AbsoluteLayout } from "@/core"; +import { Trigger, Text } from "@/base"; +import { SingleSelectSearcher } from "./trigger"; + +@shortcut() +export class SingleSelectTrigger extends Trigger { + static xtype = "bi.single_select_trigger"; + + constants = { height: 14, rgap: 4, lgap: 4 }; + + static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; + static EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + static EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-trigger", + allowNoSelect: false, + itemsCreator: emptyFn, + valueFormatter: emptyFn, + searcher: {}, + switcher: {}, + + adapter: null, + masker: {}, + allowEdit: true, + }); + } + + _init() { + super._init(...arguments); + + const o = this.options; + + this.searcher = createWidget(o.searcher, { + type: SingleSelectSearcher.xtype, + watermark: o.watermark, + allowNoSelect: o.allowNoSelect, + text: o.text, + height: o.height, + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + popup: {}, + adapter: o.adapter, + masker: o.masker, + value: o.value, + }); + this.searcher.on(SingleSelectSearcher.EVENT_START, () => { + this.fireEvent(SingleSelectTrigger.EVENT_START); + }); + this.searcher.on(SingleSelectSearcher.EVENT_PAUSE, () => { + this.fireEvent(SingleSelectTrigger.EVENT_PAUSE); + }); + this.searcher.on(SingleSelectSearcher.EVENT_SEARCHING, (...args) => { + this.fireEvent(SingleSelectTrigger.EVENT_SEARCHING, ...args); + }); + this.searcher.on(SingleSelectSearcher.EVENT_STOP, () => { + this.fireEvent(SingleSelectTrigger.EVENT_STOP); + }); + this.searcher.on(SingleSelectSearcher.EVENT_CHANGE, (...args) => { + this.fireEvent(SingleSelectTrigger.EVENT_CHANGE, ...args); + }); + this.searcher.on(SingleSelectSearcher.EVENT_FOCUS, () => { + this.fireEvent(SingleSelectTrigger.EVENT_FOCUS); + }); + this.searcher.on(SingleSelectSearcher.EVENT_BLUR, (...args) => { + this.fireEvent(SingleSelectTrigger.EVENT_BLUR, ...args); + }); + + createWidget({ + type: HTapeLayout.xtype, + element: this, + items: [ + { + el: this.searcher, + width: "fill", + }, + { + el: createWidget(), + width: 24, + } + ], + }); + + !o.allowEdit && + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: Text.xtype, + title: () => this.searcher.getState(), + }, + left: 0, + right: 24, + top: 0, + bottom: 0, + } + ], + }); + } + + getSearcher() { + return this.searcher; + } + + stopEditing() { + this.searcher.stopSearch(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setValue(v) { + this.searcher.setValue(v); + } + + getKey() { + return this.searcher.getKey(); + } + + getValue() { + return this.searcher.getValue(); + } +} diff --git a/packages/fineui/src/widget/singleselect/singleselectlist.insert.js b/packages/fineui/src/widget/singleselect/singleselectlist.insert.js new file mode 100644 index 000000000..63a040103 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/singleselectlist.insert.js @@ -0,0 +1,234 @@ +import { SingleSelectSearchInsertPane } from "./search"; +import { + shortcut, + extend, + emptyFn, + isKey, + createWidget, + isNotEmptyString, + i18nText, + deepClone, + VerticalFillLayout, + AbsoluteLayout, + makeObject +} from "@/core"; +import { Single, Searcher } from "@/base"; +import { SingleSelectLoader } from "./singleselect.loader"; +import { SelectPatchEditor } from "../multiselect"; +import { SearchEditor } from "../editor"; + +@shortcut() +export class SingleSelectInsertList extends Single { + static xtype = "bi.single_select_insert_list"; + + static REQ_GET_DATA_LENGTH = 0; + static REQ_GET_ALL_DATA = -1; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-insert-list", + allowNoSelect: false, + itemsCreator: emptyFn, + itemWrapper: emptyFn, + valueFormatter: emptyFn, + searcherHeight: 24, + simple: false, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + this.storeValue = o.value; + + const assertShowValue = () => { + isKey(this._startValue) && (this.storeValue = this._startValue); + // this.trigger.setValue(this.storeValue); + }; + + this.adapter = createWidget({ + type: SingleSelectLoader.xtype, + allowNoSelect: o.allowNoSelect, + cls: "popup-single-select-list bi-border-left bi-border-right bi-border-bottom", + itemsCreator: o.itemsCreator, + valueFormatter: o.valueFormatter, + itemWrapper: o.itemWrapper, + logic: { + dynamic: true, + }, + // onLoaded: o.onLoaded, + el: {}, + value: o.value, + }); + this.adapter.on(SingleSelectLoader.EVENT_CHANGE, function () { + self.storeValue = this.getValue(); + assertShowValue(); + self.fireEvent(SingleSelectInsertList.EVENT_CHANGE); + }); + + this.searcherPane = createWidget({ + type: SingleSelectSearchInsertPane.xtype, + allowNoSelect: o.allowNoSelect, + cls: "bi-border-left bi-border-right bi-border-bottom", + valueFormatter: o.valueFormatter, + keywordGetter() { + return self.trigger.getKeyword(); + }, + itemsCreator(op, callback) { + op.keywords = [self.trigger.getKeyword()]; + if (isNotEmptyString(op.keywords[0])) { + this.setKeyword(op.keywords[0]); + o.itemsCreator(op, callback); + } + }, + }); + this.searcherPane.setVisible(false); + + this.trigger = createWidget({ + type: Searcher.xtype, + el: { + type: SelectPatchEditor.xtype, + el: { + type: SearchEditor.xtype, + watermark: i18nText("BI-Basic_Search_And_Patch_Paste"), + simple: o.simple, + }, + ref(ref) { + self.editor = ref; + }, + height: o.searcherHeight, + }, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + adapter: this.adapter, + popup: this.searcherPane, + masker: false, + value: o.value, + listeners: [ + { + eventName: Searcher.EVENT_START, + action() { + self._showSearcherPane(); + self._setStartValue(); + this.setValue(deepClone(self.storeValue)); + }, + }, + { + eventName: Searcher.EVENT_STOP, + action() { + self._showAdapter(); + self._setStartValue(); + self.adapter.setValue(self.storeValue); + // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); + }, + }, + { + eventName: Searcher.EVENT_PAUSE, + action() { + const keyword = this.getKeyword(); + self.storeValue = keyword; + self._showAdapter(); + self.adapter.setValue(self.storeValue); + self._setStartValue(keyword); + assertShowValue(); + self.adapter.populate(); + self._setStartValue(); + self.fireEvent(SingleSelectInsertList.EVENT_CHANGE); + }, + }, + { + eventName: Searcher.EVENT_CHANGE, + action() { + self.storeValue = this.getValue(); + self.fireEvent(SingleSelectInsertList.EVENT_CHANGE); + }, + } + ], + }); + + createWidget({ + type: VerticalFillLayout.xtype, + rowSize: ["", "fill"], + element: this, + items: [ + { + el: this.trigger, + }, + { + el: this.adapter, + } + ], + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.searcherPane, + top: 24, + bottom: 0, + left: 0, + right: 0, + } + ], + }); + } + + _showAdapter() { + this.adapter.setVisible(true); + this.searcherPane.setVisible(false); + } + + _showSearcherPane() { + this.searcherPane.setVisible(true); + this.adapter.setVisible(false); + } + + _defaultState() { + this.trigger.stopEditing(); + } + + _assertValue() {} + + _makeMap(values) { + return makeObject(values || []); + } + + _setStartValue(value) { + this._startValue = value; + this.adapter.setStartValue(value); + } + + isAllSelected() { + return this.adapter.isAllSelected(); + } + + resize() { + // this.trigger.getCounter().adjustView(); + // this.trigger.adjustView(); + } + + setValue(v) { + this.storeValue = v; + this.adapter.setValue(this.storeValue); + this.trigger.setValue(this.storeValue); + } + + getValue() { + return deepClone(this.storeValue); + } + + populate() { + this._count = null; + this._allData = null; + this.adapter.populate(...arguments); + this.trigger.populate(...arguments); + } +} diff --git a/packages/fineui/src/widget/singleselect/trigger/editor.singleselect.js b/packages/fineui/src/widget/singleselect/trigger/editor.singleselect.js new file mode 100644 index 000000000..8320c4634 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/trigger/editor.singleselect.js @@ -0,0 +1,100 @@ +import { + shortcut, + Widget, + extend, + i18nText, + createWidget, + Controller, + isEmptyString, + isEmptyArray, + BlankSplitChar +} from "@/core"; +import { StateEditor } from "@/case"; +import { SelectPatchEditor } from "../../multiselect"; + +@shortcut() +export class SingleSelectEditor extends Widget { + static xtype = "bi.single_select_editor"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-editor", + el: {}, + text: i18nText("BI-Basic_Please_Select"), + watermark: i18nText("BI-Basic_Search"), + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget(o.el, { + type: SelectPatchEditor.xtype, + element: this, + height: o.height, + watermark: o.watermark, + allowBlank: true, + value: o.value, + defaultText: o.text, + text: o.text, + }); + + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(StateEditor.EVENT_FOCUS, () => { + this.fireEvent(SingleSelectEditor.EVENT_FOCUS); + }); + this.editor.on(StateEditor.EVENT_BLUR, () => { + this.fireEvent(SingleSelectEditor.EVENT_BLUR); + }); + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setState(state) { + this.editor.setState(state); + } + + setValue(v) { + this.editor.setValue(v); + } + + getValue() { + return this.editor.getValue(); + } + + getKeywords() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + if (/\u200b\s\u200b$/.test(val)) { + return keywords.concat([BlankSplitChar]); + } + + return keywords; + } + + getKeyword() { + const val = this.editor.getValue(); + let keywords = val.split(/\u200b\s\u200b/); + if (isEmptyString(keywords[keywords.length - 1])) { + keywords = keywords.slice(0, keywords.length - 1); + } + + return isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; + } + + populate(items) {} +} diff --git a/packages/fineui/src/widget/singleselect/trigger/index.js b/packages/fineui/src/widget/singleselect/trigger/index.js new file mode 100644 index 000000000..e5abc14b0 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/trigger/index.js @@ -0,0 +1,2 @@ +export { SingleSelectEditor } from "./editor.singleselect"; +export { SingleSelectSearcher } from "./searcher.singleselect"; diff --git a/packages/fineui/src/widget/singleselect/trigger/searcher.singleselect.js b/packages/fineui/src/widget/singleselect/trigger/searcher.singleselect.js new file mode 100644 index 000000000..31ebc6f67 --- /dev/null +++ b/packages/fineui/src/widget/singleselect/trigger/searcher.singleselect.js @@ -0,0 +1,164 @@ +import { SingleSelectSearchPane } from "../search"; +import { shortcut, Widget, extend, emptyFn, createWidget, isNotNull, isUndefined, Selection } from "@/core"; +import { SingleSelectEditor } from "./editor.singleselect"; +import { Searcher } from "@/base"; + +@shortcut() +export class SingleSelectSearcher extends Widget { + static xtype = "bi.single_select_searcher"; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_BLUR = "EVENT_BLUR"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_START = "EVENT_START"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_PAUSE = "EVENT_PAUSE"; + static EVENT_SEARCHING = "EVENT_SEARCHING"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-select-searcher", + itemsCreator: emptyFn, + el: {}, + popup: {}, + valueFormatter: emptyFn, + adapter: null, + masker: {}, + allowNoSelect: false, + }); + } + + _init() { + super._init(...arguments); + const self = this, + o = this.options; + this.editor = createWidget(o.el, { + type: SingleSelectEditor.xtype, + height: o.height, + watermark: o.watermark, + text: o.text, + listeners: [ + { + eventName: SingleSelectEditor.EVENT_FOCUS, + action: () => { + this.fireEvent(SingleSelectSearcher.EVENT_FOCUS); + }, + }, + { + eventName: SingleSelectEditor.EVENT_BLUR, + action: () => { + this.fireEvent(SingleSelectSearcher.EVENT_BLUR); + }, + } + ], + }); + + this.searcher = createWidget({ + type: Searcher.xtype, + element: this, + height: o.height, + isAutoSearch: false, + isAutoSync: false, + onSearch(op, callback) { + callback(); + }, + el: this.editor, + + popup: extend( + { + type: SingleSelectSearchPane.xtype, + allowNoSelect: o.allowNoSelect, + valueFormatter: o.valueFormatter, + keywordGetter: () => this.editor.getValue(), + itemsCreator(op, callback) { + const keyword = self.editor.getValue(); + op.keywords = [keyword]; + this.setKeyword(keyword); + o.itemsCreator(op, callback); + }, + value: o.value, + }, + o.popup + ), + + adapter: o.adapter, + masker: o.masker, + }); + this.searcher.on(Searcher.EVENT_START, () => { + this.fireEvent(SingleSelectSearcher.EVENT_START); + }); + this.searcher.on(Searcher.EVENT_PAUSE, () => { + this.fireEvent(SingleSelectSearcher.EVENT_PAUSE); + }); + this.searcher.on(Searcher.EVENT_STOP, () => { + this.fireEvent(SingleSelectSearcher.EVENT_STOP); + }); + this.searcher.on(Searcher.EVENT_CHANGE, (...args) => { + this.fireEvent(SingleSelectSearcher.EVENT_CHANGE, ...args); + }); + this.searcher.on(Searcher.EVENT_SEARCHING, () => { + const keywords = this.searcher.getKeywords(); + this.fireEvent(SingleSelectSearcher.EVENT_SEARCHING, keywords); + }); + + if (isNotNull(o.value)) { + this.setState(o.value); + } + } + + adjustView() { + this.searcher.adjustView(); + } + + isSearching() { + return this.searcher.isSearching(); + } + + stopSearch() { + this.searcher.stopSearch(); + } + + getKeyword() { + return this.editor.getKeyword(); + } + + hasMatched() { + return this.searcher.hasMatched(); + } + + hasChecked() { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + } + + setAdapter(adapter) { + this.searcher.setAdapter(adapter); + } + + setState(v) { + const o = this.options; + if (isUndefined(v)) { + this.editor.setState(Selection.None); + } else { + v = v ?? ""; + this.editor.setState(o.valueFormatter(`${v}`) || `${v}`); + } + } + + setValue(ob) { + this.setState(ob); + this.searcher.setValue(ob); + } + + getKey() { + return this.editor.getValue(); + } + + getValue() { + return this.searcher.getValue(); + } + + populate(items) { + this.searcher.populate(...arguments); + } +} diff --git a/src/widget/singleslider/__test__/singleslider.test.js b/packages/fineui/src/widget/singleslider/__test__/singleslider.test.js similarity index 100% rename from src/widget/singleslider/__test__/singleslider.test.js rename to packages/fineui/src/widget/singleslider/__test__/singleslider.test.js diff --git a/packages/fineui/src/widget/singleslider/button/editor.sign.text.js b/packages/fineui/src/widget/singleslider/button/editor.sign.text.js new file mode 100644 index 000000000..da7c44cb9 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/button/editor.sign.text.js @@ -0,0 +1,217 @@ +import { + shortcut, + Widget, + extend, + emptyFn, + createWidget, + nextTick, + Controller, + AbsoluteLayout, + VerticalLayout, + bind, + isEmpty, + isKey +} from "@/core"; +import { TextButton, Editor } from "@/base"; + +@shortcut() +export class SignTextEditor extends Widget { + static xtype = "bi.sign_text_editor"; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; + static EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + baseCls: `${conf.baseCls || ""} bi-sign-initial-editor`, + validationChecker: emptyFn, + text: "", + height: 24, + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.editor = createWidget({ + type: Editor.xtype, + simple: o.simple, + height: o.height, + hgap: 4, + vgap: 2, + value: o.value, + validationChecker: o.validationChecker, + allowBlank: false, + }); + this.text = createWidget({ + type: TextButton.xtype, + cls: "sign-editor-text", + title: () => this.getValue(), + textAlign: o.textAlign, + height: o.height, + hgap: 4, + handler: () => { + this._showInput(); + this.editor.focus(); + this.editor.selectAll(); + }, + }); + this.text.on(TextButton.EVENT_CHANGE, () => { + nextTick(() => { + this.fireEvent(SignTextEditor.EVENT_CLICK_LABEL); + }); + }); + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: this.text, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }); + this.editor.on(Controller.EVENT_CHANGE, (...args) => { + this.fireEvent(Controller.EVENT_CHANGE, ...args); + }); + this.editor.on(Editor.EVENT_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(SignTextEditor.EVENT_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_CHANGE_CONFIRM, (...args) => { + this._showHint(); + this._checkText(); + this.fireEvent(SignTextEditor.EVENT_CHANGE_CONFIRM, ...args); + }); + this.editor.on(Editor.EVENT_ERROR, () => { + this._checkText(); + }); + createWidget({ + type: VerticalLayout.xtype, + scrolly: false, + element: this, + items: [this.editor], + }); + this._showHint(); + this._checkText(); + } + + _checkText() { + const o = this.options; + nextTick( + bind(() => { + if (this.editor.getValue() === "") { + this.text.setValue(o.watermark || ""); + this.text.element.addClass("bi-water-mark"); + } else { + let v = this.editor.getValue(); + v = isEmpty(v) || v === o.text ? o.text : v + o.text; + this.text.setValue(v); + this.text.element.removeClass("bi-water-mark"); + } + }, this) + ); + } + + _showInput() { + this.editor.visible(); + this.text.invisible(); + } + + _showHint() { + this.editor.invisible(); + this.text.visible(); + } + + setTitle(title) { + this.text.setTitle(title); + } + + setWarningTitle(title) { + this.text.setWarningTitle(title); + } + + focus() { + this._showInput(); + this.editor.focus(); + } + + blur() { + this.editor.blur(); + this._showHint(); + this._checkText(); + } + + doRedMark() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doRedMark(...arguments); + } + + unRedMark() { + this.text.unRedMark(...arguments); + } + + doHighLight() { + if (this.editor.getValue() === "" && isKey(this.options.watermark)) { + return; + } + this.text.doHighLight(...arguments); + } + + unHighLight() { + this.text.unHighLight(...arguments); + } + + isValid() { + return this.editor.isValid(); + } + + setErrorText(text) { + this.editor.setErrorText(text); + } + + getErrorText() { + return this.editor.getErrorText(); + } + + isEditing() { + return this.editor.isEditing(); + } + + getLastValidValue() { + return this.editor.getLastValidValue(); + } + + getLastChangedValue() { + return this.editor.getLastChangedValue(); + } + + setValue(v) { + this.editor.setValue(v); + this._checkText(); + } + + getValue() { + return this.editor.getValue(); + } + + getState() { + return this.text.getValue(); + } + + setState(v) { + const o = this.options; + this._showHint(); + v = isEmpty(v) || v === o.text ? o.text : v + o.text; + this.text.setValue(v); + } +} diff --git a/packages/fineui/src/widget/singleslider/button/iconbutton.slider.js b/packages/fineui/src/widget/singleslider/button/iconbutton.slider.js new file mode 100644 index 000000000..d68233b10 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/button/iconbutton.slider.js @@ -0,0 +1,24 @@ +import { shortcut, Widget, Layout } from "@/core"; + +@shortcut() +export class SliderIconButton extends Widget { + static xtype = "bi.single_slider_button"; + + props = { + baseCls: "bi-single-slider-button slider-button bi-high-light-border", + height: 8, + width: 8, + }; + constants = { + LARGE_SIZE: 16, + NORMAL_SIZE: 12, + LARGE_OFFSET: 4, + NORMAL_OFFSET: 6, + }; + + render() { + return { + type: Layout.xtype, + }; + } +} diff --git a/packages/fineui/src/widget/singleslider/index.js b/packages/fineui/src/widget/singleslider/index.js new file mode 100644 index 000000000..1142afc23 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/index.js @@ -0,0 +1,5 @@ +export { SingleSlider } from "./singleslider"; +export { SingleSliderLabel } from "./singleslider.label"; +export { SingleSliderNormal } from "./singleslider.normal"; +export { SignTextEditor } from "./button/editor.sign.text"; +export { SliderIconButton } from "./button/iconbutton.slider"; diff --git a/packages/fineui/src/widget/singleslider/singleslider.js b/packages/fineui/src/widget/singleslider/singleslider.js new file mode 100644 index 000000000..622113833 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/singleslider.js @@ -0,0 +1,414 @@ +import { SliderIconButton } from "./button/iconbutton.slider"; +import { SignTextEditor } from "./button/editor.sign.text"; +import { + shortcut, + createWidget, + parseFloat, + toPix, + Layout, + VerticalAdaptLayout, + AbsoluteLayout, + VerticalLayout, + HorizontalAutoLayout, + clamp, + isNumeric, + isNull, + parseInt, + i18nText, + isNotEmptyString, + MouseMoveTracker +} from "@/core"; +import { Single } from "@/base"; +import { SignEditor } from "@/case"; + +@shortcut() +export class SingleSlider extends Single { + static xtype = "bi.single_slider"; + + _constant = { + EDITOR_WIDTH: 90, + EDITOR_HEIGHT: 20, + SLIDER_WIDTH_HALF: 15, + SLIDER_WIDTH: 30, + SLIDER_HEIGHT: 30, + TRACK_HEIGHT: 24, + TRACK_GAP_HALF: 7, + TRACK_GAP: 14, + }; + + props = { + baseCls: "bi-single-slider bi-slider-track", + digit: false, + unit: "", + value: "", + min: 0, + max: 100, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + beforeMount() { + const { value, min, max } = this.options; + this.setMinAndMax({ + min, + max, + }); + this.setValue(value); + this.populate(); + } + + render() { + const o = this.options; + const c = this._constant; + this.enable = false; + this.value = ""; + + this.grayTrack = createWidget({ + type: Layout.xtype, + cls: "gray-track", + height: 6, + }); + this.blueTrack = createWidget({ + type: Layout.xtype, + cls: "blue-track bi-high-light-background", + height: 6, + }); + this.track = this._createTrackWrapper(); + + this.slider = createWidget({ + type: SliderIconButton.xtype, + }); + this._draggable(this.slider); + const sliderVertical = createWidget({ + type: VerticalAdaptLayout.xtype, + cls: "slider-wrapper", + columnSize: ["fill"], + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.slider, + top: 8, + } + ], + height: c.SLIDER_HEIGHT, + } + ], + hgap: c.SLIDER_WIDTH_HALF, + height: c.SLIDER_HEIGHT, + }); + // 这边其实是有问题的,拖拽区域是个圆,在圆的边缘拖拽后放开,这边计算出来的蓝条宽度实际上会比放开时长一点或者短一点 + sliderVertical.element.click(e => { + if (this.enable && this.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { + const offset = e.clientX - this.element.offset().left - c.SLIDER_WIDTH_HALF; + const trackLength = this.track.element[0].scrollWidth - c.TRACK_GAP; + let percent = 0; + if (offset < 0) { + percent = 0; + } + if (offset > 0 && offset < trackLength) { + percent = (offset * 100) / this._getGrayTrackLength(); + } + if (offset >= trackLength) { + percent = 100; + } + const significantPercent = parseFloat(percent.toFixed(1)); + this._setAllPosition(significantPercent); + let v = this._getValueByPercent(significantPercent); + v = o.digit === false ? v : v.toFixed(o.digit); + this.label.setValue(v); + this.value = v; + this.fireEvent(SingleSlider.EVENT_CHANGE); + } + }); + this.label = createWidget({ + type: SignTextEditor.xtype, + cls: "slider-editor-button", + text: o.unit, + width: toPix(c.EDITOR_WIDTH, 2), + height: toPix(c.EDITOR_HEIGHT, 2), + allowBlank: false, + textAlign: "center", + validationChecker: v => this._checkValidation(v), + }); + this.label.element.hover( + () => { + this.label.element.removeClass("bi-border").addClass("bi-border"); + }, + () => { + this.label.element.removeClass("bi-border"); + } + ); + this.label.on(SignEditor.EVENT_CONFIRM, () => { + const v = parseFloat(this.label.getValue()); + const percent = this._getPercentByValue(v); + const significantPercent = parseFloat(percent.toFixed(1)); + this._setAllPosition(significantPercent); + this.setValue(v); + this.value = v; + this.fireEvent(SingleSlider.EVENT_CHANGE); + }); + this._setVisible(false); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.track, + width: "100%", + height: c.TRACK_HEIGHT, + } + ], + } + ], + hgap: c.TRACK_GAP_HALF, + height: c.TRACK_HEIGHT, + }, + top: 23, + left: 0, + width: "100%", + }, + { + el: sliderVertical, + top: 20, + left: 0, + width: "100%", + }, + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: HorizontalAutoLayout.xtype, + items: [this.label], + } + ], + // height: c.EDITOR_HEIGHT + }, + top: 0, + left: 0, + width: "100%", + } + ], + }; + } + + _draggable(widget) { + const o = this.options; + let startDrag = false; + let size = 0, + offset = 0, + defaultSize = 0; + const mouseMoveTracker = new MouseMoveTracker( + deltaX => { + if (mouseMoveTracker.isDragging()) { + startDrag = true; + offset += deltaX; + size = optimizeSize(defaultSize + offset); + widget.element.addClass("dragging"); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); // 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 + this._setBlueTrack(significantPercent); + this._setLabelPosition(significantPercent); + this._setSliderPosition(significantPercent); + let v = this._getValueByPercent(significantPercent); + v = o.digit === false ? v : v.toFixed(o.digit); + this.label.setValue(v); + this.value = v; + } + }, + () => { + if (startDrag === true) { + size = optimizeSize(size); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); + this._setSliderPosition(significantPercent); + size = 0; + offset = 0; + defaultSize = size; + startDrag = false; + } + widget.element.removeClass("dragging"); + mouseMoveTracker.releaseMouseMoves(); + this.fireEvent(SingleSlider.EVENT_CHANGE); + }, + window + ); + widget.element.on("mousedown", function (event) { + if (!widget.isEnabled()) { + return; + } + defaultSize = this.offsetLeft; + optimizeSize(defaultSize); + mouseMoveTracker.captureMouseMoves(event); + }); + + const optimizeSize = s => clamp(s, 0, this._getGrayTrackLength()); + } + + _createTrackWrapper() { + return createWidget({ + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.grayTrack, + top: 0, + left: 0, + width: "100%", + }, + { + el: this.blueTrack, + top: 0, + left: 0, + width: "0%", + } + ], + } + ], + hgap: 8, + height: 8, + }, + top: 8, + left: 0, + width: "100%", + } + ], + }); + } + + _checkValidation(v) { + const o = this.options; + let valid = false; + if (isNumeric(v) && !(isNull(v) || v < this.min || v > this.max)) { + if (o.digit === false) { + valid = true; + } else { + const dotText = `${v}`.split(".")[1] || ""; + valid = dotText.length === o.digit; + } + } + + return valid; + } + + _setBlueTrack(percent) { + this.blueTrack.element.css({ width: `${percent}%` }); + } + + _setLabelPosition(percent) { + // this.label.element.css({left: percent + "%"}); + } + + _setSliderPosition(percent) { + this.slider.element.css({ left: `${percent}%` }); + } + + _setAllPosition(percent) { + this._setSliderPosition(percent); + this._setLabelPosition(percent); + this._setBlueTrack(percent); + } + + _setVisible(visible) { + this.slider.setVisible(visible); + this.label.setVisible(visible); + } + + _getGrayTrackLength() { + return this.grayTrack.element[0].scrollWidth; + } + + _getValueByPercent(percent) { + const thousandth = parseInt(percent * 10); + + return ((this.max - this.min) * thousandth) / 1000 + this.min; + } + + _getPercentByValue(v) { + return ((v - this.min) * 100) / (this.max - this.min); + } + + getValue() { + return this.value; + } + + setValue(v) { + const o = this.options; + v = parseFloat(v); + v = o.digit === false ? v : v.toFixed(o.digit); + if (!isNaN(v)) { + if (this._checkValidation(v)) { + this.value = v; + } + if (v > this.max) { + this.value = this.max; + } + if (v < this.min) { + this.value = this.min; + } + } + } + + _setEnable(b) { + super._setEnable.apply(this, [b]); + if (b) { + this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); + } else { + this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); + } + } + + setMinAndMax(v) { + const minNumber = this.options.min = parseFloat(v.min); + const maxNumber = this.options.max = parseFloat(v.max); + if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber)) { + this.min = minNumber; + this.max = maxNumber; + } + } + + reset() { + this._setVisible(false); + this.enable = false; + this.value = ""; + this.min = 0; + this.max = 0; + this._setBlueTrack(0); + } + + populate() { + const o = this.options; + if (!isNaN(this.min) && !isNaN(this.max)) { + this._setVisible(true); + this.enable = true; + if (o.digit) { + this.label.setErrorText(i18nText("BI-Basic_Please_Enter_Number_Between", this.min, this.max)); + } else { + this.label.setErrorText(i18nText("BI-Basic_Please_Enter_Integer_Number_Between", this.min, this.max)); + } + + if (isNumeric(this.value) || isNotEmptyString(this.value)) { + this.label.setValue(this.value); + this._setAllPosition(this._getPercentByValue(this.value)); + } else { + this.label.setValue(this.max); + this._setAllPosition(100); + } + } + } +} diff --git a/packages/fineui/src/widget/singleslider/singleslider.label.js b/packages/fineui/src/widget/singleslider/singleslider.label.js new file mode 100644 index 000000000..7e95212f2 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/singleslider.label.js @@ -0,0 +1,371 @@ +import { SliderIconButton } from "./button/iconbutton.slider"; +import { + shortcut, + createWidget, + parseFloat, + toPix, + Layout, + VerticalAdaptLayout, + AbsoluteLayout, + VerticalLayout, + HorizontalAutoLayout, + clamp, + isNumeric, + isNull, + parseInt, + isNotEmptyString, + MouseMoveTracker +} from "@/core"; +import { Single, Label } from "@/base"; + +@shortcut() +export class SingleSliderLabel extends Single { + static xtype = "bi.single_slider_label"; + _constant = { + EDITOR_WIDTH: 90, + EDITOR_HEIGHT: 20, + HEIGHT: 20, + SLIDER_WIDTH_HALF: 15, + SLIDER_WIDTH: 30, + SLIDER_HEIGHT: 30, + TRACK_HEIGHT: 24, + TRACK_GAP_HALF: 7, + TRACK_GAP: 14, + }; + props = { + baseCls: "bi-single-slider-label bi-slider-track", + digit: false, + unit: "", + value: "", + min: 0, + max: 100, + }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + beforeMount() { + const { value, min, max } = this.options; + this.setMinAndMax({ + min, + max, + }); + this.setValue(value); + this.populate(); + } + + render() { + const o = this.options; + const c = this._constant; + this.enable = false; + this.value = ""; + + this.grayTrack = createWidget({ + type: Layout.xtype, + cls: "gray-track", + height: 6, + }); + this.blueTrack = createWidget({ + type: Layout.xtype, + cls: "blue-track bi-high-light-background", + height: 6, + }); + this.track = this._createTrackWrapper(); + + this.slider = createWidget({ + type: SliderIconButton.xtype, + }); + this._draggable(this.slider); + const sliderVertical = createWidget({ + type: VerticalAdaptLayout.xtype, + columnSize: ["fill"], + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.slider, + top: 8, + } + ], + height: c.SLIDER_HEIGHT, + } + ], + hgap: c.SLIDER_WIDTH_HALF, + height: c.SLIDER_HEIGHT, + }); + sliderVertical.element.click(e => { + if (this.enable && this.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { + const offset = e.clientX - this.element.offset().left - c.SLIDER_WIDTH_HALF; + const trackLength = this.track.element[0].scrollWidth - c.TRACK_GAP; + let percent = 0; + if (offset < 0) { + percent = 0; + } + if (offset > 0 && offset < trackLength) { + percent = (offset * 100) / this._getGrayTrackLength(); + } + if (offset >= trackLength) { + percent = 100; + } + const significantPercent = parseFloat(percent.toFixed(1)); + this._setAllPosition(significantPercent); + let v = this._getValueByPercent(significantPercent); + v = o.digit === false ? v : v.toFixed(o.digit); + this.label.setText(v + o.unit); + this.value = v; + this.fireEvent(SingleSliderLabel.EVENT_CHANGE); + } + }); + this.label = createWidget({ + type: Label.xtype, + height: c.HEIGHT, + width: toPix(c.EDITOR_WIDTH, 2), + }); + + this._setVisible(false); + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.track, + width: "100%", + height: c.TRACK_HEIGHT, + } + ], + } + ], + hgap: c.TRACK_GAP_HALF, + height: c.TRACK_HEIGHT, + }, + top: 13, + left: 0, + width: "100%", + }, + { + el: sliderVertical, + top: 10, + left: 0, + width: "100%", + }, + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: HorizontalAutoLayout.xtype, + items: [this.label], + } + ], + height: c.EDITOR_HEIGHT, + }, + top: 0, + left: 0, + width: "100%", + } + ], + }; + } + + _draggable(widget) { + const o = this.options; + let startDrag = false; + let size = 0, + offset = 0, + defaultSize = 0; + const mouseMoveTracker = new MouseMoveTracker( + deltaX => { + if (mouseMoveTracker.isDragging()) { + startDrag = true; + offset += deltaX; + size = optimizeSize(defaultSize + offset); + widget.element.addClass("dragging"); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); // 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 + this._setBlueTrack(significantPercent); + this._setLabelPosition(significantPercent); + this._setSliderPosition(significantPercent); + let v = this._getValueByPercent(significantPercent); + v = o.digit === false ? v : v.toFixed(o.digit); + this.label.setValue(v + o.unit); + this.value = v; + this.fireEvent(SingleSliderLabel.EVENT_CHANGE); + } + }, + () => { + if (startDrag === true) { + size = optimizeSize(size); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); + this._setSliderPosition(significantPercent); + size = 0; + offset = 0; + defaultSize = size; + startDrag = false; + } + widget.element.removeClass("dragging"); + mouseMoveTracker.releaseMouseMoves(); + this.fireEvent(SingleSliderLabel.EVENT_CHANGE); + }, + window + ); + widget.element.on("mousedown", function (event) { + if (!widget.isEnabled()) { + return; + } + defaultSize = this.offsetLeft; + optimizeSize(defaultSize); + mouseMoveTracker.captureMouseMoves(event); + }); + + const optimizeSize = s => clamp(s, 0, this._getGrayTrackLength()); + } + + _createTrackWrapper() { + return createWidget({ + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.grayTrack, + top: 0, + left: 0, + width: "100%", + }, + { + el: this.blueTrack, + top: 0, + left: 0, + width: "0%", + } + ], + } + ], + hgap: 8, + height: 8, + }, + top: 8, + left: 0, + width: "100%", + } + ], + }); + } + + _checkValidation(v) { + return isNumeric(v) && !(isNull(v) || v < this.min || v > this.max); + } + + _setBlueTrack(percent) { + this.blueTrack.element.css({ width: `${percent}%` }); + } + + _setLabelPosition(percent) { + // this.label.element.css({left: percent + "%"}); + } + + _setSliderPosition(percent) { + this.slider.element.css({ left: `${percent}%` }); + } + + _setAllPosition(percent) { + this._setSliderPosition(percent); + this._setLabelPosition(percent); + this._setBlueTrack(percent); + } + + _setVisible(visible) { + this.slider.setVisible(visible); + this.label.setVisible(visible); + } + + _getGrayTrackLength() { + return this.grayTrack.element[0].scrollWidth; + } + + _getValueByPercent(percent) { + const thousandth = parseInt(percent * 10); + + return ((this.max - this.min) * thousandth) / 1000 + this.min; + } + + _getPercentByValue(v) { + return ((v - this.min) * 100) / (this.max - this.min); + } + + _setEnable(b) { + super._setEnable.apply(this, [b]); + if (b) { + this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); + } else { + this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); + } + } + + getValue() { + return this.value; + } + + setValue(v) { + const o = this.options; + v = parseFloat(v); + v = o.digit === false ? v : v.toFixed(o.digit); + if (!isNaN(v)) { + if (this._checkValidation(v)) { + this.value = v; + } + if (v > this.max) { + this.value = this.max; + } + if (v < this.min) { + this.value = this.min; + } + } + } + + setMinAndMax(v) { + const minNumber = parseFloat(v.min); + const maxNumber = parseFloat(v.max); + if (!isNaN(minNumber) && !isNaN(maxNumber) && maxNumber > minNumber) { + this.min = minNumber; + this.max = maxNumber; + } + } + + reset() { + this._setVisible(false); + this.enable = false; + this.value = ""; + this.min = 0; + this.max = 0; + this._setBlueTrack(0); + } + + populate() { + const o = this.options; + if (!isNaN(this.min) && !isNaN(this.max)) { + this._setVisible(true); + this.enable = true; + if (isNumeric(this.value) || isNotEmptyString(this.value)) { + this.label.setValue(this.value + o.unit); + this._setAllPosition(this._getPercentByValue(this.value)); + } else { + this.label.setValue(this.max + o.unit); + this._setAllPosition(100); + } + } + } +} diff --git a/packages/fineui/src/widget/singleslider/singleslider.normal.js b/packages/fineui/src/widget/singleslider/singleslider.normal.js new file mode 100644 index 000000000..c7e4dde99 --- /dev/null +++ b/packages/fineui/src/widget/singleslider/singleslider.normal.js @@ -0,0 +1,336 @@ +import { SliderIconButton } from "./button/iconbutton.slider"; +import { + shortcut, + createWidget, + parseFloat, + VerticalAdaptLayout, + AbsoluteLayout, + VerticalLayout, + clamp, + Layout, + isNull, + parseInt, + isNumeric, + isNotEmptyString, + MouseMoveTracker +} from "@/core"; +import { Single } from "@/base"; +import { SingleSlider } from "./singleslider"; + +@shortcut() +export class SingleSliderNormal extends Single { + static xtype = "bi.single_slider_normal"; + _constant = { + HEIGHT: 28, + SLIDER_WIDTH_HALF: 15, + SLIDER_WIDTH: 30, + SLIDER_HEIGHT: 30, + TRACK_HEIGHT: 24, + TRACK_GAP_HALF: 7, + TRACK_GAP: 14, + }; + props = { + baseCls: "bi-single-slider-normal bi-slider-track", + min: 0, + max: 100, + value: "", + }; + + static EVENT_DRAG = "EVENT_DRAG"; + + beforeMount() { + const { value, min, max } = this.options; + this.setMinAndMax({ + min, + max, + }); + this.setValue(value); + this.populate(); + } + + render() { + const c = this._constant; + + const track = this._createTrack(); + this.slider = createWidget({ + type: SliderIconButton.xtype, + }); + this._draggable(this.slider); + + const sliderVertical = createWidget({ + type: VerticalAdaptLayout.xtype, + columnSize: ["fill"], + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.slider, + top: 8, + } + ], + height: c.SLIDER_HEIGHT, + } + ], + hgap: c.SLIDER_WIDTH_HALF, + height: c.SLIDER_HEIGHT, + }); + sliderVertical.element.click(e => { + if (this.enable && this.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { + const offset = e.clientX - this.element.offset().left - c.SLIDER_WIDTH_HALF; + const trackLength = this.track.element[0].scrollWidth - c.TRACK_GAP; + let percent = 0; + if (offset < 0) { + percent = 0; + } + if (offset > 0 && offset < trackLength) { + percent = (offset * 100) / this._getGrayTrackLength(); + } + if (offset >= trackLength) { + percent = 100; + } + const significantPercent = parseFloat(percent.toFixed(1)); + this._setAllPosition(significantPercent); + const v = this._getValueByPercent(significantPercent); + this.value = v; + this.fireEvent(SingleSlider.EVENT_CHANGE); + } + }); + + return { + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: track, + width: "100%", + height: c.TRACK_HEIGHT, + } + ], + } + ], + hgap: c.TRACK_GAP_HALF, + height: c.TRACK_HEIGHT, + }, + top: 3, + left: 0, + width: "100%", + }, + { + el: sliderVertical, + top: 0, + left: 0, + width: "100%", + } + ], + }; + } + + _draggable(widget) { + const o = this.options; + let startDrag = false; + let size = 0, + offset = 0, + defaultSize = 0; + const mouseMoveTracker = new MouseMoveTracker( + deltaX => { + if (mouseMoveTracker.isDragging()) { + startDrag = true; + offset += deltaX; + size = optimizeSize(defaultSize + offset); + widget.element.addClass("dragging"); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); // 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 + this._setBlueTrack(significantPercent); + this._setSliderPosition(significantPercent); + let v = this._getValueByPercent(significantPercent); + v = o.digit === false ? v : v.toFixed(o.digit); + this.value = v; + this.fireEvent(SingleSliderNormal.EVENT_DRAG, v); + } + }, + () => { + if (startDrag === true) { + size = optimizeSize(size); + const percent = (size * 100) / this._getGrayTrackLength(); + const significantPercent = parseFloat(percent.toFixed(1)); + this._setSliderPosition(significantPercent); + size = 0; + offset = 0; + defaultSize = size; + startDrag = false; + } + widget.element.removeClass("dragging"); + mouseMoveTracker.releaseMouseMoves(); + this.fireEvent(SingleSlider.EVENT_CHANGE); + }, + window + ); + widget.element.on("mousedown", function (event) { + if (!widget.isEnabled()) { + return; + } + defaultSize = this.offsetLeft; + optimizeSize(defaultSize); + mouseMoveTracker.captureMouseMoves(event); + }); + + const optimizeSize = s => clamp(s, 0, this._getGrayTrackLength()); + } + + _createTrack() { + this.grayTrack = createWidget({ + type: Layout.xtype, + cls: "gray-track", + height: 6, + }); + this.blueTrack = createWidget({ + type: Layout.xtype, + cls: "blue-track bi-high-light-background", + height: 6, + }); + if (this.options.color) { + this.blueTrack.element.css({ + "background-color": this.options.color, + }); + } + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: VerticalLayout.xtype, + items: [ + { + type: AbsoluteLayout.xtype, + items: [ + { + el: this.grayTrack, + top: 0, + left: 0, + width: "100%", + }, + { + el: this.blueTrack, + top: 0, + left: 0, + width: "0%", + } + ], + } + ], + hgap: 8, + height: 8, + }, + top: 8, + left: 0, + width: "100%", + } + ], + ref: _ref => { + this.track = _ref; + }, + }; + } + + _checkValidation(v) { + return !(isNull(v) || v < this.min || v > this.max); + } + + _setBlueTrack(percent) { + this.blueTrack.element.css({ width: `${percent}%` }); + } + + _setSliderPosition(percent) { + this.slider.element.css({ left: `${percent}%` }); + } + + _setAllPosition(percent) { + this._setSliderPosition(percent); + this._setBlueTrack(percent); + } + + _setVisible(visible) { + this.slider.setVisible(visible); + } + + _getGrayTrackLength() { + return this.grayTrack.element[0].scrollWidth; + } + + _getValueByPercent(percent) { + const thousandth = parseInt(percent * 10); + + return ((this.max - this.min) * thousandth) / 1000 + this.min; + } + + _getPercentByValue(v) { + return ((v - this.min) * 100) / (this.max - this.min); + } + + _setEnable(b) { + super._setEnable.apply(this, [b]); + if (b) { + this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); + } else { + this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); + } + } + + getValue() { + return this.value; + } + + setValue(v) { + const value = parseFloat(v); + if (!isNaN(value)) { + if (this._checkValidation(value)) { + this.value = value; + } + if (value > this.max) { + this.value = this.max; + } + if (value < this.min) { + this.value = this.min; + } + } + } + + setMinAndMax(v) { + const minNumber = parseFloat(v.min); + const maxNumber = parseFloat(v.max); + if (!isNaN(minNumber) && !isNaN(maxNumber) && maxNumber > minNumber) { + this.min = minNumber; + this.max = maxNumber; + } + } + + reset() { + this._setVisible(false); + this.enable = false; + this.value = ""; + this.min = 0; + this.max = 0; + this._setBlueTrack(0); + } + + populate() { + if (!isNaN(this.min) && !isNaN(this.max)) { + this._setVisible(true); + this.enable = true; + if (isNumeric(this.value) || isNotEmptyString(this.value)) { + this._setAllPosition(this._getPercentByValue(this.value)); + } else { + this._setAllPosition(100); + } + } + } +} diff --git a/src/widget/singletree/__test__/singletree.combo.test.js b/packages/fineui/src/widget/singletree/__test__/singletree.combo.test.js similarity index 100% rename from src/widget/singletree/__test__/singletree.combo.test.js rename to packages/fineui/src/widget/singletree/__test__/singletree.combo.test.js diff --git a/packages/fineui/src/widget/singletree/singletree.combo.js b/packages/fineui/src/widget/singletree/singletree.combo.js new file mode 100644 index 000000000..66cc15d95 --- /dev/null +++ b/packages/fineui/src/widget/singletree/singletree.combo.js @@ -0,0 +1,139 @@ +import { + shortcut, + Widget, + extend, + createWidget, + toPix, + Controller, + isKey, + isNull, + isEmptyArray, + isEmptyString, + isArray, + contains, + find +} from "@/core"; +import { Combo } from "@/base"; +import { SingleTreeTrigger } from "./singletree.trigger"; +import { SingleTreePopup } from "./singletree.popup"; + +@shortcut() +export class SingleTreeCombo extends Widget { + static xtype = "bi.single_tree_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + _defaultConfig(config) { + return extend(super._defaultConfig(...arguments), { + baseCls: `bi-single-tree-combo ${config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"}`, + trigger: {}, + height: 24, + text: "", + items: [], + value: "", + allowClear: false, + }); + } + + _init() { + const self = this, + o = this.options; + super._init(...arguments); + + this.trigger = createWidget( + extend( + { + type: SingleTreeTrigger.xtype, + text: o.text, + defaultText: o.defaultText, + height: toPix(o.height, 2), + items: o.items, + value: o.value, + allowClear: o.allowClear, + warningTitle: o.warningTitle, + }, + o.trigger + ) + ); + + this.trigger.on(SingleTreeTrigger.EVENT_CLEAR, () => { + self._clear(); + }); + + this.popup = createWidget({ + type: SingleTreePopup.xtype, + items: o.items, + value: o.value, + }); + + this.combo = createWidget({ + type: Combo.xtype, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + container: o.container, + element: this, + adjustLength: 2, + el: this.trigger, + popup: { + el: this.popup, + }, + }); + + this.combo.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, function () { + self.fireEvent(SingleTreeCombo.EVENT_BEFORE_POPUPVIEW, arguments); + }); + + this.popup.on(SingleTreePopup.EVENT_CHANGE, () => { + self.setValue(self.popup.getValue()); + self.combo.hideView(); + self.fireEvent(SingleTreeCombo.EVENT_CHANGE); + }); + + if (isKey(o.value)) { + this._checkError(o.value); + } + } + + _checkError(v) { + if (isNull(v) || isEmptyArray(v) || isEmptyString(v)) { + this.trigger.options.tipType = "success"; + this.trigger.element.removeClass("error"); + this.element.removeClass("error"); + } else { + v = isArray(v) ? v : [v]; + const result = find(this.options.items, (idx, item) => contains(v, item.value)); + if (isNull(result)) { + this.trigger.setTipType("warning"); + this.element.removeClass("error").addClass("error"); + this.trigger.element.removeClass("error").addClass("error"); + } else { + this.trigger.setTipType("success"); + this.trigger.element.removeClass("error"); + this.element.removeClass("error"); + } + } + } + + _clear() { + this.setValue([]); + } + + populate(items) { + this.combo.populate(items); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.trigger.setValue(v); + this.popup.setValue(v); + this._checkError(v); + } + + getValue() { + return this.popup.getValue(); + } +} diff --git a/packages/fineui/src/widget/singletree/singletree.popup.js b/packages/fineui/src/widget/singletree/singletree.popup.js new file mode 100644 index 000000000..65bcc5241 --- /dev/null +++ b/packages/fineui/src/widget/singletree/singletree.popup.js @@ -0,0 +1,67 @@ +import { shortcut, extend, i18nText, createWidget, Controller, isArray, VerticalLayout } from "@/core"; +import { Pane } from "@/base"; +import { LevelTree } from "@/case"; + +@shortcut() +export class SingleTreePopup extends Pane { + static xtype = "bi.single_level_tree"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-level-tree", + tipText: i18nText("BI-No_Selected_Item"), + items: [], + value: "", + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.tree = createWidget({ + type: LevelTree.xtype, + expander: { + isDefaultInit: true, + }, + items: o.items, + value: o.value, + chooseType: Selection.Single, + }); + + createWidget({ + type: VerticalLayout.xtype, + element: this, + vgap: 5, + items: [this.tree], + }); + + this.tree.on(Controller.EVENT_CHANGE, function () { + self.fireEvent(Controller.EVENT_CHANGE, arguments); + }); + + this.tree.on(LevelTree.EVENT_CHANGE, () => { + self.fireEvent(SingleTreePopup.EVENT_CHANGE); + }); + + this.check(); + } + + getValue() { + return this.tree.getValue(); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.tree.setValue(v); + } + + populate(items) { + super.populate(...arguments); + this.tree.populate(items); + } +} diff --git a/packages/fineui/src/widget/singletree/singletree.trigger.js b/packages/fineui/src/widget/singletree/singletree.trigger.js new file mode 100644 index 000000000..e7f4cc916 --- /dev/null +++ b/packages/fineui/src/widget/singletree/singletree.trigger.js @@ -0,0 +1,86 @@ +import { shortcut, extend, emptyFn, createWidget, contains, isArray, some } from "@/core"; +import { Trigger } from "@/base"; +import { SelectTextTrigger } from "@/case"; + +@shortcut() +export class SingleTreeTrigger extends Trigger { + static xtype = "bi.single_tree_trigger"; + + static EVENT_CLEAR = "EVENT_CLEAR"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-single-tree-trigger", + height: 24, + text: "", + items: [], + value: "", + allowClear: false, + valueFormatter: emptyFn, + }); + } + + _init() { + super._init(...arguments); + + const self = this, + o = this.options; + + this.trigger = createWidget({ + type: SelectTextTrigger.xtype, + element: this, + text: o.text, + defaultText: o.defaultText, + items: o.items, + height: o.height, + warningTitle: o.warningTitle, + tipType: o.tipType, + value: o.value, + allowClear: o.allowClear, + valueFormatter: o.valueFormatter, + listeners: [ + { + eventName: SelectTextTrigger.EVENT_CLEAR, + action() { + self.fireEvent(SingleTreeTrigger.EVENT_CLEAR); + }, + } + ], + }); + } + + _checkTitle() { + const val = this.getValue(); + some(this.options.items, (i, item) => { + if (contains(val, item.value)) { + this.trigger.setTitle(item.text || item.value); + + return true; + } + }); + } + + setValue(v) { + v = isArray(v) ? v : [v]; + this.options.value = v; + this.trigger.setValue(v); + this._checkTitle(); + } + + setTipType(v) { + this.options.tipType = v; + this.trigger.setTipType(v); + } + + getValue() { + return this.options.value || []; + } + + getTextor() { + return this.trigger.getTextor(); + } + + populate(items) { + this.trigger.populate(items); + } +} diff --git a/src/widget/textvaluedownlistcombo/__test__/combo.textvaluedownlist.test.js b/packages/fineui/src/widget/textvaluedownlistcombo/__test__/combo.textvaluedownlist.test.js similarity index 100% rename from src/widget/textvaluedownlistcombo/__test__/combo.textvaluedownlist.test.js rename to packages/fineui/src/widget/textvaluedownlistcombo/__test__/combo.textvaluedownlist.test.js diff --git a/packages/fineui/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js b/packages/fineui/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js new file mode 100644 index 000000000..398888e25 --- /dev/null +++ b/packages/fineui/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js @@ -0,0 +1,117 @@ +import { DownListSelectTextTrigger } from "./trigger.textvaluedownlist"; +import { + shortcut, + Widget, + extend, + isNotNull, + createWidget, + Selection, + toPix, + isNull, + deepClone, + each, + flatten, + has, +} from "@/core"; +import { DownListCombo } from "../downlist"; + +@shortcut() +export class TextValueDownListCombo extends Widget { + static xtype = "bi.text_value_down_list_combo"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig(config) { + return extend(super._defaultConfig(...arguments), { + baseCls: + "bi-text-value-down-list-combo " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), + height: 24, + }); + } + + _init() { + const o = this.options; + super._init(...arguments); + this._createValueMap(); + + let value; + if (isNotNull(o.value)) { + value = this._digest(o.value); + } + + this.combo = createWidget({ + type: DownListCombo.xtype, + element: this, + chooseType: Selection.Single, + adjustLength: 2, + width: toPix(o.width, 2), + height: toPix(o.height, 2), + el: { + type: DownListSelectTextTrigger.xtype, + ref: _ref => { + this.trigger = _ref; + }, + cls: "text-value-down-list-trigger", + height: toPix(o.height, 2), + items: o.items, + text: o.text, + value, + }, + value: isNull(value) ? [] : [value], + items: deepClone(o.items), + }); + + this.combo.on(DownListCombo.EVENT_CHANGE, () => { + const currentVal = this.combo.getValue()[0].value; + if (currentVal !== this.value) { + this.setValue(currentVal); + this.fireEvent(TextValueDownListCombo.EVENT_CHANGE); + } + }); + + this.combo.on(DownListCombo.EVENT_SON_VALUE_CHANGE, () => { + const currentVal = this.combo.getValue()[0].childValue; + if (currentVal !== this.value) { + this.setValue(currentVal); + this.fireEvent(TextValueDownListCombo.EVENT_CHANGE); + } + }); + } + + _createValueMap() { + this.valueMap = {}; + each(flatten(this.options.items), (idx, item) => { + if (has(item, "el")) { + each(item.children, (id, it) => { + this.valueMap[it.value] = { value: item.el.value, childValue: it.value }; + }); + } else { + this.valueMap[item.value] = { value: item.value }; + } + }); + } + + _digest(v) { + this.value = v; + + return this.valueMap[v]; + } + + setValue(v) { + v = this._digest(v); + this.combo.setValue([v]); + this.trigger?.setValue(v); + } + + getValue() { + const v = this.combo.getValue()[0]; + + return [v.childValue || v.value]; + } + + populate(items) { + this.options.items = flatten(items); + this.combo.populate(items); + this._createValueMap(); + } +} diff --git a/packages/fineui/src/widget/textvaluedownlistcombo/index.js b/packages/fineui/src/widget/textvaluedownlistcombo/index.js new file mode 100644 index 000000000..740fc4bea --- /dev/null +++ b/packages/fineui/src/widget/textvaluedownlistcombo/index.js @@ -0,0 +1,2 @@ +export { TextValueDownListCombo } from "./combo.textvaluedownlist"; +export { DownListSelectTextTrigger } from "./trigger.textvaluedownlist"; diff --git a/packages/fineui/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js b/packages/fineui/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js new file mode 100644 index 000000000..31faad5e8 --- /dev/null +++ b/packages/fineui/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js @@ -0,0 +1,54 @@ +import { shortcut, extend, createWidget, isNull, flatten, deepClone, each, has, concat } from "@/core"; +import { Trigger } from "@/base"; +import { SelectTextTrigger } from "@/case"; + +@shortcut() +export class DownListSelectTextTrigger extends Trigger { + static xtype = "bi.down_list_select_text_trigger"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-down-list-select-text-trigger", + height: 24, + text: "", + }); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.trigger = createWidget({ + type: SelectTextTrigger.xtype, + element: this, + height: o.height, + items: this._formatItemArray(o.items), + text: o.text, + value: isNull(o.value) ? "" : o.value.childValue || o.value.value, + }); + } + + _formatItemArray() { + const sourceArray = flatten(deepClone(this.options.items)); + let targetArray = []; + each(sourceArray, (idx, item) => { + if (has(item, "el")) { + each(item.children, (id, it) => { + it.text = `${item.el.text}(${it.text})`; + }); + targetArray = concat(targetArray, item.children); + } else { + targetArray.push(item); + } + }); + + return targetArray; + } + + setValue(vals) { + this.trigger.setValue(vals.childValue || vals.value); + } + + populate(items) { + this.trigger.populate(this._formatItemArray(items)); + } +} diff --git a/src/widget/time/__test__/time.combo.test.js b/packages/fineui/src/widget/time/__test__/time.combo.test.js similarity index 100% rename from src/widget/time/__test__/time.combo.test.js rename to packages/fineui/src/widget/time/__test__/time.combo.test.js diff --git a/packages/fineui/src/widget/time/datetime.popup.js b/packages/fineui/src/widget/time/datetime.popup.js new file mode 100644 index 000000000..f70181e26 --- /dev/null +++ b/packages/fineui/src/widget/time/datetime.popup.js @@ -0,0 +1,127 @@ +import { + VTapeLayout, + shortcut, + Widget, + i18nText, + CenterAdaptLayout, + GridLayout, + isNull, + isEmptyObject, + isEmptyString +} from "@/core"; +import { TextButton } from "@/base"; +import { DynamicDateTimeSelect } from "../dynamicdatetime"; + +@shortcut() +export class TimePopup extends Widget { + static xtype = "bi.time_popup"; + + props = { + baseCls: "bi-date-time-popup", + height: 68, + }; + + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static BUTTON_NOW_EVENT_CHANGE = "BUTTON_NOW_EVENT_CHANGE"; + static CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; + + render() { + const o = this.options; + + return { + type: VTapeLayout.xtype, + items: [ + { + el: { + type: CenterAdaptLayout.xtype, + cls: "bi-split-top", + items: [ + { + type: DynamicDateTimeSelect.xtype, + value: o.value, + ref: _ref => { + this.timeSelect = _ref; + }, + } + ], + }, + hgap: 10, + height: 44, + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + shadow: true, + text: i18nText("BI-Basic_Clears"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(TimePopup.BUTTON_CLEAR_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + shadow: true, + text: i18nText("BI-Basic_Now"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(TimePopup.BUTTON_NOW_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-high-light bi-split-top", + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(TimePopup.BUTTON_OK_EVENT_CHANGE); + }, + } + ], + } + ] + ], + }, + height: 24, + } + ], + }; + } + + setValue(value) { + if (this._checkValueValid(value)) { + this.timeSelect.setValue(); + } else { + this.timeSelect.setValue({ + hour: value.hour, + minute: value.minute, + second: value.second, + }); + } + } + + getValue() { + return this.timeSelect.getValue(); + } + + _checkValueValid(value) { + return isNull(value) || isEmptyObject(value) || isEmptyString(value); + } +} diff --git a/packages/fineui/src/widget/time/index.js b/packages/fineui/src/widget/time/index.js new file mode 100644 index 000000000..da4e7bbe8 --- /dev/null +++ b/packages/fineui/src/widget/time/index.js @@ -0,0 +1,3 @@ +export { TimePopup } from "./datetime.popup"; +export { TimeCombo } from "./time.combo"; +export { TimeTrigger } from "./time.trigger"; diff --git a/packages/fineui/src/widget/time/time.combo.js b/packages/fineui/src/widget/time/time.combo.js new file mode 100644 index 000000000..f6375da3a --- /dev/null +++ b/packages/fineui/src/widget/time/time.combo.js @@ -0,0 +1,277 @@ +import { + HorizontalFillLayout, + shortcut, + toPix, + getDate, + isNotEmptyString, + isEqual, + isEmptyString, + AbsoluteLayout +} from "@/core"; +import { TimeTrigger } from "./time.trigger"; +import { Single, IconButton, Combo } from "@/base"; +import { TimePopup } from "./datetime.popup"; + +@shortcut() +export class TimeCombo extends Single { + static xtype = "bi.time_combo"; + + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + constants = { + popupHeight: 80, + popupWidth: 240, + comboAdjustHeight: 1, + border: 1, + iconWidth: 24, + }; + + props = { + baseCls: "bi-time-combo", + height: 24, + format: "", + allowEdit: false, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + }; + + _init() { + super._init(...arguments); + } + + render() { + const opts = this.options; + this.storeTriggerValue = ""; + this.storeValue = opts.value; + + const popup = { + type: TimePopup.xtype, + value: opts.value, + listeners: [ + { + eventName: TimePopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.hidePopupView(); + this.fireEvent(TimeCombo.EVENT_CONFIRM); + }, + }, + { + eventName: TimePopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.hidePopupView(); + this.fireEvent(TimeCombo.EVENT_CONFIRM); + }, + }, + { + eventName: TimePopup.BUTTON_NOW_EVENT_CHANGE, + action: () => { + this._setNowTime(); + }, + } + ], + ref: _ref => { + this.popup = _ref; + }, + }; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: Combo.xtype, + cls: "bi-border bi-border-radius", + container: opts.container, + toggle: false, + isNeedAdjustHeight: opts.isNeedAdjustHeight, + isNeedAdjustWidth: opts.isNeedAdjustWidth, + el: { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", this.constants.iconWidth], + height: toPix(opts.height, 2), + items: [ + { + type: TimeTrigger.xtype, + height: toPix(opts.height, 2), + allowEdit: opts.allowEdit, + watermark: opts.watermark, + format: opts.format, + value: opts.value, + ref: _ref => { + this.trigger = _ref; + }, + listeners: [ + { + eventName: "EVENT_KEY_DOWN", + action: () => { + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } + this.fireEvent(TimeCombo.EVENT_KEY_DOWN, arguments); + }, + }, + { + eventName: "EVENT_STOP", + action: () => { + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + }, + }, + { + eventName: "EVENT_FOCUS", + action: () => { + this.storeTriggerValue = this.trigger.getKey(); + if (!this.combo.isViewVisible()) { + this.combo.showView(); + } + this.fireEvent("EVENT_FOCUS"); + }, + }, + { + eventName: "EVENT_BLUR", + action: () => { + this.fireEvent("EVENT_BLUR"); + }, + }, + { + eventName: "EVENT_ERROR", + action: () => { + const date = getDate(); + this.storeValue = { + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + }; + this.fireEvent("EVENT_ERROR"); + }, + }, + { + eventName: "EVENT_VALID", + action: () => { + this.fireEvent("EVENT_VALID"); + }, + }, + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_CONFIRM", + action: () => { + if (this.combo.isViewVisible()) { + return; + } + const dateStore = this.storeTriggerValue; + const dateObj = this.trigger.getKey(); + if (isNotEmptyString(dateObj) && !isEqual(dateObj, dateStore)) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.trigger.getValue()); + } else if (isEmptyString(dateObj)) { + this.storeValue = null; + this.trigger.setValue(); + } + this.fireEvent("EVENT_CONFIRM"); + }, + } + ], + }, + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button time-font", + width: this.constants.iconWidth, + listeners: [ + { + eventName: IconButton.EVENT_CHANGE, + action: () => { + if (this.combo.isViewVisible()) { + // this.combo.hideView(); + } else { + this.combo.showView(); + } + }, + } + ], + ref: _ref => { + this.triggerBtn = _ref; + }, + }, + } + ], + }, + adjustLength: this.constants.comboAdjustHeight, + popup: { + el: popup, + width: opts.isNeedAdjustWidth ? opts.width : this.constants.popupWidth, + stopPropagation: false, + }, + hideChecker: e => this.triggerBtn.element.find(e.target).length === 0, + listeners: [ + { + eventName: Combo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.popup.setValue(this.storeValue); + this.fireEvent(TimeCombo.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + ref: _ref => { + this.combo = _ref; + }, + }, + top: 0, + left: 0, + right: 0, + bottom: 0, + } + ], + }; + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + } + + getValue() { + return this.storeValue; + } + + hidePopupView() { + this.combo.hideView(); + } + + _setNowTime() { + const date = getDate(); + const nowTome = { + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + }; + this.setValue(nowTome); + this.hidePopupView(); + this.fireEvent(TimeCombo.EVENT_CONFIRM); + } + + focus() { + this.trigger.focus(); + } + + blur() { + this.trigger.blur(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/time/time.trigger.js b/packages/fineui/src/widget/time/time.trigger.js new file mode 100644 index 000000000..526678025 --- /dev/null +++ b/packages/fineui/src/widget/time/time.trigger.js @@ -0,0 +1,252 @@ +import { + shortcut, + i18nText, + bind, + isNotNull, + isNotEmptyString, + isEqual, + AbsoluteLayout, + any, + print, + parseDateTime, + isEmptyObject, + getDate, + isNotEmptyObject +} from "@/core"; +import { Trigger, Text } from "@/base"; +import { SignEditor } from "@/case"; + +@shortcut() +export class TimeTrigger extends Trigger { + static xtype = "bi.time_trigger"; + + _const = { + COMPARE_FORMAT: "%H:%M:%S", + COMPLETE_COMPARE_FORMAT: "%Y-%M-%d %H:%M:%S %P", + FORMAT_ARRAY: [ + "%H:%M:%S", + "%I:%M:%S", + "%l:%M:%S", + "%k:%M:%S", + "%l:%M:%S %p", + "%l:%M:%S %P", + "%H:%M:%S %p", + "%H:%M:%S %P", + "%l:%M", + "%k:%M", + "%I:%M", + "%H:%M", + "%M:%S" + ], + DEFAULT_DATE_STRING: "2000-01-01", + DEFAULT_HOUR: "00", + }; + + props() { + return { + extraCls: "bi-time-trigger", + value: {}, + format: "", + allowEdit: false, + watermark: i18nText("BI-Basic_Unrestricted"), + }; + } + + render() { + const o = this.options; + this.storeTriggerValue = ""; + this.storeValue = o.value; + + return { + type: AbsoluteLayout.xtype, + items: [ + { + el: { + type: SignEditor.xtype, + height: o.height, + validationChecker: v => this._dateCheck(v), + quitChecker() { + return false; + }, + ref: _ref => { + this.editor = _ref; + }, + value: this._formatValue(o.value), + hgap: 4, + allowBlank: true, + watermark: o.watermark, + title: bind(this._getTitle, this), + listeners: [ + { + eventName: "EVENT_KEY_DOWN", + action: (...args) => { + this.fireEvent("EVENT_KEY_DOWN", ...args); + }, + }, + { + eventName: "EVENT_FOCUS", + action: () => { + this.storeTriggerValue = this.getKey(); + this.fireEvent("EVENT_FOCUS"); + }, + }, + { + eventName: "EVENT_BLUR", + action: () => { + this.fireEvent("EVENT_BLUR"); + }, + }, + { + eventName: "EVENT_STOP", + action: () => { + this.fireEvent("EVENT_STOP"); + }, + }, + { + eventName: "EVENT_VALID", + action: () => { + this.fireEvent("EVENT_VALID"); + }, + }, + { + eventName: "EVENT_ERROR", + action: () => { + this.fireEvent("EVENT_ERROR"); + }, + }, + { + eventName: "EVENT_CONFIRM", + action: () => { + const value = this.editor.getValue(); + if (isNotNull(value)) { + this.editor.setState(value); + } + if (isNotEmptyString(value) && !isEqual(this.storeTriggerValue, this.getKey())) { + const date = value.match(/\d+/g); + this.storeValue = { + hour: date[0] | 0, + minute: date[1] | 0, + second: date[2] | 0, + }; + } + this.fireEvent("EVENT_CONFIRM"); + }, + }, + { + eventName: "EVENT_START", + action: () => { + this.fireEvent("EVENT_START"); + }, + }, + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + } + ], + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + { + el: { + type: Text.xtype, + invisible: o.allowEdit, + cls: "show-text", + title: bind(this._getTitle, this), + hgap: 4, + }, + left: 0, + right: 0, + top: 0, + bottom: 0, + } + ], + }; + } + + _dateCheck(date) { + const c = this._const; + + return any( + c.FORMAT_ARRAY, + (idx, format) => + print( + parseDateTime( + `${c.DEFAULT_DATE_STRING} ${this._getCompleteHMS(date, format)}`, + c.COMPLETE_COMPARE_FORMAT + ), + format + ) === date + ); + } + + _getCompleteHMS(str, format) { + const c = this._const; + switch (format) { + case "%M:%S": + str = `${c.DEFAULT_HOUR}:${str}`; + break; + default: + break; + } + + return str; + } + + _getTitle() { + const storeValue = this.storeValue || {}; + if (isEmptyObject(storeValue)) { + return this.options.watermark; + } + const date = getDate(); + + return print( + getDate(date.getFullYear(), 0, 1, storeValue.hour, storeValue.minute, storeValue.second), + this._getFormatString() + ); + } + + _getFormatString() { + return this.options.format || this._const.COMPARE_FORMAT; + } + + _formatValue(v) { + const now = getDate(); + + return isNotEmptyObject(v) + ? print( + getDate(now.getFullYear(), now.getMonth(), now.getDay(), v.hour, v.minute, v.second), + this._getFormatString() + ) + : ""; + } + + getKey() { + return this.editor.getValue(); + } + + setValue(v) { + this.storeValue = v; + this.editor.setValue(this._formatValue(v)); + } + + getValue() { + return this.storeValue; + } + + focus() { + this.editor.focus(); + } + + blur() { + this.editor.blur(); + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/src/widget/timeinterval/__test__/timeinterval.test.js b/packages/fineui/src/widget/timeinterval/__test__/timeinterval.test.js similarity index 100% rename from src/widget/timeinterval/__test__/timeinterval.test.js rename to packages/fineui/src/widget/timeinterval/__test__/timeinterval.test.js diff --git a/packages/fineui/src/widget/timeinterval/dateinterval.js b/packages/fineui/src/widget/timeinterval/dateinterval.js new file mode 100644 index 000000000..76a7ff381 --- /dev/null +++ b/packages/fineui/src/widget/timeinterval/dateinterval.js @@ -0,0 +1,244 @@ +import { + HorizontalFillLayout, + shortcut, + extend, + createWidget, + i18nText, + print, + parseDateTime, + checkDateVoid, + checkDateLegal, + isNotNull, +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { DynamicDateCombo } from "../dynamicdate"; + +@shortcut() +export class DateInterval extends Single { + static xtype = "bi.date_interval"; + + constants = { + height: 24, + width: 24, + lgap: 15, + offset: 0, + timeErrorCls: "time-error", + }; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: "bi-date-interval", + minDate: "1900-01-01", + maxDate: "2099-12-31", + height: 24, + supportDynamic: true, + simple: false, + }); + } + + render() { + const o = this.options; + o.value = o.value || {}; + this.left = this._createCombo(o.value.start, o.watermark?.start); + this.right = this._createCombo(o.value.end, o.watermark?.end); + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: this.left, + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: this.right, + }, + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + const combo = createWidget({ + type: DynamicDateCombo.xtype, + supportDynamic: o.supportDynamic, + minDate: o.minDate, + maxDate: o.maxDate, + simple: o.simple, + behaviors: o.behaviors, + watermark, + value: v, + height: o.height, + listeners: [ + { + eventName: DynamicDateCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, + action: () => { + this.fireEvent(DateInterval.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); + }, + }, + ], + }); + combo.on(DynamicDateCombo.EVENT_ERROR, () => { + this._clearTitle(); + Bubbles.hide("error"); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(DateInterval.EVENT_ERROR); + }); + + combo.on(DynamicDateCombo.EVENT_VALID, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if (this._check(smallDate, bigDate) && this._compare(smallDate, bigDate)) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(DateInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + }); + + combo.on(DynamicDateCombo.EVENT_FOCUS, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if (this._check(smallDate, bigDate) && this._compare(smallDate, bigDate)) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(DateInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + }); + + // combo.on(DynamicDateCombo.EVENT_BEFORE_POPUPVIEW, () => { + // this.left.hidePopupView(); + // this.right.hidePopupView(); + // }); + + combo.on(DynamicDateCombo.EVENT_CONFIRM, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if (this._check(smallDate, bigDate) && this._compare(smallDate, bigDate)) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + this.fireEvent(DateInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(DateInterval.EVENT_CHANGE); + } + }); + + return combo; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || + print(parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || + print(parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || + print(parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date + ); + } + + _checkVoid(obj) { + const o = this.options; + + return !checkDateVoid(obj.year, obj.month, obj.day, o.minDate, o.maxDate)[0]; + } + + _check(smallDate, bigDate) { + const smallObj = smallDate.match(/\d+/g), + bigObj = bigDate.match(/\d+/g); + + return ( + this._dateCheck(smallDate) && + checkDateLegal(smallDate) && + this._checkVoid({ + year: smallObj[0], + month: smallObj[1], + day: smallObj[2], + }) && + this._dateCheck(bigDate) && + checkDateLegal(bigDate) && + this._checkVoid({ + year: bigObj[0], + month: bigObj[1], + day: bigObj[2], + }) + ); + } + + _compare(smallDate, bigDate) { + smallDate = print(parseDateTime(smallDate, "%Y-%X-%d"), "%Y-%X-%d"); + bigDate = print(parseDateTime(bigDate, "%Y-%X-%d"), "%Y-%X-%d"); + + return isNotNull(smallDate) && isNotNull(bigDate) && smallDate > bigDate; + } + + _setTitle(v) { + this.left.setTitle(v); + this.right.setTitle(v); + this.label.setTitle(v); + } + + _clearTitle() { + this.left.setTitle(""); + this.right.setTitle(""); + this.label.setTitle(""); + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.left.setMinDate(minDate); + this.right.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.left.setMaxDate(maxDate); + this.right.setMaxDate(maxDate); + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + } + + getValue() { + return { + start: this.left.getValue(), + end: this.right.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/timeinterval/index.js b/packages/fineui/src/widget/timeinterval/index.js new file mode 100644 index 000000000..58eb61b77 --- /dev/null +++ b/packages/fineui/src/widget/timeinterval/index.js @@ -0,0 +1,3 @@ +export { DateInterval } from "./dateinterval"; +export { TimeInterval } from "./timeinterval"; +export { TimePeriods } from "./timeperiods"; diff --git a/packages/fineui/src/widget/timeinterval/timeinterval.js b/packages/fineui/src/widget/timeinterval/timeinterval.js new file mode 100644 index 000000000..b1c9848c2 --- /dev/null +++ b/packages/fineui/src/widget/timeinterval/timeinterval.js @@ -0,0 +1,250 @@ +import { + HorizontalFillLayout, + shortcut, + extend, + createWidget, + i18nText, + print, + parseDateTime, + checkDateVoid, + checkDateLegal, + isNotNull +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { DynamicDateTimeCombo } from "../dynamicdatetime"; + +@shortcut() +export class TimeInterval extends Single { + static xtype = "bi.time_interval"; + + constants = { + height: 24, + width: 24, + lgap: 15, + offset: 0, + timeErrorCls: "time-error", + }; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + const conf = super._defaultConfig(...arguments); + + return extend(conf, { + extraCls: "bi-time-interval", + minDate: "1900-01-01", + maxDate: "2099-12-31", + height: 24, + supportDynamic: true, + }); + } + + render() { + const o = this.options; + o.value = o.value || {}; + this.left = this._createCombo(o.value.start, o.watermark?.start); + this.right = this._createCombo(o.value.end, o.watermark?.end); + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: this.left, + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: this.right, + } + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + const combo = createWidget({ + type: DynamicDateTimeCombo.xtype, + simple: o.simple, + supportDynamic: o.supportDynamic, + minDate: o.minDate, + maxDate: o.maxDate, + behaviors: o.behaviors, + watermark, + value: v, + height: o.height, + }); + combo.on(DynamicDateTimeCombo.EVENT_ERROR, () => { + this._clearTitle(); + Bubbles.hide("error"); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(TimeInterval.EVENT_ERROR); + }); + + combo.on(DynamicDateTimeCombo.EVENT_VALID, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(TimeInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + }); + + combo.on(DynamicDateTimeCombo.EVENT_FOCUS, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(TimeInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + }); + + // 不知道干啥的,先注释掉 + // combo.on(DynamicDateTimeCombo.EVENT_BEFORE_POPUPVIEW, () => { + // this.left.hidePopupView(); + // this.right.hidePopupView(); + // }); + + combo.on(DynamicDateTimeCombo.EVENT_CONFIRM, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + this.fireEvent(TimeInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(TimeInterval.EVENT_CHANGE); + } + }); + + return combo; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%x-%d %H:%M:%S"), "%Y-%x-%d %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%x-%e %H:%M:%S"), "%Y-%x-%e %H:%M:%S") === date || + print(parseDateTime(date, "%Y-%X-%e %H:%M:%S"), "%Y-%X-%e %H:%M:%S") === date + ); + } + + _checkVoid(obj) { + const o = this.options; + + return !checkDateVoid(obj.year, obj.month, obj.day, o.minDate, o.maxDate)[0]; + } + + _check(smallDate, bigDate) { + const smallObj = smallDate.match(/\d+/g), + bigObj = bigDate.match(/\d+/g); + + return ( + this._dateCheck(smallDate) && + checkDateLegal(smallDate) && + this._checkVoid({ + year: smallObj[0], + month: smallObj[1], + day: smallObj[2], + }) && + this._dateCheck(bigDate) && + checkDateLegal(bigDate) && + this._checkVoid({ + year: bigObj[0], + month: bigObj[1], + day: bigObj[2], + }) + ); + } + + _compare(smallDate, bigDate) { + smallDate = print(parseDateTime(smallDate, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S"); + bigDate = print(parseDateTime(bigDate, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S"); + + return isNotNull(smallDate) && isNotNull(bigDate) && smallDate > bigDate; + } + + _setTitle(v) { + this.left.setTitle(v); + this.right.setTitle(v); + this.label.setTitle(v); + } + + _clearTitle() { + this.left.setTitle(""); + this.right.setTitle(""); + this.label.setTitle(""); + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.left.setMinDate(minDate); + this.right.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.left.setMaxDate(maxDate); + this.right.setMaxDate(maxDate); + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + } + + getValue() { + return { + start: this.left.getValue(), + end: this.right.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/timeinterval/timeperiods.js b/packages/fineui/src/widget/timeinterval/timeperiods.js new file mode 100644 index 000000000..2c8d90a96 --- /dev/null +++ b/packages/fineui/src/widget/timeinterval/timeperiods.js @@ -0,0 +1,103 @@ +import { HorizontalFillLayout, shortcut, extend } from "@/core"; +import { Single, Label } from "@/base"; +import { TimeCombo } from "../time"; + +@shortcut() +export class TimePeriods extends Single { + static xtype = "bi.time_periods"; + + props = { + extraCls: "bi-time-interval", + value: {}, + }; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + const o = this.options; + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: extend( + { + ref: _ref => { + this.left = _ref; + }, + }, + this._createCombo(o.value.start, o.watermark?.start) + ), + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: extend( + { + ref: _ref => { + this.right = _ref; + }, + }, + this._createCombo(o.value.end, o.watermark?.end) + ), + } + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + + return { + type: TimeCombo.xtype, + value: v, + height: o.height, + watermark, + listeners: [ + { + eventName: TimeCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.left.hidePopupView(); + this.right.hidePopupView(); + }, + }, + { + eventName: TimeCombo.EVENT_CHANGE, + action: () => { + this.fireEvent(TimePeriods.EVENT_CHANGE); + }, + }, + { + eventName: TimeCombo.EVENT_CONFIRM, + action: () => { + this.fireEvent(TimePeriods.EVENT_CONFIRM); + }, + } + ], + }; + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + } + + getValue() { + return { + start: this.left.getValue(), + end: this.right.getValue(), + }; + } +} diff --git a/src/widget/year/__test__/combo.year.test.js b/packages/fineui/src/widget/year/__test__/combo.year.test.js similarity index 100% rename from src/widget/year/__test__/combo.year.test.js rename to packages/fineui/src/widget/year/__test__/combo.year.test.js diff --git a/packages/fineui/src/widget/year/card.dynamic.year.js b/packages/fineui/src/widget/year/card.dynamic.year.js new file mode 100644 index 000000000..020af63a2 --- /dev/null +++ b/packages/fineui/src/widget/year/card.dynamic.year.js @@ -0,0 +1,129 @@ +import { checkDateVoid, i18nText, isNotEmptyString, parseDateTime, shortcut, VerticalLayout, Widget, SIZE_CONSANTS } from "@/core"; +import { Bubbles, Label } from "@/base"; +import { DynamicDateCard } from "@/widget/dynamicdate/dynamicdate.card"; +import { DynamicDateHelper } from "@/widget/dynamicdate/dynamicdate.caculate"; +import { DynamicDateParamItem } from "@/widget/dynamicdate/dynamicdate.param.item"; + +/** + * 年份展示面板 + * + * Created by GUY on 2015/9/2. + * @class YearCard + * @extends Trigger + */ + +@shortcut() +export class DynamicYearCard extends Widget { + static xtype = "bi.dynamic_year_card"; + static EVENT_CHANGE = "EVENT_CHANGE"; + props = { + baseCls: "bi-year-card", + }; + render() { + return { + type: VerticalLayout.xtype, + ref: _ref => { + this.wrapper = _ref; + }, + items: [ + { + type: Label.xtype, + text: i18nText("BI-Multi_Date_Relative_Current_Time"), + textAlign: "left", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }, + { + type: DynamicDateParamItem.xtype, + ref: _ref => { + this.item = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action: () => { + Bubbles.hide("dynamic-year-error"); + }, + } + ], + } + ], + vgap: 10, + hgap: 10, + }; + } + _checkDate() { + const o = this.options; + const date = DynamicDateHelper.getCalculation(this._getValue()); + + return !checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; + } + + _createValue(type, v) { + return { + dateType: type, + value: Math.abs(v), + offset: v > 0 ? 1 : 0, + }; + } + + _getErrorText() { + const o = this.options; + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText("BI-Basic_Year_Range_Error", start.getFullYear(), end.getFullYear()); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + v = v || { year: 0 }; + this.item.setValue(this._createValue(DynamicDateCard.TYPE.YEAR, v.year)); + } + + _getValue() { + const value = this.item.getValue(); + + return { + year: value.offset === 0 ? -value.value : +value.value, + }; + } + + getInputValue() { + return this._getValue(); + } + + getValue() { + return this.checkValidation() ? this._getValue() : {}; + } + + checkValidation(show) { + let errorText; + let invalid = !this.item.checkValidation(); + if (invalid) { + errorText = i18nText("BI-Please_Input_Natural_Number"); + } else { + invalid = !this._checkDate(this._getValue()); + errorText = this._getErrorText(); + } + invalid && show && Bubbles.show("dynamic-year-error", errorText, this.item, {}); + + return !invalid; + } +} diff --git a/packages/fineui/src/widget/year/card.year.js b/packages/fineui/src/widget/year/card.year.js new file mode 100644 index 000000000..5af1fa99c --- /dev/null +++ b/packages/fineui/src/widget/year/card.year.js @@ -0,0 +1,217 @@ +import { + shortcut, + Widget, + extend, + createWidget, + getDate, + bind, + Controller, + isKey, + HTapeLayout, + CenterAdaptLayout, + Layout, + each, + isNotEmptyString, + checkDateVoid, + parseInt +} from "@/core"; +import { YearCalendar } from "@/case"; +import { IconButton, Navigation } from "@/base"; + +@shortcut() +export class StaticYearCard extends Widget { + static xtype = "bi.static_year_card"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + baseCls: "bi-year-card", + behaviors: {}, + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + }); + } + + _createYearCalendar(v) { + const o = this.options, + y = this._year; + const calendar = createWidget({ + type: YearCalendar.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + logic: { + dynamic: true, + }, + year: y + v * 12, + }); + calendar.setValue(this._year); + + return calendar; + } + + _init() { + super._init(...arguments); + const o = this.options; + + this.selectedYear = this._year = getDate().getFullYear(); + this.backBtn = createWidget({ + type: IconButton.xtype, + cls: "pre-page-h-font", + width: 25, + height: 25, + value: -1, + listeners: [ + { + eventName: IconButton.EVENT_CHANGE, + action: () => { + this.navigation.setSelect(this.navigation.getSelect() - 1); + this._checkLeftValid(); + this._checkRightValid(); + }, + } + ], + }); + + this.preBtn = createWidget({ + type: IconButton.xtype, + cls: "next-page-h-font", + width: 25, + height: 25, + value: 1, + listeners: [ + { + eventName: IconButton.EVENT_CHANGE, + action: () => { + this.navigation.setSelect(this.navigation.getSelect() + 1); + this._checkLeftValid(); + this._checkRightValid(); + }, + } + ], + }); + + this.navigation = createWidget({ + type: Navigation.xtype, + direction: "top", + element: this, + single: true, + logic: { + dynamic: true, + }, + tab: { + type: HTapeLayout.xtype, + cls: "bi-split-top bi-split-bottom", + height: 30, + items: [ + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.backBtn], + }, + width: 25, + }, + { + type: Layout.xtype, + }, + { + el: { + type: CenterAdaptLayout.xtype, + items: [this.preBtn], + }, + width: 25, + } + ], + }, + cardCreator: bind(this._createYearCalendar, this), + + afterCardShow: () => { + this.navigation.setValue(this.selectedYear); + // var calendar = this.getSelectedCard(); + // this.backBtn.setEnable(!calendar.isFrontYear()); + // this.preBtn.setEnable(!calendar.isFinalYear()); + }, + }); + + this.navigation.on(Navigation.EVENT_CHANGE, () => { + this.selectedYear = this.navigation.getValue(); + this.fireEvent(Controller.EVENT_CHANGE, ...arguments); + this.fireEvent(StaticYearCard.EVENT_CHANGE, this.selectedYear); + }); + + if (isKey(o.value)) { + this.setValue(o.value); + } + } + + _checkLeftValid() { + const valid = true; + this.backBtn.setEnable(valid); + + return valid; + } + + _checkRightValid() { + const valid = true; + this.preBtn.setEnable(valid); + + return valid; + } + + _checkMin() { + const o = this.options; + each(this.navigation.getAllCard(), (idx, calendar) => { + calendar.setMinDate(o.min); + }); + } + + _checkMax() { + const o = this.options; + each(this.navigation.getAllCard(), (idx, calendar) => { + calendar.setMaxDate(o.max); + }); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + this._checkLeftValid(); + this._checkRightValid(); + this._checkMin(); + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + this._checkLeftValid(); + this._checkRightValid(); + this._checkMax(); + } + } + + getValue() { + return { + year: this.selectedYear, + }; + } + + setValue(obj) { + const o = this.options; + obj = obj || {}; + let v = obj.year; + if (checkDateVoid(v, 1, 1, o.min, o.max)[0]) { + v = getDate().getFullYear(); + this.selectedYear = ""; + this.navigation.setSelect(YearCalendar.getPageByYear(v)); + this.navigation.setValue(""); + } else { + this.selectedYear = parseInt(v); + this.navigation.setSelect(YearCalendar.getPageByYear(v)); + this.navigation.setValue(this.selectedYear); + } + this._checkLeftValid(); + this._checkRightValid(); + } +} diff --git a/packages/fineui/src/widget/year/combo.year.js b/packages/fineui/src/widget/year/combo.year.js new file mode 100644 index 000000000..b1ce3612f --- /dev/null +++ b/packages/fineui/src/widget/year/combo.year.js @@ -0,0 +1,245 @@ +import { IconButton, Combo } from "@/base"; +import { shortcut, Widget, toPix, getDate, isNotNull, AbsoluteLayout, HorizontalFillLayout, extend, createWidget } from "@/core"; +import { DynamicYearTrigger } from "@/widget/year/trigger.year"; +import { DynamicYearPopup } from "@/widget/year/popup.year"; +import { DynamicDateCombo } from "@/widget/dynamicdate/dynamicdate.combo"; + +@shortcut() +export class DynamicYearCombo extends Widget { + static xtype = "bi.dynamic_year_combo"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_FOCUS = "EVENT_FOCUS"; + + static Static = 1; + static Dynamic = 2; + + _const = { + iconWidth: 24, + }; + + props = { + baseCls: "bi-year-combo", + behaviors: {}, + minDate: "1900-01-01", // 最小日期 + maxDate: "2099-12-31", // 最大日期 + height: 24, + supportDynamic: true, + }; + + _init() { + const o = this.options; + super._init(...arguments); + this.storeValue = o.value; + const border = o.simple ? 1 : 2; + this.trigger = createWidget({ + type: DynamicYearTrigger.xtype, + simple: o.simple, + min: o.minDate, + max: o.maxDate, + height: toPix(o.height, border), + value: o.value || "", + watermark: o.watermark, + }); + this.trigger.on(DynamicYearTrigger.EVENT_KEY_DOWN, () => { + if (this.combo.isViewVisible()) { + this.combo.hideView(); + } + }); + this.trigger.on(DynamicYearTrigger.EVENT_FOCUS, () => { + this.storeTriggerValue = this.getKey(); + this.fireEvent(DynamicYearCombo.EVENT_FOCUS); + }); + this.trigger.on(DynamicYearTrigger.EVENT_START, () => { + this.combo.isViewVisible() && this.combo.hideView(); + }); + this.trigger.on(DynamicYearTrigger.EVENT_STOP, () => { + this.combo.showView(); + }); + this.trigger.on(DynamicYearTrigger.EVENT_ERROR, () => { + this.combo.isViewVisible() && this.combo.hideView(); + this.comboWrapper.element.addClass("error"); + this.fireEvent(DynamicYearCombo.EVENT_ERROR); + }); + this.trigger.on(DynamicYearTrigger.EVENT_VALID, () => { + this.comboWrapper.element.removeClass("error"); + this.fireEvent(DynamicYearCombo.EVENT_VALID); + }); + this.trigger.on(DynamicYearTrigger.EVENT_CONFIRM, () => { + if (this.combo.isViewVisible()) { + return; + } + if (this.getKey() && this.getKey() !== this.storeTriggerValue) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.storeValue); + } else if (!this.getKey()) { + this.storeValue = null; + this.setValue(); + } + this._checkDynamicValue(this.storeValue); + this.fireEvent(DynamicYearCombo.EVENT_CONFIRM); + }); + this.combo = createWidget({ + type: Combo.xtype, + container: o.container, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + el: this.trigger, + destroyWhenHide: true, + adjustLength: 1, + popup: { + minWidth: 85, + stopPropagation: false, + el: { + type: DynamicYearPopup.xtype, + supportDynamic: o.supportDynamic, + ref: _ref => { + this.popup = _ref; + }, + listeners: [ + { + eventName: DynamicYearPopup.EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicYearCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearPopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.combo.hideView(); + this.fireEvent(DynamicYearCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearPopup.BUTTON_lABEL_EVENT_CHANGE, + action: () => { + const date = getDate(); + this.setValue({ type: DynamicYearCombo.Static, value: { year: date.getFullYear() } }); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearPopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + } + ], + behaviors: o.behaviors, + min: o.minDate, + max: o.maxDate, + }, + value: o.value || "", + }, + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.popup.setMinDate(o.minDate); + this.popup.setMaxDate(o.maxDate); + this.popup.setValue(this.storeValue); + this.fireEvent(DynamicYearCombo.EVENT_BEFORE_POPUPVIEW); + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: HorizontalFillLayout.xtype, + columnSize: ["", "fill"], + cls: `${o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + ref: _ref => { + this.comboWrapper = _ref; + }, + items: [ + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-change-h-font", + width: this._const.iconWidth, + height: toPix(o.height, border), + ref: _ref => { + this.changeIcon = _ref; + }, + }, + }, + this.combo + ], + }, + top: 0, + left: 0, + right: 0, + bottom: 0, + } + ], + }); + this._checkDynamicValue(o.value); + } + + _checkDynamicValue(v) { + let type = null; + if (isNotNull(v)) { + type = v.type; + } + switch (type) { + case DynamicYearCombo.Dynamic: + this.changeIcon.setVisible(true); + break; + default: + this.changeIcon.setVisible(false); + break; + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.trigger.setMinDate(minDate); + this.popup && this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.trigger.setMaxDate(maxDate); + this.popup && this.popup.setMaxDate(maxDate); + } + + hideView() { + this.combo.hideView(); + } + + getKey() { + return `${this.trigger.getKey()}`; + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + this._checkDynamicValue(v); + } + + getValue() { + return this.storeValue; + } + + isStateValid() { + return this.trigger.isValid(); + } + + setWaterMark(v) { + this.trigger.setWaterMark(v); + } +} +extend(DynamicYearCombo, { + Static: 1, + Dynamic: 2, +}); diff --git a/packages/fineui/src/widget/year/index.js b/packages/fineui/src/widget/year/index.js new file mode 100644 index 000000000..060417a74 --- /dev/null +++ b/packages/fineui/src/widget/year/index.js @@ -0,0 +1,5 @@ +export { DynamicYearCard } from "./card.dynamic.year"; +export { StaticYearCard } from "./card.year"; +export { DynamicYearCombo } from "./combo.year"; +export { DynamicYearPopup } from "./popup.year"; +export { DynamicYearTrigger } from "./trigger.year"; diff --git a/packages/fineui/src/widget/year/popup.year.js b/packages/fineui/src/widget/year/popup.year.js new file mode 100644 index 000000000..5400407c0 --- /dev/null +++ b/packages/fineui/src/widget/year/popup.year.js @@ -0,0 +1,290 @@ +import { + shortcut, + Widget, + toPix, + i18nText, + VerticalLayout, + GridLayout, + print, + getDate, + checkDateVoid, + createItems, + SIZE_CONSANTS +} from "@/core"; +import { TextButton, Tab } from "@/base"; +import { LinearSegment } from "@/case"; +import { DynamicDateCombo } from "@/widget/dynamicdate/dynamicdate.combo"; +import { DynamicDateHelper } from "@/widget/dynamicdate/dynamicdate.caculate"; +import { DynamicYearMonthPopup } from "../yearmonth/popup.yearmonth"; +import { DynamicYearCard } from "@/widget/year/card.dynamic.year"; +import { DynamicYearCombo } from "@/widget/year/combo.year"; +import { StaticYearCard } from "@/widget/year/card.year"; + +@shortcut() +export class DynamicYearPopup extends Widget { + static xtype = "bi.dynamic_year_popup"; + props = { + baseCls: "bi-dynamic-year-popup", + behaviors: {}, + min: "1900-01-01", + max: "2099-12-31", + width: 180, + supportDynamic: true, + }; + constants = { + tabHeight: 40, + }; + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + this.storeValue = { type: DynamicYearCombo.Static }; + + return { + type: VerticalLayout.xtype, + items: [ + { + el: this._getTabJson(), + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_Clear"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearPopup.BUTTON_CLEAR_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + shadow: true, + text: i18nText("BI-Basic_Current_Year"), + disabled: this._checkTodayValid(), + ref: _ref => { + this.yearButton = _ref; + }, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearPopup.BUTTON_lABEL_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent(DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); + } else { + this.fireEvent(DynamicYearPopup.BUTTON_OK_EVENT_CHANGE); + } + }, + } + ], + } + ] + ], + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }, + } + ], + }; + } + + _setInnerValue() { + if (this.dateTab.getSelect() === DynamicDateCombo.Static) { + this.yearButton.setValue(i18nText("BI-Basic_Current_Year")); + this.yearButton.setEnable(!this._checkYearValid()); + } else { + let date = DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); + date = print(date, "%Y"); + this.yearButton.setValue(date); + this.yearButton.setEnable(false); + } + } + + _checkYearValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; + } + + _getTabJson() { + const o = this.options; + + return { + type: Tab.xtype, + logic: { + dynamic: true, + }, + ref: _ref => { + this.dateTab = _ref; + }, + tab: { + type: LinearSegment.xtype, + invisible: !o.supportDynamic, + height: this.constants.tabHeight, + items: createItems( + [ + { + text: i18nText("BI-Basic_Year_Fen"), + value: DynamicYearCombo.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicYearCombo.Dynamic, + } + ], + { + textAlign: "center", + } + ), + }, + cardCreator: v => { + switch (v) { + case DynamicYearCombo.Dynamic: + return { + type: DynamicYearCard.xtype, + cls: "dynamic-year-pane", + min: o.min, + max: o.max, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._setInnerValue(this.year, v); + }, + } + ], + ref: _ref => { + this.dynamicPane = _ref; + }, + }; + case DynamicYearCombo.Static: + default: + return { + type: StaticYearCard.xtype, + behaviors: o.behaviors, + min: o.min, + max: o.max, + listeners: [ + { + eventName: StaticYearCard.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearPopup.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.year = _ref; + }, + }; + } + }, + listeners: [ + { + eventName: Tab.EVENT_CHANGE, + action: () => { + const v = this.dateTab.getSelect(); + switch (v) { + case DynamicYearCombo.Static: { + const date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + this.year.setValue({ year: date.getFullYear() }); + this._setInnerValue(); + break; + } + case DynamicYearCombo.Dynamic: + default: + if (this.storeValue && this.storeValue.type === DynamicYearCombo.Dynamic) { + this.dynamicPane.setValue(this.storeValue.value); + } else { + this.dynamicPane.setValue({ + year: 0, + }); + } + this._setInnerValue(); + break; + } + }, + } + ], + }; + } + + _checkTodayValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.year && this.year.setMinDate(minDate); + this.dynamicPane && this.dynamicPane.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.year && this.year.setMaxDate(maxDate); + this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); + } + } + + setValue(v) { + this.storeValue = v; + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + this._setInnerValue(); + break; + case DynamicDateCombo.Static: + default: + this.year.setValue(value); + this.yearButton.setValue(i18nText("BI-Basic_Current_Year")); + this.yearButton.setEnable(!this._checkTodayValid()); + break; + } + } + + getValue() { + return { + type: this.dateTab.getSelect(), + value: this.dateTab.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/year/trigger.year.js b/packages/fineui/src/widget/year/trigger.year.js new file mode 100644 index 000000000..8e7562601 --- /dev/null +++ b/packages/fineui/src/widget/year/trigger.year.js @@ -0,0 +1,234 @@ +import { + shortcut, + extend, + i18nText, + bind, + createWidget, + isPositiveInteger, + checkDateVoid, + parseDateTime, + isNotNull, + isNotEmptyString, + parseInt, + print, + getDate, + HorizontalFillLayout, + isEmptyString +} from "@/core"; +import { Trigger, TextButton } from "@/base"; +import { SignEditor, TriggerIconButton } from "@/case"; +import { DynamicDateCombo } from "@/widget/dynamicdate/dynamicdate.combo"; +import { DynamicDateHelper } from "@/widget/dynamicdate/dynamicdate.caculate"; + +@shortcut() +export class DynamicYearTrigger extends Trigger { + static xtype = "bi.dynamic_year_trigger"; + + _const = { hgap: 4, vgap: 2, iconWidth: 24 }; + + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_START = "EVENT_START"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_VALID = "EVENT_VALID"; + + _defaultConfig() { + return extend(super._defaultConfig(...arguments), { + extraCls: "bi-year-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + watermark: i18nText("BI-Basic_Unrestricted"), + }); + } + + beforeInit(callback) { + const o = this.options; + o.title = bind(this._titleCreator, this); + callback(); + } + + _init() { + super._init(...arguments); + const o = this.options, + c = this._const; + this.editor = createWidget({ + type: SignEditor.xtype, + simple: o.simple, + height: o.height, + validationChecker: v => v === "" || (isPositiveInteger(v) && !checkDateVoid(v, 1, 1, o.min, o.max)[0]), + quitChecker: () => false, + hgap: c.hgap, + vgap: c.vgap, + watermark: o.watermark, + allowBlank: true, + errorText: v => { + if (isPositiveInteger(v)) { + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText("BI-Basic_Year_Range_Error", start.getFullYear(), end.getFullYear()); + } + + return i18nText("BI-Year_Trigger_Invalid_Text"); + }, + }); + this.editor.on(SignEditor.EVENT_KEY_DOWN, () => { + this.fireEvent(DynamicYearTrigger.EVENT_KEY_DOWN, ...arguments); + }); + this.editor.on(SignEditor.EVENT_FOCUS, () => { + this.fireEvent(DynamicYearTrigger.EVENT_FOCUS); + }); + this.editor.on(SignEditor.EVENT_STOP, () => { + this.fireEvent(DynamicYearTrigger.EVENT_STOP); + }); + this.editor.on(SignEditor.EVENT_CONFIRM, () => { + const value = this.editor.getValue(); + if (isNotNull(value)) { + this.editor.setValue(value); + } + if (isNotEmptyString(value)) { + this.storeValue = { + type: DynamicDateCombo.Static, + value: { + year: value, + }, + }; + } + + this.fireEvent(DynamicYearTrigger.EVENT_CONFIRM); + }); + this.editor.on(SignEditor.EVENT_SPACE, () => { + if (this.editor.isValid()) { + this.editor.blur(); + } + }); + this.editor.on(SignEditor.EVENT_START, () => { + this.fireEvent(DynamicYearTrigger.EVENT_START); + }); + this.editor.on(SignEditor.EVENT_ERROR, () => { + this.fireEvent(DynamicYearTrigger.EVENT_ERROR); + }); + this.editor.on(SignEditor.EVENT_VALID, () => { + this.fireEvent(DynamicYearTrigger.EVENT_VALID); + }); + createWidget({ + element: this, + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", ""], + items: [ + { + el: this.editor, + }, + { + el: { + type: TextButton.xtype, + baseCls: "bi-trigger-year-text", + text: i18nText("BI-Multi_Date_Year"), + }, + }, + { + el: { + type: TriggerIconButton.xtype, + width: this._const.iconWidth, + }, + } + ], + }); + this.setValue(o.value); + } + + _getText(obj) { + let value = ""; + if (isNotNull(obj.year) && parseInt(obj.year) !== 0) { + value += + Math.abs(obj.year) + + i18nText("BI-Basic_Year") + + (obj.year < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + + return value; + } + + _setInnerValue(date) { + const dateStr = print(date, "%Y"); + this.editor.setState(dateStr); + this.editor.setValue(dateStr); + } + + _titleCreator() { + const storeValue = this.storeValue || {}; + const type = storeValue.type || DynamicDateCombo.Static; + let value = storeValue.value; + if (!this.editor.isValid()) { + return ""; + } + + switch (type) { + case DynamicDateCombo.Dynamic: { + const text = this._getText(value); + let date = getDate(); + date = DynamicDateHelper.getCalculation(value); + const dateStr = print(date, "%Y"); + + return isEmptyString(text) ? dateStr : `${text}:${dateStr}`; + } + + case DynamicDateCombo.Static: + default: + value = value || {}; + + return value.year; + } + } + + setValue(v) { + let type, value; + let date = getDate(); + this.storeValue = v; + if (isNotNull(v)) { + type = v.type || DynamicDateCombo.Static; + value = v.value || v; + } + switch (type) { + case DynamicDateCombo.Dynamic: { + const text = this._getText(value); + date = DynamicDateHelper.getCalculation(value); + this._setInnerValue(date, text); + break; + } + case DynamicDateCombo.Static: + default: + value = value || {}; + this.editor.setState(value.year); + this.editor.setValue(value.year); + break; + } + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + getValue() { + return this.storeValue; + } + + getKey() { + return this.editor.getValue() | 0; + } + + setWaterMark(v) { + this.editor.setWaterMark(v); + } +} diff --git a/packages/fineui/src/widget/yearinterval/yearinterval.js b/packages/fineui/src/widget/yearinterval/yearinterval.js new file mode 100644 index 000000000..42172300f --- /dev/null +++ b/packages/fineui/src/widget/yearinterval/yearinterval.js @@ -0,0 +1,232 @@ +import { + shortcut, + HorizontalFillLayout, + createWidget, + i18nText, + print, + parseDateTime, + checkDateVoid, + isNotNull, + checkDateLegal +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { DynamicYearCombo } from "../year"; + +@shortcut() +export class YearInterval extends Single { + static xtype = "bi.year_interval"; + + constants = { + height: 24, + width: 25, + lgap: 15, + offset: -15, + timeErrorCls: "time-error", + }; + props = { + extraCls: "bi-year-interval", + minDate: "1900-01-01", + maxDate: "2099-12-31", + supportDynamic: true, + }; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + render() { + const o = this.options; + + o.value = o.value || {}; + this.left = this._createCombo(o.value.start, o.watermark?.start); + this.right = this._createCombo(o.value.end, o.watermark?.end); + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: this.left, + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: this.right, + } + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + const combo = createWidget({ + type: DynamicYearCombo.xtype, + supportDynamic: o.supportDynamic, + minDate: o.minDate, + maxDate: o.maxDate, + height: o.height, + behaviors: o.behaviors, + value: v, + watermark, + listeners: [ + { + eventName: DynamicYearCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(YearInterval.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }); + combo.on(DynamicYearCombo.EVENT_ERROR, () => { + this._clearTitle(); + Bubbles.hide("error"); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearInterval.EVENT_ERROR); + }); + + combo.on(DynamicYearCombo.EVENT_VALID, () => { + this._checkValid(); + }); + + combo.on(DynamicYearCombo.EVENT_FOCUS, () => { + this._checkValid(); + }); + + combo.on(DynamicYearCombo.EVENT_CONFIRM, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isStateValid() && + this.right.isStateValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + this.fireEvent(YearInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearInterval.EVENT_CHANGE); + } + }); + + return combo; + } + + _dateCheck(date) { + return print(parseDateTime(date, "%Y"), "%Y") === date || print(parseDateTime(date, "%Y"), "%Y") === date; + } + + _checkVoid(obj) { + const o = this.options; + + return !checkDateVoid(obj.year, 1, 1, o.minDate, o.maxDate)[0]; + } + + _check(smallDate, bigDate) { + const smallObj = smallDate.match(/\d+/g), + bigObj = bigDate.match(/\d+/g); + + let smallDate4Check = ""; + if (isNotNull(smallObj)) { + smallDate4Check = smallObj[0] || ""; + } + + let bigDate4Check = ""; + if (isNotNull(bigObj)) { + bigDate4Check = bigObj[0] || ""; + } + + return ( + this._dateCheck(smallDate4Check) && + checkDateLegal(smallDate4Check) && + this._checkVoid({ + year: smallObj[0], + month: 1, + day: 1, + }) && + this._dateCheck(bigDate4Check) && + checkDateLegal(bigDate4Check) && + this._checkVoid({ + year: bigObj[0], + month: 12, + day: 1, + }) + ); + } + + _compare(smallDate, bigDate) { + smallDate = print(parseDateTime(smallDate, "%Y"), "%Y"); + bigDate = print(parseDateTime(bigDate, "%Y"), "%Y"); + + return isNotNull(smallDate) && isNotNull(bigDate) && smallDate > bigDate; + } + + _setTitle(v) { + this.setTitle(v); + } + + _clearTitle() { + this.setTitle(""); + } + + _checkValid() { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(YearInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.left.setMinDate(minDate); + this.right.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.left.setMaxDate(maxDate); + this.right.setMaxDate(maxDate); + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + + this._checkValid(); + } + + getValue() { + return { start: this.left.getValue(), end: this.right.getValue() }; + } +} diff --git a/src/widget/yearmonth/__test__/combo.yearmonth.test.js b/packages/fineui/src/widget/yearmonth/__test__/combo.yearmonth.test.js similarity index 100% rename from src/widget/yearmonth/__test__/combo.yearmonth.test.js rename to packages/fineui/src/widget/yearmonth/__test__/combo.yearmonth.test.js diff --git a/packages/fineui/src/widget/yearmonth/card.dynamic.yearmonth.js b/packages/fineui/src/widget/yearmonth/card.dynamic.yearmonth.js new file mode 100644 index 000000000..70dab3331 --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/card.dynamic.yearmonth.js @@ -0,0 +1,189 @@ +import { + shortcut, + Widget, + i18nText, + bind, + VerticalLayout, + parseDateTime, + extend, + checkDateVoid, + isNotEmptyString, + SIZE_CONSANTS +} from "@/core"; +import { DynamicDateCard, DynamicDateParamItem, DynamicDateHelper } from "../dynamicdate"; +import { Label, Bubbles } from "@/base"; + +@shortcut() +export class DynamicYearMonthCard extends Widget { + static xtype = "bi.dynamic_year_month_card"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { baseCls: "bi-year-month-card" }; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + text: i18nText("BI-Multi_Date_Relative_Current_Time"), + textAlign: "left", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }, + { + type: VerticalLayout.xtype, + ref: _ref => { + this.wrapper = _ref; + }, + items: [ + { + el: { + type: DynamicDateParamItem.xtype, + validationChecker: bind(this._checkDate, this), + ref: _ref => { + this.year = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action: () => { + Bubbles.hide("dynamic-year-month-error"); + }, + } + ], + }, + bgap: 10, + }, + { + type: DynamicDateParamItem.xtype, + dateType: DynamicDateCard.TYPE.MONTH, + ref: _ref => { + this.month = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action: () => { + Bubbles.hide("dynamic-year-month-error"); + }, + } + ], + } + ], + } + ], + vgap: 10, + hgap: 10, + }; + } + + _getErrorText() { + const o = this.options; + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText( + "BI-Basic_Year_Month_Range_Error", + start.getFullYear(), + start.getMonth() + 1, + end.getFullYear(), + end.getMonth() + 1 + ); + } + + _checkDate(obj) { + const o = this.options; + const date = DynamicDateHelper.getCalculation(extend(this._getValue(), this._digestDateTypeValue(obj))); + + return !checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; + } + + _digestDateTypeValue(value) { + const valueMap = {}; + switch (value.dateType) { + case DynamicDateCard.TYPE.YEAR: + valueMap.year = value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.MONTH: + valueMap.month = value.offset === 0 ? -value.value : +value.value; + break; + default: + break; + } + + return valueMap; + } + + _createValue(type, v) { + return { + dateType: type, + value: Math.abs(v), + offset: v > 0 ? 1 : 0, + }; + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + v = v || { year: 0, month: 0 }; + this.year.setValue(this._createValue(DynamicDateCard.TYPE.YEAR, v.year)); + this.month.setValue(this._createValue(DynamicDateCard.TYPE.MONTH, v.month)); + } + + _getValue() { + const year = this.year.getValue(); + const month = this.month.getValue(); + + return { + year: year.offset === 0 ? -year.value : year.value, + month: month.offset === 0 ? -month.value : month.value, + }; + } + + getInputValue() { + return this._getValue(); + } + + getValue() { + return this.checkValidation() ? this._getValue() : {}; + } + + checkValidation(show) { + let errorText; + const yearInvalid = !this.year.checkValidation(); + const monthInvalid = !this.month.checkValidation(); + let invalid = yearInvalid || monthInvalid; + if (invalid) { + errorText = i18nText("BI-Please_Input_Natural_Number"); + } else { + invalid = !this._checkDate(this._getValue()); + errorText = this._getErrorText(); + } + invalid && show && Bubbles.show("dynamic-year-month-error", errorText, this.wrapper); + + return !invalid; + } +} diff --git a/packages/fineui/src/widget/yearmonth/card.static.yearmonth.js b/packages/fineui/src/widget/yearmonth/card.static.yearmonth.js new file mode 100644 index 000000000..0a478cc1b --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/card.static.yearmonth.js @@ -0,0 +1,211 @@ +import { + shortcut, + Widget, + chunk, + map, + toPix, + extend, + VerticalLayout, + CenterAdaptLayout, + parseDateTime, + each, + checkDateVoid, + contains, + getDate, + parseInt, + SIZE_CONSANTS, + LogicFactory +} from "@/core"; +import { TextItem, ButtonGroup } from "@/base"; +import { YearPicker } from "../date/calendar"; + +@shortcut() +export class StaticYearMonthCard extends Widget { + static xtype = "bi.static_year_month_card"; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + props = { baseCls: "bi-static-year-month-card", behaviors: {} }; + + _createMonths() { + // 纵向排列月 + const month = [1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12]; + const items = chunk(month, 2); + + return map(items, (i, item) => + map(item, (j, td) => { + return { + type: TextItem.xtype, + cls: "bi-list-item-select", + textAlign: "center", + whiteSpace: "nowrap", + once: false, + forceSelected: true, + height: toPix(SIZE_CONSANTS.LIST_ITEM_HEIGHT, 1), + width: 38, + value: td, + text: td, + ref: _ref => { + this.monthMap[j === 0 ? i : i + 6] = _ref; + }, + }; + }) + ); + } + + render() { + const o = this.options; + this.monthMap = {}; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: YearPicker.xtype, + cls: "bi-split-bottom", + min: o.min, + max: o.max, + ref: _ref => { + this.yearPicker = _ref; + }, + behaviors: o.behaviors, + height: 30, + listeners: [ + { + eventName: YearPicker.EVENT_CHANGE, + action: () => { + const value = this.yearPicker.getValue(); + this._checkMonthStatus(value); + this._setYear(value); + }, + } + ], + }, + { + el: { + type: ButtonGroup.xtype, + behaviors: o.behaviors, + ref: _ref => { + this.month = _ref; + }, + items: this._createMonths(), + layouts: [ + LogicFactory.createLogic( + "table", + extend( + { + dynamic: true, + }, + { + columns: 2, + rows: 6, + columnSize: [1 / 2, 1 / 2], + rowSize: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, + } + ) + ), + { + type: CenterAdaptLayout.xtype, + vgap: 1, + hgap: 2, + } + ], + value: o.value, + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: () => { + this.selectedYear = this.yearPicker.getValue(); + this.selectedMonth = this.month.getValue()[0]; + this.fireEvent(StaticYearMonthCard.EVENT_CHANGE); + }, + } + ], + }, + vgap: 5, + } + ], + }; + } + + created() { + this._checkMonthStatus(this.selectedYear); + } + + _checkMonthStatus(year) { + const o = this.options; + const minDate = parseDateTime(o.min, "%Y-%X-%d"), + maxDate = parseDateTime(o.max, "%Y-%X-%d"); + const minYear = minDate.getFullYear(), + maxYear = maxDate.getFullYear(); + let minMonth = 0; + let maxMonth = 11; + minYear === year && (minMonth = minDate.getMonth()); + maxYear === year && (maxMonth = maxDate.getMonth()); + const yearInvalid = year < minYear || year > maxYear; + each(this.monthMap, (month, obj) => { + const monthInvalid = month < minMonth || month > maxMonth; + obj.setEnable(!yearInvalid && !monthInvalid); + }); + } + + _setYear(year) { + const o = this.options; + + const dateVoid = checkDateVoid(year, this.selectedMonth, 1, o.min, o.max); + + // 在切换年的时候,如果月份不在区间内了,取消选中 + if (contains(["y", "m"], dateVoid[0])) { + this.selectedYear = year; + this.month.setValue(); + + return; + } + + this.selectedYear = year; + this.month.setValue(this.selectedMonth); + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.yearPicker.setMinDate(minDate); + this._checkMonthStatus(this.selectedYear); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.yearPicker.setMaxDate(maxDate); + this._checkMonthStatus(this.selectedYear); + } + } + + getValue() { + return { + year: this.selectedYear, + month: this.selectedMonth, + }; + } + + setValue(obj) { + const o = this.options; + const newObj = {}; + newObj.year = obj.year || 0; + newObj.month = obj.month || 0; + if (newObj.year === 0 || newObj.month === 0 || checkDateVoid(newObj.year, newObj.month, 1, o.min, o.max)[0]) { + const year = newObj.year || getDate().getFullYear(); + this.selectedYear = year; + this.selectedMonth = ""; + this.yearPicker.setValue(year); + this.month.setValue(); + } else { + this.selectedYear = parseInt(newObj.year); + this.selectedMonth = parseInt(newObj.month); + this.yearPicker.setValue(this.selectedYear); + this.month.setValue(this.selectedMonth); + } + this._checkMonthStatus(this.selectedYear); + } +} diff --git a/packages/fineui/src/widget/yearmonth/combo.yearmonth.js b/packages/fineui/src/widget/yearmonth/combo.yearmonth.js new file mode 100644 index 000000000..55e0c24da --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/combo.yearmonth.js @@ -0,0 +1,273 @@ +import { + shortcut, + createWidget, + toPix, + isEqual, + isNotEmptyString, + getDate, + AbsoluteLayout, + HorizontalFillLayout, + isNotNull, + isNotEmptyObject, + checkDateVoid +} from "@/core"; +import { Single, Combo, IconButton } from "@/base"; +import { DynamicYearMonthTrigger } from "./trigger.yearmonth"; +import { DynamicYearMonthPopup } from "./popup.yearmonth"; +import { DynamicDateCombo } from "../dynamicdate"; + +@shortcut() +export class DynamicYearMonthCombo extends Single { + static xtype = "bi.dynamic_year_month_combo"; + + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + static Static = 1; + static Dynamic = 2; + + props = { + baseCls: "bi-year-month-combo", + behaviors: {}, + minDate: "1900-01-01", + maxDate: "2099-12-31", + height: 24, + supportDynamic: true, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + }; + + _init() { + const o = this.options; + super._init(...arguments); + this.storeValue = o.value; + this.storeTriggerValue = ""; + const border = o.simple ? 1 : 2; + this.trigger = createWidget({ + type: DynamicYearMonthTrigger.xtype, + simple: o.simple, + min: o.minDate, + max: o.maxDate, + height: toPix(o.height, border), + value: o.value || "", + watermark: o.watermark, + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_KEY_DOWN, () => { + this.combo.isViewVisible() && this.combo.hideView(); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_START, () => { + this.combo.isViewVisible() && this.combo.hideView(); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_STOP, () => { + this.combo.showView(); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_ERROR, () => { + this.combo.isViewVisible() && this.combo.hideView(); + this.comboWrapper.element.addClass("error"); + this.fireEvent(DynamicYearMonthCombo.EVENT_ERROR); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_VALID, () => { + this.comboWrapper.element.removeClass("error"); + this.fireEvent(DynamicYearMonthCombo.EVENT_VALID); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_CONFIRM, () => { + const dateStore = this.storeTriggerValue; + const dateObj = this.trigger.getKey(); + if (isEqual(dateObj, dateStore)) { + return; + } + if (isNotEmptyString(dateObj) && !isEqual(dateObj, dateStore)) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.trigger.getValue()); + } + this._checkDynamicValue(this.storeValue); + this.fireEvent(DynamicYearMonthCombo.EVENT_CONFIRM); + }); + this.trigger.on(DynamicYearMonthTrigger.EVENT_FOCUS, () => { + this.storeTriggerValue = this.trigger.getKey(); + this.fireEvent(DynamicYearMonthCombo.EVENT_FOCUS); + }); + + this.combo = createWidget({ + type: Combo.xtype, + container: o.container, + isNeedAdjustHeight: o.isNeedAdjustHeight, + isNeedAdjustWidth: o.isNeedAdjustWidth, + el: this.trigger, + destroyWhenHide: true, + adjustLength: 1, + popup: { + minWidth: 100, + stopPropagation: false, + el: { + type: DynamicYearMonthPopup.xtype, + width: o.isNeedAdjustWidth ? o.width : undefined, + supportDynamic: o.supportDynamic, + ref: _ref => { + this.popup = _ref; + }, + listeners: [ + { + eventName: DynamicYearMonthPopup.EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicYearMonthCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearMonthPopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.comboWrapper.element.removeClass("error"); + this.combo.hideView(); + this.fireEvent(DynamicYearMonthCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearMonthPopup.BUTTON_lABEL_EVENT_CHANGE, + action: () => { + const date = getDate(); + this.setValue({ + type: DynamicYearMonthCombo.Static, + value: { + year: date.getFullYear(), + month: date.getMonth() + 1, + }, + }); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + const value = this.popup.getValue(); + if (this._checkValue(value)) { + this.setValue(value); + } + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + } + ], + behaviors: o.behaviors, + min: o.minDate, + max: o.maxDate, + }, + value: o.value || "", + }, + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.popup.setMinDate(o.minDate); + this.popup.setMaxDate(o.maxDate); + this.popup.setValue(this.storeValue); + this.fireEvent(DynamicYearMonthCombo.EVENT_BEFORE_POPUPVIEW); + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: HorizontalFillLayout.xtype, + columnSize: ["", "fill"], + cls: `${o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + ref: _ref => { + this.comboWrapper = _ref; + }, + items: [ + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-change-h-font", + width: toPix(o.height, border), + height: toPix(o.height, border), + ref: _ref => { + this.changeIcon = _ref; + }, + }, + }, + this.combo + ], + }, + top: 0, + left: 0, + right: 0, + bottom: 0, + } + ], + }); + this._checkDynamicValue(o.value); + } + + _checkDynamicValue(v) { + let type = null; + if (isNotNull(v)) { + type = v.type; + } + switch (type) { + case DynamicYearMonthCombo.Dynamic: + this.changeIcon.setVisible(true); + break; + default: + this.changeIcon.setVisible(false); + break; + } + } + + _checkValue(v) { + const o = this.options; + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: { + const value = v.value || {}; + + return !checkDateVoid(value.year, value.month, 1, o.minDate, o.maxDate)[0]; + } + default: + return true; + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.trigger.setMinDate(minDate); + this.popup && this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.trigger.setMaxDate(maxDate); + this.popup && this.popup.setMaxDate(maxDate); + } + + hideView() { + this.combo.hideView(); + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + this._checkDynamicValue(v); + } + + getValue() { + return this.storeValue; + } + + getKey() { + return this.trigger.getKey(); + } + + isStateValid() { + return this.trigger.isStateValid(); + } +} diff --git a/packages/fineui/src/widget/yearmonth/index.js b/packages/fineui/src/widget/yearmonth/index.js new file mode 100644 index 000000000..3ca4f52c1 --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/index.js @@ -0,0 +1,5 @@ +export { DynamicYearMonthCard } from "./card.dynamic.yearmonth"; +export { StaticYearMonthCard } from "./card.static.yearmonth"; +export { DynamicYearMonthCombo } from "./combo.yearmonth"; +export { DynamicYearMonthPopup } from "./popup.yearmonth"; +export { DynamicYearMonthTrigger } from "./trigger.yearmonth"; diff --git a/packages/fineui/src/widget/yearmonth/popup.yearmonth.js b/packages/fineui/src/widget/yearmonth/popup.yearmonth.js new file mode 100644 index 000000000..a269169b8 --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/popup.yearmonth.js @@ -0,0 +1,287 @@ +import { + shortcut, + Widget, + toPix, + i18nText, + VerticalLayout, + GridLayout, + print, + getDate, + checkDateVoid, + createItems, + SIZE_CONSANTS +} from "@/core"; +import { DynamicYearMonthCombo } from "./combo.yearmonth"; +import { TextButton, Tab } from "@/base"; +import { DynamicDateCombo, DynamicDateHelper } from "../dynamicdate"; +import { DynamicYearCombo } from "../year/combo.year"; +import { StaticYearMonthCard } from "./card.static.yearmonth"; +import { LinearSegment } from "@/case"; +import { DynamicYearMonthCard } from "./card.dynamic.yearmonth"; + +@shortcut() +export class DynamicYearMonthPopup extends Widget { + static xtype = "bi.dynamic_year_month_popup"; + + constants = { tabHeight: 40 }; + props = { + baseCls: "bi-year-month-popup", + behaviors: {}, + min: "1900-01-01", + max: "2099-12-31", + width: 180, + supportDynamic: true, + }; + + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + this.storeValue = { type: DynamicYearMonthCombo.Static }; + + return { + type: VerticalLayout.xtype, + items: [ + { + el: this._getTabJson(), + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_Clear"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearMonthPopup.BUTTON_CLEAR_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_Current_Month"), + disabled: this._checkTodayValid(), + ref: _ref => { + this.textButton = _ref; + }, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearMonthPopup.BUTTON_lABEL_EVENT_CHANGE); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + textHeight: toPix(SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), + shadow: true, + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = this.dateTab.getSelect(); + if (type === DynamicDateCombo.Dynamic) { + this.dynamicPane.checkValidation(true) && + this.fireEvent(DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); + } else { + this.fireEvent(DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); + } + }, + } + ], + } + ] + ], + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }, + } + ], + }; + } + + _setInnerValue() { + if (this.dateTab.getSelect() === DynamicDateCombo.Static) { + this.textButton.setValue(i18nText("BI-Basic_Current_Month")); + this.textButton.setEnable(!this._checkTodayValid()); + } else { + let date = DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); + date = print(date, "%Y-%x"); + this.textButton.setValue(date); + this.textButton.setEnable(false); + } + } + + _checkTodayValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; + } + + _getTabJson() { + const o = this.options; + + return { + type: Tab.xtype, + logic: { + dynamic: true, + }, + ref: _ref => { + this.dateTab = _ref; + }, + tab: { + type: LinearSegment.xtype, + cls: "bi-split-bottom", + invisible: !o.supportDynamic, + height: this.constants.tabHeight, + items: createItems( + [ + { + text: i18nText("BI-Basic_Year_Month"), + value: DynamicYearCombo.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicYearCombo.Dynamic, + } + ], + { + textAlign: "center", + } + ), + }, + cardCreator: v => { + switch (v) { + case DynamicYearCombo.Dynamic: + return { + type: DynamicYearMonthCard.xtype, + cls: "dynamic-year-month-pane", + min: this.options.min, + max: this.options.max, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._setInnerValue(this.year, v); + }, + } + ], + ref: _ref => { + this.dynamicPane = _ref; + }, + }; + case DynamicYearCombo.Static: + default: + return { + type: StaticYearMonthCard.xtype, + behaviors: o.behaviors, + min: this.options.min, + max: this.options.max, + listeners: [ + { + eventName: StaticYearMonthCard.EVENT_CHANGE, + action: () => { + this.fireEvent(DynamicYearMonthPopup.EVENT_CHANGE); + }, + } + ], + ref: _ref => { + this.year = _ref; + }, + }; + } + }, + listeners: [ + { + eventName: Tab.EVENT_CHANGE, + action: () => { + const v = this.dateTab.getSelect(); + switch (v) { + case DynamicYearCombo.Static: { + const date = DynamicDateHelper.getCalculation(this.dynamicPane.getValue()); + this.year.setValue({ + year: date.getFullYear(), + month: date.getMonth() + 1, + }); + this._setInnerValue(); + break; + } + case DynamicYearCombo.Dynamic: + default: + if (this.storeValue && this.storeValue.type === DynamicYearCombo.Dynamic) { + this.dynamicPane.setValue(this.storeValue.value); + } else { + this.dynamicPane.setValue({ + year: 0, + }); + } + this._setInnerValue(); + break; + } + }, + } + ], + }; + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.year && this.year.setMinDate(minDate); + this.dynamicPane && this.dynamicPane.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.year && this.year.setMaxDate(maxDate); + this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); + } + } + + setValue(v) { + this.storeValue = v; + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + this._setInnerValue(); + break; + case DynamicDateCombo.Static: + default: + this.year.setValue(value); + this.textButton.setValue(i18nText("BI-Basic_Current_Month")); + this.textButton.setEnable(!this._checkTodayValid()); + break; + } + } + + getValue() { + return { + type: this.dateTab.getSelect(), + value: this.dateTab.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/yearmonth/trigger.yearmonth.js b/packages/fineui/src/widget/yearmonth/trigger.yearmonth.js new file mode 100644 index 000000000..d89fa5139 --- /dev/null +++ b/packages/fineui/src/widget/yearmonth/trigger.yearmonth.js @@ -0,0 +1,362 @@ +import { + shortcut, + bind, + createWidget, + i18nText, + HTapeLayout, + CenterLayout, + HorizontalFillLayout, + isEmptyString, + parseDateTime, + isPositiveInteger, + checkDateVoid, + isNotEmptyString, + getDate, + print, + isNotNull, + checkDateLegal, + parseInt, + isNull +} from "@/core"; +import { Trigger, TextButton } from "@/base"; +import { TriggerIconButton, SignEditor } from "@/case"; +import { DynamicDateCombo, DynamicDateHelper } from "../dynamicdate"; + +@shortcut() +export class DynamicYearMonthTrigger extends Trigger { + static xtype = "bi.dynamic_year_month_trigger"; + + _const = { hgap: 4, vgap: 2, iconWidth: 24 }; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_START = "EVENT_START"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + + props() { + return { + extraCls: "bi-year-month-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + watermark: { + year: i18nText("BI-Basic_Unrestricted"), + month: i18nText("BI-Basic_Unrestricted"), + }, + }; + } + + beforeInit(callback) { + const o = this.options; + o.title = bind(this._titleCreator, this); + callback(); + } + + _init() { + super._init(...arguments); + const o = this.options; + this.yearEditor = this._createEditor(true); + this.monthEditor = this._createEditor(false); + + createWidget({ + element: this, + type: HTapeLayout.xtype, + items: [ + { + type: CenterLayout.xtype, + items: [ + { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + this.yearEditor, + { + el: { + type: TextButton.xtype, + text: i18nText("BI-Multi_Date_Year"), + }, + } + ], + }, + { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + this.monthEditor, + { + el: { + type: TextButton.xtype, + text: i18nText("BI-Multi_Date_Month"), + }, + } + ], + } + ], + }, + { + el: { + type: TriggerIconButton.xtype, + width: this._const.iconWidth, + }, + width: this._const.iconWidth, + } + ], + }); + this.setValue(o.value); + } + + _createEditor(isYear) { + const o = this.options, + c = this._const; + const editor = createWidget({ + type: SignEditor.xtype, + simple: o.simple, + height: o.height, + validationChecker: v => { + if (isYear) { + let month = this.monthEditor.getValue(); + if (isEmptyString(month)) { + month = + parseInt(v, 10) === parseDateTime(o.min, "%Y-%X-%d").getFullYear() + ? parseDateTime(o.min, "%Y-%X-%d").getMonth() + 1 + : 1; + } + + return v === "" || (isPositiveInteger(v) && !checkDateVoid(v, month, 1, o.min, o.max)[0]); + } + const year = this.yearEditor.getValue(); + + return ( + v === "" || + (isPositiveInteger(v) && + v >= 1 && + v <= 12 && + (isEmptyString(year) + ? true + : !checkDateVoid(this.yearEditor.getValue(), v, 1, o.min, o.max)[0])) + ); + }, + quitChecker: () => false, + watermark: isYear ? o.watermark?.year : o.watermark.month, + errorText: v => { + const year = isYear ? v : this.yearEditor.getValue(); + const month = isYear ? this.monthEditor.getValue() : v; + if (!isPositiveInteger(year) || !isPositiveInteger(month) || month > 12) { + return i18nText("BI-Year_Trigger_Invalid_Text"); + } + + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText( + "BI-Basic_Year_Month_Range_Error", + start.getFullYear(), + start.getMonth() + 1, + end.getFullYear(), + end.getMonth() + 1 + ); + }, + hgap: c.hgap, + vgap: c.vgap, + allowBlank: true, + }); + editor.on(SignEditor.EVENT_KEY_DOWN, () => { + this.fireEvent(DynamicYearMonthTrigger.EVENT_KEY_DOWN); + }); + editor.on(SignEditor.EVENT_FOCUS, () => { + this.fireEvent(DynamicYearMonthTrigger.EVENT_FOCUS); + }); + editor.on(SignEditor.EVENT_STOP, () => { + this.fireEvent(DynamicYearMonthTrigger.EVENT_STOP); + }); + editor.on(SignEditor.EVENT_CONFIRM, () => { + this._doEditorConfirm(editor); + this.fireEvent(DynamicYearMonthTrigger.EVENT_CONFIRM); + }); + editor.on(SignEditor.EVENT_SPACE, () => { + if (editor.isValid()) { + editor.blur(); + } + }); + editor.on(SignEditor.EVENT_START, () => { + this.fireEvent(DynamicYearMonthTrigger.EVENT_START); + }); + editor.on(SignEditor.EVENT_ERROR, () => { + this.fireEvent(DynamicYearMonthTrigger.EVENT_ERROR); + }); + editor.on(SignEditor.EVENT_VALID, () => { + const year = this.yearEditor.getValue(); + const month = this.monthEditor.getValue(); + if (isNotEmptyString(year) && isNotEmptyString(month)) { + if ( + isPositiveInteger(year) && + month >= 1 && + month <= 12 && + !checkDateVoid(year, month, 1, o.min, o.max)[0] + ) { + this.fireEvent(DynamicYearMonthTrigger.EVENT_VALID); + } + } + }); + editor.on(SignEditor.EVENT_CHANGE, () => { + if (isYear) { + this._autoSwitch(editor); + } + }); + + return editor; + } + + _titleCreator() { + const storeValue = this.storeValue || {}; + const type = storeValue.type || DynamicDateCombo.Static; + let value = storeValue.value; + if (!this.monthEditor.isValid() || !this.yearEditor.isValid()) { + return ""; + } + switch (type) { + case DynamicDateCombo.Dynamic: { + const text = this._getText(value); + let date = getDate(); + date = DynamicDateHelper.getCalculation(value); + const dateStr = print(date, "%Y-%x"); + + return isEmptyString(text) ? dateStr : `${text}:${dateStr}`; + } + case DynamicDateCombo.Static: + default: + value = value || {}; + + return this._getStaticTitle(value); + } + } + + _doEditorConfirm(editor) { + const value = editor.getValue(); + if (isNotNull(value)) { + editor.setValue(value); + } + const monthValue = this.monthEditor.getValue(); + this.storeValue = { + type: DynamicDateCombo.Static, + value: { + year: this.yearEditor.getValue(), + month: isEmptyString(this.monthEditor.getValue()) ? "" : monthValue, + }, + }; + } + + _yearCheck(v) { + const date = print(parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); + + return print(parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; + } + + _autoSwitch(editor) { + const v = editor.getValue(); + if (isNotEmptyString(v) && checkDateLegal(v)) { + if (v.length === 4 && this._yearCheck(v)) { + this._doEditorConfirm(editor); + this.fireEvent(DynamicYearMonthTrigger.EVENT_CONFIRM); + this.monthEditor.focus(); + } + } + } + + _getText(obj) { + let value = ""; + if (isNotNull(obj.year) && parseInt(obj.year) !== 0) { + value += + Math.abs(obj.year) + + i18nText("BI-Basic_Year") + + (obj.year < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + if (isNotNull(obj.month) && parseInt(obj.month) !== 0) { + value += + Math.abs(obj.month) + + i18nText("BI-Basic_Month") + + (obj.month < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind")); + } + + return value; + } + + _setInnerValue(date, text) { + this.yearEditor.setValue(date.getFullYear()); + this.monthEditor.setValue(date.getMonth() + 1); + } + + _getStaticTitle(value) { + value = value || {}; + const hasYear = !(isNull(value.year) || isEmptyString(value.year)); + const hasMonth = !(isNull(value.month) || isEmptyString(value.month)); + switch ((hasYear << 1) | hasMonth) { + // !hasYear && !hasMonth + case 0: + return ""; + // !hasYear && hasMonth + case 1: + return value.month; + // hasYear && !hasMonth + case 2: + return value.year; + // hasYear && hasMonth + case 3: + default: + return `${value.year}-${value.month}`; + } + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + let type, value; + let date = getDate(); + this.storeValue = v; + if (isNotNull(v)) { + type = v.type || DynamicDateCombo.Static; + value = v.value || v; + } + switch (type) { + case DynamicDateCombo.Dynamic: { + const text = this._getText(value); + date = DynamicDateHelper.getCalculation(value); + this._setInnerValue(date, text); + break; + } + case DynamicDateCombo.Static: + default: { + value = value || {}; + const month = isNull(value.month) ? null : value.month; + this.yearEditor.setValue(value.year); + this.monthEditor.setValue(month); + break; + } + } + } + + getValue() { + return this.storeValue; + } + + getKey() { + return `${this.yearEditor.getValue()}-${this.monthEditor.getValue()}`; + } + + isStateValid() { + return this.yearEditor.isValid() && this.monthEditor.isValid(); + } +} diff --git a/src/widget/yearmonthinterval/__test__/yearmonthinterval.test.js b/packages/fineui/src/widget/yearmonthinterval/__test__/yearmonthinterval.test.js similarity index 100% rename from src/widget/yearmonthinterval/__test__/yearmonthinterval.test.js rename to packages/fineui/src/widget/yearmonthinterval/__test__/yearmonthinterval.test.js diff --git a/packages/fineui/src/widget/yearmonthinterval/yearmonthinterval.js b/packages/fineui/src/widget/yearmonthinterval/yearmonthinterval.js new file mode 100644 index 000000000..d5689f43b --- /dev/null +++ b/packages/fineui/src/widget/yearmonthinterval/yearmonthinterval.js @@ -0,0 +1,236 @@ +import { + shortcut, + HorizontalFillLayout, + createWidget, + i18nText, + print, + parseDateTime, + checkDateVoid, + isNotNull, + checkDateLegal +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { DynamicYearMonthCombo } from "../yearmonth/combo.yearmonth"; + +@shortcut() +export class YearMonthInterval extends Single { + static xtype = "bi.year_month_interval"; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + constants = { + width: 25, + lgap: 15, + offset: -15, + timeErrorCls: "time-error", + }; + props = { + extraCls: "bi-year-month-interval", + minDate: "1900-01-01", + maxDate: "2099-12-31", + supportDynamic: true, + height: 24, + simple: false, + }; + + render() { + const o = this.options; + o.value = o.value || {}; + this.left = this._createCombo(o.value.start, o.watermark?.start); + this.right = this._createCombo(o.value.end, o.watermark?.end); + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: this.left, + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: this.right, + } + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + const combo = createWidget({ + type: DynamicYearMonthCombo.xtype, + simple: o.simple, + supportDynamic: o.supportDynamic, + height: o.height, + minDate: o.minDate, + maxDate: o.maxDate, + behaviors: o.behaviors, + value: v, + watermark, + listeners: [ + { + eventName: DynamicYearMonthCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent(YearMonthInterval.EVENT_BEFORE_POPUPVIEW); + }, + } + ], + }); + combo.on(DynamicYearMonthCombo.EVENT_ERROR, () => { + this._clearTitle(); + Bubbles.hide("error"); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearMonthInterval.EVENT_ERROR); + }); + + combo.on(DynamicYearMonthCombo.EVENT_VALID, () => { + this._checkValid(); + }); + + combo.on(DynamicYearMonthCombo.EVENT_FOCUS, () => { + this._checkValid(); + }); + + combo.on(DynamicYearMonthCombo.EVENT_CONFIRM, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isStateValid() && + this.right.isStateValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + this.fireEvent(YearMonthInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearMonthInterval.EVENT_CHANGE); + } + }); + + return combo; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%x"), "%Y-%x") === date || + print(parseDateTime(date, "%Y-%X"), "%Y-%X") === date + ); + } + + _checkVoid(obj) { + const o = this.options; + + return !checkDateVoid(obj.year, obj.month, 1, o.minDate, o.maxDate)[0]; + } + + _check(smallDate, bigDate) { + const smallObj = smallDate.match(/\d+/g), + bigObj = bigDate.match(/\d+/g); + + let smallDate4Check = ""; + if (isNotNull(smallObj)) { + smallDate4Check = `${smallObj[0] || ""}-${smallObj[1] || 1}`; + } + + let bigDate4Check = ""; + if (isNotNull(bigObj)) { + bigDate4Check = `${bigObj[0] || ""}-${bigObj[1] || 1}`; + } + + return ( + this._dateCheck(smallDate4Check) && + checkDateLegal(smallDate4Check) && + this._checkVoid({ + year: smallObj[0], + month: smallObj[1] || 1, + day: 1, + }) && + this._dateCheck(bigDate4Check) && + checkDateLegal(bigDate4Check) && + this._checkVoid({ + year: bigObj[0], + month: bigObj[1] || 1, + day: 1, + }) + ); + } + + _compare(smallDate, bigDate) { + smallDate = print(parseDateTime(smallDate, "%Y-%X"), "%Y-%X"); + bigDate = print(parseDateTime(bigDate, "%Y-%X"), "%Y-%X"); + + return isNotNull(smallDate) && isNotNull(bigDate) && smallDate > bigDate; + } + + _setTitle(v) { + this.setTitle(v); + } + + _clearTitle() { + this.setTitle(""); + } + + _checkValid() { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show("error", i18nText("BI-Time_Interval_Error_Text"), this, { + offsetStyle: "center", + }); + this.fireEvent(YearMonthInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.left.setMinDate(minDate); + this.right.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.left.setMaxDate(maxDate); + this.right.setMaxDate(maxDate); + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + + this._checkValid(); + } + + getValue() { + return { start: this.left.getValue(), end: this.right.getValue() }; + } +} diff --git a/src/widget/yearquarter/__test__/combo.yearquarter.test.js b/packages/fineui/src/widget/yearquarter/__test__/combo.yearquarter.test.js similarity index 100% rename from src/widget/yearquarter/__test__/combo.yearquarter.test.js rename to packages/fineui/src/widget/yearquarter/__test__/combo.yearquarter.test.js diff --git a/packages/fineui/src/widget/yearquarter/card.dynamic.yearquarter.js b/packages/fineui/src/widget/yearquarter/card.dynamic.yearquarter.js new file mode 100644 index 000000000..1ea538991 --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/card.dynamic.yearquarter.js @@ -0,0 +1,214 @@ +import { + shortcut, + Widget, + i18nText, + bind, + VerticalLayout, + parseDateTime, + extend, + checkDateVoid, + isNotEmptyString, + getQuarter, + SIZE_CONSANTS +} from "@/core"; +import { DynamicDateCard, DynamicDateParamItem, DynamicDateHelper } from "../dynamicdate"; +import { Label, Bubbles } from "@/base"; + +@shortcut() +export class DynamicYearQuarterCard extends Widget { + static xtype = "bi.dynamic_year_quarter_card"; + + props = { baseCls: "bi-year-quarter-card" }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + return { + type: VerticalLayout.xtype, + items: [ + { + type: Label.xtype, + text: i18nText("BI-Multi_Date_Relative_Current_Time"), + textAlign: "left", + height: SIZE_CONSANTS.LIST_ITEM_HEIGHT, + }, + { + type: VerticalLayout.xtype, + ref: _ref => { + this.wrapper = _ref; + }, + items: [ + { + el: { + type: DynamicDateParamItem.xtype, + validationChecker: bind(this._checkDate, this), + ref: _ref => { + this.year = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action: () => { + Bubbles.hide( + "dynamic-year-quarter-error" + ); + }, + } + ], + }, + bgap: 10, + }, + { + type: DynamicDateParamItem.xtype, + dateType: DynamicDateCard.TYPE.QUARTER, + ref: _ref => { + this.quarter = _ref; + }, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this.fireEvent("EVENT_CHANGE"); + }, + }, + { + eventName: "EVENT_INPUT_CHANGE", + action: () => { + Bubbles.hide( + "dynamic-year-quarter-error" + ); + }, + } + ], + } + ], + } + ], + vgap: 10, + hgap: 10, + }; + } + + _getErrorText() { + const o = this.options; + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText( + "BI-Basic_Year_Quarter_Range_Error", + start.getFullYear(), + getQuarter(start), + end.getFullYear(), + getQuarter(end) + ); + } + + _checkDate(obj) { + const o = this.options; + const date = DynamicDateHelper.getCalculation( + extend(this._getValue(), this._digestDateTypeValue(obj)) + ); + + return !checkDateVoid( + date.getFullYear(), + date.getMonth() + 1, + date.getDate(), + o.min, + o.max + )[0]; + } + + _digestDateTypeValue(value) { + const valueMap = {}; + switch (value.dateType) { + case DynamicDateCard.TYPE.YEAR: + valueMap.year = + value.offset === 0 ? -value.value : +value.value; + break; + case DynamicDateCard.TYPE.QUARTER: + valueMap.quarter = + value.offset === 0 ? -value.value : +value.value; + break; + default: + break; + } + + return valueMap; + } + + _createValue(type, v) { + return { + dateType: type, + value: Math.abs(v), + offset: v > 0 ? 1 : 0, + }; + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + v = v || { year: 0, quarter: 0 }; + this.year.setValue( + this._createValue(DynamicDateCard.TYPE.YEAR, v.year) + ); + this.quarter.setValue( + this._createValue(DynamicDateCard.TYPE.QUARTER, v.quarter) + ); + } + + _getValue() { + const year = this.year.getValue(); + const quarter = this.quarter.getValue(); + + return { + year: year.offset === 0 ? -year.value : year.value, + quarter: quarter.offset === 0 ? -quarter.value : quarter.value, + }; + } + + getInputValue() { + return this._getValue(); + } + + getValue() { + return this.checkValidation() ? this._getValue() : {}; + } + + checkValidation(show) { + let errorText; + const yearInvalid = !this.year.checkValidation(); + const quarterInvalid = !this.quarter.checkValidation(); + let invalid = yearInvalid || quarterInvalid; + if (invalid) { + errorText = i18nText("BI-Please_Input_Natural_Number"); + } else { + invalid = !this._checkDate(this._getValue()); + errorText = this._getErrorText(); + } + invalid && + show && + Bubbles.show( + "dynamic-year-quarter-error", + errorText, + this.wrapper + ); + + return !invalid; + } +} diff --git a/packages/fineui/src/widget/yearquarter/card.static.yearquarter.js b/packages/fineui/src/widget/yearquarter/card.static.yearquarter.js new file mode 100644 index 000000000..079f5284c --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/card.static.yearquarter.js @@ -0,0 +1,191 @@ +import { + shortcut, + Widget, + map, + extend, + VerticalLayout, + parseDateTime, + parseInt, + each, + checkDateVoid, + getDate, + getQuarterName, + getQuarter, + SIZE_CONSANTS +} from "@/core"; +import { TextItem, ButtonGroup } from "@/base"; +import { YearPicker } from "../date/calendar"; + +@shortcut() +export class StaticYearQuarterCard extends Widget { + static xtype = "bi.static_year_quarter_card"; + + props = { baseCls: "bi-static-year-quarter-card", behaviors: {} }; + + static EVENT_CHANGE = "EVENT_CHANGE"; + + _createQuarter() { + const items = [ + { + text: getQuarterName(1), + value: 1, + }, + { + text: getQuarterName(2), + value: 2, + }, + { + text: getQuarterName(3), + value: 3, + }, + { + text: getQuarterName(4), + value: 4, + } + ]; + + return map(items, (j, item) => extend(item, { + type: TextItem.xtype, + cls: "bi-border-radius bi-list-item-select", + textAlign: "center", + whiteSpace: "nowrap", + once: false, + forceSelected: true, + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + ref: _ref => { + this.quarterMap[j + 1] = _ref; + }, + })); + } + + render() { + const o = this.options; + this.quarterMap = {}; + + return { + type: VerticalLayout.xtype, + items: [ + { + type: YearPicker.xtype, + cls: "bi-split-bottom", + ref: _ref => { + this.yearPicker = _ref; + }, + min: o.min, + max: o.max, + behaviors: o.behaviors, + height: 30, + listeners: [ + { + eventName: YearPicker.EVENT_CHANGE, + action: () => { + const value = this.yearPicker.getValue(); + this._checkQuarterStatus(value); + this.setValue({ + year: value, + quarter: this.selectedQuarter, + }); + }, + } + ], + }, + { + el: { + type: ButtonGroup.xtype, + behaviors: o.behaviors, + ref: _ref => { + this.quarter = _ref; + }, + items: this._createQuarter(), + layouts: [ + { + type: VerticalLayout.xtype, + vgap: 10, + hgap: 12, + } + ], + value: o.value, + listeners: [ + { + eventName: ButtonGroup.EVENT_CHANGE, + action: () => { + this.selectedYear = + this.yearPicker.getValue(); + this.selectedQuarter = this.quarter.getValue()[0]; + this.fireEvent( + StaticYearQuarterCard.EVENT_CHANGE + ); + }, + } + ], + }, + vgap: 5, + } + ], + }; + } + + _checkQuarterStatus(year) { + const o = this.options; + const minDate = parseDateTime(o.min, "%Y-%X-%d"), + maxDate = parseDateTime(o.max, "%Y-%X-%d"); + const minYear = minDate.getFullYear(), + maxYear = maxDate.getFullYear(); + let minQuarter = 1; + let maxQuarter = 4; + minYear === year && (minQuarter = parseInt(getQuarter(minDate))); + maxYear === year && (maxQuarter = parseInt(getQuarter(maxDate))); + const yearInvalid = year < minYear || year > maxYear; + each(this.quarterMap, (quarter, obj) => { + const quarterInvalid = quarter < minQuarter || quarter > maxQuarter; + obj.setEnable(!yearInvalid && !quarterInvalid); + }); + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.yearPicker.setMinDate(minDate); + this._checkQuarterStatus(this.selectedYear); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.yearPicker.setMaxDate(maxDate); + this._checkQuarterStatus(this.selectedYear); + } + } + + getValue() { + return { + year: this.selectedYear, + quarter: this.selectedQuarter, + }; + } + + setValue(obj) { + const o = this.options; + const newObj = {}; + newObj.year = obj.year || 0; + newObj.quarter = obj.quarter || 0; + if ( + newObj.quarter === 0 || + newObj.year === 0 || + checkDateVoid(newObj.year, newObj.quarter, 1, o.min, o.max)[0] + ) { + const year = newObj.year || getDate().getFullYear(); + this.selectedYear = year; + this.selectedQuarter = ""; + this.yearPicker.setValue(year); + this.quarter.setValue(); + } else { + this.selectedYear = parseInt(newObj.year); + this.selectedQuarter = parseInt(newObj.quarter); + this.yearPicker.setValue(this.selectedYear); + this.quarter.setValue(this.selectedQuarter); + } + this._checkQuarterStatus(this.selectedYear); + } +} diff --git a/packages/fineui/src/widget/yearquarter/combo.yearquarter.js b/packages/fineui/src/widget/yearquarter/combo.yearquarter.js new file mode 100644 index 000000000..8255bf054 --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/combo.yearquarter.js @@ -0,0 +1,276 @@ +import { + shortcut, + Widget, + createWidget, + toPix, + isEqual, + isNotEmptyString, + getDate, + AbsoluteLayout, + HorizontalFillLayout, + isNotNull, + isNotEmptyObject, + checkDateVoid, + getQuarter +} from "@/core"; +import { DynamicYearQuarterTrigger } from "./trigger.yearquarter"; +import { DynamicYearMonthCombo } from "../yearmonth/combo.yearmonth"; +import { DynamicYearQuarterPopup } from "./popup.yearquarter"; +import { DynamicDateCombo } from "../dynamicdate"; +import { Combo, IconButton } from "@/base"; + +@shortcut() +export class DynamicYearQuarterCombo extends Widget { + static xtype = "bi.dynamic_year_quarter_combo"; + + _consts = { iconWidth: 24 }; + props = { + baseCls: "bi-year-quarter-combo", + behaviors: {}, + minDate: "1900-01-01", + maxDate: "2099-12-31", + height: 24, + supportDynamic: true, + isNeedAdjustHeight: false, + isNeedAdjustWidth: false, + }; + + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_VALID = "EVENT_VALID"; + static EVENT_FOCUS = "EVENT_FOCUS"; + static Static = 1; + static Dynamic = 2; + + _init() { + const o = this.options; + super._init(...arguments); + this.storeValue = o.value; + const border = o.simple ? 1 : 2; + this.storeTriggerValue = ""; + this.trigger = createWidget({ + type: DynamicYearQuarterTrigger.xtype, + simple: o.simple, + min: o.minDate, + max: o.maxDate, + height: toPix(o.height, border), + value: o.value || "", + watermark: o.watermark, + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_KEY_DOWN, () => { + this.combo.isViewVisible() && this.combo.hideView(); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_START, () => { + this.combo.isViewVisible() && this.combo.hideView(); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_STOP, () => { + this.combo.showView(); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_ERROR, () => { + this.combo.isViewVisible() && this.combo.hideView(); + this.comboWrapper.element.addClass("error"); + this.fireEvent(DynamicYearQuarterCombo.EVENT_ERROR); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_VALID, () => { + this.comboWrapper.element.removeClass("error"); + this.fireEvent(DynamicYearMonthCombo.EVENT_VALID); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_CONFIRM, () => { + const dateStore = this.storeTriggerValue; + const dateObj = this.trigger.getKey(); + if (isEqual(dateObj, dateStore)) { + return; + } + if (isNotEmptyString(dateObj) && !isEqual(dateObj, dateStore)) { + this.storeValue = this.trigger.getValue(); + this.setValue(this.trigger.getValue()); + } + this._checkDynamicValue(this.storeValue); + this.fireEvent(DynamicYearQuarterCombo.EVENT_CONFIRM); + }); + this.trigger.on(DynamicYearQuarterTrigger.EVENT_FOCUS, () => { + this.storeTriggerValue = this.trigger.getKey(); + this.fireEvent(DynamicYearQuarterCombo.EVENT_FOCUS); + }); + + this.combo = createWidget({ + type: Combo.xtype, + container: o.container, + isNeedAdjustHeight: o.isNeedAdjustHeight, + isNeedAdjustWidth: o.isNeedAdjustWidth, + el: this.trigger, + destroyWhenHide: true, + adjustLength: 1, + popup: { + minWidth: 85, + stopPropagation: false, + el: { + type: DynamicYearQuarterPopup.xtype, + width: o.isNeedAdjustWidth ? o.width : undefined, + supportDynamic: o.supportDynamic, + ref: _ref => { + this.popup = _ref; + }, + listeners: [ + { + eventName: DynamicYearQuarterPopup.EVENT_CHANGE, + action: () => { + this.setValue(this.popup.getValue()); + this.combo.hideView(); + this.fireEvent(DynamicYearQuarterCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearQuarterPopup.BUTTON_CLEAR_EVENT_CHANGE, + action: () => { + this.setValue(); + this.comboWrapper.element.removeClass("error"); + this.combo.hideView(); + this.fireEvent(DynamicYearQuarterCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearQuarterPopup.BUTTON_lABEL_EVENT_CHANGE, + action: () => { + const date = getDate(); + this.setValue({ + type: DynamicYearMonthCombo.Static, + value: { + year: date.getFullYear(), + quarter: getQuarter(date), + }, + }); + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + }, + { + eventName: DynamicYearQuarterPopup.BUTTON_OK_EVENT_CHANGE, + action: () => { + const value = this.popup.getValue(); + if (this._checkValue(value)) { + this.setValue(value); + } + this.combo.hideView(); + this.fireEvent(DynamicDateCombo.EVENT_CONFIRM); + }, + } + ], + behaviors: o.behaviors, + min: o.minDate, + max: o.maxDate, + }, + value: o.value || "", + }, + }); + this.combo.on(Combo.EVENT_BEFORE_POPUPVIEW, () => { + this.popup.setMinDate(o.minDate); + this.popup.setMaxDate(o.maxDate); + this.popup.setValue(this.storeValue); + this.fireEvent(DynamicYearQuarterCombo.EVENT_BEFORE_POPUPVIEW); + }); + + createWidget({ + type: AbsoluteLayout.xtype, + element: this, + items: [ + { + el: { + type: HorizontalFillLayout.xtype, + columnSize: ["", "fill"], + cls: `${o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"} bi-focus-shadow`, + ref: _ref => { + this.comboWrapper = _ref; + }, + items: [ + { + el: { + type: IconButton.xtype, + cls: "bi-trigger-icon-button date-change-h-font", + width: this._consts.iconWidth, + height: toPix(o.height, border), + ref: _ref => { + this.changeIcon = _ref; + }, + }, + }, + this.combo + ], + }, + top: 0, + left: 0, + right: 0, + bottom: 0, + } + ], + }); + this._checkDynamicValue(o.value); + } + + _checkDynamicValue(v) { + let type = null; + if (isNotNull(v)) { + type = v.type; + } + switch (type) { + case DynamicYearQuarterCombo.Dynamic: + this.changeIcon.setVisible(true); + break; + default: + this.changeIcon.setVisible(false); + break; + } + } + + _checkValue(v) { + const o = this.options; + let value; + switch (v.type) { + case DynamicDateCombo.Dynamic: + return isNotEmptyObject(v.value); + case DynamicDateCombo.Static: + value = v.value || {}; + + return !checkDateVoid(value.year, (value.quarter - 1) * 3 + 1, 1, o.minDate, o.maxDate)[0]; + default: + return true; + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.trigger.setMinDate(minDate); + this.popup && this.popup.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.trigger.setMaxDate(maxDate); + this.popup && this.popup.setMaxDate(maxDate); + } + + hideView() { + this.combo.hideView(); + } + + getKey() { + return this.trigger.getKey(); + } + + setValue(v) { + this.storeValue = v; + this.trigger.setValue(v); + this._checkDynamicValue(v); + } + + getValue() { + return this.storeValue; + } + + isStateValid() { + return this.trigger.isStateValid(); + } +} diff --git a/packages/fineui/src/widget/yearquarter/index.js b/packages/fineui/src/widget/yearquarter/index.js new file mode 100644 index 000000000..29b16b492 --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/index.js @@ -0,0 +1,6 @@ +export { DynamicYearQuarterCard } from "./card.dynamic.yearquarter"; +export { StaticYearQuarterCard } from "./card.static.yearquarter"; +export { DynamicYearQuarterCombo } from "./combo.yearquarter"; +export { DynamicYearQuarterPopup } from "./popup.yearquarter"; +export { DynamicYearQuarterTrigger } from "./trigger.yearquarter"; + diff --git a/packages/fineui/src/widget/yearquarter/popup.yearquarter.js b/packages/fineui/src/widget/yearquarter/popup.yearquarter.js new file mode 100644 index 000000000..5ac06d6a0 --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/popup.yearquarter.js @@ -0,0 +1,328 @@ +import { + shortcut, + Widget, + toPix, + i18nText, + VerticalLayout, + GridLayout, + print, + getDate, + checkDateVoid, + createItems, + getQuarter, + SIZE_CONSANTS +} from "@/core"; +import { DynamicYearQuarterCombo } from "./combo.yearquarter"; +import { TextButton, Tab } from "@/base"; +import { DynamicDateCombo, DynamicDatePopup, DynamicDateHelper } from "../dynamicdate"; +import { DynamicYearCard } from "../year/card.dynamic.year"; +import { LinearSegment } from "@/case"; +import { DynamicYearQuarterCard } from "./card.dynamic.yearquarter"; +import { StaticYearQuarterCard } from "./card.static.yearquarter"; + +@shortcut() +export class DynamicYearQuarterPopup extends Widget { + static xtype = "bi.dynamic_year_quarter_popup"; + + constants = { tabHeight: 40, buttonHeight: 24 }; + props = { + baseCls: "bi-year-quarter-popup", + behaviors: {}, + min: "1900-01-01", + max: "2099-12-31", + width: 180, + supportDynamic: true, + }; + + static BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; + static BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; + static BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; + static EVENT_CHANGE = "EVENT_CHANGE"; + + render() { + this.storeValue = { type: DynamicYearQuarterCombo.Static }; + + return { + type: VerticalLayout.xtype, + items: [ + { + el: this._getTabJson(), + }, + { + el: { + type: GridLayout.xtype, + items: [ + [ + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + shadow: true, + textHeight: toPix( + SIZE_CONSANTS.TOOL_BAR_HEIGHT, + 1 + ), + text: i18nText("BI-Basic_Clear"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent( + DynamicYearQuarterPopup.BUTTON_CLEAR_EVENT_CHANGE + ); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-left bi-split-right bi-high-light bi-split-top", + textHeight: toPix( + SIZE_CONSANTS.TOOL_BAR_HEIGHT, + 1 + ), + shadow: true, + text: i18nText("BI-Basic_Current_Quarter"), + disabled: this._checkTodayValid(), + ref: _ref => { + this.textButton = _ref; + }, + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + this.fireEvent( + DynamicYearQuarterPopup.BUTTON_lABEL_EVENT_CHANGE + ); + }, + } + ], + }, + { + type: TextButton.xtype, + cls: "bi-split-top bi-high-light", + shadow: true, + textHeight: toPix( + SIZE_CONSANTS.TOOL_BAR_HEIGHT, + 1 + ), + text: i18nText("BI-Basic_OK"), + listeners: [ + { + eventName: TextButton.EVENT_CHANGE, + action: () => { + const type = + this.dateTab.getSelect(); + if ( + type === + DynamicDateCombo.Dynamic + ) { + this.dynamicPane.checkValidation( + true + ) && + this.fireEvent( + DynamicDatePopup.BUTTON_OK_EVENT_CHANGE + ); + } else { + this.fireEvent(DynamicYearQuarterPopup + .BUTTON_OK_EVENT_CHANGE + ); + } + }, + } + ], + } + ] + ], + height: SIZE_CONSANTS.TOOL_BAR_HEIGHT, + }, + } + ], + }; + } + + _setInnerValue() { + if (this.dateTab.getSelect() === DynamicYearQuarterCombo.Static) { + this.textButton.setValue(i18nText("BI-Basic_Current_Quarter")); + this.textButton.setEnable(!this._checkTodayValid()); + } else { + let date = DynamicDateHelper.getCalculation( + this.dynamicPane.getInputValue() + ); + date = print(date, "%Y-%Q"); + this.textButton.setValue(date); + this.textButton.setEnable(false); + } + } + + _checkTodayValid() { + const o = this.options; + const today = getDate(); + + return !!checkDateVoid( + today.getFullYear(), + today.getMonth() + 1, + today.getDate(), + o.min, + o.max + )[0]; + } + + _getTabJson() { + const o = this.options; + + return { + type: Tab.xtype, + logic: { + dynamic: true, + }, + ref: _ref => { + this.dateTab = _ref; + }, + tab: { + type: LinearSegment.xtype, + cls: "bi-split-bottom", + invisible: !o.supportDynamic, + height: this.constants.tabHeight, + items: createItems( + [ + { + text: i18nText("BI-Basic_Year_Quarter"), + value: DynamicYearQuarterCombo.Static, + }, + { + text: i18nText("BI-Basic_Dynamic_Title"), + value: DynamicYearQuarterCombo.Dynamic, + } + ], + { + textAlign: "center", + } + ), + }, + cardCreator: v => { + switch (v) { + case DynamicYearQuarterCombo.Dynamic: + return { + type: DynamicYearQuarterCard.xtype, + cls: "dynamic-year-quarter-pane", + min: this.options.min, + max: this.options.max, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: () => { + this._setInnerValue(this.year, v); + }, + } + ], + ref: _ref => { + this.dynamicPane = _ref; + }, + }; + case DynamicYearQuarterCombo.Static: + default: + return { + type: StaticYearQuarterCard.xtype, + behaviors: o.behaviors, + min: this.options.min, + max: this.options.max, + listeners: [ + { + eventName: DynamicYearCard.EVENT_CHANGE, + action: () => { + this.fireEvent( + DynamicYearQuarterPopup.EVENT_CHANGE + ); + }, + } + ], + ref: _ref => { + this.year = _ref; + }, + }; + } + }, + listeners: [ + { + eventName: Tab.EVENT_CHANGE, + action: () => { + const v = this.dateTab.getSelect(); + let date; + switch (v) { + case DynamicYearQuarterCombo.Static: + date = DynamicDateHelper.getCalculation( + this.dynamicPane.getValue() + ); + this.year.setValue({ + year: date.getFullYear(), + quarter: getQuarter(date), + }); + this._setInnerValue(); + break; + case DynamicYearQuarterCombo.Dynamic: + default: + if ( + this.storeValue && + this.storeValue.type === + DynamicYearQuarterCombo.Dynamic + ) { + this.dynamicPane.setValue( + this.storeValue.value + ); + } else { + this.dynamicPane.setValue({ + year: 0, + }); + } + this._setInnerValue(); + break; + } + }, + } + ], + }; + } + + setMinDate(minDate) { + if (this.options.min !== minDate) { + this.options.min = minDate; + this.year && this.year.setMinDate(minDate); + this.dynamicPane && this.dynamicPane.setMinDate(minDate); + } + } + + setMaxDate(maxDate) { + if (this.options.max !== maxDate) { + this.options.max = maxDate; + this.year && this.year.setMaxDate(maxDate); + this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); + } + } + + setValue(v) { + this.storeValue = v; + v = v || {}; + const type = v.type || DynamicDateCombo.Static; + const value = v.value || v; + this.dateTab.setSelect(type); + switch (type) { + case DynamicDateCombo.Dynamic: + this.dynamicPane.setValue(value); + this._setInnerValue(); + break; + case DynamicDateCombo.Static: + default: + this.year.setValue(value); + this.textButton.setValue(i18nText("BI-Basic_Current_Quarter")); + this.textButton.setEnable(!this._checkTodayValid()); + break; + } + } + + getValue() { + return { + type: this.dateTab.getSelect(), + value: this.dateTab.getValue(), + }; + } +} diff --git a/packages/fineui/src/widget/yearquarter/trigger.yearquarter.js b/packages/fineui/src/widget/yearquarter/trigger.yearquarter.js new file mode 100644 index 000000000..4020036c5 --- /dev/null +++ b/packages/fineui/src/widget/yearquarter/trigger.yearquarter.js @@ -0,0 +1,373 @@ +import { + shortcut, + i18nText, + createWidget, + HTapeLayout, + CenterLayout, + HorizontalFillLayout, + isEmptyString, + parseDateTime, + isPositiveInteger, + checkDateVoid, + isNotEmptyString, + isNotNull, + print, + checkDateLegal, + isNull, + parseInt, + getDate, + getQuarter +} from "@/core"; +import { Trigger, TextButton } from "@/base"; +import { TriggerIconButton, SignEditor } from "@/case"; +import { DynamicDateHelper } from "../dynamicdate"; +import { DynamicYearMonthTrigger } from "../yearmonth/trigger.yearmonth"; +import { DynamicYearQuarterCombo } from "./combo.yearquarter"; + +@shortcut() +export class DynamicYearQuarterTrigger extends Trigger { + static xtype = "bi.dynamic_year_quarter_trigger"; + + _const = { hgap: 4, vgap: 2, iconWidth: 24 }; + + static EVENT_FOCUS = "EVENT_FOCUS"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_START = "EVENT_START"; + static EVENT_CONFIRM = "EVENT_CONFIRM"; + static EVENT_STOP = "EVENT_STOP"; + static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; + static EVENT_VALID = "EVENT_VALID"; + + props() { + return { + extraCls: "bi-year-quarter-trigger", + min: "1900-01-01", // 最小日期 + max: "2099-12-31", // 最大日期 + height: 24, + watermark: { + year: i18nText("BI-Basic_Unrestricted"), + quarter: i18nText("BI-Basic_Unrestricted"), + }, + }; + } + + _init() { + super._init(...arguments); + const o = this.options; + this.yearEditor = this._createEditor(true); + this.quarterEditor = this._createEditor(false); + + // 暂时的解决方法 + // const height = o.height + 2; + + createWidget({ + element: this, + type: HTapeLayout.xtype, + items: [ + { + type: CenterLayout.xtype, + items: [ + { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + this.yearEditor, + { + el: { + type: TextButton.xtype, + text: i18nText("BI-Multi_Date_Year"), + }, + } + ], + }, + { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", ""], + items: [ + this.quarterEditor, + { + el: { + type: TextButton.xtype, + text: i18nText("BI-Multi_Date_Quarter"), + }, + } + ], + } + ], + }, + { + el: { + type: TriggerIconButton.xtype, + width: this._const.iconWidth, + }, + width: this._const.iconWidth, + } + ], + }); + this.setValue(o.value); + } + + _createEditor(isYear) { + const o = this.options, + c = this._const; + const editor = createWidget({ + type: SignEditor.xtype, + simple: o.simple, + height: o.height, + validationChecker: v => { + if (isYear) { + let month = this.quarterEditor.getValue(); + if (isEmptyString(month)) { + month = + parseInt(v, 10) === + parseDateTime(o.min, "%Y-%X-%d").getFullYear() + ? parseDateTime(o.min, "%Y-%X-%d").getMonth() + + 1 + : 1; + } else { + month = (parseInt(month, 10) - 1) * 3 + 1; + } + + return ( + v === "" || + (isPositiveInteger(v) && + !checkDateVoid(v, month, 1, o.min, o.max)[0]) + ); + } + const year = this.yearEditor.getValue(); + + return ( + v === "" || + (isPositiveInteger(v) && + v >= 1 && + v <= 4 && + (isEmptyString(year) + ? true + : !checkDateVoid( + this.yearEditor.getValue(), + (v - 1) * 3 + 1, + 1, + o.min, + o.max + )[0])) + ); + }, + quitChecker: () => false, + errorText: v => { + const year = isYear ? v : this.yearEditor.getValue(); + const quarter = isYear ? this.quarterEditor.getValue() : v; + if ( + !isPositiveInteger(year) || + !isPositiveInteger(quarter) || + quarter > 4 + ) { + return i18nText("BI-Year_Trigger_Invalid_Text"); + } + + const start = parseDateTime(o.min, "%Y-%X-%d"); + const end = parseDateTime(o.max, "%Y-%X-%d"); + + return i18nText( + "BI-Basic_Year_Quarter_Range_Error", + start.getFullYear(), + getQuarter(start), + end.getFullYear(), + getQuarter(end) + ); + }, + watermark: isYear ? o.watermark?.year : o.watermark?.quarter, + hgap: c.hgap, + vgap: c.vgap, + allowBlank: true, + }); + editor.on(SignEditor.EVENT_KEY_DOWN, () => { + this.fireEvent(DynamicYearQuarterTrigger.EVENT_KEY_DOWN); + }); + editor.on(SignEditor.EVENT_FOCUS, () => { + this.fireEvent(DynamicYearQuarterTrigger.EVENT_FOCUS); + }); + editor.on(SignEditor.EVENT_STOP, () => { + this.fireEvent(DynamicYearQuarterTrigger.EVENT_STOP); + }); + editor.on(SignEditor.EVENT_CONFIRM, () => { + this._doEditorConfirm(editor); + this.fireEvent(DynamicYearQuarterTrigger.EVENT_CONFIRM); + }); + editor.on(SignEditor.EVENT_SPACE, () => { + if (editor.isValid()) { + editor.blur(); + } + }); + editor.on(SignEditor.EVENT_START, () => { + this.fireEvent(DynamicYearQuarterTrigger.EVENT_START); + }); + editor.on(SignEditor.EVENT_ERROR, () => { + this.fireEvent(DynamicYearQuarterTrigger.EVENT_ERROR); + }); + editor.on(SignEditor.EVENT_VALID, () => { + const year = this.yearEditor.getValue(); + const quarter = this.quarterEditor.getValue(); + if (isNotEmptyString(year) && isNotEmptyString(quarter)) { + if ( + isPositiveInteger(year) && + quarter >= 1 && + quarter <= 4 && + !checkDateVoid( + year, + (quarter - 1) * 3 + 1, + 1, + o.min, + o.max + )[0] + ) { + this.fireEvent(DynamicYearMonthTrigger.EVENT_VALID); + } + } + }); + editor.on(SignEditor.EVENT_CHANGE, () => { + if (isYear) { + this._autoSwitch(editor); + } + }); + + return editor; + } + + _doEditorConfirm(editor) { + const value = editor.getValue(); + if (isNotNull(value)) { + editor.setValue(value); + } + const quarterValue = this.quarterEditor.getValue(); + this.storeValue = { + type: DynamicYearQuarterCombo.Static, + value: { + year: this.yearEditor.getValue(), + quarter: isEmptyString(this.quarterEditor.getValue()) + ? "" + : quarterValue, + }, + }; + this.setTitle(this._getStaticTitle(this.storeValue.value)); + } + + _yearCheck(v) { + const date = print(parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); + + return ( + print(parseDateTime(v, "%Y"), "%Y") === v && + date >= this.options.min && + date <= this.options.max + ); + } + + _autoSwitch(editor) { + const v = editor.getValue(); + if (isNotEmptyString(v) && checkDateLegal(v)) { + if (v.length === 4 && this._yearCheck(v)) { + this._doEditorConfirm(editor); + this.fireEvent(DynamicYearQuarterTrigger.EVENT_CONFIRM); + this.quarterEditor.focus(); + } + } + } + + _getStaticTitle(value) { + value = value || {}; + const hasYear = !(isNull(value.year) || isEmptyString(value.year)); + const hasMonth = !(isNull(value.quarter) || isEmptyString(value.quarter)); + switch ((hasYear << 1) | hasMonth) { + // !hasYear && !hasMonth + case 0: + return ""; + // !hasYear && hasMonth + case 1: + return value.quarter; + // hasYear && !hasMonth + case 2: + return value.year; + // hasYear && hasMonth + case 3: + default: + return `${value.year}-${value.quarter}`; + } + } + + _getText(obj) { + let value = ""; + if (isNotNull(obj.year) && parseInt(obj.year) !== 0) { + value += + Math.abs(obj.year) + + i18nText("BI-Basic_Year") + + (obj.year < 0 + ? i18nText("BI-Basic_Front") + : i18nText("BI-Basic_Behind")); + } + if (isNotNull(obj.quarter) && parseInt(obj.quarter) !== 0) { + value += + Math.abs(obj.quarter) + + i18nText("BI-Basic_Single_Quarter") + + (obj.quarter < 0 + ? i18nText("BI-Basic_Front") + : i18nText("BI-Basic_Behind")); + } + + return value; + } + + _setInnerValue(date, text) { + const dateStr = print(date, "%Y-%Q"); + this.yearEditor.setValue(date.getFullYear()); + this.quarterEditor.setValue(getQuarter(date)); + this.setTitle(isEmptyString(text) ? dateStr : `${text}:${dateStr}`); + } + + setMinDate(minDate) { + if (isNotEmptyString(this.options.min)) { + this.options.min = minDate; + } + } + + setMaxDate(maxDate) { + if (isNotEmptyString(this.options.max)) { + this.options.max = maxDate; + } + } + + setValue(v) { + let type, value, text, quarter; + let date = getDate(); + this.storeValue = v; + if (isNotNull(v)) { + type = v.type || DynamicYearQuarterCombo.Static; + value = v.value || v; + } + switch (type) { + case DynamicYearQuarterCombo.Dynamic: + text = this._getText(value); + date = DynamicDateHelper.getCalculation(value); + this._setInnerValue(date, text); + break; + case DynamicYearQuarterCombo.Static: + default: + value = value || {}; + quarter = isNull(value.quarter) ? null : value.quarter; + this.yearEditor.setValue(value.year); + this.quarterEditor.setValue(quarter); + this.setTitle(this._getStaticTitle(value)); + break; + } + } + + getValue() { + return this.storeValue; + } + + getKey() { + return `${this.yearEditor.getValue()}-${this.quarterEditor.getValue()}`; + } + + isStateValid() { + return this.yearEditor.isValid() && this.quarterEditor.isValid(); + } +} diff --git a/packages/fineui/src/widget/yearquarterinterval/yearquarterinterval.js b/packages/fineui/src/widget/yearquarterinterval/yearquarterinterval.js new file mode 100644 index 000000000..16fa9f4a5 --- /dev/null +++ b/packages/fineui/src/widget/yearquarterinterval/yearquarterinterval.js @@ -0,0 +1,248 @@ +import { + shortcut, + HorizontalFillLayout, + createWidget, + i18nText, + print, + parseDateTime, + checkDateVoid, + isNotNull, + checkDateLegal +} from "@/core"; +import { Single, Label, Bubbles } from "@/base"; +import { DynamicYearQuarterCombo } from "../yearquarter"; + +@shortcut() +export class YearQuarterInterval extends Single { + static xtype = "bi.year_quarter_interval"; + + constants = { + height: 24, + width: 25, + lgap: 15, + offset: -15, + timeErrorCls: "time-error", + }; + props = { + extraCls: "bi-year-quarter-interval", + minDate: "1900-01-01", + maxDate: "2099-12-31", + supportDynamic: true, + }; + + static EVENT_VALID = "EVENT_VALID"; + static EVENT_ERROR = "EVENT_ERROR"; + static EVENT_CHANGE = "EVENT_CHANGE"; + static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; + + render() { + const o = this.options; + + o.value = o.value || {}; + this.left = this._createCombo(o.value.start, o.watermark?.start); + this.right = this._createCombo(o.value.end, o.watermark?.end); + + return { + type: HorizontalFillLayout.xtype, + columnSize: ["fill", "", "fill"], + items: [ + { + el: this.left, + }, + { + el: { + type: Label.xtype, + height: o.height, + hgap: 5, + text: "-", + ref: _ref => { + this.label = _ref; + }, + }, + }, + { + el: this.right, + } + ], + }; + } + + _createCombo(v, watermark) { + const o = this.options; + const combo = createWidget({ + type: DynamicYearQuarterCombo.xtype, + supportDynamic: o.supportDynamic, + minDate: o.minDate, + maxDate: o.maxDate, + behaviors: o.behaviors, + value: v, + height: o.height, + watermark, + listeners: [ + { + eventName: DynamicYearQuarterCombo.EVENT_BEFORE_POPUPVIEW, + action: () => { + this.fireEvent( + YearQuarterInterval.EVENT_BEFORE_POPUPVIEW + ); + }, + } + ], + }); + combo.on(DynamicYearQuarterCombo.EVENT_ERROR, () => { + this._clearTitle(); + Bubbles.hide("error"); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearQuarterInterval.EVENT_ERROR); + }); + + combo.on(DynamicYearQuarterCombo.EVENT_VALID, () => { + this._checkValid(); + }); + + combo.on(DynamicYearQuarterCombo.EVENT_FOCUS, () => { + this._checkValid(); + }); + + combo.on(DynamicYearQuarterCombo.EVENT_CONFIRM, () => { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isStateValid() && + this.right.isStateValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + this.fireEvent(YearQuarterInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + this.fireEvent(YearQuarterInterval.EVENT_CHANGE); + } + }); + + return combo; + } + + _dateCheck(date) { + return ( + print(parseDateTime(date, "%Y-%Q"), "%Y-%Q") === date || + print(parseDateTime(date, "%Y-%q"), "%Y-%q") === date + ); + } + + _checkVoid(obj) { + const o = this.options; + + return !checkDateVoid( + obj.year, + (obj.quarter - 1) * 3 + 1, + 1, + o.minDate, + o.maxDate + )[0]; + } + + _check(smallDate, bigDate) { + const smallObj = smallDate.match(/\d+/g), + bigObj = bigDate.match(/\d+/g); + + let smallDate4Check = ""; + if (isNotNull(smallObj)) { + smallDate4Check = `${smallObj[0] || ""}-${smallObj[1] || 1}`; + } + + let bigDate4Check = ""; + if (isNotNull(bigObj)) { + bigDate4Check = `${bigObj[0] || ""}-${bigObj[1] || 1}`; + } + + return ( + this._dateCheck(smallDate4Check) && + checkDateLegal(smallDate4Check) && + this._checkVoid({ + year: smallObj[0], + quarter: smallObj[1] || 1, + }) && + this._dateCheck(bigDate4Check) && + checkDateLegal(bigDate4Check) && + this._checkVoid({ + year: bigObj[0], + quarter: bigObj[1] || 1, + }) + ); + } + + _compare(smallDate, bigDate) { + smallDate = print(parseDateTime(smallDate, "%Y-%Q"), "%Y-%Q"); + bigDate = print(parseDateTime(bigDate, "%Y-%Q"), "%Y-%Q"); + + return ( + isNotNull(smallDate) && isNotNull(bigDate) && smallDate > bigDate + ); + } + + _setTitle(v) { + this.setTitle(v); + } + + _clearTitle() { + this.setTitle(""); + } + + _checkValid() { + Bubbles.hide("error"); + const smallDate = this.left.getKey(), + bigDate = this.right.getKey(); + if ( + this.left.isValid() && + this.right.isValid() && + this._check(smallDate, bigDate) && + this._compare(smallDate, bigDate) + ) { + this._setTitle(i18nText("BI-Time_Interval_Error_Text")); + this.element.addClass(this.constants.timeErrorCls); + Bubbles.show( + "error", + i18nText("BI-Time_Interval_Error_Text"), + this, + { + offsetStyle: "center", + } + ); + this.fireEvent(YearQuarterInterval.EVENT_ERROR); + } else { + this._clearTitle(); + this.element.removeClass(this.constants.timeErrorCls); + } + } + + setMinDate(minDate) { + const o = this.options; + o.minDate = minDate; + this.left.setMinDate(minDate); + this.right.setMinDate(minDate); + } + + setMaxDate(maxDate) { + const o = this.options; + o.maxDate = maxDate; + this.left.setMaxDate(maxDate); + this.right.setMaxDate(maxDate); + } + + setValue(date) { + date = date || {}; + this.left.setValue(date.start); + this.right.setValue(date.end); + + this._checkValid(); + } + + getValue() { + return { start: this.left.getValue(), end: this.right.getValue() }; + } +} diff --git a/packages/fineui/src/worker.js b/packages/fineui/src/worker.js new file mode 100644 index 000000000..2956dde18 --- /dev/null +++ b/packages/fineui/src/worker.js @@ -0,0 +1,36 @@ +// sideEffects +import "./core/system"; + +import * as _core from "./core"; +import * as _base from "./base"; +import * as _fix from "./fix"; +import * as _router from "./router"; + +export * as Popper from "@popperjs/core"; + +import * as D from "@/core/decorator"; +import { Fix } from "./fix"; + +const Decorators = { ...D, Model: Fix.Model }; + +const fuiExport = { + ..._core, + ..._base, + ..._fix, + ..._router +}; + +import * as injectFn from "@/core/5.inject"; +import { _global } from "@/core/0.foundation"; +import { _defineVarProperties } from "@/core/constant/writable.var"; + +_global.BI = _global.BI || {}; + +Object.assign(_global, { + Fix: fuiExport.Fix, + _: fuiExport._, +}); + +Object.assign(_global.BI, fuiExport, injectFn, { Decorators, }); + +_defineVarProperties(_global.BI); diff --git a/packages/fineui/tsconfig.json b/packages/fineui/tsconfig.json new file mode 100644 index 000000000..26425a5c4 --- /dev/null +++ b/packages/fineui/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "sourceMap": true, + "target": "es2017", + "module": "es2015", + "moduleResolution": "node", + "lib": [ + "es2017", + "dom" + ], + "declaration": true, + "experimentalDecorators": true, + "outDir": "./dist/lib", + "baseUrl": ".", + // "strict": true, + "strictNullChecks": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "emitDeclarationOnly": true, + "paths": { + "@": ["src"] + } + }, + "include": ["typescript/*.ts", "typescript/**/*.ts", "types/*.d.ts", "src/*.js", "src/**/*.js"], + "exclude": ["typescript/index.old.ts"] +} diff --git a/packages/fineui/types/globals.d.ts b/packages/fineui/types/globals.d.ts new file mode 100644 index 000000000..00b1613f0 --- /dev/null +++ b/packages/fineui/types/globals.d.ts @@ -0,0 +1,15 @@ +interface Obj { + [key: string]: any; +} + +// declare let BI: Obj & import("../typescript/index").BI; + +declare let BI: Obj; + +// declare const Fix: Obj; + +declare interface String { + replaceAll(regx: string, callback: (str: string) => void): string; +} + +declare const _global: typeof window; diff --git a/typescript/base/a/a.ts b/packages/fineui/typescript/base/a/a.ts similarity index 100% rename from typescript/base/a/a.ts rename to packages/fineui/typescript/base/a/a.ts diff --git a/packages/fineui/typescript/base/base.ts b/packages/fineui/typescript/base/base.ts new file mode 100644 index 000000000..3c4802135 --- /dev/null +++ b/packages/fineui/typescript/base/base.ts @@ -0,0 +1,21 @@ +import { LayerController } from "../core/controller/controller.layer"; +import { BroadcastController } from "../core/controller/controller.broadcast"; +import { StyleLoaderManager } from "../core/loader/loader.style"; +import { BubblesController } from "../core/controller/controller.bubbles"; +import { PopoverController } from "../core/controller/controller.popovers"; +import { MaskersController } from "../core/controller/controller.masker"; +import { ResizeController } from "../core/controller/controller.resizer"; + +export const Layers = new LayerController(); + +export const Maskers = new MaskersController(); + +export const Bubbles = new BubblesController(); + +export const Broadcasts = new BroadcastController(); + +export const StyleLoaders = new StyleLoaderManager(); + +export const Popovers = new PopoverController(); + +export const Resizers = new ResizeController(); diff --git a/typescript/base/combination/combo.ts b/packages/fineui/typescript/base/combination/combo.ts similarity index 100% rename from typescript/base/combination/combo.ts rename to packages/fineui/typescript/base/combination/combo.ts diff --git a/typescript/base/combination/expander.ts b/packages/fineui/typescript/base/combination/expander.ts similarity index 100% rename from typescript/base/combination/expander.ts rename to packages/fineui/typescript/base/combination/expander.ts diff --git a/typescript/base/combination/group.button.ts b/packages/fineui/typescript/base/combination/group.button.ts similarity index 100% rename from typescript/base/combination/group.button.ts rename to packages/fineui/typescript/base/combination/group.button.ts diff --git a/typescript/base/combination/group.virtual.ts b/packages/fineui/typescript/base/combination/group.virtual.ts similarity index 100% rename from typescript/base/combination/group.virtual.ts rename to packages/fineui/typescript/base/combination/group.virtual.ts diff --git a/typescript/base/combination/loader.ts b/packages/fineui/typescript/base/combination/loader.ts similarity index 100% rename from typescript/base/combination/loader.ts rename to packages/fineui/typescript/base/combination/loader.ts diff --git a/typescript/base/combination/searcher.ts b/packages/fineui/typescript/base/combination/searcher.ts similarity index 100% rename from typescript/base/combination/searcher.ts rename to packages/fineui/typescript/base/combination/searcher.ts diff --git a/typescript/base/combination/switcher.ts b/packages/fineui/typescript/base/combination/switcher.ts similarity index 100% rename from typescript/base/combination/switcher.ts rename to packages/fineui/typescript/base/combination/switcher.ts diff --git a/typescript/base/combination/tab.ts b/packages/fineui/typescript/base/combination/tab.ts similarity index 100% rename from typescript/base/combination/tab.ts rename to packages/fineui/typescript/base/combination/tab.ts diff --git a/typescript/base/combination/tree.button.ts b/packages/fineui/typescript/base/combination/tree.button.ts similarity index 100% rename from typescript/base/combination/tree.button.ts rename to packages/fineui/typescript/base/combination/tree.button.ts diff --git a/packages/fineui/typescript/base/el.ts b/packages/fineui/typescript/base/el.ts new file mode 100644 index 000000000..a46444d66 --- /dev/null +++ b/packages/fineui/typescript/base/el.ts @@ -0,0 +1,6 @@ +import { Widget } from "../core/widget"; + +export declare class EL extends Widget { + setValue(v: any): void; + getValue(): any; +} diff --git a/packages/fineui/typescript/base/foundation/message.ts b/packages/fineui/typescript/base/foundation/message.ts new file mode 100644 index 000000000..2094d7fea --- /dev/null +++ b/packages/fineui/typescript/base/foundation/message.ts @@ -0,0 +1,20 @@ +type toastOptions = { + level: "success" | "warning" | "error" | "normal" | "loading" + autoClose?: boolean + callback?: Function + closable?: boolean +} + +export declare namespace Msg { + function alert(title: string, message?: string | { + [key: string]: any + }, callback?: (result?: boolean) => void): void + + function confirm(title: string, message?: string | { + [key: string]: any + }, callback?: (result: boolean) => void): void + + function prompt(title: string, message?: string, value?: any, callback?: (result: string) => void, minWidth?: number): void + + function toast(message: string | Obj, options?: toastOptions | string, context?: HTMLElement): Function +} diff --git a/typescript/base/layer/layer.popover.ts b/packages/fineui/typescript/base/layer/layer.popover.ts similarity index 100% rename from typescript/base/layer/layer.popover.ts rename to packages/fineui/typescript/base/layer/layer.popover.ts diff --git a/typescript/base/layer/layer.popup.ts b/packages/fineui/typescript/base/layer/layer.popup.ts similarity index 100% rename from typescript/base/layer/layer.popup.ts rename to packages/fineui/typescript/base/layer/layer.popup.ts diff --git a/typescript/base/list/listview.ts b/packages/fineui/typescript/base/list/listview.ts similarity index 100% rename from typescript/base/list/listview.ts rename to packages/fineui/typescript/base/list/listview.ts diff --git a/typescript/base/list/virtualgrouplist.ts b/packages/fineui/typescript/base/list/virtualgrouplist.ts similarity index 100% rename from typescript/base/list/virtualgrouplist.ts rename to packages/fineui/typescript/base/list/virtualgrouplist.ts diff --git a/typescript/base/list/virtuallist.ts b/packages/fineui/typescript/base/list/virtuallist.ts similarity index 100% rename from typescript/base/list/virtuallist.ts rename to packages/fineui/typescript/base/list/virtuallist.ts diff --git a/typescript/base/pager/pager.ts b/packages/fineui/typescript/base/pager/pager.ts similarity index 100% rename from typescript/base/pager/pager.ts rename to packages/fineui/typescript/base/pager/pager.ts diff --git a/typescript/base/pane.ts b/packages/fineui/typescript/base/pane.ts similarity index 100% rename from typescript/base/pane.ts rename to packages/fineui/typescript/base/pane.ts diff --git a/typescript/base/single/button/button.basic.ts b/packages/fineui/typescript/base/single/button/button.basic.ts similarity index 100% rename from typescript/base/single/button/button.basic.ts rename to packages/fineui/typescript/base/single/button/button.basic.ts diff --git a/typescript/base/single/button/button.node.ts b/packages/fineui/typescript/base/single/button/button.node.ts similarity index 100% rename from typescript/base/single/button/button.node.ts rename to packages/fineui/typescript/base/single/button/button.node.ts diff --git a/typescript/base/single/button/buttons/button.icon.ts b/packages/fineui/typescript/base/single/button/buttons/button.icon.ts similarity index 100% rename from typescript/base/single/button/buttons/button.icon.ts rename to packages/fineui/typescript/base/single/button/buttons/button.icon.ts diff --git a/typescript/base/single/button/buttons/button.image.ts b/packages/fineui/typescript/base/single/button/buttons/button.image.ts similarity index 100% rename from typescript/base/single/button/buttons/button.image.ts rename to packages/fineui/typescript/base/single/button/buttons/button.image.ts diff --git a/packages/fineui/typescript/base/single/button/buttons/button.text.ts b/packages/fineui/typescript/base/single/button/buttons/button.text.ts new file mode 100644 index 000000000..30ae7380e --- /dev/null +++ b/packages/fineui/typescript/base/single/button/buttons/button.text.ts @@ -0,0 +1,19 @@ +import { Label } from "../../label/label"; +import { BasicButton } from "../button.basic"; + +export declare class TextButton extends BasicButton { + static xtype: string; + static EVENT_CHANGE: string; + + props: Label['props'] & BasicButton['props']; + + setStyle(style: any): void; + + doRedMark(...args: any[]): void; + + unRedMark(...args: any[]): void; + + doHighLight(...args: any[]): void; + + unHighLight(...args: any[]): void; +} diff --git a/packages/fineui/typescript/base/single/button/buttons/button.ts b/packages/fineui/typescript/base/single/button/buttons/button.ts new file mode 100644 index 000000000..f77d0e1ea --- /dev/null +++ b/packages/fineui/typescript/base/single/button/buttons/button.ts @@ -0,0 +1,45 @@ +import { Label } from "../../label/label"; +import { AbstractLabel } from "../../label/abstract.label"; +import { IconLabel } from "../../label/icon.label"; +import { BasicButton } from "../button.basic"; + +export declare class Button extends BasicButton { + static xtype: string; + + static EVENT_CHANGE: string; + + props: { + minWidth?: number; + readonly?: boolean; + iconCls?: string; + level?: "common" | "success" | "warning" | "error" | "ignore", + block?: boolean; // 是否块状显示,即不显示边框,没有最小宽度的限制 + loading?: boolean, // 是否处于加载中 + light?: boolean, // 是否使用浅色 + plain?: boolean, // 是否是朴素按钮,和 clear 的区别是 plain 有悬浮效果 + clear?: boolean; // 是否去掉边框和背景 + ghost?: boolean; // 是否幽灵显示, 即正常状态无背景 + iconGap?: number; + iconPosition?: string; + textWidth?: number; + } & AbstractLabel["props"] & IconLabel["props"] & BasicButton["props"]; + + text: Label; + icon?: IconLabel; + + doRedMark(...args: any[]): void; + + unRedMark(...args: any[]): void; + + doHighLight(...args: any[]): void; + + unHighLight(...args: any[]): void; + + loading(): void; + + loaded(): void; + + setIcon(iconCls: string): void; + + isLoading(): boolean; +} diff --git a/typescript/base/single/button/listitem/blankicontextitem.ts b/packages/fineui/typescript/base/single/button/listitem/blankicontextitem.ts similarity index 100% rename from typescript/base/single/button/listitem/blankicontextitem.ts rename to packages/fineui/typescript/base/single/button/listitem/blankicontextitem.ts diff --git a/typescript/base/single/button/listitem/icontexticonitem.ts b/packages/fineui/typescript/base/single/button/listitem/icontexticonitem.ts similarity index 100% rename from typescript/base/single/button/listitem/icontexticonitem.ts rename to packages/fineui/typescript/base/single/button/listitem/icontexticonitem.ts diff --git a/typescript/base/single/button/listitem/icontextitem.ts b/packages/fineui/typescript/base/single/button/listitem/icontextitem.ts similarity index 100% rename from typescript/base/single/button/listitem/icontextitem.ts rename to packages/fineui/typescript/base/single/button/listitem/icontextitem.ts diff --git a/typescript/base/single/button/node/textnode.ts b/packages/fineui/typescript/base/single/button/node/textnode.ts similarity index 100% rename from typescript/base/single/button/node/textnode.ts rename to packages/fineui/typescript/base/single/button/node/textnode.ts diff --git a/typescript/base/single/editor/editor.textarea.ts b/packages/fineui/typescript/base/single/editor/editor.textarea.ts similarity index 100% rename from typescript/base/single/editor/editor.textarea.ts rename to packages/fineui/typescript/base/single/editor/editor.textarea.ts diff --git a/typescript/base/single/editor/editor.ts b/packages/fineui/typescript/base/single/editor/editor.ts similarity index 100% rename from typescript/base/single/editor/editor.ts rename to packages/fineui/typescript/base/single/editor/editor.ts diff --git a/typescript/base/single/html/html.ts b/packages/fineui/typescript/base/single/html/html.ts similarity index 100% rename from typescript/base/single/html/html.ts rename to packages/fineui/typescript/base/single/html/html.ts diff --git a/typescript/base/single/icon/icon.ts b/packages/fineui/typescript/base/single/icon/icon.ts similarity index 100% rename from typescript/base/single/icon/icon.ts rename to packages/fineui/typescript/base/single/icon/icon.ts diff --git a/typescript/base/single/iframe/iframe.ts b/packages/fineui/typescript/base/single/iframe/iframe.ts similarity index 100% rename from typescript/base/single/iframe/iframe.ts rename to packages/fineui/typescript/base/single/iframe/iframe.ts diff --git a/typescript/base/single/img/img.ts b/packages/fineui/typescript/base/single/img/img.ts similarity index 100% rename from typescript/base/single/img/img.ts rename to packages/fineui/typescript/base/single/img/img.ts diff --git a/typescript/base/single/input/checkbox.ts b/packages/fineui/typescript/base/single/input/checkbox.ts similarity index 100% rename from typescript/base/single/input/checkbox.ts rename to packages/fineui/typescript/base/single/input/checkbox.ts diff --git a/typescript/base/single/input/input.ts b/packages/fineui/typescript/base/single/input/input.ts similarity index 100% rename from typescript/base/single/input/input.ts rename to packages/fineui/typescript/base/single/input/input.ts diff --git a/typescript/base/single/input/radio/radio.ts b/packages/fineui/typescript/base/single/input/radio/radio.ts similarity index 100% rename from typescript/base/single/input/radio/radio.ts rename to packages/fineui/typescript/base/single/input/radio/radio.ts diff --git a/typescript/base/single/label/abstract.label.ts b/packages/fineui/typescript/base/single/label/abstract.label.ts similarity index 100% rename from typescript/base/single/label/abstract.label.ts rename to packages/fineui/typescript/base/single/label/abstract.label.ts diff --git a/typescript/base/single/label/html.label.ts b/packages/fineui/typescript/base/single/label/html.label.ts similarity index 100% rename from typescript/base/single/label/html.label.ts rename to packages/fineui/typescript/base/single/label/html.label.ts diff --git a/typescript/base/single/label/icon.label.ts b/packages/fineui/typescript/base/single/label/icon.label.ts similarity index 100% rename from typescript/base/single/label/icon.label.ts rename to packages/fineui/typescript/base/single/label/icon.label.ts diff --git a/typescript/base/single/label/label.ts b/packages/fineui/typescript/base/single/label/label.ts similarity index 100% rename from typescript/base/single/label/label.ts rename to packages/fineui/typescript/base/single/label/label.ts diff --git a/typescript/base/single/single.ts b/packages/fineui/typescript/base/single/single.ts similarity index 100% rename from typescript/base/single/single.ts rename to packages/fineui/typescript/base/single/single.ts diff --git a/typescript/base/single/text.ts b/packages/fineui/typescript/base/single/text.ts similarity index 100% rename from typescript/base/single/text.ts rename to packages/fineui/typescript/base/single/text.ts diff --git a/packages/fineui/typescript/base/single/tip/tip.ts b/packages/fineui/typescript/base/single/tip/tip.ts new file mode 100644 index 000000000..2b9f483a5 --- /dev/null +++ b/packages/fineui/typescript/base/single/tip/tip.ts @@ -0,0 +1,5 @@ +import { Single } from "../single"; + +export declare class Tip extends Single { + +} diff --git a/typescript/base/single/trigger/trigger.ts b/packages/fineui/typescript/base/single/trigger/trigger.ts similarity index 100% rename from typescript/base/single/trigger/trigger.ts rename to packages/fineui/typescript/base/single/trigger/trigger.ts diff --git a/typescript/base/tree/customtree.ts b/packages/fineui/typescript/base/tree/customtree.ts similarity index 100% rename from typescript/base/tree/customtree.ts rename to packages/fineui/typescript/base/tree/customtree.ts diff --git a/typescript/base/tree/ztree/asynctree.ts b/packages/fineui/typescript/base/tree/ztree/asynctree.ts similarity index 100% rename from typescript/base/tree/ztree/asynctree.ts rename to packages/fineui/typescript/base/tree/ztree/asynctree.ts diff --git a/typescript/base/tree/ztree/list/listasynctree.ts b/packages/fineui/typescript/base/tree/ztree/list/listasynctree.ts similarity index 100% rename from typescript/base/tree/ztree/list/listasynctree.ts rename to packages/fineui/typescript/base/tree/ztree/list/listasynctree.ts diff --git a/typescript/base/tree/ztree/list/listtreeview.ts b/packages/fineui/typescript/base/tree/ztree/list/listtreeview.ts similarity index 100% rename from typescript/base/tree/ztree/list/listtreeview.ts rename to packages/fineui/typescript/base/tree/ztree/list/listtreeview.ts diff --git a/typescript/base/tree/ztree/treeview.ts b/packages/fineui/typescript/base/tree/ztree/treeview.ts similarity index 100% rename from typescript/base/tree/ztree/treeview.ts rename to packages/fineui/typescript/base/tree/ztree/treeview.ts diff --git a/packages/fineui/typescript/bundle.ts b/packages/fineui/typescript/bundle.ts new file mode 100644 index 000000000..174fa3e6e --- /dev/null +++ b/packages/fineui/typescript/bundle.ts @@ -0,0 +1,5 @@ +import { Workers } from "./core/worker/workers"; +// 仅Workers是ts实现的代码,所以要挂载到BI上 +BI?.extend(BI, { + Workers: Workers +}); \ No newline at end of file diff --git a/typescript/case/button/icon/icon.change.ts b/packages/fineui/typescript/case/button/icon/icon.change.ts similarity index 100% rename from typescript/case/button/icon/icon.change.ts rename to packages/fineui/typescript/case/button/icon/icon.change.ts diff --git a/typescript/case/button/icon/icon.trigger.ts b/packages/fineui/typescript/case/button/icon/icon.trigger.ts similarity index 100% rename from typescript/case/button/icon/icon.trigger.ts rename to packages/fineui/typescript/case/button/icon/icon.trigger.ts diff --git a/typescript/case/button/icon/iconhalf/icon.half.image.ts b/packages/fineui/typescript/case/button/icon/iconhalf/icon.half.image.ts similarity index 100% rename from typescript/case/button/icon/iconhalf/icon.half.image.ts rename to packages/fineui/typescript/case/button/icon/iconhalf/icon.half.image.ts diff --git a/typescript/case/button/icon/iconhalf/icon.half.ts b/packages/fineui/typescript/case/button/icon/iconhalf/icon.half.ts similarity index 100% rename from typescript/case/button/icon/iconhalf/icon.half.ts rename to packages/fineui/typescript/case/button/icon/iconhalf/icon.half.ts diff --git a/typescript/case/button/item.multiselect.ts b/packages/fineui/typescript/case/button/item.multiselect.ts similarity index 100% rename from typescript/case/button/item.multiselect.ts rename to packages/fineui/typescript/case/button/item.multiselect.ts diff --git a/typescript/case/button/item.singleselect.radio.ts b/packages/fineui/typescript/case/button/item.singleselect.radio.ts similarity index 100% rename from typescript/case/button/item.singleselect.radio.ts rename to packages/fineui/typescript/case/button/item.singleselect.radio.ts diff --git a/typescript/case/button/item.singleselect.ts b/packages/fineui/typescript/case/button/item.singleselect.ts similarity index 100% rename from typescript/case/button/item.singleselect.ts rename to packages/fineui/typescript/case/button/item.singleselect.ts diff --git a/typescript/case/button/node/node.icon.arrow.ts b/packages/fineui/typescript/case/button/node/node.icon.arrow.ts similarity index 100% rename from typescript/case/button/node/node.icon.arrow.ts rename to packages/fineui/typescript/case/button/node/node.icon.arrow.ts diff --git a/packages/fineui/typescript/case/button/node/node.multilayer.icon.arrow.ts b/packages/fineui/typescript/case/button/node/node.multilayer.icon.arrow.ts new file mode 100644 index 000000000..9010fe6c4 --- /dev/null +++ b/packages/fineui/typescript/case/button/node/node.multilayer.icon.arrow.ts @@ -0,0 +1,9 @@ +import { NodeButton } from '../../../base/single/button/button.node'; + +export declare class MultiLayerIconArrowNode extends NodeButton { + static xtype: string; + + doRedMark(...args: any[]): void; + + unRedMark(...args: any[]): void; +} diff --git a/typescript/case/button/switch.ts b/packages/fineui/typescript/case/button/switch.ts similarity index 100% rename from typescript/case/button/switch.ts rename to packages/fineui/typescript/case/button/switch.ts diff --git a/typescript/case/button/treeitem/item.first.treeleaf.ts b/packages/fineui/typescript/case/button/treeitem/item.first.treeleaf.ts similarity index 100% rename from typescript/case/button/treeitem/item.first.treeleaf.ts rename to packages/fineui/typescript/case/button/treeitem/item.first.treeleaf.ts diff --git a/typescript/case/button/treeitem/item.last.treeleaf.ts b/packages/fineui/typescript/case/button/treeitem/item.last.treeleaf.ts similarity index 100% rename from typescript/case/button/treeitem/item.last.treeleaf.ts rename to packages/fineui/typescript/case/button/treeitem/item.last.treeleaf.ts diff --git a/typescript/case/button/treeitem/item.mid.treeleaf.ts b/packages/fineui/typescript/case/button/treeitem/item.mid.treeleaf.ts similarity index 100% rename from typescript/case/button/treeitem/item.mid.treeleaf.ts rename to packages/fineui/typescript/case/button/treeitem/item.mid.treeleaf.ts diff --git a/packages/fineui/typescript/case/button/treeitem/item.multilayer.icon.treeleaf.ts b/packages/fineui/typescript/case/button/treeitem/item.multilayer.icon.treeleaf.ts new file mode 100644 index 000000000..d22cddd8c --- /dev/null +++ b/packages/fineui/typescript/case/button/treeitem/item.multilayer.icon.treeleaf.ts @@ -0,0 +1,17 @@ +import { BasicButton } from '../../../base/single/button/button.basic'; + +export declare class MultiLayerIconTreeLeafItem extends BasicButton { + static xtype: string; + + doRedMark(...args: any[]): void; + + unRedMark(...args: any[]): void; + + doHighLight(...args: any[]): void; + + unHighLight(...args: any[]): void; + + getId(): string; + + getPId(): string; +} diff --git a/typescript/case/checkbox/check.arrownode.ts b/packages/fineui/typescript/case/checkbox/check.arrownode.ts similarity index 100% rename from typescript/case/checkbox/check.arrownode.ts rename to packages/fineui/typescript/case/checkbox/check.arrownode.ts diff --git a/typescript/case/colorchooser/colorchooser.popup.hex.ts b/packages/fineui/typescript/case/colorchooser/colorchooser.popup.hex.ts similarity index 100% rename from typescript/case/colorchooser/colorchooser.popup.hex.ts rename to packages/fineui/typescript/case/colorchooser/colorchooser.popup.hex.ts diff --git a/typescript/case/colorchooser/colorchooser.simple.ts b/packages/fineui/typescript/case/colorchooser/colorchooser.simple.ts similarity index 100% rename from typescript/case/colorchooser/colorchooser.simple.ts rename to packages/fineui/typescript/case/colorchooser/colorchooser.simple.ts diff --git a/typescript/case/colorchooser/colorchooser.ts b/packages/fineui/typescript/case/colorchooser/colorchooser.ts similarity index 100% rename from typescript/case/colorchooser/colorchooser.ts rename to packages/fineui/typescript/case/colorchooser/colorchooser.ts diff --git a/packages/fineui/typescript/case/colorchooser/colorpicker.ts b/packages/fineui/typescript/case/colorchooser/colorpicker.ts new file mode 100644 index 000000000..f3db551fe --- /dev/null +++ b/packages/fineui/typescript/case/colorchooser/colorpicker.ts @@ -0,0 +1,5 @@ +import { Widget } from "../../core/widget"; + +export declare class ColorPicker extends Widget { + static xtype: string; +} diff --git a/typescript/case/combo/bubblecombo/combo.bubble.ts b/packages/fineui/typescript/case/combo/bubblecombo/combo.bubble.ts similarity index 100% rename from typescript/case/combo/bubblecombo/combo.bubble.ts rename to packages/fineui/typescript/case/combo/bubblecombo/combo.bubble.ts diff --git a/typescript/case/combo/bubblecombo/popup.bubble.ts b/packages/fineui/typescript/case/combo/bubblecombo/popup.bubble.ts similarity index 100% rename from typescript/case/combo/bubblecombo/popup.bubble.ts rename to packages/fineui/typescript/case/combo/bubblecombo/popup.bubble.ts diff --git a/typescript/case/combo/combo.textvalue.ts b/packages/fineui/typescript/case/combo/combo.textvalue.ts similarity index 100% rename from typescript/case/combo/combo.textvalue.ts rename to packages/fineui/typescript/case/combo/combo.textvalue.ts diff --git a/typescript/case/combo/combo.textvaluesmall.ts b/packages/fineui/typescript/case/combo/combo.textvaluesmall.ts similarity index 100% rename from typescript/case/combo/combo.textvaluesmall.ts rename to packages/fineui/typescript/case/combo/combo.textvaluesmall.ts diff --git a/typescript/case/combo/editoriconcheckcombo/combo.editiconcheck.ts b/packages/fineui/typescript/case/combo/editoriconcheckcombo/combo.editiconcheck.ts similarity index 100% rename from typescript/case/combo/editoriconcheckcombo/combo.editiconcheck.ts rename to packages/fineui/typescript/case/combo/editoriconcheckcombo/combo.editiconcheck.ts diff --git a/typescript/case/combo/iconcombo/combo.icon.ts b/packages/fineui/typescript/case/combo/iconcombo/combo.icon.ts similarity index 100% rename from typescript/case/combo/iconcombo/combo.icon.ts rename to packages/fineui/typescript/case/combo/iconcombo/combo.icon.ts diff --git a/typescript/case/combo/icontextvaluecombo/combo.icontextvalue.ts b/packages/fineui/typescript/case/combo/icontextvaluecombo/combo.icontextvalue.ts similarity index 100% rename from typescript/case/combo/icontextvaluecombo/combo.icontextvalue.ts rename to packages/fineui/typescript/case/combo/icontextvaluecombo/combo.icontextvalue.ts diff --git a/typescript/case/combo/popup.textvalue.ts b/packages/fineui/typescript/case/combo/popup.textvalue.ts similarity index 100% rename from typescript/case/combo/popup.textvalue.ts rename to packages/fineui/typescript/case/combo/popup.textvalue.ts diff --git a/typescript/case/combo/searchtextvaluecombo/combo.searchtextvalue.ts b/packages/fineui/typescript/case/combo/searchtextvaluecombo/combo.searchtextvalue.ts similarity index 100% rename from typescript/case/combo/searchtextvaluecombo/combo.searchtextvalue.ts rename to packages/fineui/typescript/case/combo/searchtextvaluecombo/combo.searchtextvalue.ts diff --git a/typescript/case/combo/textvaluecheckcombo/combo.textvaluecheck.ts b/packages/fineui/typescript/case/combo/textvaluecheckcombo/combo.textvaluecheck.ts similarity index 100% rename from typescript/case/combo/textvaluecheckcombo/combo.textvaluecheck.ts rename to packages/fineui/typescript/case/combo/textvaluecheckcombo/combo.textvaluecheck.ts diff --git a/typescript/case/combo/textvaluecheckcombo/popup.textvaluecheck.ts b/packages/fineui/typescript/case/combo/textvaluecheckcombo/popup.textvaluecheck.ts similarity index 100% rename from typescript/case/combo/textvaluecheckcombo/popup.textvaluecheck.ts rename to packages/fineui/typescript/case/combo/textvaluecheckcombo/popup.textvaluecheck.ts diff --git a/typescript/case/editor/editor.shelter.ts b/packages/fineui/typescript/case/editor/editor.shelter.ts similarity index 100% rename from typescript/case/editor/editor.shelter.ts rename to packages/fineui/typescript/case/editor/editor.shelter.ts diff --git a/typescript/case/editor/editor.sign.ts b/packages/fineui/typescript/case/editor/editor.sign.ts similarity index 100% rename from typescript/case/editor/editor.sign.ts rename to packages/fineui/typescript/case/editor/editor.sign.ts diff --git a/typescript/case/editor/editor.state.ts b/packages/fineui/typescript/case/editor/editor.state.ts similarity index 100% rename from typescript/case/editor/editor.state.ts rename to packages/fineui/typescript/case/editor/editor.state.ts diff --git a/typescript/case/layer/layer.multipopup.ts b/packages/fineui/typescript/case/layer/layer.multipopup.ts similarity index 100% rename from typescript/case/layer/layer.multipopup.ts rename to packages/fineui/typescript/case/layer/layer.multipopup.ts diff --git a/typescript/case/layer/pane.list.ts b/packages/fineui/typescript/case/layer/pane.list.ts similarity index 100% rename from typescript/case/layer/pane.list.ts rename to packages/fineui/typescript/case/layer/pane.list.ts diff --git a/typescript/case/linersegment/linear.segment.ts b/packages/fineui/typescript/case/linersegment/linear.segment.ts similarity index 100% rename from typescript/case/linersegment/linear.segment.ts rename to packages/fineui/typescript/case/linersegment/linear.segment.ts diff --git a/typescript/case/list/list.select.ts b/packages/fineui/typescript/case/list/list.select.ts similarity index 100% rename from typescript/case/list/list.select.ts rename to packages/fineui/typescript/case/list/list.select.ts diff --git a/typescript/case/pager/pager.all.count.ts b/packages/fineui/typescript/case/pager/pager.all.count.ts similarity index 100% rename from typescript/case/pager/pager.all.count.ts rename to packages/fineui/typescript/case/pager/pager.all.count.ts diff --git a/typescript/case/pager/pager.direction.ts b/packages/fineui/typescript/case/pager/pager.direction.ts similarity index 100% rename from typescript/case/pager/pager.direction.ts rename to packages/fineui/typescript/case/pager/pager.direction.ts diff --git a/packages/fineui/typescript/case/segment/button.segment.ts b/packages/fineui/typescript/case/segment/button.segment.ts new file mode 100644 index 000000000..7435cb1c4 --- /dev/null +++ b/packages/fineui/typescript/case/segment/button.segment.ts @@ -0,0 +1,5 @@ +import { BasicButton } from '../../base/single/button/button.basic' + +export class SegmentButton extends BasicButton { + static xtype: string; +} \ No newline at end of file diff --git a/typescript/case/segment/segment.ts b/packages/fineui/typescript/case/segment/segment.ts similarity index 100% rename from typescript/case/segment/segment.ts rename to packages/fineui/typescript/case/segment/segment.ts diff --git a/typescript/case/toolbar/toolbar.multiselect.ts b/packages/fineui/typescript/case/toolbar/toolbar.multiselect.ts similarity index 100% rename from typescript/case/toolbar/toolbar.multiselect.ts rename to packages/fineui/typescript/case/toolbar/toolbar.multiselect.ts diff --git a/packages/fineui/typescript/case/trigger/trigger.editor.ts b/packages/fineui/typescript/case/trigger/trigger.editor.ts new file mode 100644 index 000000000..d0bfa0e50 --- /dev/null +++ b/packages/fineui/typescript/case/trigger/trigger.editor.ts @@ -0,0 +1,7 @@ +import { Trigger } from "../../base/single/trigger/trigger"; + +export declare class EditorTrigger extends Trigger { + static xtype: string; + + setText(text: string): void; +} \ No newline at end of file diff --git a/typescript/case/trigger/trigger.text.select.ts b/packages/fineui/typescript/case/trigger/trigger.text.select.ts similarity index 100% rename from typescript/case/trigger/trigger.text.select.ts rename to packages/fineui/typescript/case/trigger/trigger.text.select.ts diff --git a/typescript/case/trigger/trigger.text.ts b/packages/fineui/typescript/case/trigger/trigger.text.ts similarity index 100% rename from typescript/case/trigger/trigger.text.ts rename to packages/fineui/typescript/case/trigger/trigger.text.ts diff --git a/typescript/component/allvaluechooser/abstract.allvaluechooser.ts b/packages/fineui/typescript/component/allvaluechooser/abstract.allvaluechooser.ts similarity index 100% rename from typescript/component/allvaluechooser/abstract.allvaluechooser.ts rename to packages/fineui/typescript/component/allvaluechooser/abstract.allvaluechooser.ts diff --git a/typescript/component/allvaluechooser/combo.allvaluechooser.ts b/packages/fineui/typescript/component/allvaluechooser/combo.allvaluechooser.ts similarity index 100% rename from typescript/component/allvaluechooser/combo.allvaluechooser.ts rename to packages/fineui/typescript/component/allvaluechooser/combo.allvaluechooser.ts diff --git a/typescript/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.ts b/packages/fineui/typescript/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.ts similarity index 100% rename from typescript/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.ts rename to packages/fineui/typescript/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.ts diff --git a/typescript/component/form/form.ts b/packages/fineui/typescript/component/form/form.ts similarity index 100% rename from typescript/component/form/form.ts rename to packages/fineui/typescript/component/form/form.ts diff --git a/typescript/component/treevaluechooser/abstract.treevaluechooser.list.ts b/packages/fineui/typescript/component/treevaluechooser/abstract.treevaluechooser.list.ts similarity index 100% rename from typescript/component/treevaluechooser/abstract.treevaluechooser.list.ts rename to packages/fineui/typescript/component/treevaluechooser/abstract.treevaluechooser.list.ts diff --git a/typescript/component/treevaluechooser/abstract.treevaluechooser.ts b/packages/fineui/typescript/component/treevaluechooser/abstract.treevaluechooser.ts similarity index 100% rename from typescript/component/treevaluechooser/abstract.treevaluechooser.ts rename to packages/fineui/typescript/component/treevaluechooser/abstract.treevaluechooser.ts diff --git a/typescript/component/treevaluechooser/combo.listtreevaluechooser.ts b/packages/fineui/typescript/component/treevaluechooser/combo.listtreevaluechooser.ts similarity index 100% rename from typescript/component/treevaluechooser/combo.listtreevaluechooser.ts rename to packages/fineui/typescript/component/treevaluechooser/combo.listtreevaluechooser.ts diff --git a/typescript/component/treevaluechooser/combo.treevaluechooser.insert.ts b/packages/fineui/typescript/component/treevaluechooser/combo.treevaluechooser.insert.ts similarity index 100% rename from typescript/component/treevaluechooser/combo.treevaluechooser.insert.ts rename to packages/fineui/typescript/component/treevaluechooser/combo.treevaluechooser.insert.ts diff --git a/typescript/component/treevaluechooser/combo.treevaluechooser.ts b/packages/fineui/typescript/component/treevaluechooser/combo.treevaluechooser.ts similarity index 100% rename from typescript/component/treevaluechooser/combo.treevaluechooser.ts rename to packages/fineui/typescript/component/treevaluechooser/combo.treevaluechooser.ts diff --git a/typescript/component/treevaluechooser/pane.treevaluechooser.ts b/packages/fineui/typescript/component/treevaluechooser/pane.treevaluechooser.ts similarity index 100% rename from typescript/component/treevaluechooser/pane.treevaluechooser.ts rename to packages/fineui/typescript/component/treevaluechooser/pane.treevaluechooser.ts diff --git a/typescript/core/action/action.show.ts b/packages/fineui/typescript/core/action/action.show.ts similarity index 100% rename from typescript/core/action/action.show.ts rename to packages/fineui/typescript/core/action/action.show.ts diff --git a/typescript/core/action/action.ts b/packages/fineui/typescript/core/action/action.ts similarity index 100% rename from typescript/core/action/action.ts rename to packages/fineui/typescript/core/action/action.ts diff --git a/packages/fineui/typescript/core/base.ts b/packages/fineui/typescript/core/base.ts new file mode 100644 index 000000000..abdd7ba80 --- /dev/null +++ b/packages/fineui/typescript/core/base.ts @@ -0,0 +1,421 @@ +import { Widget } from "./widget"; + +type UnionToIntersection = ( + Union extends unknown + ? (x: Union) => void + : never + ) extends ((x: infer Intersection) => void) + ? Intersection + : never; + + +export declare function assert(v: any, is: Function): Boolean; + +export declare function warn(message: any): Boolean; + +export declare function UUID(): string; + +export declare function isWidget(widget: any): widget is Widget; + +export declare function createWidgets(items: any, options: any, context: any): any; + +export declare function createItems(data: T[], innerAttr?: U, outerAttr?: K): (U & T & K)[]; + +export declare function packageItems(items: any[], layouts: any[]): any[]; + +export declare function formatEL(obj: T): { el: T } | T; + +export declare function stripEL(obj: { el: T } | T): T; + +export declare function trans2Element(widgets: any[]): any[]; + +// 集合相关方法 +export declare function where(collection: any[] | object | string, source: object): any[]; + +export declare function findWhere(collection: any[] | object | string, callback?: Function | object | string, thisArg?: any): object | undefined; + +export declare function invoke(collection: any[] | object | string, methodName: Function | string, arg?: any): any[]; + +export declare function pluck(collection: any[] | object | string, property: string): any[]; + +export declare function shuffle(collection: any[] | object | string): any[]; + +export declare function sample(collection: any[] | object | string, n?: number): any[]; + +export declare function toArray(collection: any[] | object | string): any[]; + +export declare function size(collection: any): number; + +export declare function each(collection: ArrayLike, iteratee?: (index: number, value: T) => void, thisArg?: any): ArrayLike; +export declare function each(collection: T, iteratee?: (index: K, value: T[K]) => void, thisArg?: any): T; +export declare function each(collection: T, iteratee?: any, thisArg?: any): T; + +export declare function map(collection: T[] | object | string | null | undefined, callback?: ((index: number, value: T) => U) | object | string, thisArg?: any): U[]; + +export declare function reduce(collection: T[] | object | string, callback?: ((currentValue: T, total: U extends T ? U : T, currentIndex: number) => U extends T ? U : T) | object | string, initialValue?: U | T): U extends T ? U : T; + +export declare function reduceRight(collection: T[] | object | string, callback?: ((total: U extends T ? U : T, currentValue: T, currentIndex: number) => U extends T ? U : T) | object | string, initialValue?: U | T): U extends T ? U : T; + +export declare function find(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): T | undefined; + +export declare function filter(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): T[]; + +export declare function reject(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): T[]; + +export declare function every(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): boolean; + +export declare function all(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): boolean; + +export declare function some(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): boolean; + +export declare function any(collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any): boolean; + +export declare function max(collection: T[]): T; + +export declare function min(collection: T[]): T; + +export declare function sortBy(collection: any[] | object | string, callback?: ((index: number, value: T) => number) | object | string, thisArg?: any): any[]; + +export declare function groupBy(collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any): object; + +export declare function indexBy(collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any): object; + +export declare function countBy(collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any): object; + + +export declare function count(from: number, to: number, predicate: Function): number; + +export declare function inverse(from: number, to: number, predicate: Function): number; + +export declare function firstKey(obj: object): string; + +export declare function lastKey(obj: object): string; + +export declare function firstObject(obj: object): any; + +export declare function lastObject(obj: object): any; + +export declare function concat(obj1: any, obj2: any, ...args: any[]): any; + +export declare function backEach(obj: any, predicate: Function, context?: any): boolean; + +export declare function backAny(obj: any, predicate: Function, context?: any): boolean; + +export declare function backEvery(obj: any, predicate: Function, context?: any): boolean; + +export declare function backFindKey(obj: any, predicate: Function, context?: any): string; + +export declare function backFind(obj: any, predicate: Function, context?: any): any; + +export declare function remove(obj: any, predicate: any, context?: any): void; + +export declare function removeAt(obj: any, index: number | number[]): void; + +export declare function string2Array(str: string): string[]; + +export declare function array2String(array: any[]): string; + +export declare function abc2Int(str: string): number; + +export declare function int2Abc(num: number): string; + +// 数组相关的方法 +export declare function first(array: T[], callback?: Function | object | number | string, thisArg?: any): T; + +export declare function initial(array: T[], callback?: Function | object | number | string, thisArg?: any): T[]; + +export declare function last(array: T[], callback?: Function | object | number | string, thisArg?: any): T; + +export declare function rest(array: T[], callback?: Function | object | number | string, thisArg?: any): T[]; + +export declare function compact(array: any[]): any[]; + +export declare function flatten(array: any[], isShallow?: boolean, callback?: Function | object | string, thisArg?: any): any[]; + +export declare function without(array: any[], value?: any): any[]; + +export declare function union(...array: any[]): any[]; + +export declare function intersection(...array: any[]): any[]; + +export declare function difference(...array: any[]): any[]; + +export declare function zip(...array: any[]): any[]; + +export declare function unzip(...array: any[]): any[]; + +export declare function object(keys: string[], values?: any[]): any[]; + +export declare function indexOf(array: any[], value: any, fromIndex?: number): number; + +export declare function lastIndexOf(array: any[], value: any, fromIndex?: number): number; + +export declare function sortedIndex(array: any[], value: any, callback?: Function | object | string, thisArg?: any): number; + +export declare function range(start: number, end: number, step: number): number[]; + +export declare function take(array: T[], n: number): T[]; + +export declare function takeRight(array: T[], n: number): T[]; + +export declare function findIndex(array: T[], predicate?: ((index: number, item: T, array: T[]) => any) | object | string, thisArg?: any): number; + +export declare function findLastIndex(array: T[], predicate?: ((index: number, item: T, array: T[]) => any) | object | string, thisArg?: any): number; + +export declare function makeArray(length: number, value?: T): number[] | T[]; + +export declare function makeObject(array: any[], value: any): any; + +export declare function makeArrayByArray(array: any[], value: T): T[]; + +export declare function uniq(array: T[], isSorted?: boolean, iteratee?: any, context?: any): T[]; + +export declare function uniqBy(array: T[], iteratee?: any, context?: any): T[]; + +// 对象相关方法 +export declare function keys(object: object): string[]; + +export declare function allKeys(object: object): string[]; + +export declare function values(object: object): any[]; + +export declare function pairs(object: object): any[]; + +export declare function invert(object: object, multiValue: boolean): object; + +export declare function create(prototype: object, properties?: object): object; + +export declare function functions(object: object): string[]; + +export declare function extend(object: T): T; +export declare function extend(object: T, ...sources: U): T & UnionToIntersection>; + +export declare function defaults(object: object, ...sources: any[]): object; + +export declare function clone(object: T): T; + +export declare function property(path: any[] | string): Function; + +export declare function propertyOf(object: object): Function; + +export declare function isEqual(value: any, other: any, customizer?: Function, thisArg?: any): boolean; + +export declare function isMatch(object: object, source: object, customizer?: Function, thisArg?: any): boolean; + +export declare function isEmpty(value: any[] | object | string | null | undefined | number): boolean; + +export declare function isElement(value: any): boolean; + +export declare function isNumber(value: any): value is number; + +export declare function isString(value: any): value is string; + +export declare function isArray(value: T[] | any): value is T[]; + +export declare function isObject(value: any): value is object; + +export declare function isPlainObject(value: any): value is object; + +export declare function isArguments(value: any): boolean; + +export declare function isFunction(value: any): value is Function; + +export declare function isFinite(value: any): value is number; + +export declare function isBoolean(value: any): value is boolean; + +export declare function isDate(value: any): value is Date; + +export declare function isRegExp(value: any): value is RegExp; + +export declare function isError(value: any): value is Error; + +export declare function isNaN(value: any): value is number; + +export declare function isUndefined(value: any): value is undefined; + +export declare function zipObject(props: any[], values?: any[]): object; + +export declare function cloneDeep(value: T): T; + +export declare function findKey(object: object, predicate?: Function | object | string, thisArg?: any): any; + +export declare function pick(object: object, predicate?: Function | string | string[], thisArg?: any): object; + +export declare function omit(object: object, predicate?: Function | string | string[], thisArg?: any): object; + +export declare function tap(value: any, interceptor: Function, thisArg?: any): any; + +export declare function inherit(sb: any, sp: any, overrides?: any): any; + +export declare function init(): void; + +export declare function has(obj: object, keys: string | string[]): boolean; + +export declare function freeze(value: T): T; + +export declare function isKey(key: any): key is (number | string); + +export declare function isCapitalEqual(a: string | null | undefined, b: string | null | undefined): boolean; + +export declare function isWidthOrHeight(w: number | string): boolean; + +export declare function isNotNull(obj: T): obj is NonNullable; + +export declare function isNull(obj: any): obj is (undefined | null); + +export declare function isEmptyArray(arr: T[] | U): arr is T[] & { length: 0 }; + +export declare function isNotEmptyArray(arr: T[] | U): arr is [T, ...T[]]; + +export declare function isEmptyObject(obj: any): boolean; + +export declare function isNotEmptyObject(obj: any): obj is object; + +export declare function isWindow(obj: any): obj is Window; + +export declare function deepClone(obj: T): T; + +export declare function deepExtend(object: TObject, source: TSource): TObject & TSource; + +export declare function deepExtend(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + +export declare function deepExtend(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; + +export declare function deepExtend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; + +export declare function deepExtend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; + +export declare function deepExtend(object: any, ...otherArgs: any[]): any; + +export declare function isDeepMatch(object: any, attrs: any): boolean; + +export declare function contains(obj: any[], target: any, fromIndex?: number): boolean; + +export declare function deepContains(obj: any[], copy: any): boolean; + +export declare function deepIndexOf(obj: any[], target: any): number; + +export declare function deepRemove(obj: any[], target: any): boolean; + +export declare function deepWithout(obj: any[], target: any): any[]; + +export declare function deepUnique(array: any[]): any[]; + +export declare function deepDiff(object: any, other: any): string[]; + +export declare function uniqueId(prefix?: string): string; + +export declare function result(object: any, key: string, defaultValue?: any): any; + +export declare function chain(value: any): any; + +export declare function iteratee(func?: Function, thisArg?: any): Function; + +export declare function unescape(str?: string): string; + +export declare function bind(func: T, thisArg: any, ...partials: any): T; + +export declare function once(func: Function): Function; + +export declare function partial(func: Function, ...partials: any): Function; + +export declare function debounce(func: T, wait?: number, options?: any): T; + +export declare function throttle(func: T, wait?: number, options?: any): T; + +export declare function delay(func: Function, wait: number, ...args: any[]): number; + +export declare function defer(func: Function, ...args: any[]): number; + +export declare function wrap(value: any, wrapper: Function): Function; + +export declare function nextTick(func?: Function): Promise; + +export declare function random(min?: number, max?: number, floating?: boolean): number; + +export declare function parseInt(s: string | number): number; + +export declare function parseSafeInt(s: string): number; + +export declare function parseFloat(string: string): number; + +export declare function isNaturalNumber(value: string | number): boolean; + +export declare function isPositiveInteger(value: string | number): boolean; + +export declare function isNegativeInteger(value: string | number): boolean; + +export declare function isInteger(value: string | number): boolean; + +export declare function isNumeric(value: string | number): boolean; + +export declare function isFloat(value: string | number): boolean; + +export declare function isOdd(value: string | number): boolean; + +export declare function isEven(value: string | number): boolean; + +export declare function sum(array: any[], iteratee?: Function, context?: any): number; + +export declare function average(array: any[], iteratee?: Function, context?: any): number; + +export declare function trim(string?: string, chars?: string): string; + +export declare function toUpperCase(string: string): string; + +export declare function toLowerCase(string: string): string; + +export declare function isEndWithBlank(string: string): boolean; + +export declare function isLiteral(string: string): boolean; + +export declare function stripQuotes(string: string): string; + +export declare function camelize(string: string): string; + +export declare function hyphenate(string: string): string; + +export declare function isNotEmptyString(string: any): boolean; + +export declare function isEmptyString(str: any): str is ""; + +export declare function encrypt(type: string, text: string, key: string): string; + +export declare function escape(string: string): string; + +export declare function leftPad(val: string, size: number, ch: string): string; + +export declare function format(format: string, ...str: string[]): string; + +export declare function isLeapYear(year: number): boolean; + +export declare function checkDateVoid(YY: string | number, MM: string | number, DD: string | number, minDate: string, maxDate: string): (number | string)[]; + +export declare function checkDateLegal(str: string): boolean; + +export declare function parseDateTime(str: string, fmt: string): Date; + +export declare function getDate(...args: (number | string)[]): Date; + +export declare function getTime(...args: any[]): number; + +export declare function clamp(number: number, lower: number, upper: number): number; + +/** + * 判断一个对象是不是promise + * @param obj 对象 + */ +export declare function isPromise(obj: any): obj is Promise; + +export declare function set( + object: TObject, + path: string | string[], + value: any +): TObject; + +export declare function get( + object: TObject, + path: TKey | [TKey] | string | null | undefined, + defaultValue?: any +): TObject[TKey] | any; diff --git a/typescript/core/behavior/behavior.highlight.ts b/packages/fineui/typescript/core/behavior/behavior.highlight.ts similarity index 100% rename from typescript/core/behavior/behavior.highlight.ts rename to packages/fineui/typescript/core/behavior/behavior.highlight.ts diff --git a/typescript/core/behavior/behavior.redmark.ts b/packages/fineui/typescript/core/behavior/behavior.redmark.ts similarity index 100% rename from typescript/core/behavior/behavior.redmark.ts rename to packages/fineui/typescript/core/behavior/behavior.redmark.ts diff --git a/typescript/core/behavior/behavior.ts b/packages/fineui/typescript/core/behavior/behavior.ts similarity index 100% rename from typescript/core/behavior/behavior.ts rename to packages/fineui/typescript/core/behavior/behavior.ts diff --git a/typescript/core/controller/controller.broadcast.ts b/packages/fineui/typescript/core/controller/controller.broadcast.ts similarity index 100% rename from typescript/core/controller/controller.broadcast.ts rename to packages/fineui/typescript/core/controller/controller.broadcast.ts diff --git a/packages/fineui/typescript/core/controller/controller.bubbles.ts b/packages/fineui/typescript/core/controller/controller.bubbles.ts new file mode 100644 index 000000000..63a2e44bd --- /dev/null +++ b/packages/fineui/typescript/core/controller/controller.bubbles.ts @@ -0,0 +1,14 @@ +import { Controller } from './controller'; + +export declare class BubblesController extends Controller { + + show(name: string, text: string, context: any, opt: any): BubblesController + + hide(name: string): BubblesController + + has(name: string): boolean + + remove(name: string): BubblesController + + removeAll(): BubblesController +} diff --git a/typescript/core/controller/controller.layer.ts b/packages/fineui/typescript/core/controller/controller.layer.ts similarity index 100% rename from typescript/core/controller/controller.layer.ts rename to packages/fineui/typescript/core/controller/controller.layer.ts diff --git a/packages/fineui/typescript/core/controller/controller.masker.ts b/packages/fineui/typescript/core/controller/controller.masker.ts new file mode 100644 index 000000000..dfed62baa --- /dev/null +++ b/packages/fineui/typescript/core/controller/controller.masker.ts @@ -0,0 +1,5 @@ +import { LayerController } from "./controller.layer"; + +export declare class MaskersController extends LayerController { + +} diff --git a/packages/fineui/typescript/core/controller/controller.popovers.ts b/packages/fineui/typescript/core/controller/controller.popovers.ts new file mode 100644 index 000000000..96a088dba --- /dev/null +++ b/packages/fineui/typescript/core/controller/controller.popovers.ts @@ -0,0 +1,13 @@ +import { Controller } from "./controller"; + +export declare class PopoverController extends Controller { + create(name: string, options: any, context?: any): PopoverController; + + open(name: string): PopoverController; + + close(name: string): PopoverController; + + remove(name: string): PopoverController; + + removeAll(): void; +} diff --git a/packages/fineui/typescript/core/controller/controller.resizer.ts b/packages/fineui/typescript/core/controller/controller.resizer.ts new file mode 100644 index 000000000..eff904fb3 --- /dev/null +++ b/packages/fineui/typescript/core/controller/controller.resizer.ts @@ -0,0 +1,14 @@ +import { Layout } from "../wrapper/layout"; +import { Controller } from "./controller"; + +type ResizeHandler = (event: DeviceOrientationEvent | UIEvent) => any; + +export declare class ResizeController extends Controller { + add(name: string, resizer: Layout | ResizeHandler): () => this; + + get(name: string): Layout | ResizeHandler; + + has(name: string): boolean; + + remove(name: string): this; +} diff --git a/typescript/core/controller/controller.ts b/packages/fineui/typescript/core/controller/controller.ts similarity index 100% rename from typescript/core/controller/controller.ts rename to packages/fineui/typescript/core/controller/controller.ts diff --git a/packages/fineui/typescript/core/decorator/decorator.ts b/packages/fineui/typescript/core/decorator/decorator.ts new file mode 100644 index 000000000..6389f8b68 --- /dev/null +++ b/packages/fineui/typescript/core/decorator/decorator.ts @@ -0,0 +1,146 @@ +import { Fix } from "../../fix/fix"; + +export type Constructor = new(...args: any[]) => T; + +/** + * 注册widget + */ +export function shortcut() { + return function decorator(Target: Constructor & { xtype: string }): void { + BI.shortcut(Target.xtype, Target); + }; +} + +/** + * 注册provider + */ +export function provider() { + return function decorator(Target: Constructor & { xtype: string }): void { + BI.provider(Target.xtype, Target); + }; +} + +/** + * 注册model + */ +export function model() { + return function decorator + }>(Target: U): void { + BI.model(Target.xtype, Target); + }; +} + +/** + * 类注册_store属性 + * @param Model model类 + * @param opts 额外条件 + */ +export function store(Model: Constructor & { xtype: string }, opts: { + props?(this: unknown): { [key: string]: unknown } +} = {}) { + return function classDecorator(constructor: U) { + return class extends constructor { + _store() { + const props = opts.props ? opts.props.apply(this) : undefined; + + return BI.Models.getModel(Model.xtype, props); + } + }; + }; +} + +/** + * 注册mixin + * ie8下不能使用 + */ +export function mixin() { + return function decorator(Target: Constructor & { xtype: string }): void { + const mixin: { + [key: string]: Function; + } = {}; + + Object.getOwnPropertyNames(Target.prototype).forEach(name => { + if (name === "constructor") { + return; + } + + mixin[name] = Target.prototype[name]; + }); + + Fix.mixin(Target.xtype, mixin); + }; +} + +/** + * 类注册mixins属性 + * ie8下不能使用 + * @param Mixins + */ +export function mixins(...Mixins: ({ new(...args: any[]): {} } & { xtype: string })[]) { + return function classDecorator(constructor: U) { + const mixins: string[] = []; + + Mixins.forEach(mixin => { + mixin.xtype && mixins.push(mixin.xtype); + }); + + return class extends constructor { + mixins = mixins; + }; + }; +} + +/** + * Model基类 + */ +export class Model +} = {}> extends Fix.Model { + // @ts-ignore this["computed"][key]为空 + model: Pick<{ [key in keyof U["types"]]: U["types"][key] }, U["context"][number]> & ReturnType & { [key in keyof this["computed"]]: ReturnType }; + + store: this["actions"]; + + state(): { [key: string]: unknown } | {} { + return {}; + } + + context: U["context"]; + + actions: { [key: string]: (...args: any[]) => any } | {}; + + childContext: ReadonlyArray)>; + + // @ts-ignore this["computed"][key]为空 + TYPE: Pick<{ [key in keyof this["computed"]]: ReturnType } & { [key in keyof ReturnType]: ReturnType[key] }, this["childContext"][number]>; + + computed: { [key: string]: () => unknown } | {}; +} + +/* 分享一段很好看的代码 +// union to intersection of functions +type UnionToIoF = + (U extends any ? (k: (x: U) => void) => void : never) extends + ((k: infer I) => void) ? I : never + +// return last element from Union +type UnionPop = UnionToIoF extends { (a: infer A): void; } ? A : never; + +// prepend an element to a tuple. +type Prepend> = + ((a: U, ...r: T) => void) extends (...r: infer R) => void ? R : never; + +type UnionToTupleRecursively> = { + 1: Result; + 0: UnionToTupleRecursively_, Result>; + // 0: UnionToTupleRecursively>, Prepend, Result>> +}[[Union] extends [never] ? 1 : 0]; + +type UnionToTupleRecursively_> = + UnionToTupleRecursively, Prepend>; + +type UnionToTuple = UnionToTupleRecursively; +*/ diff --git a/packages/fineui/typescript/core/foundation.ts b/packages/fineui/typescript/core/foundation.ts new file mode 100644 index 000000000..74899e9fc --- /dev/null +++ b/packages/fineui/typescript/core/foundation.ts @@ -0,0 +1,3 @@ +export declare const _global: any; + +export declare const prepares: Function[]; diff --git a/packages/fineui/typescript/core/func/alias.ts b/packages/fineui/typescript/core/func/alias.ts new file mode 100644 index 000000000..36f865eb9 --- /dev/null +++ b/packages/fineui/typescript/core/func/alias.ts @@ -0,0 +1,17 @@ +export declare function jsonDecode(text: string): any; + +export declare function jsonEncode(json: any): any; + +export declare function contentFormat(cv: any, fmt: string): string; + +export declare function htmlDecode(text: string): string; + +export declare function htmlEncode(text: string): string; + +export declare function getEncodeURL(urlTemplate: string, param: any): string; + +export declare function encodeURIComponent(url: string): string; + +export declare function decodeURIComponent(url: string): string; + + diff --git a/packages/fineui/typescript/core/func/array.ts b/packages/fineui/typescript/core/func/array.ts new file mode 100644 index 000000000..cece77dc4 --- /dev/null +++ b/packages/fineui/typescript/core/func/array.ts @@ -0,0 +1,6 @@ +export declare function pushArray(sArray: any[], array: any[]): void; + +export declare function pushDistinct(sArray: any[], obj: any): void; + +export declare function pushDistinctArray(sArray: any[], array: any[]): void; + diff --git a/packages/fineui/typescript/core/func/date.ts b/packages/fineui/typescript/core/func/date.ts new file mode 100644 index 000000000..a65bc1523 --- /dev/null +++ b/packages/fineui/typescript/core/func/date.ts @@ -0,0 +1,91 @@ +export interface Date { + SECOND: number; + MINUTE: number; + HOUR: number; + DAY: number; + WEEK: number; + _DN: string[]; + _SDN: string[]; + _FD: number; + _MN: string[]; + _SMN: number[]; + _QN: string[]; + _MD: number[]; + _OFFSET: number[]; +} + +/** + * 获取时区 + */ +export declare function getTimezone(date: Date): string; + +/** + * 获取指定月共有多少天 + */ +export declare function getMonthDays(date: Date, month: number): number; + +/** + * 获取指定月的最后一天 + */ +export declare function getLastDateOfMonth(data: Date): Date; + +/** + * 获取指定时间距离当年已经过了多少天 + */ +export declare function getDayOfYear(data: Date): number; + +/** + * 获取指定时间距离当年已经过了多少周 + */ +export declare function getWeekNumber(data: Date): number; + +/** + * 获取指定时间的所处季度 + */ +export declare function getQuarter(date: Date): number; + +/** + * 离当前时间多少天的时间 + */ +export declare function getOffsetDate(date: Date, offset: number): Date; + +/** + * 离当前时间多少天季度的时间 + */ +export declare function getOffsetQuarter(date: Date, n: number): Date; + +/** + * 得到本季度的起始月份 + */ +export declare function getQuarterStartMonth(date: Date): number; + +/** + * 获得本季度的起始日期 + */ +export declare function getQuarterStartDate(date: Date): number; + +/** + * 获取本季度的其实日期 + */ +export declare function getQuarterEndDate(date: Date): number; + +/** + * 指定日期n个月之前或之后的日期 + */ +export declare function getOffsetMonth(date: Date, n: number): Date; + +/** + * 获取本周的起始日期 + */ +export declare function getWeekStartDate(date: Date): Date; + +/** + * 获取本周的结束日期 + */ +export declare function getWeekEndDate(date: Date): Date; + +/** + * 格式化打印日期 + */ +export declare function print(date: Date, str: string): string; + diff --git a/packages/fineui/typescript/core/func/function.ts b/packages/fineui/typescript/core/func/function.ts new file mode 100644 index 000000000..fe6117901 --- /dev/null +++ b/packages/fineui/typescript/core/func/function.ts @@ -0,0 +1,43 @@ +/** + * 创建唯一的名字 + * @param array 已有的名字集合 + * @param name 待生成的名字 + * @return 生成后的名字 + */ +export declare function createDistinctName(array: any[], name: string): string; + +/** + * 获取搜索结果 + * @param items 待搜索的数据 + * @param keyword 关键字 + * @param param 搜索哪个属性 + */ +export declare function getSearchResult(items: any, keyword: any, param?: string): { find: any[], match: any[] }; + +/** + * 获取编码后的url + * @param urlTemplate url模板 + * @param param 参数 + */ +export declare function getEncodeURL(urlTemplate: string, param: any): string; + +/** + * 获取按GB2312排序的结果 + * @param items + * @param key + */ +export declare function getSortedResult(items: T[], key?: string | Function): T[]; + +/** + * 在方法A执行之前执行方法B + * @param sFunc 方法A + * @param func 方法B + */ +export declare function beforeFunc(sFunc: Function, func: Function): Function; + +/** + * 在方法A执行之后执行方法B + * @param sFunc 方法A + * @param func 方法B + */ +export declare function afterFunc(sFunc: Function, func: Function): Function; diff --git a/packages/fineui/typescript/core/func/index.ts b/packages/fineui/typescript/core/func/index.ts new file mode 100644 index 000000000..549301263 --- /dev/null +++ b/packages/fineui/typescript/core/func/index.ts @@ -0,0 +1,6 @@ +export * from "./array"; +export * from "./string"; +export * from "./number"; +export * as Func from "./function"; +export * from "./date"; +export * from "./alias"; diff --git a/packages/fineui/typescript/core/func/number.ts b/packages/fineui/typescript/core/func/number.ts new file mode 100644 index 000000000..eab11a8f7 --- /dev/null +++ b/packages/fineui/typescript/core/func/number.ts @@ -0,0 +1,31 @@ +/** + * 加法函数,用来得到精确的加法结果 + * @param {Number} num 被加数 + * @param {Number} arg 加数 + * @return {Number} 两个数字相加后的结果 + */ +export declare function add(num: number, arg: number): number; + +/** + * 减法函数,用来得到精确的减法结果 + * @param {Number} num 被减数 + * @param {Number} arg 减数 + * @return {Number} 两个数字相减后的结果 + */ +export declare function sub(num: number, arg: number): number; + +/** + * 乘法函数,用来得到精确的乘法结果 + * @param {Number} num 被乘数 + * @param {Number} arg 乘数 + * @return {Number} 两个数字相乘后的结果 + */ +export declare function mul(num: number, arg: number): number; + +/** + * 除法函数,用来得到精确的除法结果 + * @param {Number} num 被除数 + * @param {Number} arg 除数 + * @return {Number} 两个数字相除后的结果 + */ +export declare function div(num: number, arg: number): number; diff --git a/packages/fineui/typescript/core/func/string.ts b/packages/fineui/typescript/core/func/string.ts new file mode 100644 index 000000000..1d45839a6 --- /dev/null +++ b/packages/fineui/typescript/core/func/string.ts @@ -0,0 +1,57 @@ +/** + * 判断字符串是否已指定的字符串开始 + * @param str source字符串 + * @param {String} startTag 指定的开始字符串 + * @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false + */ +export declare function startWith(str: string, startTag: string): boolean; + +/** + * 判断字符串是否以指定的字符串结束 + * @deprecated 废弃了,用原生的endsWith吧 + * @param str source字符串 + * @param {String} endTag 指定的字符串 + * @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false + */ +export declare function endWith(str: string, endTag: string): boolean; + +/** + * 获取url中指定名字的参数 + * @param str source字符串 + * @param {String} name 参数的名字 + * @return {String} 参数的值 + */ +export declare function getQuery(str: string, name: string): string | null; + +/** + * 给url加上给定的参数 + * @param str source字符串 + * @param {Object} paras 参数对象,是一个键值对对象 + * @return {String} 添加了给定参数的url + */ +export declare function appendQuery(str: string, paras: { [key: string]: string | number }): string; + +/** + * 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 + * @param str source字符串 + * @param {String} s1 要替换的字符串的正则表达式 + * @param {String} s2 替换的结果字符串 + * @returns {String} 替换后的字符串 + */ +export declare function replaceAll(str: string, s1: string, s2: string): string; + +/** + * 总是让字符串以指定的字符开头 + * @param str source字符串 + * @param {String} start 指定的字符 + * @returns {String} 以指定字符开头的字符串 + */ +export declare function perfectStart(str: string, start: string): string; + +/** + * 获取字符串中某字符串的所有项位置数组 + * @param str source字符串 + * @param {String} sub 子字符串 + * @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 + */ +export declare function allIndexOf(str: string, sub: string): number[]; diff --git a/packages/fineui/typescript/core/i18n.ts b/packages/fineui/typescript/core/i18n.ts new file mode 100644 index 000000000..fbf04617a --- /dev/null +++ b/packages/fineui/typescript/core/i18n.ts @@ -0,0 +1,3 @@ +export declare function addI18n(v: string | object): string; + +export declare function i18nText(key: string, ..._args: any[]): string; diff --git a/packages/fineui/typescript/core/inject.ts b/packages/fineui/typescript/core/inject.ts new file mode 100644 index 000000000..cfdcdf794 --- /dev/null +++ b/packages/fineui/typescript/core/inject.ts @@ -0,0 +1,45 @@ +import { Widget } from "./widget"; + +export declare function module(xtype: string, cls: any): void; + +export declare function constant(xtype: string, cls: T): (() => T); + +export declare function model(xtype: string, cls: any): Function; + +export declare function store(xtype: string, cls: any): Function; + +export declare function service(xtype: string, cls: any): Function; + +export declare function provider(xtype: string, cls: any): Function; + +export declare namespace Modules { + function getModule(type: string): any; + + function getAllModules(): any; +} + +export declare namespace Constants { + function getConstant(type: string): any; +} + +export declare namespace Models { + function getModel(type: string, options?: any): any; +} + +export declare namespace Stores { + function getStore(type: string, options?: any): any; +} + +export declare namespace Providers { + function getProvider(type: string, options?: any): any; +} + +export declare namespace Services { + function getService(type: string, options?: any): any; +} + +export declare function createWidget(item: any, options?: any, context?: Widget, lazy?: boolean): Widget + +export declare function point(type: string, action: string, pointFn: Function, after: any): void + +export declare function config(type: string, configFn: Function, opt?: any): Function diff --git a/packages/fineui/typescript/core/loader/loader.style.ts b/packages/fineui/typescript/core/loader/loader.style.ts new file mode 100644 index 000000000..6ec21ccdd --- /dev/null +++ b/packages/fineui/typescript/core/loader/loader.style.ts @@ -0,0 +1,12 @@ +import { OB } from "../ob"; + +export declare class StyleLoaderManager extends OB { + + loadStyle(name: string, styleString: string): void + + get(name: string): HTMLElement + + has(name: string): boolean + + removeStyle(name: string): void +} diff --git a/typescript/core/ob.ts b/packages/fineui/typescript/core/ob.ts similarity index 100% rename from typescript/core/ob.ts rename to packages/fineui/typescript/core/ob.ts diff --git a/packages/fineui/typescript/core/platform/web/detectElementResize.ts b/packages/fineui/typescript/core/platform/web/detectElementResize.ts new file mode 100644 index 000000000..1c15161db --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/detectElementResize.ts @@ -0,0 +1,5 @@ +import { Widget } from "../../widget"; + +export declare function addResizeListener(widget: Widget, fn: Function): Function + +export declare function removeResizeListener(widget: Widget, fn?: Function): void diff --git a/packages/fineui/typescript/core/platform/web/dom.ts b/packages/fineui/typescript/core/platform/web/dom.ts new file mode 100644 index 000000000..de155ec8d --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/dom.ts @@ -0,0 +1,125 @@ +import { Widget } from "../../widget"; + +export declare function ready(fn: Function): void + +export declare function patchProps(fromElement: any, toElement: any): void + +export declare function hang(doms: Widget[]): DocumentFragment + +export declare function isExist(obj: Widget): boolean + +export declare function preloadImages(srcArray: string[], onload: Function): void + +export declare function getTextSizeWidth(text: string, fontSize?: number): number + +export declare function getTextSizeHeight(text: string, fontSize?: number): number + +export declare function getScrollWidth(): number + +export declare function getImage(param: string, fillStyle?: string, backgroundColor?: string): { + width: number, + height: number, + src: string, + style: string, + param: string +} + +export declare function isColor(color: string): boolean + +export declare function isRGBColor(color: string): boolean + +export declare function isHexColor(color: string): boolean + +export declare function isDarkColor(hex: string): boolean + +export declare function getContrastColor(color: string): string + +export declare function rgb2hex(rgbColour: string): string + +export declare function rgb2json(rgbColour: string): { r: number, g: number, b: number } + +export declare function rgba2json(rgbColour: string): { r: number, g: number, b: number, a: number } + +export declare function json2rgb(rgb: { r: number, g: number, b: number }): string + +export declare function json2rgba(rgba: { r: number, g: number, b: number, a: number }): string + +export declare function int2hex(strNum: number): string + +export declare function hex2rgb(color: string): string + +export declare function rgba2rgb(rgbColor: string, bgColor?: string): string + +export declare function getLeftPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getInnerLeftPosition(combo: Widget, popup?: Widget, extraWidth?: number): { left: number } + +export declare function getRightPosition(combo: Widget, popup?: Widget, extraWidth?: number): { left: number } + +export declare function getInnerRightPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getTopPosition(combo: Widget, popup: Widget, extraHeight?: number): { top: number } + +export declare function getBottomPosition(combo: Widget, popup?: Widget, extraHeight?: number): { top: number } + +export declare function isLeftSpaceEnough(combo: Widget, popup: Widget, extraWidth?: number): boolean + +export declare function isInnerLeftSpaceEnough(combo: Widget, popup: Widget, extraWidth?: number): boolean + +export declare function isRightSpaceEnough(combo: Widget, popup: Widget, extraWidth?: number): boolean + +export declare function isInnerRightSpaceEnough(combo: Widget, popup: Widget, extraWidth?: number): boolean + +export declare function isTopSpaceEnough(combo: Widget, popup?: Widget, extraHeight?: number): boolean + +export declare function isBottomSpaceEnough(combo: Widget, popup?: Widget, extraHeight?: number): boolean + +export declare function isRightSpaceLarger(combo: Widget): boolean + +export declare function isBottomSpaceLarger(combo: Widget): boolean + +export declare function getLeftAlignPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getLeftAdaptPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getRightAlignPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getRightAdaptPosition(combo: Widget, popup: Widget, extraWidth?: number): { left: number } + +export declare function getTopAlignPosition(combo: Widget, popup: Widget, extraHeight?: number, needAdaptHeight?: boolean): { + top: number, + adaptHeight?: number +} + +export declare function getTopAdaptPosition(combo: Widget, popup: Widget, extraHeight?: number, needAdaptHeight?: boolean): { + top: number, + adaptHeight?: number +} + +export declare function getBottomAlignPosition(combo: Widget, popup: Widget, extraHeight?: number, needAdaptHeight?: boolean): { + top: number, + adaptHeight?: number +} + +export declare function getBottomAdaptPosition(combo: Widget, popup: Widget, extraHeight?: number, needAdaptHeight?: boolean): { + top: number, + adaptHeight?: number +} + +export declare function getCenterAdaptPosition(combo: Widget, popup: Widget): { left: number } + +export declare function getMiddleAdaptPosition(combo: Widget, popup: Widget): { top: number } + +export declare function getComboPositionByDirections(combo: Widget, popup: Widget, extraWidth?: number, extraHeight?: number, needAdaptHeight?: number, directions?: number): { + dir: string, + left?: number, + top?: number, + change?: string +} + +export declare function getComboPosition(combo: Widget, popup: Widget, extraWidth?: number, extraHeight?: number, needAdaptHeight?: number, directions?: number): { + dir: string, + left?: number, + top?: number, + change?: string +} diff --git a/packages/fineui/typescript/core/platform/web/eventListener.ts b/packages/fineui/typescript/core/platform/web/eventListener.ts new file mode 100644 index 000000000..335d39637 --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/eventListener.ts @@ -0,0 +1,5 @@ +export declare function listen(target: EventTarget, eventType: string, callback: Function): { remove: () => void } + +export declare function capture(target: EventTarget, eventType: string, callback: Function): { remove: () => void } + +export declare function registerDefault(): void diff --git a/packages/fineui/typescript/core/platform/web/function.ts b/packages/fineui/typescript/core/platform/web/function.ts new file mode 100644 index 000000000..ab3190757 --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/function.ts @@ -0,0 +1,21 @@ +export declare function isIE(): boolean; + +export declare function getIEVersion(): number; + +export declare function isEdge(): boolean; + +export declare function isChrome(): boolean; + +export declare function isFireFox(): boolean; + +export declare function isOpera(): boolean; + +export declare function isSafari(): boolean; + +export declare function isMac(): boolean; + +export declare function isWindows(): boolean; + +export declare function isSupportCss3(style: any): boolean; + +export declare function getSafariVersion(): number; diff --git a/packages/fineui/typescript/core/platform/web/index.ts b/packages/fineui/typescript/core/platform/web/index.ts new file mode 100644 index 000000000..f9146475b --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/index.ts @@ -0,0 +1,6 @@ +export * from "./function"; +export * as EventListener from "./eventListener"; +export * as ResizeDetector from "./detectElementResize"; +export * from "./load"; +export * as DOM from "./dom"; +export declare var $: any; diff --git a/packages/fineui/typescript/core/platform/web/load.ts b/packages/fineui/typescript/core/platform/web/load.ts new file mode 100644 index 000000000..144150ff5 --- /dev/null +++ b/packages/fineui/typescript/core/platform/web/load.ts @@ -0,0 +1 @@ +export declare function $import(src: string, ext?: string, must?: boolean): void diff --git a/packages/fineui/typescript/core/plugin.ts b/packages/fineui/typescript/core/plugin.ts new file mode 100644 index 000000000..16ea5f8e6 --- /dev/null +++ b/packages/fineui/typescript/core/plugin.ts @@ -0,0 +1,12 @@ +import { Widget } from "./widget"; + +type configWidgetFn = (type: string, options: Obj) => void +type configObjectFn = (type: string, widget: Widget) => void + +export declare namespace Plugin { + function config(widgetFunction: configWidgetFn | configWidgetFn[], objectFunction: configObjectFn | configObjectFn[]): void + + function configWidget(shortcut: string, widgetFunction: configWidgetFn): void + + function registerObject(shortcut: string, objectFunction: configObjectFn): void +} diff --git a/packages/fineui/typescript/core/utils/aes.ts b/packages/fineui/typescript/core/utils/aes.ts new file mode 100644 index 000000000..88d4efa92 --- /dev/null +++ b/packages/fineui/typescript/core/utils/aes.ts @@ -0,0 +1,3 @@ +export declare function aesEncrypt(text: string, key: string): string + +export declare function aesDecrypt(text: string, key: string): string diff --git a/packages/fineui/typescript/core/utils/aspect.ts b/packages/fineui/typescript/core/utils/aspect.ts new file mode 100644 index 000000000..6dfdbc888 --- /dev/null +++ b/packages/fineui/typescript/core/utils/aspect.ts @@ -0,0 +1,11 @@ +export declare function before(target: object, methodName: string, advice: Function): { + advice: Function, + index: number, + remove: () => void +} + +export declare function after(target: object, methodName: string, advice: Function): { + advice: Function, + index: number, + remove: () => void +} diff --git a/packages/fineui/typescript/core/utils/base64.ts b/packages/fineui/typescript/core/utils/base64.ts new file mode 100644 index 000000000..04b7c2fc4 --- /dev/null +++ b/packages/fineui/typescript/core/utils/base64.ts @@ -0,0 +1,3 @@ +export declare function encode(input: string): string + +export declare function decode(text: string): string diff --git a/packages/fineui/typescript/core/utils/cache.ts b/packages/fineui/typescript/core/utils/cache.ts new file mode 100644 index 000000000..af0130637 --- /dev/null +++ b/packages/fineui/typescript/core/utils/cache.ts @@ -0,0 +1,23 @@ +export declare function setUsername(username: string): void + +export declare function getUsername(): string + +export declare function _getKeyPrefix(): string + +export declare function _generateKey(key?: string): void + +export declare function getItem(key?: string): string + +export declare function setItem(key: string, value: any): void + +export declare function removeItem(key: string): void + +export declare function clear(): void + +export declare function keys(): string[] + +export declare function addCookie(name: string, value: any, path?: string, expiresHours?: number): void + +export declare function getCookie(name: string): string + +export declare function deleteCookie(name: string, path?: string): void diff --git a/typescript/core/utils/cellSizeAndPositionManager.ts b/packages/fineui/typescript/core/utils/cellSizeAndPositionManager.ts similarity index 100% rename from typescript/core/utils/cellSizeAndPositionManager.ts rename to packages/fineui/typescript/core/utils/cellSizeAndPositionManager.ts diff --git a/packages/fineui/typescript/core/utils/chinesePY.ts b/packages/fineui/typescript/core/utils/chinesePY.ts new file mode 100644 index 000000000..c7b5a0df0 --- /dev/null +++ b/packages/fineui/typescript/core/utils/chinesePY.ts @@ -0,0 +1 @@ +export declare function makeFirstPY(str: string, options?: { ignoreMulti?: boolean, splitChar?: string }): string diff --git a/typescript/core/utils/events/mousemovetracker.ts b/packages/fineui/typescript/core/utils/events/mousemovetracker.ts similarity index 100% rename from typescript/core/utils/events/mousemovetracker.ts rename to packages/fineui/typescript/core/utils/events/mousemovetracker.ts diff --git a/typescript/core/utils/events/wheelhandler.ts b/packages/fineui/typescript/core/utils/events/wheelhandler.ts similarity index 100% rename from typescript/core/utils/events/wheelhandler.ts rename to packages/fineui/typescript/core/utils/events/wheelhandler.ts diff --git a/typescript/core/utils/heap.ts b/packages/fineui/typescript/core/utils/heap.ts similarity index 100% rename from typescript/core/utils/heap.ts rename to packages/fineui/typescript/core/utils/heap.ts diff --git a/packages/fineui/typescript/core/utils/index.ts b/packages/fineui/typescript/core/utils/index.ts new file mode 100644 index 000000000..8982a20f2 --- /dev/null +++ b/packages/fineui/typescript/core/utils/index.ts @@ -0,0 +1,16 @@ +export * from "./aes"; +export * as aspect from "./aspect"; +export * from "./base64"; +export * as Cache from "./cache"; +export * from "./chinesePY"; +export * from "./events/mousemovetracker"; +export * from "./events/wheelhandler"; +export * from "./cellSizeAndPositionManager"; +export * from "./heap"; +export * from "./linkedHashMap"; +export * from "./lru"; +export * from "./prefixIntervalTree"; +export * from "./queue"; +export * from "./sectionManager"; +export * from "./tree"; +export * from "./vector"; diff --git a/typescript/core/utils/linkedHashMap.ts b/packages/fineui/typescript/core/utils/linkedHashMap.ts similarity index 100% rename from typescript/core/utils/linkedHashMap.ts rename to packages/fineui/typescript/core/utils/linkedHashMap.ts diff --git a/typescript/core/utils/lru.ts b/packages/fineui/typescript/core/utils/lru.ts similarity index 100% rename from typescript/core/utils/lru.ts rename to packages/fineui/typescript/core/utils/lru.ts diff --git a/typescript/core/utils/prefixIntervalTree.ts b/packages/fineui/typescript/core/utils/prefixIntervalTree.ts similarity index 100% rename from typescript/core/utils/prefixIntervalTree.ts rename to packages/fineui/typescript/core/utils/prefixIntervalTree.ts diff --git a/typescript/core/utils/queue.ts b/packages/fineui/typescript/core/utils/queue.ts similarity index 100% rename from typescript/core/utils/queue.ts rename to packages/fineui/typescript/core/utils/queue.ts diff --git a/typescript/core/utils/sectionManager.ts b/packages/fineui/typescript/core/utils/sectionManager.ts similarity index 100% rename from typescript/core/utils/sectionManager.ts rename to packages/fineui/typescript/core/utils/sectionManager.ts diff --git a/typescript/core/utils/tree.ts b/packages/fineui/typescript/core/utils/tree.ts similarity index 100% rename from typescript/core/utils/tree.ts rename to packages/fineui/typescript/core/utils/tree.ts diff --git a/typescript/core/utils/vector.ts b/packages/fineui/typescript/core/utils/vector.ts similarity index 100% rename from typescript/core/utils/vector.ts rename to packages/fineui/typescript/core/utils/vector.ts diff --git a/packages/fineui/typescript/core/var.ts b/packages/fineui/typescript/core/var.ts new file mode 100644 index 000000000..580091fb2 --- /dev/null +++ b/packages/fineui/typescript/core/var.ts @@ -0,0 +1,143 @@ +export declare const MAX: number; +export declare const MIN: number; +export declare const EVENT_RESPONSE_TIME: number; +export declare const zIndex_layer: number; +export declare const zIndex_popover: number; +export declare const zIndex_popup: number; +export declare const zIndex_masker: number; +export declare const zIndex_tip: number; +export declare const emptyStr: string; +export declare const emptyFn: Function; +export declare const empty: null; +export declare const Key: { + 48: string; + 49: string; + 50: string; + 51: string; + 52: string; + 53: string; + 54: string; + 55: string; + 56: string; + 57: string; + 65: string; + 66: string; + 67: string; + 68: string; + 69: string; + 70: string; + 71: string; + 72: string; + 73: string; + 74: string; + 75: string; + 76: string; + 77: string; + 78: string; + 79: string; + 80: string; + 81: string; + 82: string; + 83: string; + 84: string; + 85: string; + 86: string; + 87: string; + 88: string; + 89: string; + 90: string; + 96: string; + 97: string; + 98: string; + 99: string; + 100: string; + 101: string; + 102: string; + 103: string; + 104: string; + 105: string; + 106: string; + 107: string; + 109: string; + 110: string; + 111: string; +}; +export declare const KeyCode: { + BACKSPACE: number; + COMMA: number; + DELETE: number; + DOWN: number; + END: number; + ENTER: number; + ESCAPE: number; + HOME: number; + LEFT: number; + NUMPAD_ADD: number; + NUMPAD_DECIMAL: number; + NUMPAD_DIVIDE: number; + NUMPAD_ENTER: number; + NUMPAD_MULTIPLY: number; + NUMPAD_SUBTRACT: number; + PAGE_DOWN: number; + PAGE_UP: number; + PERIOD: number; + RIGHT: number; + SPACE: number; + TAB: number; + UP: number; +}; +export declare const Status: { + SUCCESS: number; + WRONG: number; + START: number; + END: number; + WAITING: number; + READY: number; + RUNNING: number; + OUTOFBOUNDS: number; + NULL: number; +}; +export declare const Direction: { + Top: string; + Bottom: string; + Left: string; + Right: string; + Custom: string; +}; +export declare const Axis: { + Vertical: string; + Horizontal: string; +}; +export declare const Selection: { + Default: number; + None: number; + Single: number; + Multi: number; + All: number; +}; +export declare const HorizontalAlign: { + Left: string; + Right: string; + Center: string; + Stretch: string; +}; +export declare const VerticalAlign: { + Middle: string; + Top: string; + Bottom: string; + Stretch: string; +}; +export declare const StartOfWeek: number; +export declare const BlankSplitChar: string; +export declare const Events: Record; + +type SetFunc = (value: any) => void; + +export declare const setEventResponseTime: SetFunc; +export declare const setPixUnit: SetFunc; +export declare const setPixRatio: SetFunc; +export declare const setStartOfWeek: SetFunc; +export declare const setBlankSplitChar: SetFunc; +export declare const setPixFormat: SetFunc; +export declare const setToPix: SetFunc; +export declare const setEventBlur: SetFunc; diff --git a/packages/fineui/typescript/core/widget.ts b/packages/fineui/typescript/core/widget.ts new file mode 100644 index 000000000..f01b9a517 --- /dev/null +++ b/packages/fineui/typescript/core/widget.ts @@ -0,0 +1,418 @@ +import { OB } from "./ob"; + +interface RenderEngine { + // TODO: 完成jquery文件夹后把这块改了 + /** + * 创建元素方法,返回的类jQuery对象 + * @param widget widget对象 + */ + createElement: (widget: any) => any; + + /** + * 创建DocumentFragment对象 + */ + createFragment: () => DocumentFragment; +} + +export declare class Widget extends OB { + /** + * 注册渲染引擎 + * @param engine 引擎 + */ + static registerRenderEngine(engine: RenderEngine): void; + + /** + * 渲染引擎 + */ + static _renderEngine: RenderEngine; + + /** + * 出现loading的锁 + */ + __asking: boolean; + + /** + * 同步锁 + */ + __async: boolean; + + /** + * widget类标识符 + */ + widgetName: string | null; + + /** + * 是否为根节点 + */ + _isRoot: boolean; + + /** + * 父节点 + */ + _parent: Widget | null; + // TODO: 完成jquery文件夹后把这块改了 + /** + * 真实dom的类jQuery对象 + */ + element: { + width(): number; + height(): number; + width(width: number | string): Widget["element"]; + height(height: number | string): Widget["element"]; + [key: string]: any; + }; + + /** + * 子元素 + */ + _children: { + [key: string]: Widget; + }; + + /** + * 是否已挂载 + */ + _isMounted: boolean; + + /** + * 手动设置enable + */ + _manualSetEnable: boolean; + + /** + * 手动设置valid + */ + _manualSetValid: boolean; + + _store(): void; + + // 生命周期函数 + /** + * 初始化前 + */ + beforeInit?(cb: Function): void; + + /** + * 渲染前 + */ + beforeRender?(cb: Function): void; + + /** + * 创建前 + */ + beforeCreate?(): void; + + /** + * 创建 + */ + created?(): void; + + /** + * 渲染 + */ + render?(): any; + + /** + * 挂载前 + */ + beforeMount?(): void; + + /** + * 挂载 + */ + mounted?(): void; + + /** + * 更新前 + */ + shouldUpdate?(): boolean; + + /** + * 更新 + */ + update?(...args: any[]): void; + + /** + * 销毁前 + */ + beforeDestroy?(): void; + + /** + * 销毁 + */ + destroyed?(): void; + + /** + * 初始化render函数 + */ + _initRender: () => void; + + /** + * 内部主render函数 + */ + _render: () => void; + + /** + * 初始化根节点 + */ + _initRoot: () => void; + + /** + * 初始化元素宽度 + */ + _initElementWidth: () => void; + + /** + * 初始化元素高度 + */ + _initElementHeight: () => void; + + /** + * 初始化元素可见 + */ + _initVisual: () => void; + + /** + * 初始化元素可用不可用 + */ + _initEffects: () => void; + + /** + * 设置mounted锁 + */ + _initState: () => void; + + /** + * 生成真实dom + */ + _initElement: () => void; + + /** + * 设置父节点 + */ + _setParent: () => void; + + /** + * @param force 是否强制挂载子节点 + * @param deep 子节点是否也是按照当前force处理 + * @param lifeHook 生命周期钩子触不触发,默认触发 + * @param predicate 递归每个widget的回调 + */ + _mount(force?: boolean, deep?: boolean, lifeHook?: boolean, predicate?: Function): boolean; + + /** + * 挂载子节点 + */ + _mountChildren?(): void; + + /** + * 是否已挂载 + */ + isMounted(): boolean; + + /** + * 设置宽度 + */ + setWidth(w: number | string): void; + + /** + * 设置高度 + */ + setHeight(h: number | string): void; + + /** + * 设置可用 + */ + _setEnable(enable: boolean): void; + + /** + * 设置合法 + */ + _setValid(valid: boolean): void; + + /** + * 设置可见 + */ + _setVisible(visible: boolean): void; + + /** + * 设置是否可用 + */ + setEnable(enable: boolean): void; + + /** + * 设置是否可见 + */ + setVisible(visible: boolean): void; + + /** + * 设置是否合法 + */ + setValid(valid: boolean): void; + + /** + * 设置反馈效果 + * @param args arguments参数 + */ + doBehavior(...args: any[]): void; + + /** + * 获取宽度 + */ + getWidth(): number; + + /** + * 获取高度 + */ + getHeight(): number; + + /** + * 是否合法 + */ + isValid(): boolean; + + /** + * 新增子元素 + */ + addWidget(widget: Widget): Widget; + addWidget(_name: any, _widget: Widget): Widget; + + /** + * 根据wigetname获取子元素实例 + */ + getWidgetByName(_name: string): Widget | undefined; + + /** + * 移除子元素 + * @param nameOrWidget widgetName或widget实例 + */ + removeWidget(nameOrWidget: string | Widget): void; + + /** + * 是否有某个子元素 + */ + hasWidget(name: string): boolean; + + /** + * 获取widgetName + */ + getName(): string; + + /** + * 设置tag + * @param tag html tag + */ + setTag(tag: string): void; + + /** + * 获取tag + */ + getTag(): string; + + /** + * 设置属性 + * @param key 键 + * @param value 值 + */ + attr(key: string | { [key: string]: any }, value?: any): any; + + /** + * 获取text + */ + getText(): string; + + /** + * 设置text + */ + setText(text: string): void; + + /** + * 获取值 + */ + getValue(): any; + + /** + * 设置值 + */ + setValue(...args: any[]): void; + + /** + * 获取是否enable + */ + isEnabled(): boolean; + + /** + * 是否可见 + */ + isVisible(): boolean; + + /** + * disable元素 + */ + disable(): void; + + /** + * enable元素 + */ + enable(): void; + + /** + * 是widget合法 + */ + valid(): void; + + /** + * 使元素不合法 + */ + invalid(): void; + + /** + * 使不可见 + */ + invisible(..._args: any[]): void; + + /** + * 可见 + */ + visible(..._args: any[]): void; + + /** + * 清除子元素 + */ + __d(): void; + + /** + * 取消挂载 + */ + _unMount(): void; + + /** + * watch响应式数据 + */ + __watch any>(getter: T, handler: Function, options?: Obj): ReturnType + + /** + * hang元素 + */ + isolate(): void; + + /** + * 请除元素 + */ + empty(): void; + + /** + * 刷新控件 + */ + reset(): void; + + /** + * 内部destory方法 + */ + _destroy(): void; + + /** + * destory元素 + */ + destroy(): void; +} diff --git a/typescript/core/worker/action/worker.action.ts b/packages/fineui/typescript/core/worker/action/worker.action.ts similarity index 100% rename from typescript/core/worker/action/worker.action.ts rename to packages/fineui/typescript/core/worker/action/worker.action.ts diff --git a/packages/fineui/typescript/core/worker/controller/worker.controller.ts b/packages/fineui/typescript/core/worker/controller/worker.controller.ts new file mode 100644 index 000000000..d4b913a13 --- /dev/null +++ b/packages/fineui/typescript/core/worker/controller/worker.controller.ts @@ -0,0 +1,131 @@ +import type { IWorkerController, IWorkerMessage } from "../worker.core"; +import { WorkerChannel } from "../worker.channel"; + +/** + * 通信控制器 + * + * @class WorkerBaseController + */ +export class WorkerBaseController implements IWorkerController { + /** + * 原生 worker, 在子类中实例化 + */ + protected worker: Worker; + + /** + * 通信 Channel, 在子类中实例化 + */ + protected channel: WorkerChannel; + + /** + * 事务处理器 Map + */ + protected actionHandlerMap: { + [propsName: string]: (payload: any) => any; + }; + + public constructor() { + this.actionHandlerMap = {}; + } + + /** + * 发送事务,不等待结果 + * + * @param actionType 事务类型 + * @param payload 负载 + */ + public request(actionType: string, payload: any): void { + if (this.channel) { + return this.channel.request(actionType, payload); + } + + console.error("No channel."); + + return; + } + + /** + * 发送 Promise 形式的事务, 在 then 中获取响应 + * + * @param actionType 事务类型 + * @param payload 负载 + * @param [timeout] 响应的超时; Worker 通道是可靠的, 超时后只上报, 不阻止当前请求 + */ + public requestPromise(actionType: string, payload: any = "", timeout?: number): Promise { + // 有 Channel 实例才能进行通信, 此时还没有实例化是浏览器不支持创建 worker + if (this.channel) { + return this.channel.requestPromise(actionType, payload, timeout); + } + + // 兼容上层调用的 .then().catch() + return Promise.reject(new Error("No channel.")); + } + + /** + * 添加事务处理器, 不允许重复添加 + * + * @param actionType 事务类型 + * @param handler 事务处理器 + */ + public addActionHandler(actionType: string, handler: (payload: any) => any): void { + if (this.hasActionHandler(actionType)) { + throw new Error(`Add action \`${actionType}\` handler repeat`); + } + this.actionHandlerMap[actionType] = handler; + } + + /** + * 事务处理器, 提供给通信 Channel 调用 + * + * @param message 会话消息 + * @returns + */ + public actionHandler(message: IWorkerMessage): Promise { + const { actionType, payload } = message; + + if (this.hasActionHandler(actionType)) { + // 执行指定的事务处理器, 并返回 Promise 封装的事务结果 + try { + const actionResult = this.actionHandlerMap[actionType](payload); + + // 对于 Promise 形式的结果, 需要进行 Promise 错误捕获 + if (BI.isPromise(actionResult)) { + return actionResult.catch((error: any) => Promise.reject(error)); + } + + // 对数据结果, 包装为 Promise + return Promise.resolve(actionResult); + } catch (error) { + // 继续抛出给外层 + return Promise.reject(error); + } + } else { + throw new Error(`Not Found Session Handler \`${actionType}\`.`); + } + } + + /** + * 添加 worker onmessage 事件的回调 + * + * @param {(event: any) => void} onmessage 回调函数 + * @returns {() => void} 移除监听函数 + */ + public addOnmessageListener(onmessage: (event: any) => void): () => void { + this.worker.addEventListener("message", onmessage); + + // 返回移除监听函数 + return () => { + this.worker.removeEventListener("message", onmessage); + }; + } + + /** + * 判断是否有指定事务的处理器 + * + * @param actionType 事务类型 + * @returns {boolean} + */ + protected hasActionHandler(actionType: string): boolean { + return !!this.actionHandlerMap[actionType]; + } +} diff --git a/typescript/core/worker/controller/worker.main_thread.controller.ts b/packages/fineui/typescript/core/worker/controller/worker.main_thread.controller.ts similarity index 100% rename from typescript/core/worker/controller/worker.main_thread.controller.ts rename to packages/fineui/typescript/core/worker/controller/worker.main_thread.controller.ts diff --git a/typescript/core/worker/controller/worker.worker_thread.controller.ts b/packages/fineui/typescript/core/worker/controller/worker.worker_thread.controller.ts similarity index 100% rename from typescript/core/worker/controller/worker.worker_thread.controller.ts rename to packages/fineui/typescript/core/worker/controller/worker.worker_thread.controller.ts diff --git a/typescript/core/worker/worker.channel.ts b/packages/fineui/typescript/core/worker/worker.channel.ts similarity index 100% rename from typescript/core/worker/worker.channel.ts rename to packages/fineui/typescript/core/worker/worker.channel.ts diff --git a/typescript/core/worker/worker.core.ts b/packages/fineui/typescript/core/worker/worker.core.ts similarity index 100% rename from typescript/core/worker/worker.core.ts rename to packages/fineui/typescript/core/worker/worker.core.ts diff --git a/typescript/core/worker/worker.main_thread.ts b/packages/fineui/typescript/core/worker/worker.main_thread.ts similarity index 100% rename from typescript/core/worker/worker.main_thread.ts rename to packages/fineui/typescript/core/worker/worker.main_thread.ts diff --git a/typescript/core/worker/worker.worker_thread.ts b/packages/fineui/typescript/core/worker/worker.worker_thread.ts similarity index 100% rename from typescript/core/worker/worker.worker_thread.ts rename to packages/fineui/typescript/core/worker/worker.worker_thread.ts diff --git a/typescript/core/worker/workers.ts b/packages/fineui/typescript/core/worker/workers.ts similarity index 100% rename from typescript/core/worker/workers.ts rename to packages/fineui/typescript/core/worker/workers.ts diff --git a/typescript/core/wrapper/layout.ts b/packages/fineui/typescript/core/wrapper/layout.ts similarity index 100% rename from typescript/core/wrapper/layout.ts rename to packages/fineui/typescript/core/wrapper/layout.ts diff --git a/typescript/core/wrapper/layout/adapt/absolute.center.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/absolute.center.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/absolute.center.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/absolute.center.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.center.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.center.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.center.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.center.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.horizontal.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.leftrightvertical.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.leftrightvertical.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.leftrightvertical.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.leftrightvertical.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.leftvertical.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.leftvertical.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.leftvertical.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.leftvertical.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.table.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.table.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.table.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.table.ts diff --git a/typescript/core/wrapper/layout/adapt/adapt.vertical.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/adapt.vertical.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/adapt.vertical.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/adapt.vertical.ts diff --git a/typescript/core/wrapper/layout/adapt/auto.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/auto.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/auto.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/auto.horizontal.ts diff --git a/typescript/core/wrapper/layout/adapt/float.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/float.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/float.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/float.horizontal.ts diff --git a/typescript/core/wrapper/layout/adapt/inline.vertical.ts b/packages/fineui/typescript/core/wrapper/layout/adapt/inline.vertical.ts similarity index 100% rename from typescript/core/wrapper/layout/adapt/inline.vertical.ts rename to packages/fineui/typescript/core/wrapper/layout/adapt/inline.vertical.ts diff --git a/typescript/core/wrapper/layout/fill/fill.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/fill/fill.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/fill/fill.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/fill/fill.horizontal.ts diff --git a/typescript/core/wrapper/layout/fill/fill.vertical.ts b/packages/fineui/typescript/core/wrapper/layout/fill/fill.vertical.ts similarity index 100% rename from typescript/core/wrapper/layout/fill/fill.vertical.ts rename to packages/fineui/typescript/core/wrapper/layout/fill/fill.vertical.ts diff --git a/typescript/core/wrapper/layout/layout.absolute.ts b/packages/fineui/typescript/core/wrapper/layout/layout.absolute.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.absolute.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.absolute.ts diff --git a/typescript/core/wrapper/layout/layout.adaptive.ts b/packages/fineui/typescript/core/wrapper/layout/layout.adaptive.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.adaptive.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.adaptive.ts diff --git a/packages/fineui/typescript/core/wrapper/layout/layout.border.ts b/packages/fineui/typescript/core/wrapper/layout/layout.border.ts new file mode 100644 index 000000000..d65f18a57 --- /dev/null +++ b/packages/fineui/typescript/core/wrapper/layout/layout.border.ts @@ -0,0 +1,5 @@ +import { Layout } from "../layout"; + +export declare class BorderLayout extends Layout { + static xtype: string; +} diff --git a/typescript/core/wrapper/layout/layout.card.ts b/packages/fineui/typescript/core/wrapper/layout/layout.card.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.card.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.card.ts diff --git a/typescript/core/wrapper/layout/layout.default.ts b/packages/fineui/typescript/core/wrapper/layout/layout.default.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.default.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.default.ts diff --git a/typescript/core/wrapper/layout/layout.flow.ts b/packages/fineui/typescript/core/wrapper/layout/layout.flow.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.flow.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.flow.ts diff --git a/typescript/core/wrapper/layout/layout.grid.ts b/packages/fineui/typescript/core/wrapper/layout/layout.grid.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.grid.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.grid.ts diff --git a/typescript/core/wrapper/layout/layout.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/layout.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.horizontal.ts diff --git a/packages/fineui/typescript/core/wrapper/layout/layout.inline.ts b/packages/fineui/typescript/core/wrapper/layout/layout.inline.ts new file mode 100644 index 000000000..36e818244 --- /dev/null +++ b/packages/fineui/typescript/core/wrapper/layout/layout.inline.ts @@ -0,0 +1,5 @@ +import { Layout } from "../layout"; + +export declare class InlineLayout extends Layout { + static xtype: string; +} diff --git a/typescript/core/wrapper/layout/layout.table.ts b/packages/fineui/typescript/core/wrapper/layout/layout.table.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.table.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.table.ts diff --git a/typescript/core/wrapper/layout/layout.tape.ts b/packages/fineui/typescript/core/wrapper/layout/layout.tape.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.tape.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.tape.ts diff --git a/typescript/core/wrapper/layout/layout.td.ts b/packages/fineui/typescript/core/wrapper/layout/layout.td.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.td.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.td.ts diff --git a/typescript/core/wrapper/layout/layout.vertical.ts b/packages/fineui/typescript/core/wrapper/layout/layout.vertical.ts similarity index 100% rename from typescript/core/wrapper/layout/layout.vertical.ts rename to packages/fineui/typescript/core/wrapper/layout/layout.vertical.ts diff --git a/typescript/core/wrapper/layout/middle/middle.center.ts b/packages/fineui/typescript/core/wrapper/layout/middle/middle.center.ts similarity index 100% rename from typescript/core/wrapper/layout/middle/middle.center.ts rename to packages/fineui/typescript/core/wrapper/layout/middle/middle.center.ts diff --git a/typescript/core/wrapper/layout/middle/middle.float.center.ts b/packages/fineui/typescript/core/wrapper/layout/middle/middle.float.center.ts similarity index 100% rename from typescript/core/wrapper/layout/middle/middle.float.center.ts rename to packages/fineui/typescript/core/wrapper/layout/middle/middle.float.center.ts diff --git a/typescript/core/wrapper/layout/sticky/sticky.horizontal.ts b/packages/fineui/typescript/core/wrapper/layout/sticky/sticky.horizontal.ts similarity index 100% rename from typescript/core/wrapper/layout/sticky/sticky.horizontal.ts rename to packages/fineui/typescript/core/wrapper/layout/sticky/sticky.horizontal.ts diff --git a/typescript/core/wrapper/layout/sticky/sticky.vertical.ts b/packages/fineui/typescript/core/wrapper/layout/sticky/sticky.vertical.ts similarity index 100% rename from typescript/core/wrapper/layout/sticky/sticky.vertical.ts rename to packages/fineui/typescript/core/wrapper/layout/sticky/sticky.vertical.ts diff --git a/packages/fineui/typescript/fix/fix.ts b/packages/fineui/typescript/fix/fix.ts new file mode 100644 index 000000000..2e1019e2e --- /dev/null +++ b/packages/fineui/typescript/fix/fix.ts @@ -0,0 +1,18 @@ +export declare namespace Fix { + function define(model: any): any + + function watch(model: any, expOrFn: string | Function, cb: Function, options: Obj): Function[] + + function set(target: any, key: string, val: any): void + + function del(target: any, key: string): void + + function toJSON(model: any): any + + function mixin(xtype: string, mixin: any): void + + class Model { + + } + +} diff --git a/packages/fineui/typescript/index.old.ts b/packages/fineui/typescript/index.old.ts new file mode 100644 index 000000000..b45e94dfb --- /dev/null +++ b/packages/fineui/typescript/index.old.ts @@ -0,0 +1,597 @@ +// import { Combo } from "./base/combination/combo"; +// import { ButtonGroup } from "./base/combination/group.button"; +// import { Tab } from "./base/combination/tab"; +// import { Pane } from "./base/pane"; +// import { BasicButton } from "./base/single/button/button.basic"; +// import { NodeButton } from "./base/single/button/button.node"; +// import { Button } from "./base/single/button/buttons/button"; +// import { TextButton } from "./base/single/button/buttons/button.text"; +// import { IconTextItem } from "./base/single/button/listitem/icontextitem"; +// import { Editor } from "./base/single/editor/editor"; +// import { Iframe } from "./base/single/iframe/iframe"; +// import { Checkbox } from "./base/single/input/checkbox"; +// import { Input } from "./base/single/input/input"; +// import { AbstractLabel } from "./base/single/label/abstract.label"; +// import { Label } from "./base/single/label/label"; +// import { Single } from "./base/single/single"; +// import { Text } from "./base/single/text"; +// import { Trigger } from "./base/single/trigger/trigger"; +// import { IconChangeButton } from "./case/button/icon/icon.change"; +// import { MultiSelectItem } from "./case/button/item.multiselect"; +// import { BubbleCombo } from "./case/combo/bubblecombo/combo.bubble"; +// import { TextValueCombo } from "./case/combo/combo.textvalue"; +// import { TextValueComboPopup } from "./case/combo/popup.textvalue"; +// import { SmallTextValueCombo } from "./case/combo/combo.textvaluesmall"; +// import { SearchTextValueCombo } from "./case/combo/searchtextvaluecombo/combo.searchtextvalue"; +// import { SignEditor } from "./case/editor/editor.sign"; +// import { StateEditor } from "./case/editor/editor.state"; +// import { AllValueMultiTextValueCombo } from "./component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo"; +// import { Form } from "./component/form/form"; +// import { AbstractTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser"; +// import { AbstractListTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser.list"; +// import { Action, ActionFactory } from "./core/action/action"; +// import { ShowAction } from "./core/action/action.show"; +// import { _base } from "./core/base"; +// import { Behavior, BehaviorFactory } from "./core/behavior/behavior"; +// import { HighlightBehavior } from "./core/behavior/behavior.highlight"; +// import { RedMarkBehavior } from "./core/behavior/behavior.redmark"; +// import * as decorator from "./core/decorator/decorator"; +// import { _func } from "./core/func"; +// import { _i18n } from "./core/i18n"; +// import { _Plugin } from "./core/plugin"; +// import { _var } from "./core/var"; +// import { OB } from "./core/ob"; +// import { Widget } from "./core/widget"; +// import { _inject } from "./core/inject"; +// import { Layout } from "./core/wrapper/layout"; +// import { AbsoluteLayout } from "./core/wrapper/layout/layout.absolute"; +// import { HTapeLayout, VTapeLayout } from "./core/wrapper/layout/layout.tape"; +// import { HorizontalFillLayout } from "./core/wrapper/layout/fill/fill.horizontal"; +// import { VerticalFillLayout } from "./core/wrapper/layout/fill/fill.vertical"; +// import { VerticalLayout } from "./core/wrapper/layout/layout.vertical"; +// import { DefaultLayout } from "./core/wrapper/layout/layout.default"; +// import { DownListCombo } from "./widget/downlist/combo.downlist"; +// import { DownListPopup } from "./widget/downlist/popup.downlist"; +// import { Icon } from "./base/single/icon/icon"; +// import { LeftVerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.leftvertical"; +// import { +// LeftRightVerticalAdaptLayout, +// RightVerticalAdaptLayout, +// } from "./core/wrapper/layout/adapt/adapt.leftrightvertical"; +// import { IconTextIconItem } from "./base/single/button/listitem/icontexticonitem"; +// import { HorizontalAutoLayout } from "./core/wrapper/layout/adapt/auto.horizontal"; +// import { InlineVerticalAdaptLayout } from "./core/wrapper/layout/adapt/inline.vertical"; +// import { TableAdaptLayout } from "./core/wrapper/layout/adapt/adapt.table"; +// import { IconButton } from "./base/single/button/buttons/button.icon"; +// import { TextEditor } from "./widget/editor/editor.text"; +// import { IconLabel } from "./base/single/label/icon.label"; +// import { Popover, BarPopover } from "./base/layer/layer.popover"; +// import { IconCombo } from "./case/combo/iconcombo/combo.icon"; +// import { DynamicDateCombo } from "./widget/dynamicdate/dynamicdate.combo"; +// import { CustomTree } from "./base/tree/customtree"; +// import { ButtonTree } from "./base/combination/tree.button"; +// import { IconArrowNode } from "./case/button/node/node.icon.arrow"; +// import { MidTreeLeafItem } from "./case/button/treeitem/item.mid.treeleaf"; +// import { FirstTreeLeafItem } from "./case/button/treeitem/item.first.treeleaf"; +// import { LastTreeLeafItem } from "./case/button/treeitem/item.last.treeleaf"; +// import { SmallTextEditor } from "./widget/editor/editor.text.small"; +// import { MultifileEditor } from "./widget/editor/editor.multifile"; +// import { AbsoluteCenterLayout } from "./core/wrapper/layout/adapt/absolute.center"; +// import { HorizontalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.horizontal"; +// import { FloatLeftLayout, FloatRightLayout } from "./core/wrapper/layout/layout.flow"; +// import { CenterAdaptLayout } from "./core/wrapper/layout/adapt/adapt.center"; +// import { VerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.vertical"; +// import { MultiSelectInsertCombo } from "./widget/multiselect/multiselect.insert.combo"; +// import { MultiSelectCombo } from "./widget/multiselect/multiselect.combo"; +// import { SearchEditor } from "./widget/editor/editor.search"; +// import { MultiLayerSingleLevelTree } from "./widget/multilayersingletree/multilayersingletree.leveltree"; +// import { SimpleColorChooser } from "./case/colorchooser/colorchooser.simple"; +// import { ColorChooser } from "./case/colorchooser/colorchooser"; +// import { A } from "./base/a/a"; +// import { Html } from "./base/single/html/html"; +// import { Switcher } from "./base/combination/switcher"; +// import { Expander } from "./base/combination/expander"; +// import { Loader } from "./base/combination/loader"; +// import { ListPane } from "./case/layer/pane.list"; +// import { MultiPopupView } from "./case/layer/layer.multipopup"; +// import { MultiSelectBar } from "./case/toolbar/toolbar.multiselect"; +// import { SelectList } from "./case/list/list.select"; +// import { AbstractAllValueChooser } from "./component/allvaluechooser/abstract.allvaluechooser"; +// import { AllValueChooserCombo } from "./component/allvaluechooser/combo.allvaluechooser"; +// import { TextAreaEditor } from "./base/single/editor/editor.textarea"; +// import { SingleSelectItem } from "./case/button/item.singleselect"; +// import { DynamicDateTimeCombo } from "./widget/dynamicdatetime/dynamicdatetime.combo"; +// import { MultiTreeCombo } from "./widget/multitree/multi.tree.combo"; +// import { CenterLayout } from "./core/wrapper/layout/middle/middle.center"; +// import { VirtualGroup } from "./base/combination/group.virtual"; +// import { GridLayout } from "./core/wrapper/layout/layout.grid"; +// import { TriggerIconButton } from "./case/button/icon/icon.trigger"; +// import { Searcher } from "./base/combination/searcher"; +// import { ListTreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.listtreevaluechooser"; +// import { TreeValueChooserCombo } from "./component/treevaluechooser/combo.treevaluechooser"; +// import { TreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.treevaluechooser.insert"; +// import { Radio } from "./base/single/input/radio/radio"; +// import { MultiLayerSelectTreePopup } from "./widget/multilayerselecttree/multilayerselecttree.popup"; +// import { MultiLayerSingleTreePopup } from "./widget/multilayersingletree/multilayersingletree.popup"; +// import { MultiLayerDownListPopup } from "./widget/multilayerdownlist/multilayerdownlist.popup"; +// import { TreeView } from "./base/tree/ztree/treeview"; +// import { MultiTreePopup } from "./widget/multitree/multi.tree.popup"; +// import { SingleSelectRadioItem } from "./case/button/item.singleselect.radio"; +// import { SingleSelectInsertCombo } from "./widget/singleselect/singleselect.insert.combo"; +// import { SingleSelectCombo } from "./widget/singleselect/singleselect.combo"; +// import { CardLayout } from "./core/wrapper/layout/layout.card"; +// import { DynamicYearMonthCombo } from "./widget/yearmonth/combo.yearmonth"; +// import { TimeCombo } from "./widget/time/time.combo"; +// import { ListTreeView } from "./base/tree/ztree/list/listtreeview"; +// import { ListAsyncTree } from "./base/tree/ztree/list/listasynctree"; +// import { AsyncTree } from "./base/tree/ztree/asynctree"; +// import { MultiLayerSingleTreeCombo } from "./widget/multilayersingletree/multilayersingletree.combo"; +// import { MultiLayerSelectTreeCombo } from "./widget/multilayerselecttree/multilayerselecttree.combo"; +// import { MultiLayerDownListCombo } from "./widget/multilayerdownlist/multilayerdownlist.combo"; +// import { MultiTreeListCombo } from "./widget/multitree/multi.tree.list.combo"; +// import { MultiTreeInsertCombo } from "./widget/multitree/multi.tree.insert.combo"; +// import { TextValueDownListCombo } from "./widget/textvaluedownlistcombo/combo.textvaluedownlist"; +// import { Switch } from "./case/button/switch"; +// import { HorizontalLayout } from "./core/wrapper/layout/layout.horizontal"; +// import { ShelterEditor } from "./case/editor/editor.shelter"; +// import { TextTrigger } from "./case/trigger/trigger.text"; +// import { SelectTextTrigger } from "./case/trigger/trigger.text.select"; +// import { DateInterval } from "./widget/timeinterval/dateinterval"; +// import { DynamicDatePane } from "./widget/datepane/datepane"; +// import { AllCountPager } from "./case/pager/pager.all.count"; +// import { DirectionPager } from "./case/pager/pager.direction"; +// import { PopupView } from "./base/layer/layer.popup"; +// import { BubblePopupView, BubblePopupBarView, TextBubblePopupBarView } from "./case/combo/bubblecombo/popup.bubble"; +// import { ArrowTreeGroupNodeCheckbox } from "./case/checkbox/check.arrownode"; +// import { NumberInterval } from "./widget/numberinterval/numberinterval"; +// import { DynamicYearQuarterCombo } from "./widget/yearquarter/combo.yearquarter"; +// import { DynamicYearCombo } from "./widget/year/combo.year"; +// import { DynamicYearPopup } from "./widget/year/popup.year"; +// import { IntervalSlider } from "./widget/intervalslider/intervalslider"; +// import { MultiSelectInsertList } from "./widget/multiselectlist/multiselectlist.insert"; +// import { YearMonthInterval } from "./widget/yearmonthinterval/yearmonthinterval"; +// import { NumberEditor } from "./widget/numbereditor/numbereditor"; +// import { TextValueCheckCombo } from "./case/combo/textvaluecheckcombo/combo.textvaluecheck"; +// import { Segment } from "./case/segment/segment"; +// import { LinearSegment } from "./case/linersegment/linear.segment"; +// import { Img } from "./base/single/img/img"; +// import { EditorIconCheckCombo } from "./case/combo/editoriconcheckcombo/combo.editiconcheck"; +// import { IconTextValueCombo } from "./case/combo/icontextvaluecombo/combo.icontextvalue"; +// import { ListView } from "./base/list/listview"; +// import { VirtualList } from "./base/list/virtuallist"; +// import { VirtualGroupList } from "./base/list/virtualgrouplist"; +// import { FloatCenterLayout } from "./core/wrapper/layout/middle/middle.float.center"; +// import { _msg } from "./base/foundation/message"; +// import { _web } from "./core/platform/web"; +// import { DynamicYearMonthPopup } from "./widget/yearmonth/popup.yearmonth"; +// import { _utils } from "./core/utils"; +// import { Controller } from "./core/controller/controller"; +// import { LayerController } from "./core/controller/controller.layer"; +// import { DateCalendarPopup } from "./widget/date/calendar/popup.calendar.date"; +// import { Tree, Node } from "./core/utils/tree"; +// import { TextNode } from "./base/single/button/node/textnode"; +// import { TextValueCheckComboPopup } from "./case/combo/textvaluecheckcombo/popup.textvaluecheck"; +// import { ImageButton } from "./base/single/button/buttons/button.image"; +// import { History, Router } from "./router/router"; +// import { DateTimeCombo } from "./widget/datetime/datetime.combo"; +// import { FloatHorizontalLayout } from "./core/wrapper/layout/adapt/float.horizontal"; +// import { AdaptiveLayout } from "./core/wrapper/layout/layout.adaptive"; +// import { HexColorChooserPopup } from "./case/colorchooser/colorchooser.popup.hex"; +// import { BlankIconTextItem } from "./base/single/button/listitem/blankicontextitem"; +// import { Broadcasts, Layers } from "./base/base"; +// import { BroadcastController } from "./core/controller/controller.broadcast"; +// import { Pager } from "./base/pager/pager"; +// import { TimeInterval } from "./widget/timeinterval/timeinterval"; +// import { DynamicDateTimePane } from "./widget/datetimepane/datetimepane"; +// import { SingleSelectInsertList } from "./widget/singleselect/singleselectlist.insert"; +// import { MultiSelectTree } from "./widget/multiselecttree/multiselecttree"; +// import { HtmlLabel } from "./base/single/label/html.label"; +// import { TreeValueChooserPane } from "./component/treevaluechooser/pane.treevaluechooser"; +// import { TdLayout } from "./core/wrapper/layout/layout.td"; +// import { MultiLayerSelectLevelTree } from "./widget/multilayerselecttree/multilayerselecttree.leveltree"; +// import { SelectTreeExpander } from "./widget/selecttree/selecttree.expander"; +// import { DownListGroupItem } from "./widget/downlist/item.downlistgroup"; +// import { VerticalStickyLayout } from "./core/wrapper/layout/sticky/sticky.vertical"; +// import { HorizontalStickyLayout } from "./core/wrapper/layout/sticky/sticky.horizontal"; +// import { TableLayout } from "./core/wrapper/layout/layout.table"; +// import "./shims-tsx"; +// import { Workers } from "./core/worker/workers"; +// +// +// export interface BI extends _func, _i18n, _base, _inject, _var, _web, _utils { +// OB: typeof OB; +// Plugin: _Plugin; +// Widget: typeof Widget; +// Single: typeof Single; +// BasicButton: typeof BasicButton; +// NodeButton: typeof NodeButton; +// Checkbox: typeof Checkbox; +// Button: typeof Button; +// TextButton: typeof TextButton; +// IconChangeButton: typeof IconChangeButton; +// Trigger: typeof Trigger; +// Action: typeof Action; +// ActionFactory: typeof ActionFactory; +// ShowAction: typeof ShowAction; +// Controller: typeof Controller; +// Layers: Layers; +// LayerController: typeof LayerController; +// Broadcasts: Broadcasts; +// BroadcastController: typeof BroadcastController; +// Behavior: typeof Behavior; +// BehaviorFactory: typeof BehaviorFactory; +// HighlightBehavior: typeof HighlightBehavior; +// RedMarkBehavior: typeof RedMarkBehavior; +// Pane: typeof Pane; +// Tab: typeof Tab; +// ButtonGroup: typeof ButtonGroup; +// Combo: typeof Combo; +// TextValueCombo: typeof TextValueCombo; +// TextValueComboPopup: typeof TextValueComboPopup; +// SmallTextValueCombo: typeof SmallTextValueCombo; +// BubbleCombo: typeof BubbleCombo; +// AllValueMultiTextValueCombo: typeof AllValueMultiTextValueCombo; +// Form: typeof Form; +// IconTextItem: typeof IconTextItem; +// MultiSelectItem: typeof MultiSelectItem; +// AbstractLabel: typeof AbstractLabel; +// Label: typeof Label; +// Text: typeof Text; +// Editor: typeof Editor; +// SignEditor: typeof SignEditor; +// StateEditor: typeof StateEditor; +// Layout: typeof Layout; +// HTapeLayout: typeof HTapeLayout; +// VTapeLayout: typeof VTapeLayout; +// AbstractTreeValueChooser: typeof AbstractTreeValueChooser; +// AbstractListTreeValueChooser: typeof AbstractListTreeValueChooser; +// ListTreeValueChooserInsertCombo: typeof ListTreeValueChooserInsertCombo; +// TreeValueChooserCombo: typeof TreeValueChooserCombo; +// TreeValueChooserInsertCombo: typeof TreeValueChooserInsertCombo; +// MultiLayerSelectTreePopup: typeof MultiLayerSelectTreePopup; +// MultiLayerSingleTreePopup: typeof MultiLayerSingleTreePopup; +// MultiLayerDownListPopup: typeof MultiLayerDownListPopup; +// TreeView: typeof TreeView; +// ListTreeView: typeof ListTreeView; +// ListAsyncTree: typeof ListAsyncTree; +// AsyncTree: typeof AsyncTree; +// MultiLayerSingleTreeCombo: typeof MultiLayerSingleTreeCombo; +// MultiLayerSelectTreeCombo: typeof MultiLayerSelectTreeCombo; +// MultiLayerDownListCombo: typeof MultiLayerDownListCombo; +// MultiTreeListCombo: typeof MultiTreeListCombo; +// MultiTreeInsertCombo: typeof MultiTreeInsertCombo; +// Decorators: typeof decorator; +// DownListCombo: typeof DownListCombo; +// DownListPopup: typeof DownListPopup; +// Iframe: typeof Iframe; +// AbsoluteLayout: typeof AbsoluteLayout; +// HorizontalFillLayout: typeof HorizontalFillLayout; +// VerticalFillLayout: typeof VerticalFillLayout; +// VerticalLayout: typeof VerticalLayout; +// DefaultLayout: typeof DefaultLayout; +// Input: typeof Input; +// SearchTextValueCombo: typeof SearchTextValueCombo; +// Icon: typeof Icon; +// LeftVerticalAdaptLayout: typeof LeftVerticalAdaptLayout; +// LeftRightVerticalAdaptLayout: typeof LeftRightVerticalAdaptLayout; +// IconTextIconItem: typeof IconTextIconItem; +// HorizontalAutoLayout: typeof HorizontalAutoLayout; +// InlineVerticalAdaptLayout: typeof InlineVerticalAdaptLayout; +// RightVerticalAdaptLayout: typeof RightVerticalAdaptLayout; +// TableAdaptLayout: typeof TableAdaptLayout; +// AbsoluteCenterLayout: typeof AbsoluteCenterLayout; +// HorizontalAdaptLayout: typeof HorizontalAdaptLayout; +// FloatLeftLayout: typeof FloatLeftLayout; +// FloatRightLayout: typeof FloatRightLayout; +// CenterAdaptLayout: typeof CenterAdaptLayout; +// VerticalAdaptLayout: typeof VerticalAdaptLayout; +// IconButton: typeof IconButton; +// TriggerIconButton: typeof TriggerIconButton; +// Searcher: typeof Searcher; +// TextEditor: typeof TextEditor; +// Radio: typeof Radio; +// A: typeof A; +// Html: typeof Html; +// Switcher: typeof Switcher; +// Expander: typeof Expander; +// Loader: typeof Loader; +// ListPane: typeof ListPane; +// MultiPopupView: typeof MultiPopupView; +// MultiSelectBar: typeof MultiSelectBar; +// SelectList: typeof SelectList; +// IconLabel: typeof IconLabel; +// Popover: typeof Popover; +// BarPopover: typeof BarPopover; +// IconCombo: typeof IconCombo; +// DynamicDateCombo: typeof DynamicDateCombo; +// CustomTree: typeof CustomTree; +// ButtonTree: typeof ButtonTree; +// IconArrowNode: typeof IconArrowNode; +// MidTreeLeafItem: typeof MidTreeLeafItem; +// FirstTreeLeafItem: typeof FirstTreeLeafItem; +// LastTreeLeafItem: typeof LastTreeLeafItem; +// SmallTextEditor: typeof SmallTextEditor; +// MultifileEditor: typeof MultifileEditor; +// MultiSelectInsertCombo: typeof MultiSelectInsertCombo; +// MultiSelectCombo: typeof MultiSelectCombo; +// SearchEditor: typeof SearchEditor; +// MultiLayerSingleLevelTree: typeof MultiLayerSingleLevelTree; +// SimpleColorChooser: typeof SimpleColorChooser; +// ColorChooser: typeof ColorChooser; +// AbstractAllValueChooser: typeof AbstractAllValueChooser; +// AllValueChooserCombo: typeof AllValueChooserCombo; +// TextAreaEditor: typeof TextAreaEditor; +// SingleSelectItem: typeof SingleSelectItem; +// DynamicDateTimeCombo: typeof DynamicDateTimeCombo; +// MultiTreeCombo: typeof MultiTreeCombo; +// CenterLayout: typeof CenterLayout; +// VirtualGroup: typeof VirtualGroup; +// GridLayout: typeof GridLayout; +// MultiTreePopup: typeof MultiTreePopup; +// SingleSelectRadioItem: typeof SingleSelectRadioItem; +// SingleSelectInsertCombo: typeof SingleSelectInsertCombo; +// SingleSelectCombo: typeof SingleSelectCombo; +// CardLayout: typeof CardLayout; +// DynamicYearMonthCombo: typeof DynamicYearMonthCombo; +// TimeCombo: typeof TimeCombo; +// TextValueDownListCombo: typeof TextValueDownListCombo; +// Switch: typeof Switch; +// HorizontalLayout: typeof HorizontalLayout; +// ShelterEditor: typeof ShelterEditor; +// TextTrigger: typeof TextTrigger; +// SelectTextTrigger: typeof SelectTextTrigger; +// DateInterval: typeof DateInterval; +// DynamicDatePane: typeof DynamicDatePane; +// AllCountPager: typeof AllCountPager; +// DirectionPager: typeof DirectionPager; +// Pager: typeof Pager; +// PopupView: typeof PopupView; +// BubblePopupView: typeof BubblePopupView; +// BubblePopupBarView: typeof BubblePopupBarView; +// TextBubblePopupBarView: typeof TextBubblePopupBarView; +// ArrowTreeGroupNodeCheckbox: typeof ArrowTreeGroupNodeCheckbox; +// NumberInterval: typeof NumberInterval; +// DynamicYearQuarterCombo: typeof DynamicYearQuarterCombo; +// DynamicYearCombo: typeof DynamicYearCombo; +// DynamicYearPopup: typeof DynamicYearPopup; +// IntervalSlider: typeof IntervalSlider; +// MultiSelectInsertList: typeof MultiSelectInsertList; +// YearMonthInterval: typeof YearMonthInterval; +// TextValueCheckCombo: typeof TextValueCheckCombo; +// NumberEditor: typeof NumberEditor; +// Segment: typeof Segment; +// LinearSegment: typeof LinearSegment; +// Img: typeof Img; +// EditorIconCheckCombo: typeof EditorIconCheckCombo; +// IconTextValueCombo: typeof IconTextValueCombo; +// ListView: typeof ListView; +// VirtualList: typeof VirtualList; +// VirtualGroupList: typeof VirtualGroupList; +// FloatCenterLayout: typeof FloatCenterLayout; +// Msg: _msg; +// DynamicYearMonthPopup: typeof DynamicYearMonthPopup; +// DateCalendarPopup: typeof DateCalendarPopup; +// TextNode: typeof TextNode; +// TextValueCheckComboPopup: typeof TextValueCheckComboPopup; +// ImageButton: typeof ImageButton; +// Router: typeof Router; +// history: History, +// DateTimeCombo: typeof DateTimeCombo; +// FloatHorizontalLayout: typeof FloatHorizontalLayout; +// AdaptiveLayout: typeof AdaptiveLayout; +// HexColorChooserPopup: typeof HexColorChooserPopup; +// BlankIconTextItem: typeof BlankIconTextItem; +// TimeInterval: typeof TimeInterval; +// DynamicDateTimePane: typeof DynamicDateTimePane; +// SingleSelectInsertList: typeof SingleSelectInsertList; +// MultiSelectTree: typeof MultiSelectTree; +// HtmlLabel: typeof HtmlLabel; +// TreeValueChooserPane: typeof TreeValueChooserPane; +// TdLayout: typeof TdLayout; +// MultiLayerSelectLevelTree: typeof MultiLayerSelectLevelTree; +// SelectTreeExpander: typeof SelectTreeExpander; +// DownListGroupItem: typeof DownListGroupItem; +// VerticalStickyLayout: typeof VerticalStickyLayout; +// HorizontalStickyLayout: typeof HorizontalStickyLayout; +// TableLayout: typeof TableLayout; +// Workers: typeof Workers; +// } +// +// export default { +// Decorators: decorator, +// Workers, +// }; +// export { +// OB, +// Widget, +// Single, +// BasicButton, +// Checkbox, +// Icon, +// LeftVerticalAdaptLayout, +// LeftRightVerticalAdaptLayout, +// SearchTextValueCombo, +// Input, +// IconTextItem, +// AllValueMultiTextValueCombo, +// IconTextIconItem, +// Layout, +// HorizontalAutoLayout, +// InlineVerticalAdaptLayout, +// RightVerticalAdaptLayout, +// TableAdaptLayout, +// AbsoluteCenterLayout, +// HorizontalAdaptLayout, +// FloatLeftLayout, +// FloatRightLayout, +// HorizontalFillLayout, +// VerticalFillLayout, +// VerticalLayout, +// AbsoluteLayout, +// DefaultLayout, +// HTapeLayout, +// CenterAdaptLayout, +// VTapeLayout, +// VerticalAdaptLayout, +// IconButton, +// Trigger, +// TriggerIconButton, +// Action, +// ActionFactory, +// ShowAction, +// Controller, +// LayerController, +// BroadcastController, +// Behavior, +// BehaviorFactory, +// RedMarkBehavior, +// HighlightBehavior, +// Searcher, +// AbstractLabel, +// Label, +// TextButton, +// DownListCombo, +// DownListPopup, +// IconChangeButton, +// Button, +// TextEditor, +// A, +// Html, +// Switcher, +// Expander, +// BubbleCombo, +// Loader, +// ListPane, +// MultiPopupView, +// MultiSelectBar, +// SelectList, +// TextValueCombo, +// TextValueComboPopup, +// SmallTextValueCombo, +// Editor, +// IconLabel, +// Popover, +// BarPopover, +// Tab, +// AbstractTreeValueChooser, +// AbstractListTreeValueChooser, +// ListTreeValueChooserInsertCombo, +// TreeValueChooserCombo, +// TreeValueChooserInsertCombo, +// MultiLayerSelectTreePopup, +// MultiLayerSingleTreePopup, +// MultiLayerDownListPopup, +// TreeView, +// ListTreeView, +// ListAsyncTree, +// AsyncTree, +// MultiLayerSingleTreeCombo, +// MultiLayerSelectTreeCombo, +// MultiLayerDownListCombo, +// MultiTreeListCombo, +// MultiTreeInsertCombo, +// Combo, +// IconCombo, +// DynamicDateCombo, +// Radio, +// MultiSelectItem, +// CustomTree, +// ButtonGroup, +// ButtonTree, +// NodeButton, +// IconArrowNode, +// MidTreeLeafItem, +// FirstTreeLeafItem, +// LastTreeLeafItem, +// SmallTextEditor, +// MultifileEditor, +// SignEditor, +// StateEditor, +// MultiSelectInsertCombo, +// MultiSelectCombo, +// SearchEditor, +// Text, +// Pane, +// MultiLayerSingleLevelTree, +// ColorChooser, +// SimpleColorChooser, +// AbstractAllValueChooser, +// AllValueChooserCombo, +// TextAreaEditor, +// SingleSelectItem, +// DynamicDateTimeCombo, +// MultiTreeCombo, +// CenterLayout, +// VirtualGroup, +// GridLayout, +// MultiTreePopup, +// SingleSelectRadioItem, +// SingleSelectInsertCombo, +// SingleSelectCombo, +// CardLayout, +// DynamicYearMonthCombo, +// TimeCombo, +// Iframe, +// TextValueDownListCombo, +// Switch, +// HorizontalLayout, +// ShelterEditor, +// Form, +// TextTrigger, +// SelectTextTrigger, +// DateInterval, +// DynamicDatePane, +// AllCountPager, +// Pager, +// PopupView, +// BubblePopupView, +// BubblePopupBarView, +// TextBubblePopupBarView, +// ArrowTreeGroupNodeCheckbox, +// NumberInterval, +// DynamicYearQuarterCombo, +// DynamicYearCombo, +// DynamicYearPopup, +// IntervalSlider, +// MultiSelectInsertList, +// YearMonthInterval, +// TextValueCheckCombo, +// NumberEditor, +// Segment, +// LinearSegment, +// Img, +// EditorIconCheckCombo, +// IconTextValueCombo, +// ListView, +// VirtualList, +// VirtualGroupList, +// FloatCenterLayout, +// DynamicYearMonthPopup, +// DateCalendarPopup, +// Tree, +// Node, +// TextNode, +// TextValueCheckComboPopup, +// ImageButton, +// Router, +// History, +// DateTimeCombo, +// FloatHorizontalLayout, +// AdaptiveLayout, +// HexColorChooserPopup, +// BlankIconTextItem, +// TimeInterval, +// DynamicDateTimePane, +// SingleSelectInsertList, +// MultiSelectTree, +// HtmlLabel, +// TreeValueChooserPane, +// TdLayout, +// MultiLayerSelectLevelTree, +// SelectTreeExpander, +// DirectionPager, +// DownListGroupItem, +// HorizontalStickyLayout, +// VerticalStickyLayout, +// TableLayout, +// }; diff --git a/packages/fineui/typescript/index.ts b/packages/fineui/typescript/index.ts new file mode 100644 index 000000000..3e85c960b --- /dev/null +++ b/packages/fineui/typescript/index.ts @@ -0,0 +1,221 @@ +export * from "./core/foundation"; +export * from "./core/action/action.show"; +export * from "./core/action/action"; +export * from "./core/behavior/behavior"; +export * from "./core/behavior/behavior.highlight"; +export * from "./core/behavior/behavior.redmark"; +export * from "./core/controller/controller.broadcast"; +export * from "./core/controller/controller"; +export * from "./core/controller/controller.layer"; +export * as Decorators from "./core/decorator/decorator"; +export * from "./core/base"; +export * from "./core/i18n"; +export * from "./core/func"; +export * from "./core/inject"; +export * from "./core/ob"; +export * from "./core/plugin"; +export * from "./core/var"; +export * from "./core/widget"; +export * from "./core/utils"; +export * from "./core/platform/web"; +export * from "./core/worker/workers"; +export { Combo } from "./base/combination/combo"; +export { ButtonGroup } from "./base/combination/group.button"; +export { Tab } from "./base/combination/tab"; +export { Pane } from "./base/pane"; +export { BasicButton } from "./base/single/button/button.basic"; +export { NodeButton } from "./base/single/button/button.node"; +export { Button } from "./base/single/button/buttons/button"; +export { TextButton } from "./base/single/button/buttons/button.text"; +export { IconTextItem } from "./base/single/button/listitem/icontextitem"; +export { Editor } from "./base/single/editor/editor"; +export { Iframe } from "./base/single/iframe/iframe"; +export { Checkbox } from "./base/single/input/checkbox"; +export { Input } from "./base/single/input/input"; +export { AbstractLabel } from "./base/single/label/abstract.label"; +export { Label } from "./base/single/label/label"; +export { Single } from "./base/single/single"; +export { Text } from "./base/single/text"; +export { Trigger } from "./base/single/trigger/trigger"; +export { Tip } from "./base/single/tip/tip"; +export { IconChangeButton } from "./case/button/icon/icon.change"; +export { MultiSelectItem } from "./case/button/item.multiselect"; +export { BubbleCombo } from "./case/combo/bubblecombo/combo.bubble"; +export { TextValueCombo } from "./case/combo/combo.textvalue"; +export { TextValueComboPopup } from "./case/combo/popup.textvalue"; +export { SmallTextValueCombo } from "./case/combo/combo.textvaluesmall"; +export { SearchTextValueCombo } from "./case/combo/searchtextvaluecombo/combo.searchtextvalue"; +export { SignEditor } from "./case/editor/editor.sign"; +export { StateEditor } from "./case/editor/editor.state"; +export { AllValueMultiTextValueCombo } from "./component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo"; +export { Form } from "./component/form/form"; +export { AbstractTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser"; +export { AbstractListTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser.list"; +export { Action, ActionFactory } from "./core/action/action"; +export { ShowAction } from "./core/action/action.show"; +export { Behavior, BehaviorFactory } from "./core/behavior/behavior"; +export { HighlightBehavior } from "./core/behavior/behavior.highlight"; +export { RedMarkBehavior } from "./core/behavior/behavior.redmark"; + +export { OB } from "./core/ob"; +export { Widget } from "./core/widget"; +export { Layout } from "./core/wrapper/layout"; +export { AbsoluteLayout } from "./core/wrapper/layout/layout.absolute"; +export { HTapeLayout, VTapeLayout } from "./core/wrapper/layout/layout.tape"; +export { HorizontalFillLayout } from "./core/wrapper/layout/fill/fill.horizontal"; +export { VerticalFillLayout } from "./core/wrapper/layout/fill/fill.vertical"; +export { VerticalLayout } from "./core/wrapper/layout/layout.vertical"; +export { DefaultLayout } from "./core/wrapper/layout/layout.default"; +export { InlineLayout } from "./core/wrapper/layout/layout.inline"; +export { DownListCombo } from "./widget/downlist/combo.downlist"; +export { DownListPopup } from "./widget/downlist/popup.downlist"; +export { EL } from "./base/el"; +export { Icon } from "./base/single/icon/icon"; +export { LeftVerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.leftvertical"; +export { + LeftRightVerticalAdaptLayout, + RightVerticalAdaptLayout +} from "./core/wrapper/layout/adapt/adapt.leftrightvertical"; +export { IconTextIconItem } from "./base/single/button/listitem/icontexticonitem"; +export { HorizontalAutoLayout } from "./core/wrapper/layout/adapt/auto.horizontal"; +export { InlineVerticalAdaptLayout } from "./core/wrapper/layout/adapt/inline.vertical"; +export { TableAdaptLayout } from "./core/wrapper/layout/adapt/adapt.table"; +export { IconButton } from "./base/single/button/buttons/button.icon"; +export { TextEditor } from "./widget/editor/editor.text"; +export { IconLabel } from "./base/single/label/icon.label"; +export { Popover, BarPopover } from "./base/layer/layer.popover"; +export { IconCombo } from "./case/combo/iconcombo/combo.icon"; +export { DynamicDateCombo } from "./widget/dynamicdate/dynamicdate.combo"; +export { CustomTree } from "./base/tree/customtree"; +export { ButtonTree } from "./base/combination/tree.button"; +export { IconArrowNode } from "./case/button/node/node.icon.arrow"; +export { MultiLayerIconArrowNode } from "./case/button/node/node.multilayer.icon.arrow"; +export { MidTreeLeafItem } from "./case/button/treeitem/item.mid.treeleaf"; +export { FirstTreeLeafItem } from "./case/button/treeitem/item.first.treeleaf"; +export { LastTreeLeafItem } from "./case/button/treeitem/item.last.treeleaf"; +export { MultiLayerIconTreeLeafItem } from "./case/button/treeitem/item.multilayer.icon.treeleaf"; +export { SmallTextEditor } from "./widget/editor/editor.text.small"; +export { MultifileEditor } from "./widget/editor/editor.multifile"; +export { AbsoluteCenterLayout } from "./core/wrapper/layout/adapt/absolute.center"; +export { HorizontalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.horizontal"; +export { FloatLeftLayout, FloatRightLayout } from "./core/wrapper/layout/layout.flow"; +export { CenterAdaptLayout } from "./core/wrapper/layout/adapt/adapt.center"; +export { VerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.vertical"; +export { MultiSelectInsertCombo } from "./widget/multiselect/multiselect.insert.combo"; +export { MultiSelectCombo } from "./widget/multiselect/multiselect.combo"; +export { SearchEditor } from "./widget/editor/editor.search"; +export { MultiLayerSingleLevelTree } from "./widget/multilayersingletree/multilayersingletree.leveltree"; +export { SimpleColorChooser } from "./case/colorchooser/colorchooser.simple"; +export { ColorChooser } from "./case/colorchooser/colorchooser"; +export { ColorPicker } from "./case/colorchooser/colorpicker"; +export { A } from "./base/a/a"; +export { Html } from "./base/single/html/html"; +export { Switcher } from "./base/combination/switcher"; +export { Expander } from "./base/combination/expander"; +export { Loader } from "./base/combination/loader"; +export { ListPane } from "./case/layer/pane.list"; +export { MultiPopupView } from "./case/layer/layer.multipopup"; +export { MultiSelectBar } from "./case/toolbar/toolbar.multiselect"; +export { SelectList } from "./case/list/list.select"; +export { AbstractAllValueChooser } from "./component/allvaluechooser/abstract.allvaluechooser"; +export { AllValueChooserCombo } from "./component/allvaluechooser/combo.allvaluechooser"; +export { TextAreaEditor } from "./base/single/editor/editor.textarea"; +export { SingleSelectItem } from "./case/button/item.singleselect"; +export { DynamicDateTimeCombo } from "./widget/dynamicdatetime/dynamicdatetime.combo"; +export { MultiTreeCombo } from "./widget/multitree/multi.tree.combo"; +export { CenterLayout } from "./core/wrapper/layout/middle/middle.center"; +export { VirtualGroup } from "./base/combination/group.virtual"; +export { GridLayout } from "./core/wrapper/layout/layout.grid"; +export { TriggerIconButton } from "./case/button/icon/icon.trigger"; +export { Searcher } from "./base/combination/searcher"; +export { ListTreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.listtreevaluechooser"; +export { TreeValueChooserCombo } from "./component/treevaluechooser/combo.treevaluechooser"; +export { TreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.treevaluechooser.insert"; +export { Radio } from "./base/single/input/radio/radio"; +export { MultiLayerSelectTreePopup } from "./widget/multilayerselecttree/multilayerselecttree.popup"; +export { MultiLayerSingleTreePopup } from "./widget/multilayersingletree/multilayersingletree.popup"; +export { MultiLayerDownListPopup } from "./widget/multilayerdownlist/multilayerdownlist.popup"; +export { TreeView } from "./base/tree/ztree/treeview"; +export { MultiTreePopup } from "./widget/multitree/multi.tree.popup"; +export { SingleSelectRadioItem } from "./case/button/item.singleselect.radio"; +export { SingleSelectInsertCombo } from "./widget/singleselect/singleselect.insert.combo"; +export { SingleSelectCombo } from "./widget/singleselect/singleselect.combo"; +export { CardLayout } from "./core/wrapper/layout/layout.card"; +export { DynamicYearMonthCombo } from "./widget/yearmonth/combo.yearmonth"; +export { TimeCombo } from "./widget/time/time.combo"; +export { ListTreeView } from "./base/tree/ztree/list/listtreeview"; +export { ListAsyncTree } from "./base/tree/ztree/list/listasynctree"; +export { AsyncTree } from "./base/tree/ztree/asynctree"; +export { MultiLayerSingleTreeCombo } from "./widget/multilayersingletree/multilayersingletree.combo"; +export { MultiLayerSelectTreeCombo } from "./widget/multilayerselecttree/multilayerselecttree.combo"; +export { MultiLayerDownListCombo } from "./widget/multilayerdownlist/multilayerdownlist.combo"; +export { MultiTreeListCombo } from "./widget/multitree/multi.tree.list.combo"; +export { MultiTreeInsertCombo } from "./widget/multitree/multi.tree.insert.combo"; +export { TextValueDownListCombo } from "./widget/textvaluedownlistcombo/combo.textvaluedownlist"; +export { Switch } from "./case/button/switch"; +export { HorizontalLayout } from "./core/wrapper/layout/layout.horizontal"; +export { ShelterEditor } from "./case/editor/editor.shelter"; +export { EditorTrigger } from "./case/trigger/trigger.editor"; +export { TextTrigger } from "./case/trigger/trigger.text"; +export { SelectTextTrigger } from "./case/trigger/trigger.text.select"; +export { DateInterval } from "./widget/timeinterval/dateinterval"; +export { DynamicDatePane } from "./widget/datepane/datepane"; +export { AllCountPager } from "./case/pager/pager.all.count"; +export { DirectionPager } from "./case/pager/pager.direction"; +export { PopupView } from "./base/layer/layer.popup"; +export { BubblePopupView, BubblePopupBarView, TextBubblePopupBarView } from "./case/combo/bubblecombo/popup.bubble"; +export { ArrowTreeGroupNodeCheckbox } from "./case/checkbox/check.arrownode"; +export { NumberInterval } from "./widget/numberinterval/numberinterval"; +export { DynamicYearQuarterCombo } from "./widget/yearquarter/combo.yearquarter"; +export { DynamicYearCombo } from "./widget/year/combo.year"; +export { DynamicYearPopup } from "./widget/year/popup.year"; +export { IntervalSlider } from "./widget/intervalslider/intervalslider"; +export { MultiSelectInsertList } from "./widget/multiselectlist/multiselectlist.insert"; +export { YearMonthInterval } from "./widget/yearmonthinterval/yearmonthinterval"; +export { NumberEditor } from "./widget/numbereditor/numbereditor"; +export { TextValueCheckCombo } from "./case/combo/textvaluecheckcombo/combo.textvaluecheck"; +export { Segment } from "./case/segment/segment"; +export { LinearSegment } from "./case/linersegment/linear.segment"; +export { SegmentButton } from "./case/segment/button.segment"; +export { Img } from "./base/single/img/img"; +export { EditorIconCheckCombo } from "./case/combo/editoriconcheckcombo/combo.editiconcheck"; +export { IconTextValueCombo } from "./case/combo/icontextvaluecombo/combo.icontextvalue"; +export { ListView } from "./base/list/listview"; +export { VirtualList } from "./base/list/virtuallist"; +export { VirtualGroupList } from "./base/list/virtualgrouplist"; +export { FloatCenterLayout } from "./core/wrapper/layout/middle/middle.float.center"; +export { Msg } from "./base/foundation/message"; +export { DynamicYearMonthPopup } from "./widget/yearmonth/popup.yearmonth"; +export { Controller } from "./core/controller/controller"; +export { LayerController } from "./core/controller/controller.layer"; +export { DateCalendarPopup } from "./widget/date/calendar/popup.calendar.date"; +export { Tree, Node } from "./core/utils/tree"; +export { TextNode } from "./base/single/button/node/textnode"; +export { TextValueCheckComboPopup } from "./case/combo/textvaluecheckcombo/popup.textvaluecheck"; +export { ImageButton } from "./base/single/button/buttons/button.image"; +export { History, history, Router, RouterWidget, RouterView } from "./router/router"; +export { DateTimeCombo } from "./widget/datetime/datetime.combo"; +export { FloatHorizontalLayout } from "./core/wrapper/layout/adapt/float.horizontal"; +export { AdaptiveLayout } from "./core/wrapper/layout/layout.adaptive"; +export { HexColorChooserPopup } from "./case/colorchooser/colorchooser.popup.hex"; +export { BlankIconTextItem } from "./base/single/button/listitem/blankicontextitem"; +export { Broadcasts, Layers, StyleLoaders, Bubbles, Popovers, Resizers } from "./base/base"; +export { BroadcastController } from "./core/controller/controller.broadcast"; +export { Pager } from "./base/pager/pager"; +export { TimeInterval } from "./widget/timeinterval/timeinterval"; +export { DynamicDateTimePane } from "./widget/datetimepane/datetimepane"; +export { SingleSelectInsertList } from "./widget/singleselect/singleselectlist.insert"; +export { MultiSelectTree } from "./widget/multiselecttree/multiselecttree"; +export { HtmlLabel } from "./base/single/label/html.label"; +export { TreeValueChooserPane } from "./component/treevaluechooser/pane.treevaluechooser"; +export { TdLayout } from "./core/wrapper/layout/layout.td"; +export { MultiLayerSelectLevelTree } from "./widget/multilayerselecttree/multilayerselecttree.leveltree"; +export { SelectTreeExpander } from "./widget/selecttree/selecttree.expander"; +export { DownListGroupItem } from "./widget/downlist/item.downlistgroup"; +export { DownListItem } from "./widget/downlist/item.downlist"; +export { VerticalStickyLayout } from "./core/wrapper/layout/sticky/sticky.vertical"; +export { HorizontalStickyLayout } from "./core/wrapper/layout/sticky/sticky.horizontal"; +export { TableLayout } from "./core/wrapper/layout/layout.table"; +export { Collapse } from "./widget/collapse/collapse"; +export { Workers } from "./core/worker/workers"; +export { Fix } from "./fix/fix"; diff --git a/packages/fineui/typescript/router/router.ts b/packages/fineui/typescript/router/router.ts new file mode 100644 index 000000000..1ac76c266 --- /dev/null +++ b/packages/fineui/typescript/router/router.ts @@ -0,0 +1,251 @@ +import { Widget } from '../core/widget'; + +type Component = any +type Dictionary = { [key: string]: T } +type ErrorHandler = (err: Error) => void + +export type RouterMode = "hash" | "history" | "abstract" +export type RawLocation = string | Location +export type RedirectOption = RawLocation | ((to: Route) => RawLocation) +export type NavigationGuardNext = ( + to?: RawLocation | false | void +) => void + +export type NavigationGuard = ( + to: Route, + from: Route, + next: NavigationGuardNext +) => any + +interface _History { + current: Route; +} + +export declare class VueRouter { + constructor(options?: Obj) + + mode: RouterMode; + currentRoute: Route; + + history: _History; + + beforeEach(guard: NavigationGuard): Function + + beforeResolve(guard: NavigationGuard): Function + + afterEach(hook: (to: Route, from: Route) => any): Function + + push(location: RawLocation): Promise + + replace(location: RawLocation): Promise + + push( + location: RawLocation, + onComplete?: Function, + onAbort?: ErrorHandler + ): void + + replace( + location: RawLocation, + onComplete?: Function, + onAbort?: ErrorHandler + ): void + + go(n: number): void + + back(): void + + forward(): void + + match(raw: RawLocation, current?: Route, redirectedFrom?: Location): Route + + getMatchedComponents(to?: RawLocation | Route): Component[] + + onReady(cb: Function, errorCb?: ErrorHandler): void + + onError(cb: ErrorHandler): void + + addRoutes(routes: RouteConfig[]): void + + addRoute(parent: string, route: RouteConfig): void + addRoute(route: RouteConfig): void + + getRoutes(): RouteRecordPublic[] + + resolve( + to: RawLocation, + current?: Route, + append?: boolean + ): { + location: Location + route: Route + href: string + // backwards compat + normalizedTo: Location + resolved: Route + } + +} + +type RoutePropsFunction = (route: Route) => Object + +interface _RouteConfigBase { + path: string; + name?: string; + children?: RouteConfig[]; + redirect?: RedirectOption; + alias?: string | string[]; + meta?: RouteMeta; + beforeEnter?: NavigationGuard; + caseSensitive?: boolean; + pathToRegexpOptions?: PathToRegexpOptions; +} + +interface RouteConfigSingleView extends _RouteConfigBase { + component?: Component; + props?: boolean | Object | RoutePropsFunction; +} + +interface RouteConfigMultipleViews extends _RouteConfigBase { + components?: Dictionary; + props?: Dictionary; +} + +type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews + +interface PathToRegexpOptions { + sensitive?: boolean; + strict?: boolean; + end?: boolean; +} + +interface _RouteConfigBase { + path: string; + name?: string; + children?: RouteConfig[]; + redirect?: RedirectOption; + alias?: string | string[]; + meta?: RouteMeta; + beforeEnter?: NavigationGuard; + caseSensitive?: boolean; + pathToRegexpOptions?: PathToRegexpOptions; +} + +interface RouteRecord { + path: string; + regex: RegExp; + components: Dictionary; + name?: string; + parent?: RouteRecord; + redirect?: RedirectOption; + matchAs?: string; + meta: RouteMeta; + beforeEnter?: ( + route: Route, + redirect: (location: RawLocation) => void, + next: () => void + ) => any; + props: + | boolean + | Object + | RoutePropsFunction + | Dictionary; +} + +interface RouteRecordPublic { + path: string; + components: Dictionary; + name?: string; + redirect?: RedirectOption; + meta: any; + beforeEnter?: ( + route: Route, + redirect: (location: RawLocation) => void, + next: () => void + ) => any; + props: + | boolean + | Object + | RoutePropsFunction + | Dictionary; +} + + +interface Location { + name?: string; + path?: string; + hash?: string; + query?: Dictionary; + params?: Dictionary; + append?: boolean; + replace?: boolean; +} + +interface Route { + path: string; + name?: string | null; + hash: string; + query: Dictionary; + params: Dictionary; + fullPath: string; + matched: RouteRecord[]; + redirectedFrom?: string; + meta?: RouteMeta; +} + +interface RouteMeta extends Record { +} + + +export declare class Router { + constructor(op: { [key: string]: any }); + + static $router: VueRouter; + + static isSameRoute: (a: Route, b: Route, onlyPath?: boolean) => boolean; + + route(route: string, callback: Function): this; + route(route: string, name: string, callback?: Function): this; + + execute(callback?: Function, args?: any[]): void; + + navigate(fragment: string, options?: { [key: string]: any } | boolean): this; +} + +export declare class History { + atRoot(): boolean; + + getSearch(): string; + + getHash(window?: Window): string; + + getPath(): string; + + getFragment(fragment?: string): string; + + start(op?: { [key: string]: any }): void; + + stop(): void; + + route(route: string, callback: Function): void; + + checkRoute(route: string): { route: string, callback: Function }; + + unRoute(route: string): void; + + checkUrl(e?: Event): void; + + loadUrl(fragment: string): boolean; + + navigate(fragment: string, options?: { [key: string]: any } | boolean): void; +} + +export const history = new History(); + +export declare class RouterWidget { + static xtype: string; +} + +export declare class RouterView extends Widget { + static xtype: string; +} diff --git a/typescript/shims-tsx.ts b/packages/fineui/typescript/shims-tsx.ts similarity index 100% rename from typescript/shims-tsx.ts rename to packages/fineui/typescript/shims-tsx.ts diff --git a/typescript/widget/collapse/collapse.ts b/packages/fineui/typescript/widget/collapse/collapse.ts similarity index 100% rename from typescript/widget/collapse/collapse.ts rename to packages/fineui/typescript/widget/collapse/collapse.ts diff --git a/typescript/widget/date/calendar/popup.calendar.date.ts b/packages/fineui/typescript/widget/date/calendar/popup.calendar.date.ts similarity index 100% rename from typescript/widget/date/calendar/popup.calendar.date.ts rename to packages/fineui/typescript/widget/date/calendar/popup.calendar.date.ts diff --git a/typescript/widget/datepane/datepane.ts b/packages/fineui/typescript/widget/datepane/datepane.ts similarity index 100% rename from typescript/widget/datepane/datepane.ts rename to packages/fineui/typescript/widget/datepane/datepane.ts diff --git a/typescript/widget/datetime/datetime.combo.ts b/packages/fineui/typescript/widget/datetime/datetime.combo.ts similarity index 100% rename from typescript/widget/datetime/datetime.combo.ts rename to packages/fineui/typescript/widget/datetime/datetime.combo.ts diff --git a/typescript/widget/datetimepane/datetimepane.ts b/packages/fineui/typescript/widget/datetimepane/datetimepane.ts similarity index 100% rename from typescript/widget/datetimepane/datetimepane.ts rename to packages/fineui/typescript/widget/datetimepane/datetimepane.ts diff --git a/typescript/widget/downlist/combo.downlist.ts b/packages/fineui/typescript/widget/downlist/combo.downlist.ts similarity index 100% rename from typescript/widget/downlist/combo.downlist.ts rename to packages/fineui/typescript/widget/downlist/combo.downlist.ts diff --git a/packages/fineui/typescript/widget/downlist/item.downlist.ts b/packages/fineui/typescript/widget/downlist/item.downlist.ts new file mode 100644 index 000000000..a051ef50e --- /dev/null +++ b/packages/fineui/typescript/widget/downlist/item.downlist.ts @@ -0,0 +1,10 @@ +import { BasicButton } from "../../base/single/button/button.basic"; + +export declare class DownListItem extends BasicButton { + static xtype: string; + static EVENT_CHANGE: string; + + doRedMark(...args: any[]): void; + + unRedMark(...args: any[]): void; +} diff --git a/typescript/widget/downlist/item.downlistgroup.ts b/packages/fineui/typescript/widget/downlist/item.downlistgroup.ts similarity index 100% rename from typescript/widget/downlist/item.downlistgroup.ts rename to packages/fineui/typescript/widget/downlist/item.downlistgroup.ts diff --git a/typescript/widget/downlist/popup.downlist.ts b/packages/fineui/typescript/widget/downlist/popup.downlist.ts similarity index 100% rename from typescript/widget/downlist/popup.downlist.ts rename to packages/fineui/typescript/widget/downlist/popup.downlist.ts diff --git a/typescript/widget/dynamicdate/dynamicdate.combo.ts b/packages/fineui/typescript/widget/dynamicdate/dynamicdate.combo.ts similarity index 100% rename from typescript/widget/dynamicdate/dynamicdate.combo.ts rename to packages/fineui/typescript/widget/dynamicdate/dynamicdate.combo.ts diff --git a/typescript/widget/dynamicdatetime/dynamicdatetime.combo.ts b/packages/fineui/typescript/widget/dynamicdatetime/dynamicdatetime.combo.ts similarity index 100% rename from typescript/widget/dynamicdatetime/dynamicdatetime.combo.ts rename to packages/fineui/typescript/widget/dynamicdatetime/dynamicdatetime.combo.ts diff --git a/typescript/widget/editor/editor.multifile.ts b/packages/fineui/typescript/widget/editor/editor.multifile.ts similarity index 100% rename from typescript/widget/editor/editor.multifile.ts rename to packages/fineui/typescript/widget/editor/editor.multifile.ts diff --git a/typescript/widget/editor/editor.search.ts b/packages/fineui/typescript/widget/editor/editor.search.ts similarity index 100% rename from typescript/widget/editor/editor.search.ts rename to packages/fineui/typescript/widget/editor/editor.search.ts diff --git a/typescript/widget/editor/editor.text.small.ts b/packages/fineui/typescript/widget/editor/editor.text.small.ts similarity index 100% rename from typescript/widget/editor/editor.text.small.ts rename to packages/fineui/typescript/widget/editor/editor.text.small.ts diff --git a/typescript/widget/editor/editor.text.ts b/packages/fineui/typescript/widget/editor/editor.text.ts similarity index 100% rename from typescript/widget/editor/editor.text.ts rename to packages/fineui/typescript/widget/editor/editor.text.ts diff --git a/typescript/widget/intervalslider/intervalslider.ts b/packages/fineui/typescript/widget/intervalslider/intervalslider.ts similarity index 100% rename from typescript/widget/intervalslider/intervalslider.ts rename to packages/fineui/typescript/widget/intervalslider/intervalslider.ts diff --git a/typescript/widget/multilayerdownlist/multilayerdownlist.combo.ts b/packages/fineui/typescript/widget/multilayerdownlist/multilayerdownlist.combo.ts similarity index 100% rename from typescript/widget/multilayerdownlist/multilayerdownlist.combo.ts rename to packages/fineui/typescript/widget/multilayerdownlist/multilayerdownlist.combo.ts diff --git a/typescript/widget/multilayerdownlist/multilayerdownlist.popup.ts b/packages/fineui/typescript/widget/multilayerdownlist/multilayerdownlist.popup.ts similarity index 100% rename from typescript/widget/multilayerdownlist/multilayerdownlist.popup.ts rename to packages/fineui/typescript/widget/multilayerdownlist/multilayerdownlist.popup.ts diff --git a/typescript/widget/multilayerselecttree/multilayerselecttree.combo.ts b/packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.combo.ts similarity index 100% rename from typescript/widget/multilayerselecttree/multilayerselecttree.combo.ts rename to packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.combo.ts diff --git a/typescript/widget/multilayerselecttree/multilayerselecttree.leveltree.ts b/packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.leveltree.ts similarity index 100% rename from typescript/widget/multilayerselecttree/multilayerselecttree.leveltree.ts rename to packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.leveltree.ts diff --git a/typescript/widget/multilayerselecttree/multilayerselecttree.popup.ts b/packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.popup.ts similarity index 100% rename from typescript/widget/multilayerselecttree/multilayerselecttree.popup.ts rename to packages/fineui/typescript/widget/multilayerselecttree/multilayerselecttree.popup.ts diff --git a/typescript/widget/multilayersingletree/multilayersingletree.combo.ts b/packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.combo.ts similarity index 100% rename from typescript/widget/multilayersingletree/multilayersingletree.combo.ts rename to packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.combo.ts diff --git a/typescript/widget/multilayersingletree/multilayersingletree.leveltree.ts b/packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.leveltree.ts similarity index 100% rename from typescript/widget/multilayersingletree/multilayersingletree.leveltree.ts rename to packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.leveltree.ts diff --git a/typescript/widget/multilayersingletree/multilayersingletree.popup.ts b/packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.popup.ts similarity index 100% rename from typescript/widget/multilayersingletree/multilayersingletree.popup.ts rename to packages/fineui/typescript/widget/multilayersingletree/multilayersingletree.popup.ts diff --git a/packages/fineui/typescript/widget/multiselect/multiselect.combo.ts b/packages/fineui/typescript/widget/multiselect/multiselect.combo.ts new file mode 100644 index 000000000..1fc48731b --- /dev/null +++ b/packages/fineui/typescript/widget/multiselect/multiselect.combo.ts @@ -0,0 +1,66 @@ +import { Single } from "../../base/single/single"; + +export declare class MultiSelectCombo extends Single { + static xtype: string; + static EVENT_BLUR: string; + static EVENT_FOCUS: string; + static EVENT_STOP: string; + static EVENT_SEARCHING: string; + static EVENT_CLICK_ITEM: string; + static EVENT_CONFIRM: string; + static REQ_GET_DATA_LENGTH: 1; + static REQ_GET_ALL_DATA: -1; + static EVENT_AFTER_HIDEVIEW: string; + + props: { + itemsCreator: (options: any, callback: () => any[]) => void; + itemHeight: number; + text: string; + valueFormatter: (v: string) => string; + allowEdit: boolean; + } & Single["props"]; + + _itemsCreator4Trigger(op: any, callback: Function): void; + + _stopEditing(): void; + + _defaultState(): void; + + _assertValue(): void; + + _makeMap(): Obj; + + _joinKeywords(keywords: string[], callback: Function): void; + + _joinAll(res: { + type: number; + value: string[]; + assist: string[]; + }, callback: Function): void; + + _adjust(callback: Function): void; + + _join(): void; + + _setStartValue(value: string): void; + + _populate(...args: any[]): void; + + showView(): void; + + hideView(): void; + + setValue(value: { + type: number; + value: string[]; + assist: string[]; + }): void; + + getValue(): { + type: number; + value: string[]; + assist: string[]; + }; + + populate(...args: any[]): void; +} diff --git a/packages/fineui/typescript/widget/multiselect/multiselect.insert.combo.ts b/packages/fineui/typescript/widget/multiselect/multiselect.insert.combo.ts new file mode 100644 index 000000000..bd0a75ece --- /dev/null +++ b/packages/fineui/typescript/widget/multiselect/multiselect.insert.combo.ts @@ -0,0 +1,71 @@ +import { Single } from "../../base/single/single"; + +export declare class MultiSelectInsertCombo extends Single { + static xtype: string; + static EVENT_FOCUS: string; + static EVENT_BLUR: string; + static EVENT_STOP: string; + static EVENT_SEARCHING: string; + static EVENT_CLICK_ITEM: string; + static EVENT_CONFIRM: string; + static EVENT_ADD_ITEM: string; + static REQ_GET_DATA_LENGTH: 1; + static REQ_GET_ALL_DATA: -1; + static EVENT_AFTER_HIDEVIEW: string; + + props: { + itemsCreator?: Function; + valueFormatter?: Function; + itemHeight?: number; + allowEdit?: boolean; + text?: string; + watermark?: string; + container?: any; + } & Single["props"]; + + _itemsCreator4Trigger(op: any, callback: Function): void; + + _addItem(assertShowValue: () => void, matched: boolean): void; + + _stopEditing(): void; + + _defaultState(): void; + + _assertValue(): void; + + _makeMap(): Obj; + + _joinKeywords(keywords: string[], callback: Function): void; + + _joinAll(res: { + type: string; + value: string[]; + assist: string[]; + }, callback: Function): void; + + _adjust(callback: Function): void; + + _join(): void; + + _setStartValue(value: string): void; + + _populate(...args: any[]): void; + + showView(): void; + + hideView(): void; + + setValue(value?: { + type: number; + value: string[]; + assist: string[]; + }): void; + + getValue(): { + type: number; + value: string[]; + assist: string[]; + }; + + populate(...args: any[]): void; +} diff --git a/typescript/widget/multiselectlist/multiselectlist.insert.ts b/packages/fineui/typescript/widget/multiselectlist/multiselectlist.insert.ts similarity index 100% rename from typescript/widget/multiselectlist/multiselectlist.insert.ts rename to packages/fineui/typescript/widget/multiselectlist/multiselectlist.insert.ts diff --git a/typescript/widget/multiselecttree/multiselecttree.ts b/packages/fineui/typescript/widget/multiselecttree/multiselecttree.ts similarity index 100% rename from typescript/widget/multiselecttree/multiselecttree.ts rename to packages/fineui/typescript/widget/multiselecttree/multiselecttree.ts diff --git a/typescript/widget/multitree/multi.tree.combo.ts b/packages/fineui/typescript/widget/multitree/multi.tree.combo.ts similarity index 100% rename from typescript/widget/multitree/multi.tree.combo.ts rename to packages/fineui/typescript/widget/multitree/multi.tree.combo.ts diff --git a/typescript/widget/multitree/multi.tree.insert.combo.ts b/packages/fineui/typescript/widget/multitree/multi.tree.insert.combo.ts similarity index 100% rename from typescript/widget/multitree/multi.tree.insert.combo.ts rename to packages/fineui/typescript/widget/multitree/multi.tree.insert.combo.ts diff --git a/typescript/widget/multitree/multi.tree.list.combo.ts b/packages/fineui/typescript/widget/multitree/multi.tree.list.combo.ts similarity index 100% rename from typescript/widget/multitree/multi.tree.list.combo.ts rename to packages/fineui/typescript/widget/multitree/multi.tree.list.combo.ts diff --git a/typescript/widget/multitree/multi.tree.popup.ts b/packages/fineui/typescript/widget/multitree/multi.tree.popup.ts similarity index 100% rename from typescript/widget/multitree/multi.tree.popup.ts rename to packages/fineui/typescript/widget/multitree/multi.tree.popup.ts diff --git a/typescript/widget/numbereditor/numbereditor.ts b/packages/fineui/typescript/widget/numbereditor/numbereditor.ts similarity index 100% rename from typescript/widget/numbereditor/numbereditor.ts rename to packages/fineui/typescript/widget/numbereditor/numbereditor.ts diff --git a/typescript/widget/numberinterval/numberinterval.ts b/packages/fineui/typescript/widget/numberinterval/numberinterval.ts similarity index 100% rename from typescript/widget/numberinterval/numberinterval.ts rename to packages/fineui/typescript/widget/numberinterval/numberinterval.ts diff --git a/typescript/widget/selecttree/selecttree.expander.ts b/packages/fineui/typescript/widget/selecttree/selecttree.expander.ts similarity index 100% rename from typescript/widget/selecttree/selecttree.expander.ts rename to packages/fineui/typescript/widget/selecttree/selecttree.expander.ts diff --git a/typescript/widget/singleselect/singleselect.combo.ts b/packages/fineui/typescript/widget/singleselect/singleselect.combo.ts similarity index 100% rename from typescript/widget/singleselect/singleselect.combo.ts rename to packages/fineui/typescript/widget/singleselect/singleselect.combo.ts diff --git a/typescript/widget/singleselect/singleselect.insert.combo.ts b/packages/fineui/typescript/widget/singleselect/singleselect.insert.combo.ts similarity index 100% rename from typescript/widget/singleselect/singleselect.insert.combo.ts rename to packages/fineui/typescript/widget/singleselect/singleselect.insert.combo.ts diff --git a/typescript/widget/singleselect/singleselectlist.insert.ts b/packages/fineui/typescript/widget/singleselect/singleselectlist.insert.ts similarity index 100% rename from typescript/widget/singleselect/singleselectlist.insert.ts rename to packages/fineui/typescript/widget/singleselect/singleselectlist.insert.ts diff --git a/typescript/widget/textvaluedownlistcombo/combo.textvaluedownlist.ts b/packages/fineui/typescript/widget/textvaluedownlistcombo/combo.textvaluedownlist.ts similarity index 100% rename from typescript/widget/textvaluedownlistcombo/combo.textvaluedownlist.ts rename to packages/fineui/typescript/widget/textvaluedownlistcombo/combo.textvaluedownlist.ts diff --git a/typescript/widget/time/time.combo.ts b/packages/fineui/typescript/widget/time/time.combo.ts similarity index 100% rename from typescript/widget/time/time.combo.ts rename to packages/fineui/typescript/widget/time/time.combo.ts diff --git a/typescript/widget/timeinterval/dateinterval.ts b/packages/fineui/typescript/widget/timeinterval/dateinterval.ts similarity index 100% rename from typescript/widget/timeinterval/dateinterval.ts rename to packages/fineui/typescript/widget/timeinterval/dateinterval.ts diff --git a/typescript/widget/timeinterval/timeinterval.ts b/packages/fineui/typescript/widget/timeinterval/timeinterval.ts similarity index 100% rename from typescript/widget/timeinterval/timeinterval.ts rename to packages/fineui/typescript/widget/timeinterval/timeinterval.ts diff --git a/typescript/widget/year/combo.year.ts b/packages/fineui/typescript/widget/year/combo.year.ts similarity index 100% rename from typescript/widget/year/combo.year.ts rename to packages/fineui/typescript/widget/year/combo.year.ts diff --git a/typescript/widget/year/popup.year.ts b/packages/fineui/typescript/widget/year/popup.year.ts similarity index 100% rename from typescript/widget/year/popup.year.ts rename to packages/fineui/typescript/widget/year/popup.year.ts diff --git a/typescript/widget/yearmonth/combo.yearmonth.ts b/packages/fineui/typescript/widget/yearmonth/combo.yearmonth.ts similarity index 100% rename from typescript/widget/yearmonth/combo.yearmonth.ts rename to packages/fineui/typescript/widget/yearmonth/combo.yearmonth.ts diff --git a/typescript/widget/yearmonth/popup.yearmonth.ts b/packages/fineui/typescript/widget/yearmonth/popup.yearmonth.ts similarity index 100% rename from typescript/widget/yearmonth/popup.yearmonth.ts rename to packages/fineui/typescript/widget/yearmonth/popup.yearmonth.ts diff --git a/typescript/widget/yearmonthinterval/yearmonthinterval.ts b/packages/fineui/typescript/widget/yearmonthinterval/yearmonthinterval.ts similarity index 100% rename from typescript/widget/yearmonthinterval/yearmonthinterval.ts rename to packages/fineui/typescript/widget/yearmonthinterval/yearmonthinterval.ts diff --git a/typescript/widget/yearquarter/combo.yearquarter.ts b/packages/fineui/typescript/widget/yearquarter/combo.yearquarter.ts similarity index 100% rename from typescript/widget/yearquarter/combo.yearquarter.ts rename to packages/fineui/typescript/widget/yearquarter/combo.yearquarter.ts diff --git a/ui/less/app.less b/packages/fineui/ui/less/app.less similarity index 100% rename from ui/less/app.less rename to packages/fineui/ui/less/app.less diff --git a/ui/less/background.less b/packages/fineui/ui/less/background.less similarity index 100% rename from ui/less/background.less rename to packages/fineui/ui/less/background.less diff --git a/private/less/font.less b/packages/fineui/ui/less/font.less similarity index 100% rename from private/less/font.less rename to packages/fineui/ui/less/font.less diff --git a/private/less/icon.less b/packages/fineui/ui/less/icon.less similarity index 100% rename from private/less/icon.less rename to packages/fineui/ui/less/icon.less diff --git a/ui/less/var.less b/packages/fineui/ui/less/var.less similarity index 100% rename from ui/less/var.less rename to packages/fineui/ui/less/var.less diff --git a/packages/fineui/webpack/attachments.js b/packages/fineui/webpack/attachments.js new file mode 100644 index 000000000..3adb47d20 --- /dev/null +++ b/packages/fineui/webpack/attachments.js @@ -0,0 +1,47 @@ +const { sync, uniq } = require("./utils"); + +const jqueryPolyfill = "./src/core/platform/web/jquery/jquery.polyfill.js"; +const configJS = "./src/core/platform/web/config.js"; + +const runtimePolyfill = ["core-js/stable"]; + +const basicAttachmentMap = { + polyfill: sync(["src/polyfill/**/*.js"]).concat(runtimePolyfill), + resource: sync(["src/less/resource/**/*.less"]), + font: sync(["public/less/font.less"]), + ts: ["./typescript/bundle.ts"], + ui: sync(["ui/less/app.less", "ui/less/**/*.less", "ui/js/**/*.js"]), + less: sync([ + "src/less/core/**/*.less", + "src/less/theme/**/*.less", + "src/less/base/**/*.less", + "src/less/case/**/*.less", + "src/less/widget/**/*.less", + "src/less/component/**/*.less" + ]), + js_bundle: sync(["src/bundle.js"]), + js_worker: sync(["src/worker.js"]) +}; + +const bundleCss = [].concat(basicAttachmentMap.less, sync(["public/less/app.less", "public/less/**/*.less"])); + +const fineui = [].concat( + bundleCss, + basicAttachmentMap.polyfill, + basicAttachmentMap.js_bundle, + basicAttachmentMap.ui, + basicAttachmentMap.ts, + configJS +); + +const fineuiForWorker = [].concat( + basicAttachmentMap.js_worker, + basicAttachmentMap.ui, + basicAttachmentMap.ts +); + +module.exports = { + fineui: uniq(fineui), + fineuiForWorker: uniq(fineuiForWorker), + bundleCss, +}; diff --git a/webpack/dirs.js b/packages/fineui/webpack/dirs.js similarity index 100% rename from webpack/dirs.js rename to packages/fineui/webpack/dirs.js diff --git a/webpack/utils.js b/packages/fineui/webpack/utils.js similarity index 100% rename from webpack/utils.js rename to packages/fineui/webpack/utils.js diff --git a/packages/fineui/webpack/webpack.common.js b/packages/fineui/webpack/webpack.common.js new file mode 100644 index 000000000..dd5582d7b --- /dev/null +++ b/packages/fineui/webpack/webpack.common.js @@ -0,0 +1,129 @@ +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const autoprefixer = require("autoprefixer"); +const path = require("path"); +const fs = require("fs"); +const dirs = require("./dirs"); +const attachments = require("./attachments"); +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); +const childProcess = require("child_process"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); +const webpack = require("webpack"); +const TerserPlugin = require("terser-webpack-plugin"); + +let lessVariables = {}; +if (process.env.LESS_CONFIG_PATH) { + const lessConfigPath = path.isAbsolute(process.env.LESS_CONFIG_PATH) + ? process.env.LESS_CONFIG_PATH + : path.resolve(__dirname, "../lessconfig", process.env.LESS_CONFIG_PATH); + lessVariables = fs.existsSync(lessConfigPath) ? require(lessConfigPath) || {} : {}; +} + +function git(command) { + return childProcess.execSync(`git ${command}`).toString().trim(); +} + +module.exports = { + entry: { + fineui: attachments.fineui, + }, + externals: { + lodash: "_", + underscore: "_", + }, + resolve: { + mainFields: ["module", "main"], + extensions: [".js", ".ts"], + alias: { + "@": path.resolve(__dirname, "../src"), + }, + }, + + module: { + rules: [ + { + test: /\.(jsx?|tsx?)$/i, + include: [ + dirs.NODE_MODULES, + dirs.PRIVATE, + dirs.PUBLIC, + dirs.MOBILE, + dirs.DEMO, + dirs.I18N, + dirs.UI, + dirs.FIX, + dirs.TYPESCRIPT, + dirs.SRC, + ], + exclude: /node_modules(\/|\\)core-js/, + use: [ + { + loader: "babel-loader", + options: { + configFile: dirs.BABEL_CONFIG, + }, + }, + ], + }, + { + test: /\.(css|less)$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + url: false, + }, + }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: [autoprefixer], + }, + }, + }, + { + loader: "less-loader", + options: { + lessOptions: { + relativeUrls: false, + modifyVars: lessVariables, + }, + }, + }, + ], + }, + ], + }, + + plugins: [ + new MiniCssExtractPlugin({ + filename: "[name].css", + }), + new ForkTsCheckerWebpackPlugin({}), + ], + + optimization: { + usedExports: false, + minimize: true, + minimizer: [ + new TerserPlugin({ + include: /\.min/, + parallel: true, + terserOptions: { + format: { + comments: /\/*! time:(.*?); branch:(.*?); commit:(.*?)/, + }, + }, + }), + new webpack.BannerPlugin({ + banner: `time: ${new Date().toLocaleString("en-US")}; branch: ${git( + 'name-rev --name-only HEAD' + )}; commit: ${git( + 'rev-parse HEAD' + )}` + }), + new CssMinimizerPlugin(), + ], + }, +}; diff --git a/packages/fineui/webpack/webpack.css.js b/packages/fineui/webpack/webpack.css.js new file mode 100644 index 000000000..428c70865 --- /dev/null +++ b/packages/fineui/webpack/webpack.css.js @@ -0,0 +1,11 @@ +const { merge } = require("webpack-merge"); +const prod = require("./webpack.prod.js"); +const attachments = require("./attachments"); +prod.entry = {}; + +module.exports = merge(prod, { + mode: "production", + entry: { + [`${process.env.LESS_FILE_NAME}.min`]: attachments.bundleCss, + }, +}); diff --git a/packages/fineui/webpack/webpack.dev.js b/packages/fineui/webpack/webpack.dev.js new file mode 100644 index 000000000..e858e890b --- /dev/null +++ b/packages/fineui/webpack/webpack.dev.js @@ -0,0 +1,20 @@ +const common = require("./webpack.common.js"); +const { merge } = require("webpack-merge"); +const dirs = require("./dirs"); + + +module.exports = merge(common, { + mode: "development", + + devtool: "inline-source-map", + + output: { + path: dirs.DEST, + filename: "[name].js", + }, + + devServer: { + port: 9001, + // liveReload: true, + } +}); diff --git a/packages/fineui/webpack/webpack.prod.js b/packages/fineui/webpack/webpack.prod.js new file mode 100644 index 000000000..d1d7b9ffc --- /dev/null +++ b/packages/fineui/webpack/webpack.prod.js @@ -0,0 +1,24 @@ +const common = require("./webpack.common.js"); +const { merge } = require("webpack-merge"); +const dirs = require("./dirs"); +const attachments = require("./attachments"); + +module.exports = merge(common, { + mode: "production", + target: ["web", "es5"], + + entry: { + "fineui.min": attachments.fineui, + "fineui.worker.min": attachments.fineuiForWorker, + "fineui.worker": attachments.fineuiForWorker, + "fineui_without_jquery_polyfill.min":attachments.fineuiForWorker, + }, + + output: { + path: dirs.DEST, + filename: "[name].js", + publicPath: "" + }, + + devtool: "hidden-source-map" +}); diff --git a/plugins/webpack-fui-worker-plugin/constants.js b/plugins/webpack-fui-worker-plugin/constants.js deleted file mode 100644 index 7b80ac3dc..000000000 --- a/plugins/webpack-fui-worker-plugin/constants.js +++ /dev/null @@ -1,9 +0,0 @@ -const WorkerPluginName = 'FuiWorkerPlugin'; -const WorkerLoaderName = 'FuiWorkerWorkerLoader'; -const FileNamePrefix = 'worker-'; - -module.exports = { - WorkerPluginName, - WorkerLoaderName, - FileNamePrefix, -}; diff --git a/plugins/webpack-fui-worker-plugin/empty.js b/plugins/webpack-fui-worker-plugin/empty.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/plugins/webpack-fui-worker-plugin/index.js b/plugins/webpack-fui-worker-plugin/index.js deleted file mode 100644 index 2fa9b3ed0..000000000 --- a/plugins/webpack-fui-worker-plugin/index.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * worker-plugin - */ - -const path = require('path'); -const webpack = require('webpack'); -const { WorkerPluginName } = require('./constants'); -const ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers'); - -class FuiWorkerPlugin { - constructor(options = {}) { - this.options = options; - } - - apply(compiler) { - // 为主线程构建添加 __WORKER__ 环境变量, 构建中区分不同线程源码, 实现代码拆减 - compiler.hooks.afterPlugins.tap(WorkerPluginName, compiler => { - new webpack.DefinePlugin({ - // __WORKER__ 表示当前所在线程是否是 worker 线程 - // 主线程构建中为 false - __WORKER__: false, - }).apply(compiler); - }); - - // 添加自定义的worker entry-loader - compiler.hooks.afterResolvers.tap(WorkerPluginName, compiler => { - /** - * https://webpack.js.org/configuration/resolve/#resolveloader - * 使用 resolveloader 添加自定义的 worker loader - */ - if (!compiler.options.resolveLoader) { - compiler.options.resolveLoader = { - alias: {}, - }; - } - if (!compiler.options.resolveLoader.alias) { - compiler.options.resolveLoader.alias = {}; - } - - // 动态添加 worker 的 worker-loader, 命名为 "fui-worker" - compiler.options.resolveLoader.alias['fui-worker'] = path.resolve(__dirname, './worker-loader.js'); - }); - - // 将FuiWorkerPlugin的参数传递给fui-worker loader - compiler.hooks.compilation.tap(WorkerPluginName, compilation => { - compilation.hooks.normalModuleLoader.tap(WorkerPluginName, (context, module) => { - // 仅提供给fui-worker - const fuiLoader = module.loaders.find(loader => loader.loader.indexOf('fui-worker') !== -1); - - if (fuiLoader) { - const resource = module.resource; - - if (!resource) return; - - // fui-worker通过options读取 - context.options = context.options || {}; - - const index = resource.indexOf('?'); - - if (ModuleFilenameHelpers.matchObject( - this.options, - index < 0 ? resource : resource.substr(0, index) - )) { - for (const key of Object.keys(this.options)) { - // 忽略关键属性 - if (key === "include" || key === "exclude" || key === "test") { - continue; - } - - context.options[key] = this.options[key]; - } - } - } - }) - }) - } -} - -module.exports = FuiWorkerPlugin; diff --git a/plugins/webpack-fui-worker-plugin/worker-loader.js b/plugins/webpack-fui-worker-plugin/worker-loader.js deleted file mode 100644 index d07756e01..000000000 --- a/plugins/webpack-fui-worker-plugin/worker-loader.js +++ /dev/null @@ -1,135 +0,0 @@ -/* - * fui-worker worker-loader - */ - -const webpack = require('webpack'); -const loaderUtils = require('loader-utils'); -const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); -const { WorkerLoaderName, FileNamePrefix } = require('./constants'); -const { resolve } = require('path'); - -// 正常 loader 处理逻辑 -function loader() { - const callback = this.async(); - this.cacheable(false); - - // 过滤掉当前的 worker-loader, 保留 worker 侧构建需要的其他 loader(babel-loader/ts-loader 等) - const otherLoaders = this.loaders.filter((loader, index) => { - if (index === this.loaderIndex) { - return false; - } - - return true; - }); - /** - * 拼接构建需要的 loader 字符串, 用于指定 childCompiler 的构建 loader - * 比如: /path/to/babel-loader/lib/index.js!/path/to/ts-loader/index.js! - */ - const loaderPath = otherLoaders.reduce((pre, loader) => `${pre}${loader.path}!`, ''); - - /** - * worker 独立构建的 entry - * 构建 loader + worker 源码入口文件路径 - * - * https://webpack.js.org/concepts/loaders/#inline - * `!!` 实现在 childCompiler 中忽略其他所有 loader, 只保留主构建的 loader - * 不然 worker 入口在 childCompiler 中会继续由 worker-loader 处理, 造成死循环 - */ - const workerEntry = `!!${loaderPath}${this.resourcePath}`; - - // 把资源纳入构建流程的依赖, 实现 dev 模式下的 watch - this.addDependency(workerEntry); - - // 生成的 service 独立 bundle 名称 - const entryFileName = `${FileNamePrefix}index`; - - // 获取传递给 loader 的 options - const options = Object.assign(loaderUtils.getOptions(this) || {}, this.options); - - // 创建 childCompiler, 用于实现 worker 构建为独立 js 资源 - const childCompiler = this._compilation.createChildCompiler(WorkerLoaderName, { - globalObject: 'this', - }); - childCompiler.context = this._compiler.context; - - // 指定独立构建的 entry 和生成 js 资源名称 - new SingleEntryPlugin(this.context, workerEntry, entryFileName).apply(childCompiler); - - // 设置 worker 侧的环境变量 - new webpack.DefinePlugin({ - __WORKER__: true, - }).apply(childCompiler); - - // 添加 window 全局对象, 映射为 worker 线程全局对象 self - // 如果在 worker 源码中添加, 可能没有前置到所有引用模块前 - new webpack.BannerPlugin({ - banner: 'self.window = self;', - raw: true, - entryOnly: true, - }).apply(childCompiler); - - // 去除源码中的less css引用 - const regExp = /\.(css|less)$/; - - new webpack.NormalModuleReplacementPlugin( - regExp, - result => { - if (regExp.test(result.request)) { - result.request = resolve(__dirname, './empty.js'); - } - - if (regExp.test(result.resource)) { - result.resource = resolve(__dirname, './empty.js'); - } - }, - ).apply(childCompiler); - - const subCache = `subcache ${__dirname} ${workerEntry}`; - childCompiler.hooks.compilation.tap(WorkerLoaderName, compilation => { - if (compilation.cache) { - if (!compilation.cache[subCache]) compilation.cache[subCache] = {}; - compilation.cache = compilation.cache[subCache]; - } - }); - - childCompiler.runAsChild((error, entries, compilation) => { - if (!error && compilation.errors && compilation.errors.length) { - // eslint-disable-next-line no-param-reassign - error = compilation.errors[0]; - } - - // compatible with Array (v4) and Set (v5) prototypes - const entry = entries && entries[0] && entries[0].files.values().next().value; - if (!error && !entry) { - // eslint-disable-next-line no-param-reassign - error = Error(`${WorkerLoaderName}, no entry for ${workerEntry}`); - } - - if (error) { - return callback(error); - } - - // 支持blob url形式 - return options.inline - ? callback( - null, - // 插入代码的转译和压缩由主构建配置的 babel/ts loader 处理, 不需要 worker-worker 来处理 - // 添加 @ts-nocheck 避免 ts-check 报错 - // 修复export const 下 const不会被转译的问题 - // safari浏览器下blob需指定type - `// @ts-nocheck - export default window.URL.createObjectURL(new Blob([${JSON.stringify(compilation.assets[entry].source())}], { type: 'text/javascript' })); - ` - ) - : callback( - null, - `// @ts-nocheck - export default __webpack_public_path__ + ${JSON.stringify(entry)}; - ` - ) - }); - - return; -} - -module.exports = loader; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..f6bd75b75 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5045 @@ +lockfileVersion: 5.4 + +importers: + + .: + specifiers: + '@babel/cli': ^7.21.0 + '@babel/core': ^7.21.0 + '@babel/runtime': ^7.21.0 + '@fui/babel-preset-fineui': ^3.0.1 + babel-loader: ^9.1.2 + babel-plugin-module-resolver: ^5.0.0 + css-loader: ^6.7.3 + html-webpack-plugin: ^5.5.0 + less: ^4.1.3 + less-loader: ^11.1.0 + npm-run-all: ^4.1.5 + style-loader: ^3.3.1 + typescript: ^4.9.5 + webpack: ^5.75.0 + webpack-bundle-analyzer: ^4.8.0 + webpack-cli: ^5.0.1 + webpack-dev-server: ^4.11.1 + devDependencies: + '@babel/cli': 7.21.0_@babel+core@7.21.0 + '@babel/core': 7.21.0 + '@babel/runtime': 7.21.0 + '@fui/babel-preset-fineui': 3.0.1_wrscgf77uttxqznv3myecs4fba + babel-loader: 9.1.2_tkx7iv5lytdmlhrwm4n6r336ei + babel-plugin-module-resolver: 5.0.0 + css-loader: 6.7.3_webpack@5.76.0 + html-webpack-plugin: 5.5.0_webpack@5.76.0 + less: 4.1.3 + less-loader: 11.1.0_less@4.1.3+webpack@5.76.0 + npm-run-all: 4.1.5 + style-loader: 3.3.1_webpack@5.76.0 + typescript: 4.9.5 + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-bundle-analyzer: 4.8.0 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + webpack-dev-server: 4.11.1_66fuqojgvlon52mqukkfkspvqe + + packages/demo: + specifiers: + '@fui/core': workspace:^2.0.20230208163847 + dependencies: + '@fui/core': link:../fineui + + packages/fineui: + specifiers: + '@babel/core': ^7.21.0 + '@juggle/resize-observer': ^3.4.0 + '@popperjs/core': 2.11.6 + '@types/yargs': 17.0.13 + jquery: 3.6.3 + yargs: 17.6.2 + dependencies: + '@babel/core': 7.21.0 + '@juggle/resize-observer': 3.4.0 + '@popperjs/core': 2.11.6 + '@types/yargs': 17.0.13 + jquery: 3.6.3 + yargs: 17.6.2 + +packages: + + /@ampproject/remapping/2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.17 + + /@babel/cli/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-xi7CxyS8XjSyiwUGCfwf+brtJxjW1/ZTcBUkP10xawIEXLX5HzLn+3aXkgxozcP2UhRhtKTmQurw9Uaes7jZrA==} + engines: {node: '>=6.9.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@jridgewell/trace-mapping': 0.3.17 + commander: 4.1.1 + convert-source-map: 1.9.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + make-dir: 2.1.0 + slash: 2.0.0 + optionalDependencies: + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.5.3 + dev: true + + /@babel/code-frame/7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + + /@babel/compat-data/7.21.0: + resolution: {integrity: sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==} + engines: {node: '>=6.9.0'} + + /@babel/core/7.21.0: + resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.21.1 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helpers': 7.21.0 + '@babel/parser': 7.21.2 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.2 + '@babel/types': 7.21.2 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + + /@babel/generator/7.21.1: + resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.17 + jsesc: 2.5.2 + + /@babel/helper-annotate-as-pure/7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: + resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-explode-assignable-expression': 7.18.6 + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.21.0 + '@babel/core': 7.21.0 + '@babel/helper-validator-option': 7.21.0 + browserslist: 4.21.5 + lru-cache: 5.1.1 + semver: 6.3.0 + + /@babel/helper-create-class-features-plugin/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-member-expression-to-functions': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/helper-split-export-declaration': 7.18.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.3.1 + dev: true + + /@babel/helper-define-map/7.18.6: + resolution: {integrity: sha512-XSOjXUDG7KODvtURN1p29hGHa4RFgqBQELuBowUOBt3alf2Ny/oNFJygS4yCXwM0vMoqLDjE1O7wSmocUmQ3Kg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.21.0 + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.21.0: + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + + /@babel/helper-explode-assignable-expression/7.18.6: + resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-function-name/7.21.0: + resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/types': 7.21.2 + + /@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + + /@babel/helper-member-expression-to-functions/7.21.0: + resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-module-imports/7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + + /@babel/helper-module-transforms/7.21.2: + resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.2 + '@babel/types': 7.21.2 + transitivePeerDependencies: + - supports-color + + /@babel/helper-optimise-call-expression/7.18.6: + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-plugin-utils/7.20.2: + resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-wrap-function': 7.20.5 + '@babel/types': 7.21.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers/7.20.7: + resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-member-expression-to-functions': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.2 + '@babel/types': 7.21.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + + /@babel/helper-skip-transparent-expression-wrappers/7.20.0: + resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + dev: true + + /@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.2 + + /@babel/helper-string-parser/7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-option/7.21.0: + resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} + engines: {node: '>=6.9.0'} + + /@babel/helper-wrap-function/7.20.5: + resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.21.0 + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.2 + '@babel/types': 7.21.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers/7.21.0: + resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/traverse': 7.21.2 + '@babel/types': 7.21.2 + transitivePeerDependencies: + - supports-color + + /@babel/highlight/7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + + /@babel/parser/7.21.2: + resolution: {integrity: sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.21.2 + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-proposal-optional-chaining': 7.21.0_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-async-generator-functions/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties/7.5.0_@babel+core@7.21.0: + resolution: {integrity: sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-static-block/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-decorators/7.4.4_@babel+core@7.21.0: + resolution: {integrity: sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-decorators': 7.21.0_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-logical-assignment-operators/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-object-rest-spread/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.0 + '@babel/core': 7.21.0 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-optional-chaining/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.0 + dev: true + + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-private-property-in-object/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-regexp-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.21.0: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.21.0: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.21.0: + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-decorators/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.21.0: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.21.0: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.21.0: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.21.0: + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.21.0: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.21.0: + resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-arrow-functions/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-async-to-generator/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-block-scoping/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-classes/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-classes/7.5.5_@babel+core@7.21.0: + resolution: {integrity: sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-define-map': 7.18.6 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/template': 7.20.7 + dev: true + + /@babel/plugin-transform-destructuring/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-regexp-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-for-of/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-modules-amd/7.20.11_@babel+core@7.21.0: + resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs/7.21.2_@babel+core@7.21.0: + resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs/7.6.0_@babel+core@7.21.0: + resolution: {integrity: sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 + babel-plugin-dynamic-import-node: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs/7.20.11_@babel+core@7.21.0: + resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-identifier': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.21.0: + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-regexp-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-proto-to-assign/7.5.5_@babel+core@7.21.0: + resolution: {integrity: sha512-1vlFiFiIfKXBVm2SJtPr65x7NUAv4Sa3qhBbH4TnSXaUTDQnOSf+W8vNq3BNliaI28kwT8aD3rMTTsEryJpDZw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + lodash: 4.17.21 + dev: true + + /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/plugin-transform-react-jsx': 7.21.0_@babel+core@7.21.0 + dev: true + + /@babel/plugin-transform-react-jsx/7.13.12_@babel+core@7.21.0: + resolution: {integrity: sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.21.0 + '@babel/types': 7.21.2 + dev: true + + /@babel/plugin-transform-react-jsx/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.21.0 + '@babel/types': 7.21.2 + dev: true + + /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.21.0: + resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-runtime/7.19.6_@babel+core@7.21.0: + resolution: {integrity: sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.21.0 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.21.0 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.21.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-spread/7.20.7_@babel+core@7.21.0: + resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + dev: true + + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.21.0: + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-typescript/7.21.0_@babel+core@7.21.0: + resolution: {integrity: sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-class-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.21.0: + resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.21.0: + resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-create-regexp-features-plugin': 7.21.0_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/preset-env/7.16.11_@babel+core@7.21.0: + resolution: {integrity: sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.0 + '@babel/core': 7.21.0 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-proposal-async-generator-functions': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-class-static-block': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-object-rest-spread': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-optional-chaining': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-proposal-private-property-in-object': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.0 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.21.0 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.21.0 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.0 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.0 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.0 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.21.0 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.21.0 + '@babel/plugin-transform-arrow-functions': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-async-to-generator': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-block-scoping': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-transform-classes': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-transform-computed-properties': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-destructuring': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-for-of': 7.21.0_@babel+core@7.21.0 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-modules-amd': 7.20.11_@babel+core@7.21.0 + '@babel/plugin-transform-modules-commonjs': 7.21.2_@babel+core@7.21.0 + '@babel/plugin-transform-modules-systemjs': 7.20.11_@babel+core@7.21.0 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.21.0 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.21.0 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-spread': 7.20.7_@babel+core@7.21.0 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.21.0 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.21.0 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.21.0 + '@babel/preset-modules': 0.1.5_@babel+core@7.21.0 + '@babel/types': 7.21.2 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.21.0 + babel-plugin-polyfill-corejs3: 0.5.3_@babel+core@7.21.0 + babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.21.0 + core-js-compat: 3.29.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules/0.1.5_@babel+core@7.21.0: + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.21.0 + '@babel/types': 7.21.2 + esutils: 2.0.3 + dev: true + + /@babel/preset-react/7.13.13_@babel+core@7.21.0: + resolution: {integrity: sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-react-jsx': 7.13.12_@babel+core@7.21.0 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.21.0 + '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.21.0 + dev: true + + /@babel/preset-typescript/7.3.3_@babel+core@7.21.0: + resolution: {integrity: sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-transform-typescript': 7.21.0_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/regjsgen/0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime/7.21.0: + resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + dev: true + + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.21.2 + '@babel/types': 7.21.2 + + /@babel/traverse/7.21.2: + resolution: {integrity: sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.21.1 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.21.2 + '@babel/types': 7.21.2 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/types/7.21.2: + resolution: {integrity: sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@discoveryjs/json-ext/0.5.7: + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + dev: true + + /@fui/babel-preset-fineui/3.0.1_wrscgf77uttxqznv3myecs4fba: + resolution: {integrity: sha512-gEb/w9UhdDQdIJ5WYPuekj4D/a1Y4bqD0XEMpfJEfceeOqXvzFaXL+GAa7N9YFkVz1QWq5eURxTRw/QA8M9ICQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime': ^7.20.1 + dependencies: + '@babel/core': 7.21.0 + '@babel/plugin-proposal-class-properties': 7.5.0_@babel+core@7.21.0 + '@babel/plugin-proposal-decorators': 7.4.4_@babel+core@7.21.0 + '@babel/plugin-transform-classes': 7.5.5_@babel+core@7.21.0 + '@babel/plugin-transform-modules-commonjs': 7.6.0_@babel+core@7.21.0 + '@babel/plugin-transform-proto-to-assign': 7.5.5_@babel+core@7.21.0 + '@babel/plugin-transform-react-jsx': 7.13.12_@babel+core@7.21.0 + '@babel/plugin-transform-runtime': 7.19.6_@babel+core@7.21.0 + '@babel/preset-env': 7.16.11_@babel+core@7.21.0 + '@babel/preset-react': 7.13.13_@babel+core@7.21.0 + '@babel/preset-typescript': 7.3.3_@babel+core@7.21.0 + '@babel/runtime': 7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + + /@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.17 + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + /@jridgewell/trace-mapping/0.3.17: + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + + /@juggle/resize-observer/3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + dev: false + + /@leichtgewicht/ip-codec/2.0.4: + resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} + dev: true + + /@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: + resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + requiresBuild: true + dev: true + optional: true + + /@polka/url/1.0.0-next.21: + resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} + dev: true + + /@popperjs/core/2.11.6: + resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} + dev: false + + /@types/body-parser/1.19.2: + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + dependencies: + '@types/connect': 3.4.35 + '@types/node': 18.15.0 + dev: true + + /@types/bonjour/3.5.10: + resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} + dependencies: + '@types/node': 18.15.0 + dev: true + + /@types/connect-history-api-fallback/1.3.5: + resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} + dependencies: + '@types/express-serve-static-core': 4.17.33 + '@types/node': 18.15.0 + dev: true + + /@types/connect/3.4.35: + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + dependencies: + '@types/node': 18.15.0 + dev: true + + /@types/eslint-scope/3.7.4: + resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} + dependencies: + '@types/eslint': 8.21.1 + '@types/estree': 0.0.51 + dev: true + + /@types/eslint/8.21.1: + resolution: {integrity: sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ==} + dependencies: + '@types/estree': 0.0.51 + '@types/json-schema': 7.0.11 + dev: true + + /@types/estree/0.0.51: + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + dev: true + + /@types/express-serve-static-core/4.17.33: + resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} + dependencies: + '@types/node': 18.15.0 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 + dev: true + + /@types/express/4.17.17: + resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + dependencies: + '@types/body-parser': 1.19.2 + '@types/express-serve-static-core': 4.17.33 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.1 + dev: true + + /@types/html-minifier-terser/6.1.0: + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + dev: true + + /@types/http-proxy/1.17.10: + resolution: {integrity: sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==} + dependencies: + '@types/node': 18.15.0 + dev: true + + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/mime/3.0.1: + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + dev: true + + /@types/node/18.15.0: + resolution: {integrity: sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==} + dev: true + + /@types/qs/6.9.7: + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: true + + /@types/range-parser/1.2.4: + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + dev: true + + /@types/retry/0.12.0: + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + dev: true + + /@types/serve-index/1.9.1: + resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} + dependencies: + '@types/express': 4.17.17 + dev: true + + /@types/serve-static/1.15.1: + resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} + dependencies: + '@types/mime': 3.0.1 + '@types/node': 18.15.0 + dev: true + + /@types/sockjs/0.3.33: + resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} + dependencies: + '@types/node': 18.15.0 + dev: true + + /@types/ws/8.5.4: + resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} + dependencies: + '@types/node': 18.15.0 + dev: true + + /@types/yargs-parser/21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: false + + /@types/yargs/17.0.13: + resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: false + + /@webassemblyjs/ast/1.11.1: + resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + dev: true + + /@webassemblyjs/floating-point-hex-parser/1.11.1: + resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} + dev: true + + /@webassemblyjs/helper-api-error/1.11.1: + resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} + dev: true + + /@webassemblyjs/helper-buffer/1.11.1: + resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} + dev: true + + /@webassemblyjs/helper-numbers/1.11.1: + resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.1 + '@webassemblyjs/helper-api-error': 1.11.1 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode/1.11.1: + resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} + dev: true + + /@webassemblyjs/helper-wasm-section/1.11.1: + resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + dev: true + + /@webassemblyjs/ieee754/1.11.1: + resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128/1.11.1: + resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8/1.11.1: + resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} + dev: true + + /@webassemblyjs/wasm-edit/1.11.1: + resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/helper-wasm-section': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + '@webassemblyjs/wasm-opt': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + '@webassemblyjs/wast-printer': 1.11.1 + dev: true + + /@webassemblyjs/wasm-gen/1.11.1: + resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/ieee754': 1.11.1 + '@webassemblyjs/leb128': 1.11.1 + '@webassemblyjs/utf8': 1.11.1 + dev: true + + /@webassemblyjs/wasm-opt/1.11.1: + resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + dev: true + + /@webassemblyjs/wasm-parser/1.11.1: + resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-api-error': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/ieee754': 1.11.1 + '@webassemblyjs/leb128': 1.11.1 + '@webassemblyjs/utf8': 1.11.1 + dev: true + + /@webassemblyjs/wast-printer/1.11.1: + resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@xtuc/long': 4.2.2 + dev: true + + /@webpack-cli/configtest/2.0.1_66fuqojgvlon52mqukkfkspvqe: + resolution: {integrity: sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + dependencies: + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + dev: true + + /@webpack-cli/info/2.0.1_66fuqojgvlon52mqukkfkspvqe: + resolution: {integrity: sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + dependencies: + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + dev: true + + /@webpack-cli/serve/2.0.1_nekbz7mv5jjnaufwg2vs32i4fu: + resolution: {integrity: sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + dependencies: + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + webpack-dev-server: 4.11.1_66fuqojgvlon52mqukkfkspvqe + dev: true + + /@xtuc/ieee754/1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long/4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + + /accepts/1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /acorn-import-assertions/1.8.0_acorn@8.8.2: + resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.8.2 + dev: true + + /acorn-walk/8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn/8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv-formats/2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.12.0 + dev: true + + /ajv-keywords/3.5.2_ajv@6.12.6: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + + /ajv-keywords/5.1.0_ajv@8.12.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + dependencies: + ajv: 8.12.0 + fast-deep-equal: 3.1.3 + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv/8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-html-community/0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /anymatch/3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /array-flatten/1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-flatten/2.1.2: + resolution: {integrity: sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==} + dev: true + + /available-typed-arrays/1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /babel-loader/9.1.2_tkx7iv5lytdmlhrwm4n6r336ei: + resolution: {integrity: sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + dependencies: + '@babel/core': 7.21.0 + find-cache-dir: 3.3.2 + schema-utils: 4.0.0 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /babel-plugin-dynamic-import-node/2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + dependencies: + object.assign: 4.1.4 + dev: true + + /babel-plugin-module-resolver/5.0.0: + resolution: {integrity: sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==} + engines: {node: '>= 16'} + dependencies: + find-babel-config: 2.0.0 + glob: 8.1.0 + pkg-up: 3.1.0 + reselect: 4.1.7 + resolve: 1.22.1 + dev: true + + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.21.0: + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.0 + '@babel/core': 7.21.0 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3/0.5.3_@babel+core@7.21.0: + resolution: {integrity: sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + core-js-compat: 3.29.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.21.0: + resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + core-js-compat: 3.29.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.21.0: + resolution: {integrity: sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.21.0: + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.0 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.21.0 + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /batch/0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /body-parser/1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /bonjour-service/1.1.0: + resolution: {integrity: sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==} + dependencies: + array-flatten: 2.1.2 + dns-equal: 1.0.0 + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + dev: true + + /boolbase/1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browserslist/4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001464 + electron-to-chromium: 1.4.327 + node-releases: 2.0.10 + update-browserslist-db: 1.0.10_browserslist@4.21.5 + + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /bytes/3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: true + + /bytes/3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.0 + dev: true + + /camel-case/4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + dependencies: + pascal-case: 3.1.2 + tslib: 2.5.0 + dev: true + + /caniuse-lite/1.0.30001464: + resolution: {integrity: sha512-oww27MtUmusatpRpCGSOneQk2/l5czXANDSFvsc7VuOQ86s3ANhZetpwXNf1zY/zdfP63Xvjz325DAdAoES13g==} + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + requiresBuild: true + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chrome-trace-event/1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + dev: true + + /clean-css/5.3.2: + resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} + engines: {node: '>= 10.0'} + dependencies: + source-map: 0.6.1 + dev: true + + /cliui/8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + + /clone-deep/4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name/1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /colorette/2.0.19: + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} + dev: true + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander/4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /commander/8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: true + + /commander/9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /commondir/1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /compressible/2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression/1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /connect-history-api-fallback/2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + dev: true + + /content-disposition/0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type/1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: true + + /convert-source-map/1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + /cookie-signature/1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie/0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /copy-anything/2.0.6: + resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + dependencies: + is-what: 3.14.1 + dev: true + + /core-js-compat/3.29.0: + resolution: {integrity: sha512-ScMn3uZNAFhK2DGoEfErguoiAHhV2Ju+oJo/jK08p7B3f3UhocUrCCkTvnZaiS+edl5nlIoiBXKcwMc6elv4KQ==} + dependencies: + browserslist: 4.21.5 + dev: true + + /core-util-is/1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cross-spawn/6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.1 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-loader/6.7.3_webpack@5.76.0: + resolution: {integrity: sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + dependencies: + icss-utils: 5.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-modules-extract-imports: 3.0.0_postcss@8.4.21 + postcss-modules-local-by-default: 4.0.0_postcss@8.4.21 + postcss-modules-scope: 3.0.0_postcss@8.4.21 + postcss-modules-values: 4.0.0_postcss@8.4.21 + postcss-value-parser: 4.2.0 + semver: 7.3.8 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /css-select/4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + dev: true + + /css-what/6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + optional: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /default-gateway/6.0.3: + resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} + engines: {node: '>= 10'} + dependencies: + execa: 5.1.1 + dev: true + + /define-lazy-prop/2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-properties/1.2.0: + resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /depd/1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: true + + /depd/2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /destroy/1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /detect-node/2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + dev: true + + /dns-equal/1.0.0: + resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} + dev: true + + /dns-packet/5.4.0: + resolution: {integrity: sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==} + engines: {node: '>=6'} + dependencies: + '@leichtgewicht/ip-codec': 2.0.4 + dev: true + + /dom-converter/0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + dependencies: + utila: 0.4.0 + dev: true + + /dom-serializer/1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + dev: true + + /domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler/4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils/2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + dev: true + + /dot-case/3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.5.0 + dev: true + + /duplexer/0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + dev: true + + /ee-first/1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /electron-to-chromium/1.4.327: + resolution: {integrity: sha512-DIk2H4g/3ZhjgiABJjVdQvUdMlSABOsjeCm6gmUzIdKxAuFrGiJ8QXMm3i09grZdDBMC/d8MELMrdwYRC0+YHg==} + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /encodeurl/1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /enhanced-resolve/5.12.0: + resolution: {integrity: sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.10 + tapable: 2.2.1 + dev: true + + /entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + + /envinfo/7.8.1: + resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /errno/0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + requiresBuild: true + dependencies: + prr: 1.0.1 + dev: true + optional: true + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract/1.21.1: + resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.2.0 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.10 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + safe-regex-test: 1.0.0 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + dev: true + + /es-module-lexer/0.9.3: + resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + dev: true + + /es-set-tostringtag/2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.0 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + + /escape-html/1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag/1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /eventemitter3/4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: true + + /events/3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + + /execa/5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /express/4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fastest-levenshtein/1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + dev: true + + /faye-websocket/0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + dependencies: + websocket-driver: 0.7.4 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler/1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /find-babel-config/2.0.0: + resolution: {integrity: sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==} + engines: {node: '>=16.0.0'} + dependencies: + json5: 2.2.3 + path-exists: 4.0.0 + dev: true + + /find-cache-dir/3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-up/3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /for-each/0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /forwarded/0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fresh/0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /fs-monkey/1.0.3: + resolution: {integrity: sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==} + dev: true + + /fs-readdir-recursive/1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name/1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.1 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names/1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: false + + /get-intrinsic/1.2.0: + resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + + /get-stream/6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-to-regexp/0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob/8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + /globalthis/1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.0 + dev: true + + /gopd/1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.0 + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /gzip-size/6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + dependencies: + duplexer: 0.1.2 + dev: true + + /handle-thing/2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + dev: true + + /has-bigints/1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors/1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.0 + dev: true + + /has-proto/1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /he/1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /hosted-git-info/2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /hpack.js/2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + dev: true + + /html-entities/2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + dev: true + + /html-minifier-terser/6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.2 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.16.6 + dev: true + + /html-webpack-plugin/5.5.0_webpack@5.76.0: + resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==} + engines: {node: '>=10.13.0'} + peerDependencies: + webpack: ^5.20.0 + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.17.21 + pretty-error: 4.0.0 + tapable: 2.2.1 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /htmlparser2/6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + dev: true + + /http-deceiver/1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + dev: true + + /http-errors/1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + dev: true + + /http-errors/2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /http-parser-js/0.5.8: + resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + dev: true + + /http-proxy-middleware/2.0.6_@types+express@4.17.17: + resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + dependencies: + '@types/express': 4.17.17 + '@types/http-proxy': 1.17.10 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.5 + transitivePeerDependencies: + - debug + dev: true + + /http-proxy/1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.2 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: true + + /human-signals/2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /iconv-lite/0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + optional: true + + /icss-utils/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.21 + dev: true + + /image-size/0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /import-local/3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot/1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.0 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /interpret/3.1.1: + resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} + engines: {node: '>=10.13.0'} + dev: true + + /ipaddr.js/1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /ipaddr.js/2.0.1: + resolution: {integrity: sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==} + engines: {node: '>= 10'} + dev: true + + /is-array-buffer/3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + is-typed-array: 1.1.10 + dev: true + + /is-arrayish/0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable/1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-plain-obj/3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + dev: true + + /is-plain-object/2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer/1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array/1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-what/3.14.1: + resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + dev: true + + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /isarray/1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isexe/2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject/3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /jest-worker/27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 18.15.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jquery/3.6.3: + resolution: {integrity: sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==} + dev: false + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + /json-parse-better-errors/1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json5/2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + /kind-of/6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /klona/2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + dev: true + + /less-loader/11.1.0_less@4.1.3+webpack@5.76.0: + resolution: {integrity: sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==} + engines: {node: '>= 14.15.0'} + peerDependencies: + less: ^3.5.0 || ^4.0.0 + webpack: ^5.0.0 + dependencies: + klona: 2.0.6 + less: 4.1.3 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /less/4.1.3: + resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + copy-anything: 2.0.6 + parse-node-version: 1.0.1 + tslib: 2.5.0 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.10 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /load-json-file/4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.10 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /loader-runner/4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + + /locate-path/3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash.debounce/4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /lower-case/2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.5.0 + dev: true + + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-dir/2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.1 + dev: true + + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /media-typer/0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /memfs/3.4.13: + resolution: {integrity: sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==} + engines: {node: '>= 4.0.0'} + dependencies: + fs-monkey: 1.0.3 + dev: true + + /memorystream/0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + dev: true + + /merge-descriptors/1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /methods/1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime/1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /minimalistic-assert/1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch/5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /mrmime/1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + dev: true + + /ms/2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms/2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /multicast-dns/7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + dependencies: + dns-packet: 5.4.0 + thunky: 1.1.0 + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /needle/3.2.0: + resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} + engines: {node: '>= 4.4.x'} + hasBin: true + requiresBuild: true + dependencies: + debug: 3.2.7 + iconv-lite: 0.6.3 + sax: 1.2.4 + transitivePeerDependencies: + - supports-color + dev: true + optional: true + + /negotiator/0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /neo-async/2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /nice-try/1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + dev: true + + /no-case/3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.5.0 + dev: true + + /node-forge/1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: true + + /node-releases/2.0.10: + resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + + /normalize-package-data/2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.1 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-all/4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.5 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.0 + string.prototype.padend: 3.1.4 + dev: true + + /npm-run-path/4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /nth-check/2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-inspect/1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /obuf/1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + dev: true + + /on-finished/2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /on-headers/1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /open/8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /opener/1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + dev: true + + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-locate/3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-retry/4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + dev: true + + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /param-case/3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + dependencies: + dot-case: 3.0.4 + tslib: 2.5.0 + dev: true + + /parse-json/4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /parse-node-version/1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + dev: true + + /parseurl/1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /pascal-case/3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + dependencies: + no-case: 3.0.4 + tslib: 2.5.0 + dev: true + + /path-exists/3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-to-regexp/0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /path-type/3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pidtree/0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify/3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pify/4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /pkg-dir/4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /pkg-up/3.1.0: + resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} + engines: {node: '>=8'} + dependencies: + find-up: 3.0.0 + dev: true + + /postcss-modules-extract-imports/3.0.0_postcss@8.4.21: + resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-modules-local-by-default/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + icss-utils: 5.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-modules-scope/3.0.0_postcss@8.4.21: + resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-modules-values/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + icss-utils: 5.1.0_postcss@8.4.21 + postcss: 8.4.21 + dev: true + + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /pretty-error/4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + dependencies: + lodash: 4.17.21 + renderkid: 3.0.0 + dev: true + + /process-nextick-args/2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /proxy-addr/2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /prr/1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + dev: true + optional: true + + /punycode/2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /qs/6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /range-parser/1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raw-body/2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /read-pkg/3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + dev: true + + /readable-stream/2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream/3.6.1: + resolution: {integrity: sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /rechoir/0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + dependencies: + resolve: 1.22.1 + dev: true + + /regenerate-unicode-properties/10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate/1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime/0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-transform/0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.21.0 + dev: true + + /regexp.prototype.flags/1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + functions-have-names: 1.2.3 + dev: true + + /regexpu-core/5.3.1: + resolution: {integrity: sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser/0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /relateurl/0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + dev: true + + /renderkid/3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.17.21 + strip-ansi: 6.0.1 + dev: true + + /require-directory/2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: false + + /require-from-string/2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /requires-port/1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + + /reselect/4.1.7: + resolution: {integrity: sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==} + dev: true + + /resolve-cwd/3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /retry/0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test/1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + is-regex: 1.1.4 + dev: true + + /safer-buffer/2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /sax/1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: true + optional: true + + /schema-utils/3.1.1: + resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.11 + ajv: 6.12.6 + ajv-keywords: 3.5.2_ajv@6.12.6 + dev: true + + /schema-utils/4.0.0: + resolution: {integrity: sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==} + engines: {node: '>= 12.13.0'} + dependencies: + '@types/json-schema': 7.0.11 + ajv: 8.12.0 + ajv-formats: 2.1.1 + ajv-keywords: 5.1.0_ajv@8.12.0 + dev: true + + /select-hose/2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + dev: true + + /selfsigned/2.1.1: + resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} + engines: {node: '>=10'} + dependencies: + node-forge: 1.3.1 + dev: true + + /semver/5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + + /semver/7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send/0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /serialize-javascript/6.0.1: + resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-index/1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.6.3 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /serve-static/1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /setprototypeof/1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + dev: true + + /setprototypeof/1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /shallow-clone/3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + + /shebang-command/1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shell-quote/1.8.0: + resolution: {integrity: sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + object-inspect: 1.12.3 + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /sirv/1.0.19: + resolution: {integrity: sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.21 + mrmime: 1.0.1 + totalist: 1.1.0 + dev: true + + /slash/2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + dev: true + + /sockjs/0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spdx-correct/3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.12 + dev: true + + /spdx-exceptions/2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse/3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.12 + dev: true + + /spdx-license-ids/3.0.12: + resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} + dev: true + + /spdy-transport/3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + dependencies: + debug: 4.3.4 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.1 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /spdy/4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + dependencies: + debug: 4.3.4 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /statuses/1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: true + + /statuses/2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string.prototype.padend/3.1.4: + resolution: {integrity: sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.1 + dev: true + + /string.prototype.trimend/1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.1 + dev: true + + /string.prototype.trimstart/1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.1 + dev: true + + /string_decoder/1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder/1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-bom/3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline/2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /style-loader/3.3.1_webpack@5.76.0: + resolution: {integrity: sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + dependencies: + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color/8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /tapable/2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /terser-webpack-plugin/5.3.7_webpack@5.76.0: + resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + jest-worker: 27.5.1 + schema-utils: 3.1.1 + serialize-javascript: 6.0.1 + terser: 5.16.6 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /terser/5.16.6: + resolution: {integrity: sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.2 + acorn: 8.8.2 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /thunky/1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toidentifier/1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /totalist/1.1.0: + resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==} + engines: {node: '>=6'} + dev: true + + /tslib/2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + dev: true + + /type-is/1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /typed-array-length/1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.10 + dev: true + + /typescript/4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /unbox-primitive/1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unicode-canonical-property-names-ecmascript/2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript/2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript/2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript/2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unpipe/1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /update-browserslist-db/1.0.10_browserslist@4.21.5: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /utila/0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + dev: true + + /utils-merge/1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uuid/8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + + /validate-npm-package-license/3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vary/1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /watchpack/2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.10 + dev: true + + /wbuf/1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + dependencies: + minimalistic-assert: 1.0.1 + dev: true + + /webpack-bundle-analyzer/4.8.0: + resolution: {integrity: sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==} + engines: {node: '>= 10.13.0'} + hasBin: true + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.8.2 + acorn-walk: 8.2.0 + chalk: 4.1.2 + commander: 7.2.0 + gzip-size: 6.0.0 + lodash: 4.17.21 + opener: 1.5.2 + sirv: 1.0.19 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /webpack-cli/5.0.1_jkfmkh54fty5hi5ax7xfrvyyji: + resolution: {integrity: sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==} + engines: {node: '>=14.15.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + webpack: 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 2.0.1_66fuqojgvlon52mqukkfkspvqe + '@webpack-cli/info': 2.0.1_66fuqojgvlon52mqukkfkspvqe + '@webpack-cli/serve': 2.0.1_nekbz7mv5jjnaufwg2vs32i4fu + colorette: 2.0.19 + commander: 9.5.0 + cross-spawn: 7.0.3 + envinfo: 7.8.1 + fastest-levenshtein: 1.0.16 + import-local: 3.1.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-bundle-analyzer: 4.8.0 + webpack-dev-server: 4.11.1_66fuqojgvlon52mqukkfkspvqe + webpack-merge: 5.8.0 + dev: true + + /webpack-dev-middleware/5.3.3_webpack@5.76.0: + resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + dependencies: + colorette: 2.0.19 + memfs: 3.4.13 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.0.0 + webpack: 5.76.0_webpack-cli@5.0.1 + dev: true + + /webpack-dev-server/4.11.1_66fuqojgvlon52mqukkfkspvqe: + resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} + engines: {node: '>= 12.13.0'} + hasBin: true + peerDependencies: + webpack: ^4.37.0 || ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/bonjour': 3.5.10 + '@types/connect-history-api-fallback': 1.3.5 + '@types/express': 4.17.17 + '@types/serve-index': 1.9.1 + '@types/serve-static': 1.15.1 + '@types/sockjs': 0.3.33 + '@types/ws': 8.5.4 + ansi-html-community: 0.0.8 + bonjour-service: 1.1.0 + chokidar: 3.5.3 + colorette: 2.0.19 + compression: 1.7.4 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.18.2 + graceful-fs: 4.2.10 + html-entities: 2.3.3 + http-proxy-middleware: 2.0.6_@types+express@4.17.17 + ipaddr.js: 2.0.1 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.0.0 + selfsigned: 2.1.1 + serve-index: 1.9.1 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack: 5.76.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + webpack-dev-middleware: 5.3.3_webpack@5.76.0 + ws: 8.12.1 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + dev: true + + /webpack-merge/5.8.0: + resolution: {integrity: sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==} + engines: {node: '>=10.0.0'} + dependencies: + clone-deep: 4.0.1 + wildcard: 2.0.0 + dev: true + + /webpack-sources/3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack/5.76.0_webpack-cli@5.0.1: + resolution: {integrity: sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 0.0.51 + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/wasm-edit': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + acorn: 8.8.2 + acorn-import-assertions: 1.8.0_acorn@8.8.2 + browserslist: 4.21.5 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.12.0 + es-module-lexer: 0.9.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.10 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.1.1 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.7_webpack@5.76.0 + watchpack: 2.4.0 + webpack-cli: 5.0.1_jkfmkh54fty5hi5ax7xfrvyyji + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + + /websocket-driver/0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + dependencies: + http-parser-js: 0.5.8 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + dev: true + + /websocket-extensions/0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + dev: true + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-typed-array/1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + + /which/1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wildcard/2.0.0: + resolution: {integrity: sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==} + dev: true + + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /ws/7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /ws/8.12.1: + resolution: {integrity: sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /y18n/5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: false + + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yargs-parser/21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: false + + /yargs/17.6.2: + resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 000000000..ee102735a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/*" diff --git a/private/less/app.less b/private/less/app.less deleted file mode 100644 index dd4d62029..000000000 --- a/private/less/app.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/app.less"; -@import "var.less"; diff --git a/private/less/background.less b/private/less/background.less deleted file mode 100644 index 0897148ea..000000000 --- a/private/less/background.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/background.less"; -@import "var.less"; diff --git a/private/less/var.less b/private/less/var.less deleted file mode 100644 index c427442d3..000000000 --- a/private/less/var.less +++ /dev/null @@ -1,4 +0,0 @@ -@webUrl: './'; -@fontUrl: '@{webUrl}font/'; //图片的基本地址 -@imageUrl: '@{webUrl}images/1x/'; //图片的基本地址 -@image2xUrl: '@{webUrl}images/2x/'; //2倍图片的基本地址 diff --git a/public/js/index.js b/public/js/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/less/app.less b/public/less/app.less deleted file mode 100644 index dd4d62029..000000000 --- a/public/less/app.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/app.less"; -@import "var.less"; diff --git a/public/less/background.less b/public/less/background.less deleted file mode 100644 index 0897148ea..000000000 --- a/public/less/background.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/background.less"; -@import "var.less"; diff --git a/public/less/font.less b/public/less/font.less deleted file mode 100644 index d7399c46e..000000000 --- a/public/less/font.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/font.less"; -@import "var.less"; diff --git a/public/less/icon.less b/public/less/icon.less deleted file mode 100644 index 8aa44a2ae..000000000 --- a/public/less/icon.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "../../src/less/resource/icon.less"; -@import "var.less"; - - - diff --git a/public/less/var.less b/public/less/var.less deleted file mode 100644 index 88ff90275..000000000 --- a/public/less/var.less +++ /dev/null @@ -1,4 +0,0 @@ -@webUrl: 'https://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/'; -@fontUrl: '@{webUrl}font/'; //图片的基本地址 -@imageUrl: '@{webUrl}images/1x/'; //图片的基本地址 -@image2xUrl: '@{webUrl}images/2x/'; //2倍图片的基本地址 diff --git a/publish.bat b/publish.bat index c174aa424..4fab82770 100644 --- a/publish.bat +++ b/publish.bat @@ -1 +1,2 @@ +cd packages/fineui npm run publishToPrivate \ No newline at end of file diff --git a/publish.sh b/publish.sh index c174aa424..6a9deae69 100644 --- a/publish.sh +++ b/publish.sh @@ -1 +1,2 @@ +cd packages/fineui npm run publishToPrivate \ No newline at end of file diff --git a/scripts/chinese.js b/scripts/chinese.js new file mode 100644 index 000000000..61969fbee --- /dev/null +++ b/scripts/chinese.js @@ -0,0 +1,23 @@ +const { tranvase } = require("./lib/utils"); +const fs = require("fs"); + +const config = { + handler: filePath => { + if (filePath.includes("test") || filePath.includes("dist")) { + return; + } + let content = fs.readFileSync(filePath).toString(); + let reg = /(['"`])(.*?)\1/g; + if (reg.test(content)) { + Array.from(content.matchAll(reg)) + .map(el => el[2]) + .forEach(el => { + if (Array.from(el).some(el => el.charCodeAt(0) > 255)) { + console.log(filePath, el); + } + }); + } + }, +}; + +tranvase(process.argv[2], config); diff --git a/scripts/code.static.js b/scripts/code.static.js new file mode 100644 index 000000000..526f97788 --- /dev/null +++ b/scripts/code.static.js @@ -0,0 +1,89 @@ +/** + * @file 各模块文件数量统计脚本(从 BI 搬过来的) + */ +let fs = require('fs'); +let path = require('path'); + +const rootPath = path.resolve(__dirname, '../packages'); +// 获取所有的模块名 +const modules = fs.readdirSync(rootPath); +const result = []; + +let jsFileCount = 0; +let tsFileCount = 0; +let tsxFileCount = 0; + +const file = async filePath => { + if ( + filePath.endsWith('.js') && + filePath.indexOf('/dist/') < 0 && + filePath.indexOf('/webpack/') < 0 && + filePath.indexOf('/webui-bi/private/') < 0 + ) { + console.log(jsFileCount + ':' + path.normalize(filePath)); + jsFileCount++; + } + if (filePath.endsWith('.ts')) { + tsFileCount++; + } + if (filePath.endsWith('.tsx')) { + tsxFileCount++; + } +}; + +const reset = () => { + jsFileCount = 0; + tsFileCount = 0; + tsxFileCount = 0; +}; + +// 递归所有文件夹统计 +const codeStat = async (pt, lineFun) => { + let files = fs.readdirSync(pt); + files + .map(file => { + return `${pt}/${file}`; + }) + .forEach(file => { + let stat = fs.statSync(file); + if (stat.isDirectory()) { + if ( + file.indexOf('__test__') > -1 || + file.indexOf('__point__') > -1 || + file.indexOf('third') > -1 || + file.indexOf('__e2e__') > -1 || + file.indexOf('__integration__') > -1 || + file.indexOf('node_modules') > -1 + ) { + return; + } + codeStat(file, lineFun); + return; + } + if (file.indexOf('.DS_Store') > -1) { + return; + } + lineFun(file); + }); +}; + +const statisticFile = () => { + modules.forEach(i => { + codeStat(`${rootPath}/${i}/src`, file); + result.push({ + name: i, + jsFileCount, + tsFileCount, + tsxFileCount, + allFileCount: jsFileCount + tsFileCount + tsxFileCount, + }); + reset(); + }); + + console.table(result); +}; + +statisticFile(); +module.exports = { + statisticFile, +}; diff --git a/scripts/lib/fui.component.json b/scripts/lib/fui.component.json new file mode 100644 index 000000000..22d45963a --- /dev/null +++ b/scripts/lib/fui.component.json @@ -0,0 +1,398 @@ +{ + "bi.pane": "Pane", + "bi.button": "Button", + "bi.horizontal": "HorizontalLayout", + "bi.horizontal_adapt": "HorizontalAdaptLayout", + "bi.popup_view": "PopupView", + "bi.collection_view": "CollectionView", + "bi.grid_view": "GridView", + "bi.list_view": "ListView", + "bi.bubble": "Bubble", + "bi.virtual_list": "VirtualList", + "bi.combo": "Combo", + "bi.expander": "Expander", + "bi.button_group": "ButtonGroup", + "bi.combo_group": "ComboGroup", + "bi.virtual_group": "VirtualGroup", + "bi.loader": "Loader", + "bi.navigation": "Navigation", + "bi.searcher": "Searcher", + "bi.switcher": "Switcher", + "bi.tab": "Tab", + "bi.button_tree": "ButtonTree", + "bi.context": "Context", + "bi.el": "EL", + "bi.bar_popover": "BarPopover", + "bi.searcher_view": "SearcherView", + "bi.single": "Single", + "bi.text": "Text", + "bi.a": "A", + "bi.loading_bar": "LoadingBar", + "bi.basic_button": "BasicButton", + "bi.node_button": "NodeButton", + "bi.icon_button": "IconButton", + "bi.image_button": "ImageButton", + "bi.text_button": "TextButton", + "bi.blank_icon_icon_text_item": "BlankIconIconTextItem", + "bi.blank_icon_text_icon_item": "BlankIconTextIconItem", + "bi.blank_icon_text_item": "BlankIconTextItem", + "bi.icon_text_icon_item": "IconTextIconItem", + "bi.icon_text_item": "IconTextItem", + "bi.text_icon_item": "TextIconItem", + "bi.text_item": "TextItem", + "bi.icon_text_icon_node": "IconTextIconNode", + "bi.icon_text_node": "IconTextNode", + "bi.text_icon_node": "TextIconNode", + "bi.text_node": "TextNode", + "bi.editor": "Editor", + "bi.multifile_editor": "MultifileEditor", + "bi.textarea_editor": "TextAreaEditor", + "bi.html": "Html", + "bi.icon": "Icon", + "bi.iframe": "Iframe", + "bi.img": "Img", + "bi.image_checkbox": "ImageCheckbox", + "bi.checkbox": "Checkbox", + "bi.file": "File", + "bi.input": "Input", + "bi.image_radio": "ImageRadio", + "bi.radio": "Radio", + "bi.instruction": "Instruction", + "bi.html_label": "HtmlLabel", + "bi.icon_label": "IconLabel", + "bi.label": "Label", + "bi.link": "Link", + "bi.pure_text": "PureText", + "bi.custom_tree": "CustomTree", + "bi.icon_change_button": "IconChangeButton", + "bi.trigger_icon_button": "TriggerIconButton", + "bi.half_icon_button": "HalfIconButton", + "bi.half_button": "HalfButton", + "bi.multi_select_item": "MultiSelectItem", + "bi.single_select_icon_text_item": "SingleSelectIconTextItem", + "bi.single_select_item": "SingleSelectItem", + "bi.single_select_radio_item": "SingleSelectRadioItem", + "bi.arrow_group_node": "ArrowNode", + "bi.icon_arrow_node": "IconArrowNode", + "bi.multilayer_icon_arrow_node": "MultiLayerIconArrowNode", + "bi.plus_group_node": "PlusGroupNode", + "bi.tree_node_switcher": "TreeNodeSwitcher", + "bi.tree_node": "BasicTreeNode", + "bi.first_plus_group_node": "FirstPlusGroupNode", + "bi.mid_plus_group_node": "MidPlusGroupNode", + "bi.last_plus_group_node": "LastPlusGroupNode", + "bi.switch": "Switch", + "bi.icon_tree_leaf_item": "IconTreeLeafItem", + "bi.multilayer_icon_tree_leaf_item": "MultiLayerIconTreeLeafItem", + "bi.tree_item": "BasicTreeItem", + "bi.first_tree_leaf_item": "FirstTreeLeafItem", + "bi.mid_tree_leaf_item": "MidTreeLeafItem", + "bi.last_tree_leaf_item": "LastTreeLeafItem", + "bi.root_tree_leaf_item": "RootTreeLeafItem", + "bi.calendar": "Calendar", + "bi.year_calendar": "YearCalendar", + "bi.arrow_group_node_checkbox": "ArrowTreeGroupNodeCheckbox", + "bi.checking_mark_node": "CheckingMarkNode", + "bi.first_tree_node_checkbox": "FirstTreeNodeCheckbox", + "bi.last_tree_node_checkbox": "LastTreeNodeCheckbox", + "bi.mid_tree_node_checkbox": "MidTreeNodeCheckbox", + "bi.tree_node_checkbox": "TreeNodeCheckbox", + "bi.custom_color_chooser": "CustomColorChooser", + "bi.color_chooser": "ColorChooser", + "bi.hex_color_chooser_popup": "HexColorChooserPopup", + "bi.simple_hex_color_chooser_popup": "SimpleHexColorChooserPopup", + "bi.color_chooser_popup": "ColorChooserPopup", + "bi.simple_color_chooser_popup": "SimpleColorChooserPopup", + "bi.simple_color_chooser": "SimpleColorChooser", + "bi.color_chooser_trigger": "ColorChooserTrigger", + "bi.long_color_chooser_trigger": "LongColorChooserTrigger", + "bi.color_picker_button": "ColorPickerButton", + "bi.color_picker_show_button": "ColorChooserShowButton", + "bi.hex_color_picker": "HexColorPicker", + "bi.color_picker": "ColorPicker", + "bi.hex_color_picker_editor": "HexColorPickerEditor", + "bi.simple_hex_color_picker_editor": "SimpleHexColorPickerEditor", + "bi.color_picker_editor": "ColorPickerEditor", + "bi.simple_color_picker_editor": "SimpleColorPickerEditor", + "bi.farbtastic": "Farbtastic", + "bi.bubble_combo": "BubbleCombo", + "bi.bubble_popup_view": "BubblePopupView", + "bi.bubble_bar_popup_view": "BubblePopupBarView", + "bi.text_bubble_bar_popup_view": "TextBubblePopupBarView", + "bi.editor_icon_check_combo": "EditorIconCheckCombo", + "bi.icon_combo": "IconCombo", + "bi.icon_combo_popup": "IconComboPopup", + "bi.icon_combo_trigger": "IconComboTrigger", + "bi.icon_text_value_combo": "IconTextValueCombo", + "bi.icon_text_value_combo_popup": "IconTextValueComboPopup", + "bi.search_text_value_combo": "SearchTextValueCombo", + "bi.search_text_value_combo_popup": "SearchTextValueComboPopup", + "bi.search_text_value_trigger": "SearchTextValueTrigger", + "bi.text_value_check_combo": "TextValueCheckCombo", + "bi.text_value_check_combo_popup": "TextValueCheckComboPopup", + "bi.text_value_combo": "TextValueCombo", + "bi.small_text_value_combo": "SmallTextValueCombo", + "bi.text_value_combo_popup": "TextValueComboPopup", + "bi.clear_editor": "ClearEditor", + "bi.default_text_editor": "DefaultTextEditor", + "bi.shelter_editor": "ShelterEditor", + "bi.sign_editor": "SignEditor", + "bi.state_editor": "StateEditor", + "bi.simple_state_editor": "SimpleStateEditor", + "bi.multi_popup_view": "MultiPopupView", + "bi.popup_panel": "PopupPanel", + "bi.list_pane": "ListPane", + "bi.panel": "Panel", + "bi.linear_segment_button": "LinearSegmentButton", + "bi.linear_segment": "LinearSegment", + "bi.select_list": "SelectList", + "bi.lazy_loader": "LazyLoader", + "bi.list_loader": "ListLoader", + "bi.sort_list": "SortList", + "bi.all_count_pager": "AllCountPager", + "bi.detail_pager": "DetailPager", + "bi.direction_pager": "DirectionPager", + "bi.segment_button": "SegmentButton", + "bi.segment": "Segment", + "bi.multi_select_bar": "MultiSelectBar", + "bi.level_tree": "LevelTree", + "bi.tree_expander": "TreeExpander", + "bi.tree_expander.popup": "TreeExpanderPopup", + "bi.editor_trigger": "EditorTrigger", + "bi.icon_trigger": "IconTrigger", + "bi.icon_text_trigger": "IconTextTrigger", + "bi.select_icon_text_trigger": "SelectIconTextTrigger", + "bi.text_trigger": "TextTrigger", + "bi.select_text_trigger": "SelectTextTrigger", + "bi.small_select_text_trigger": "SmallSelectTextTrigger", + "bi.small_text_trigger": "SmallTextTrigger", + "bi.async_tree": "AsyncTree", + "bi.list_async_tree": "ListAsyncTree", + "bi.list_part_tree": "ListPartTree", + "bi.list_tree_view": "ListTreeView", + "bi.part_tree": "PartTree", + "bi.display_tree": "DisplayTree", + "bi.list_display_tree": "ListDisplayTree", + "bi.simple_tree": "SimpleTreeView", + "bi.tree_view": "TreeView", + "bi.all_value_chooser_combo": "AllValueChooserCombo", + "bi.all_value_chooser_pane": "AllValueChooserPane", + "bi.all_value_multi_text_value_combo": "AllValueMultiTextValueCombo", + "bi.form_field": "FormField", + "bi.custom_form": "Form", + "bi.list_tree_value_chooser_insert_combo": "ListTreeValueChooserInsertCombo", + "bi.tree_value_chooser_insert_combo": "TreeValueChooserInsertCombo", + "bi.tree_value_chooser_combo": "TreeValueChooserCombo", + "bi.tree_value_chooser_pane": "TreeValueChooserPane", + "bi.value_chooser_insert_combo": "ValueChooserInsertCombo", + "bi.value_chooser_combo": "ValueChooserCombo", + "bi.value_chooser_no_bar_combo": "ValueChooserNoBarCombo", + "bi.value_chooser_pane": "ValueChooserPane", + "bi.absolute_horizontal_adapt": "AbsoluteHorizontalLayout", + "bi.absolute_left_right_vertical_adapt": "AbsoluteLeftRightVerticalAdaptLayout", + "bi.absolute_right_vertical_adapt": "AbsoluteRightVerticalAdaptLayout", + "bi.absolute_vertical_adapt": "AbsoluteVerticalLayout", + "bi.center_adapt": "CenterAdaptLayout", + "bi.left_right_vertical_adapt": "LeftRightVerticalAdaptLayout", + "bi.left_vertical_adapt": "LeftVerticalAdaptLayout", + "bi.right_vertical_adapt": "RightVerticalAdaptLayout", + "bi.table_adapt": "TableAdaptLayout", + "bi.vertical_adapt": "VerticalAdaptLayout", + "bi.horizontal_auto": "HorizontalAutoLayout", + "bi.inline_center_adapt": "InlineCenterAdaptLayout", + "bi.inline_horizontal_adapt": "InlineHorizontalAdaptLayout", + "bi.inline_vertical_adapt": "InlineVerticalAdaptLayout", + "bi.vtape_auto": "AutoVerticalTapeLayout", + "bi.horizontal_float_fill": "FloatHorizontalFillLayout", + "bi.flex_center_adapt": "FlexCenterLayout", + "bi.flex_horizontal_adapt": "FlexHorizontalCenter", + "bi.flex_horizontal_center_adapt": "FlexHorizontalCenterAdapt", + "bi.flex_horizontal": "FlexHorizontalLayout", + "bi.flex_left_right_vertical_adapt": "FlexLeftRightVerticalAdaptLayout", + "bi.flex_vertical_adapt": "FlexVerticalCenter", + "bi.flex_vertical_center_adapt": "FlexVerticalCenterAdapt", + "bi.flex_vertical": "FlexVerticalLayout", + "bi.flex_scrollable_center_adapt": "FlexWrapperCenterLayout", + "bi.flex_scrollable_horizontal_adapt": "FlexWrapperHorizontalCenter", + "bi.flex_scrollable_horizontal_center_adapt": "FlexWrapperHorizontalCenterAdapt", + "bi.flex_scrollable_horizontal": "FlexWrapperHorizontalLayout", + "bi.flex_scrollable_vertical_adapt": "FlexWrapperVerticalCenter", + "bi.flex_scrollable_vertical_center_adapt": "FlexWrapperVerticalCenterAdapt", + "bi.flex_scrollable_vertical": "FlexWrapperVerticalLayout", + "bi.absolute_center_float": "FloatAbsoluteCenterLayout", + "bi.absolute_horizontal_float": "FloatAbsoluteHorizontalLayout", + "bi.absolute_left_right_vertical_float": "FloatAbsoluteLeftRightVerticalAdaptLayout", + "bi.absolute_right_vertical_float": "FloatAbsoluteRightVerticalAdaptLayout", + "bi.absolute_vertical_float": "FloatAbsoluteVerticalLayout", + "bi.horizontal_float": "FloatHorizontalLayout", + "bi.absolute": "AbsoluteLayout", + "bi.adaptive": "AdaptiveLayout", + "bi.border": "BorderLayout", + "bi.card": "CardLayout", + "bi.default": "DefaultLayout", + "bi.division": "DivisionLayout", + "bi.left": "FloatLeftLayout", + "bi.right": "FloatRightLayout", + "bi.grid": "GridLayout", + "bi.inline": "InlineLayout", + "bi.lattice": "LatticeLayout", + "bi.table": "TableLayout", + "bi.htape": "HTapeLayout", + "bi.vtape": "VTapeLayout", + "bi.td": "TdLayout", + "bi.vertical": "VerticalLayout", + "bi.window": "WindowLayout", + "bi.center": "CenterLayout", + "bi.float_center": "FloatCenterLayout", + "bi.horizontal_center": "HorizontalCenterLayout", + "bi.vertical_center": "VerticalCenterLayout", + "bi.responsive_flex_horizontal": "ResponsiveFlexHorizontalLayout", + "bi.responsive_flex_scrollable_horizontal": "ResponsiveFlexWrapperHorizontalLayout", + "bi.responsive_inline": "ResponsiveInlineLayout", + "bi.horizontal_sticky": "HorizontalStickyLayout", + "bi.vertical_sticky": "VerticalStickyLayout", + "bi.layout": "Layout", + "bi.router": "RouterWidget", + "bi.router_view": "RouterView", + "bi.collapse": "Collapse", + "bi.month_date_combo": "MonthDateCombo", + "bi.year_date_combo": "YearDateCombo", + "bi.date_picker": "DatePicker", + "bi.year_picker": "YearPicker", + "bi.date_calendar_popup": "DateCalendarPopup", + "bi.month_popup": "MonthPopup", + "bi.year_popup": "YearPopup", + "bi.date_triangle_trigger": "DateTriangleTrigger", + "bi.static_date_pane_card": "StaticDatePaneCard", + "bi.dynamic_date_pane": "DynamicDatePane", + "bi.date_time_combo": "DateTimeCombo", + "bi.date_time_popup": "DateTimePopup", + "bi.date_time_trigger": "DateTimeTrigger", + "bi.static_date_time_pane_card": "StaticDateTimePaneCard", + "bi.dynamic_date_time_pane": "DynamicDateTimePane", + "bi.down_list_combo": "DownListCombo", + "bi.down_list_group": "DownListGroup", + "bi.down_list_item": "DownListItem", + "bi.down_list_group_item": "DownListGroupItem", + "bi.down_list_popup": "DownListPopup", + "bi.dynamic_date_card": "DynamicDateCard", + "bi.dynamic_date_combo": "DynamicDateCombo", + "bi.dynamic_date_param_item": "DynamicDateParamItem", + "bi.dynamic_date_popup": "DynamicDatePopup", + "bi.dynamic_date_trigger": "DynamicDateTrigger", + "bi.dynamic_date_time_combo": "DynamicDateTimeCombo", + "bi.dynamic_date_time_popup": "DynamicDateTimePopup", + "bi.dynamic_date_time_select": "DynamicDateTimeSelect", + "bi.dynamic_date_time_trigger": "DynamicDateTimeTrigger", + "bi.search_editor": "SearchEditor", + "bi.small_search_editor": "SmallSearchEditor", + "bi.text_editor": "TextEditor", + "bi.small_text_editor": "SmallTextEditor", + "bi.interval_slider": "IntervalSlider", + "bi.multi_layer_down_list_combo": "MultiLayerDownListCombo", + "bi.multi_layer_down_list_popup": "MultiLayerDownListPopup", + "bi.multilayer_select_tree_combo": "MultiLayerSelectTreeCombo", + "bi.multilayer_select_tree_insert_search_pane": "MultiLayerSelectTreeInsertSearchPane", + "bi.multilayer_select_level_tree": "MultiLayerSelectLevelTree", + "bi.multilayer_select_tree_popup": "MultiLayerSelectTreePopup", + "bi.multilayer_select_tree_trigger": "MultiLayerSelectTreeTrigger", + "bi.multilayer_single_tree_combo": "MultiLayerSingleTreeCombo", + "bi.multilayer_single_tree_insert_search_pane": "MultiLayerSingleTreeInsertSearchPane", + "bi.multilayer_single_level_tree": "MultiLayerSingleLevelTree", + "bi.multilayer_single_tree_popup": "MultiLayerSingleTreePopup", + "bi.multilayer_single_tree_trigger": "MultiLayerSingleTreeTrigger", + "bi.multi_select_check_pane": "MultiSelectCheckPane", + "bi.display_selected_list": "DisplaySelectedList", + "bi.multi_select_inner_loader": "MultiSelectInnerLoader", + "bi.multi_select_combo": "MultiSelectCombo", + "bi.multi_select_no_bar_combo": "MultiSelectNoBarCombo", + "bi.multi_select_insert_combo": "MultiSelectInsertCombo", + "bi.multi_select_insert_no_bar_combo": "MultiSelectInsertNoBarCombo", + "bi.multi_select_insert_trigger": "MultiSelectInsertTrigger", + "bi.multi_select_loader": "MultiSelectLoader", + "bi.multi_select_no_bar_loader": "MultiSelectNoBarLoader", + "bi.multi_select_popup_view": "MultiSelectPopupView", + "bi.multi_select_no_bar_popup_view": "MultiSelectNoBarPopupView", + "bi.multi_select_trigger": "MultiSelectTrigger", + "bi.multi_select_search_insert_pane": "MultiSelectSearchInsertPane", + "bi.multi_select_search_loader": "MultiSelectSearchLoader", + "bi.multi_select_search_pane": "MultiSelectSearchPane", + "bi.multi_select_check_selected_button": "MultiSelectCheckSelectedButton", + "bi.select_patch_editor": "SelectPatchEditor", + "bi.multi_select_editor": "MultiSelectEditor", + "bi.multi_select_insert_searcher": "MultiSelectInsertSearcher", + "bi.multi_select_searcher": "MultiSelectSearcher", + "bi.multi_select_check_selected_switcher": "MultiSelectCheckSelectedSwitcher", + "bi.multi_select_insert_list": "MultiSelectInsertList", + "bi.multi_select_insert_no_bar_list": "MultiSelectInsertNoBarList", + "bi.multi_select_list": "MultiSelectList", + "bi.multi_select_tree": "MultiSelectTree", + "bi.multi_select_tree_popup": "MultiSelectTreePopup", + "bi.multi_tree_check_pane": "MultiTreeCheckPane", + "bi.multi_tree_combo": "MultiTreeCombo", + "bi.multi_tree_insert_combo": "MultiTreeInsertCombo", + "bi.multi_tree_list_combo": "MultiTreeListCombo", + "bi.multi_tree_popup_view": "MultiTreePopup", + "bi.multi_tree_check_selected_button": "MultiTreeCheckSelectedButton", + "bi.multi_tree_search_insert_pane": "MultiTreeSearchInsertPane", + "bi.multi_tree_search_pane": "MultiTreeSearchPane", + "bi.multi_list_tree_searcher": "MultiListTreeSearcher", + "bi.multi_tree_searcher": "MultiTreeSearcher", + "bi.number_editor": "NumberEditor", + "bi.number_interval": "NumberInterval", + "bi.number_interval_single_editor": "NumberIntervalSingleEidtor", + "bi.search_multi_text_value_combo": "SearchMultiTextValueCombo", + "bi.search_multi_select_trigger": "SearchMultiSelectTrigger", + "bi.search_multi_select_loader": "SearchMultiSelectLoader", + "bi.search_multi_select_popup_view": "SearchMultiSelectPopupView", + "bi.search_multi_select_searcher": "SearchMultiSelectSearcher", + "bi.select_tree_combo": "SelectTreeCombo", + "bi.select_tree_expander": "SelectTreeExpander", + "bi.select_level_tree": "SelectTreePopup", + "bi.single_select_search_loader": "SingleSelectSearchLoader", + "bi.single_select_search_insert_pane": "SingleSelectSearchInsertPane", + "bi.single_select_search_pane": "SingleSelectSearchPane", + "bi.single_select_combo": "SingleSelectCombo", + "bi.single_select_insert_combo": "SingleSelectInsertCombo", + "bi.single_select_list": "SingleSelectList", + "bi.single_select_loader": "SingleSelectLoader", + "bi.single_select_popup_view": "SingleSelectPopupView", + "bi.single_select_trigger": "SingleSelectTrigger", + "bi.single_select_insert_list": "SingleSelectInsertList", + "bi.single_select_editor": "SingleSelectEditor", + "bi.single_select_searcher": "SingleSelectSearcher", + "bi.sign_text_editor": "SignTextEditor", + "bi.single_slider_button": "SliderIconButton", + "bi.single_slider": "SingleSlider", + "bi.single_slider_label": "SingleSliderLabel", + "bi.single_slider_normal": "SingleSliderNormal", + "bi.single_tree_combo": "SingleTreeCombo", + "bi.single_level_tree": "SingleTreePopup", + "bi.single_tree_trigger": "SingleTreeTrigger", + "bi.text_value_down_list_combo": "TextValueDownListCombo", + "bi.down_list_select_text_trigger": "DownListSelectTextTrigger", + "bi.time_popup": "TimePopup", + "bi.time_combo": "TimeCombo", + "bi.time_trigger": "TimeTrigger", + "bi.date_interval": "DateInterval", + "bi.time_interval": "TimeInterval", + "bi.time_periods": "TimePeriods", + "bi.dynamic_year_card": "DynamicYearCard", + "bi.static_year_card": "StaticYearCard", + "bi.dynamic_year_combo": "DynamicYearCombo", + "bi.dynamic_year_popup": "DynamicYearPopup", + "bi.dynamic_year_trigger": "DynamicYearTrigger", + "bi.year_interval": "YearInterval", + "bi.dynamic_year_month_card": "DynamicYearMonthCard", + "bi.static_year_month_card": "StaticYearMonthCard", + "bi.dynamic_year_month_combo": "DynamicYearMonthCombo", + "bi.dynamic_year_month_popup": "DynamicYearMonthPopup", + "bi.dynamic_year_month_trigger": "DynamicYearMonthTrigger", + "bi.year_month_interval": "YearMonthInterval", + "bi.dynamic_year_quarter_card": "DynamicYearQuarterCard", + "bi.static_year_quarter_card": "StaticYearQuarterCard", + "bi.dynamic_year_quarter_combo": "DynamicYearQuarterCombo", + "bi.dynamic_year_quarter_popup": "DynamicYearQuarterPopup", + "bi.dynamic_year_quarter_trigger": "DynamicYearQuarterTrigger", + "bi.year_quarter_interval": "YearQuarterInterval" +} diff --git a/scripts/lib/fui.export.txt b/scripts/lib/fui.export.txt new file mode 100644 index 000000000..b04b355ce --- /dev/null +++ b/scripts/lib/fui.export.txt @@ -0,0 +1,789 @@ +$ +$import +A +AbsoluteCenterLayout +AbsoluteHorizontalLayout +AbsoluteLayout +AbsoluteLeftRightVerticalAdaptLayout +AbsoluteRightVerticalAdaptLayout +AbsoluteVerticalLayout +AbstractLabel +AccurateCalculationModel +Action +ActionFactory +Actions +AdaptiveLayout +AllCountPager +AllValueMultiTextValueCombo +ArrowNode +ArrowTreeGroupNodeCheckbox +AsyncTree +AutoVerticalTapeLayout +Axis +BarPopover +BasicButton +BasicTreeItem +BasicTreeNode +Behavior +BehaviorFactory +BlankIconIconTextItem +BlankIconTextIconItem +BlankIconTextItem +BlankSplitChar +BorderLayout +BroadcastController +Broadcasts +Bubble +BubbleCombo +BubblePopupBarView +BubblePopupView +Bubbles +BubblesController +Button +ButtonGroup +ButtonTree +CRYPT_TYPE +Cache +Calendar +CalendarDateItem +CardLayout +CellSizeAndPositionManager +CenterAdaptLayout +CenterLayout +Checkbox +CheckingMarkNode +ClearEditor +Collapse +CollectionView +ColorChooser +ColorChooserPopup +ColorChooserShowButton +ColorChooserTrigger +ColorPicker +ColorPickerButton +ColorPickerEditor +Combo +ComboGroup +Constants +Controller +CustomColorChooser +CustomTree +DOM +Date +DateCalendarPopup +DateInterval +DatePicker +DateTimeCombo +DateTimePopup +DateTimeTrigger +DateTriangleTrigger +DefaultLayout +DefaultTextEditor +DetailPager +Direction +DirectionPager +DisplayTree +DivisionLayout +DownListCombo +DownListGroup +DownListGroupItem +DownListItem +DownListPopup +DownListSelectTextTrigger +Drawer +DrawerController +Drawers +DynamicDateCard +DynamicDateCombo +DynamicDateHelper +DynamicDatePane +DynamicDateParamItem +DynamicDatePopup +DynamicDateTimeCombo +DynamicDateTimePane +DynamicDateTimePopup +DynamicDateTimeSelect +DynamicDateTimeTrigger +DynamicDateTrigger +DynamicYearCard +DynamicYearCombo +DynamicYearMonthCard +DynamicYearMonthCombo +DynamicYearMonthPopup +DynamicYearMonthTrigger +DynamicYearPopup +DynamicYearQuarterCard +DynamicYearQuarterCombo +DynamicYearQuarterPopup +DynamicYearQuarterTrigger +DynamicYearTrigger +EVENT_BLUR +EVENT_RESPONSE_TIME +Editor +EditorIconCheckCombo +EditorTrigger +Element +EventListener +Events +Expander +Farbtastic +File +FirstPlusGroupNode +FirstTreeLeafItem +FirstTreeNodeCheckbox +Fix +FlexCenterLayout +FlexHorizontalCenter +FlexHorizontalCenterAdapt +FlexHorizontalLayout +FlexLeftRightVerticalAdaptLayout +FlexVerticalCenter +FlexVerticalCenterAdapt +FlexVerticalLayout +FlexWrapperCenterLayout +FlexWrapperHorizontalCenter +FlexWrapperHorizontalCenterAdapt +FlexWrapperHorizontalLayout +FlexWrapperVerticalCenter +FlexWrapperVerticalCenterAdapt +FlexWrapperVerticalLayout +FloatAbsoluteCenterLayout +FloatAbsoluteHorizontalLayout +FloatAbsoluteLeftRightVerticalAdaptLayout +FloatAbsoluteRightVerticalAdaptLayout +FloatAbsoluteVerticalLayout +FloatCenterLayout +FloatHorizontalFillLayout +FloatHorizontalLayout +FloatLeftLayout +FloatRightLayout +Fragment +Func +GridLayout +GridView +HTapeLayout +HalfButton +HalfIconButton +Heap +HexColorChooserPopup +HexColorPicker +HexColorPickerEditor +HighlightBehavior +HorizontalAdaptLayout +HorizontalAlign +HorizontalAutoLayout +HorizontalCenterLayout +HorizontalFillLayout +HorizontalFillLayoutLogic +HorizontalLayout +HorizontalLayoutLogic +HorizontalStickyLayout +Html +HtmlLabel +Icon +IconArrowNode +IconButton +IconChangeButton +IconCombo +IconComboPopup +IconComboTrigger +IconLabel +IconTextIconItem +IconTextIconNode +IconTextItem +IconTextNode +IconTextTrigger +IconTextValueCombo +IconTextValueComboPopup +IconTreeLeafItem +IconTrigger +Iframe +ImageButton +ImageCheckbox +ImageRadio +Img +InlineCenterAdaptLayout +InlineHorizontalAdaptLayout +InlineLayout +InlineVerticalAdaptLayout +Input +Instruction +IntervalSlider +Key +KeyCode +LRU +Label +LastPlusGroupNode +LastTreeLeafItem +LastTreeNodeCheckbox +LatticeLayout +LayerController +Layers +Layout +LazyLoader +LeftRightVerticalAdaptLayout +LeftVerticalAdaptLayout +LevelTree +LinearSegment +LinearSegmentButton +Link +LinkHashMap +ListDisplayTree +ListLoader +ListPane +ListPartTree +ListView +ListAsyncTree +ListTreeView +Loader +LoadingBar +Logic +LogicFactory +LongColorChooserTrigger +MAX +MIN +Maskers +MaskersController +MidPlusGroupNode +MidTreeLeafItem +MidTreeNodeCheckbox +Model +Models +Modules +MonthDateCombo +MonthPopup +MouseMoveTracker +Msg +MultiLayerDownListCombo +MultiLayerDownListPopup +MultiLayerIconArrowNode +MultiLayerIconTreeLeafItem +MultiLayerSelectLevelTree +MultiLayerSelectTreeCombo +MultiLayerSingleLevelTree +MultiLayerSingleTreeCombo +MultiLayerSingleTreeInsertSearchPane +MultiLayerSingleTreePopup +MultiLayerSingleTreeTrigger +MultiPopupView +MultiSelectBar +MultiSelectCheckSelectedSwitcher +MultiSelectCombo +MultiSelectEditor +MultiSelectInsertCombo +MultiSelectInsertList +MultiSelectInsertNoBarCombo +MultiSelectInsertNoBarList +MultiSelectItem +MultiSelectList +MultiSelectNoBarCombo +MultiSelectPopupView +MultiSelectSearchPane +MultiSelectSearcher +MultiSelectTrigger +MultiTreeCombo +MultiTreeInsertCombo +MultiTreeListCombo +MultifileEditor +Navigation +Node +NodeButton +NumberEditor +NumberInterval +OB +Pager +Pane +Panel +PartTree +Plugin +PlusGroupNode +Popover +PopoverController +Popovers +PopupPanel +PopupView +PrefixIntervalTree +Providers +PureText +Queue +Radio +RedMarkBehavior +Region +ResizeController +ResizeDetector +Resizers +ResponsiveFlexHorizontalLayout +ResponsiveFlexWrapperHorizontalLayout +ResponsiveInlineLayout +RightVerticalAdaptLayout +RootTreeLeafItem +Router +RouterView +RouterWidget +SIZE_CONSANTS +STYLE_CONSTANTS +ScalingCellSizeAndPositionManager +SearchEditor +SearchMultiSelectLoader +SearchMultiSelectPopupView +SearchMultiSelectSearcher +SearchMultiSelectTrigger +SearchMultiTextValueCombo +SearchTextValueCombo +SearchTextValueComboPopup +SearchTextValueTrigger +Searcher +SearcherView +SectionManager +Segment +SegmentButton +SelectIconTextTrigger +SelectList +SelectPatchEditor +SelectTextTrigger +SelectTreeCombo +SelectTreeExpander +Selection +Services +ShelterEditor +ShowAction +ShowListener +SignEditor +SignTextEditor +SimpleColorChooser +SimpleColorChooserPopup +SimpleColorPickerEditor +SimpleHexColorChooserPopup +SimpleHexColorPickerEditor +SimpleStateEditor +SimpleTreeView +Single +SingleSelectCombo +SingleSelectEditor +SingleSelectIconTextItem +SingleSelectInsertCombo +SingleSelectInsertList +SingleSelectItem +SingleSelectList +SingleSelectLoader +SingleSelectPopupView +SingleSelectRadioItem +SingleSelectSearchInsertPane +SingleSelectSearchLoader +SingleSelectSearchPane +SingleSelectSearcher +SingleSelectTrigger +SingleSlider +SingleSliderLabel +SingleSliderNormal +SingleTreeCombo +SliderIconButton +SmallSearchEditor +SmallSelectTextTrigger +SmallTextEditor +SmallTextTrigger +SmallTextValueCombo +SortList +StartOfWeek +StateEditor +StaticDatePaneCard +StaticDateTimePaneCard +StaticYearCard +StaticYearMonthCard +StaticYearQuarterCard +Status +Stores +StyleLoaderManager +StyleLoaders +Switch +Switcher +SystemProvider +Tab +TableAdaptLayout +TableLayout +TableLayoutLogic +TdLayout +Text +TextAreaEditor +TextBubblePopupBarView +TextButton +TextEditor +TextIconItem +TextIconNode +TextItem +TextNode +TextTrigger +TextValueCheckCombo +TextValueCheckComboPopup +TextValueCombo +TextValueComboPopup +TextValueDownListCombo +TimeCombo +TimeInterval +TimePeriods +TimePopup +TimeTrigger +Tip +Toast +Tooltip +Tooltips +TooltipsController +Tree +TreeExpander +TreeExpanderPopup +TreeNodeCheckbox +TreeNodeSwitcher +TreeRenderPageService +TreeRenderScrollService +TreeView +Trigger +TriggerIconButton +UUID +VTapeLayout +Vector +VerticalAdaptLayout +VerticalAlign +VerticalCenterLayout +VerticalFillLayout +VerticalLayout +VerticalLayoutLogic +VerticalStickyLayout +VirtualGroup +VirtualGroupList +VirtualList +WheelHandler +Widget +WindowLayout +YearCalendar +YearDateCombo +YearInterval +YearMonthInterval +YearPicker +YearPopup +YearQuarterInterval +_ +_lazyCreateWidget +abc2Int +action +add +addI18n +addI18nFormatter +aesDecrypt +aesEncrypt +after +afterFunc +all +allIndexOf +allKeys +allvaluechooser +any +appendQuery +array2String +aspect +assert +average +backAny +backEach +backEvery +backFind +backFindKey +before +beforeFunc +bind +camelize +chain +changeI18n +checkDateLegal +checkDateVoid +chunk +cjkDecode +cjkEncode +cjkEncodeDO +clamp +clone +cloneDeep +compact +component +concat +config +constant +contains +contentFormat +count +countBy +create +createDistinctName +createElement +createItems +createWidget +createWidgets +date2Str +debounce +decode +decodeURIComponent +decrypt +deepClone +deepContains +deepDiff +deepExtend +deepIndexOf +deepRemove +deepUnique +deepWithout +defaults +defer +delay +difference +div +each +empty +emptyFn +emptyStr +encode +encodeURIComponent +encrypt +endWith +escape +every +extend +extendOwn +filter +find +findIndex +findKey +findLastIndex +findWhere +first +firstKey +firstObject +flatten +form +format +formatEL +freeze +functions +get +getDate +getDayOfYear +getEncodeURL +getFullDayName +getGBWidth +getIEVersion +getLastDateOfMont +getLastDateOfMonth +getMinimumFontSize +getMonthDays +getMonthName +getOffsetDate +getOffsetMonth +getOffsetQuarter +getQuarter +getQuarterEndDate +getQuarterName +getQuarterStartDate +getQuarterStartMonth +getQuery +getReference +getResource +getSafariVersion +getSearchResult +getShortDayName +getSortedResult +getTime +getTimezone +getWeekEndDate +getWeekNumber +getWeekStartDate +groupBy +h +has +history +htmlDecode +htmlEncode +hyphenate +i18nText +indexBy +indexOf +inherit +init +initial +int2Abc +intersection +inverse +invert +invoke +isArguments +isArray +isBoolean +isCapitalEqual +isChrome +isDate +isDeepMatch +isEdge +isElement +isEmpty +isEmptyArray +isEmptyObject +isEmptyString +isEndWithBlank +isEqual +isError +isEven +isFinite +isFireFox +isFloat +isFunction +isIE +isIE9Below +isInteger +isKey +isKhtml +isLeapYear +isLiteral +isMac +isMatch +isNaN +isNaturalNumber +isNegativeInteger +isNotEmptyArray +isNotEmptyObject +isNotEmptyString +isNotNull +isNull +isNumber +isNumeric +isObject +isOdd +isOpera +isPlainObject +isPositiveInteger +isPromise +isRegExp +isSafari +isString +isSupportCss3 +isUndefined +isWidget +isWidthOrHeight +isWindow +isWindows +iteratee +jQuery +jsonDecode +jsonEncode +keys +last +lastIndexOf +lastKey +lastObject +leftPad +makeArray +makeArrayByArray +makeFirstPY +makeObject +map +mapObject +matcher +max +min +model +module +mount +mul +nextTick +object +object2Date +object2Number +object2Time +omit +onBeforeMount +onBeforeUnmount +onMounted +onUnmounted +once +packageItems +pairs +parseDateTime +parseFloat +parseFmt +parseInt +parseSafeInt +partial +partition +perfectStart +pick +pickBy +pixFormat +pixRatio +pixUnit +pluck +point +print +property +propertyOf +provider +pushArray +pushDistinct +pushDistinctArray +random +range +reduce +reduceRight +reject +remove +removeAt +replaceAll +rest +result +sample +service +set +shortcut +shuffle +size +some +sortBy +sortedIndex +specialCharsMap +startWith +store +str2Date +string2Array +stripEL +stripQuotes +sub +sum +take +takeRight +tap +throttle +toArray +toLowerCase +toPix +toUpperCase +trans2Element +treeValueChooser +trim +unescape +union +uniq +uniqBy +uniqueId +unzip +useContext +useInWorker +useStore +valueChooser +values +warn +watch +where +without +wrap +zIndex_layer +zIndex_masker +zIndex_popover +zIndex_popup +zIndex_tip +zip +zipObject \ No newline at end of file diff --git a/scripts/lib/utils.js b/scripts/lib/utils.js new file mode 100644 index 000000000..35b103acf --- /dev/null +++ b/scripts/lib/utils.js @@ -0,0 +1,24 @@ +const fs = require("fs"); +const path = require("path"); + +const defaultConfig = { + handler: () => {}, + filter: filePath => filePath.endsWith(".js"), +}; + +function tranvase(filePath, config) { + const { handler, filter } = Object.assign(defaultConfig, config); + if (fs.statSync(filePath).isDirectory()) { + fs.readdirSync(filePath).forEach(fileName => { + tranvase(path.resolve(filePath, fileName), config); + }); + } else if (filter(filePath)) { + handler(filePath); + } +} + +function getFuiExports() {} + +function getFuiComponent() {} + +module.exports = { tranvase, getFuiComponent, getFuiExports }; diff --git a/scripts/rename.js b/scripts/rename.js new file mode 100644 index 000000000..ec5d4691f --- /dev/null +++ b/scripts/rename.js @@ -0,0 +1,17 @@ +/** + * 将 FineUI 模块名从 fineui 改成 @fui/core + */ +const { tranvase } = require("./lib/utils"); +const fs = require("fs"); + +const config = { + handler: filePath => { + let content = fs.readFileSync(filePath).toString(); + content = content.replace(/(?<=from ["|'])fineui(?=["|'])/g, str => { + return "@fui/core"; + }); + fs.writeFileSync(filePath, content); + }, +}; + +tranvase(process.argv[2], config); diff --git a/server.js b/server.js deleted file mode 100644 index a9fd0cede..000000000 --- a/server.js +++ /dev/null @@ -1,13 +0,0 @@ -/*eslint no-console:0 */ -'use strict'; -const express = require('express'); -const open = require('open'); -const fs=require("fs"); -const app = express(); -const port = 3000; - -app.use(express.static("./")); -app.listen(port, function() { - console.log("server start"); - open('http://localhost:' + port + '/index.html'); -}); diff --git a/src/base/0.base.js b/src/base/0.base.js deleted file mode 100644 index 1100c0709..000000000 --- a/src/base/0.base.js +++ /dev/null @@ -1,9 +0,0 @@ -BI.Resizers = new BI.ResizeController(); -BI.Layers = new BI.LayerController(); -BI.Maskers = new BI.MaskersController(); -BI.Bubbles = new BI.BubblesController(); -BI.Tooltips = new BI.TooltipsController(); -BI.Popovers = new BI.PopoverController(); -BI.Drawers = new BI.DrawerController(); -BI.Broadcasts = new BI.BroadcastController(); -BI.StyleLoaders = new BI.StyleLoaderManager(); diff --git a/src/base/1.pane.js b/src/base/1.pane.js deleted file mode 100644 index d628ae7bf..000000000 --- a/src/base/1.pane.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 当没有元素时有提示信息的view - * - * Created by GUY on 2015/9/8. - * @class BI.Pane - * @extends BI.Widget - * @abstract - */ -BI.Pane = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.Pane.superclass._defaultConfig.apply(this, arguments), { - _baseCls: "bi-pane", - tipText: BI.i18nText("BI-No_Selected_Item"), - loadingText: "", - loadingSize: "small", - overlap: true, - onLoaded: BI.emptyFn, - }); - }, - - _assertTip: function () { - var self = this, o = this.options; - if (!this._tipText) { - BI.createWidget({ - type: "bi.absolute_center_adapt", - element: this, - items: [{ - type: "bi.label", - ref: function (_ref) { - self._tipText = _ref; - }, - cls: "bi-tips", - text: o.tipText, - height: 25, - }], - }); - } - }, - - loading: function () { - var self = this, o = this.options; - var loadingAnimation = BI.createWidget(BI.Providers.getProvider("bi.provider.system").getLoading({ - loadingSize: o.loadingSize, - context: this, - })); - // pane在同步方式下由items决定tipText的显示与否 - // loading的异步情况下由loaded后对面板的populate的时机决定 - this.setTipVisible(false); - if (o.overlap === true) { - if (!BI.Layers.has(this.getName() + "-loading")) { - BI.createWidget({ - type: "bi.center_adapt", - cls: "loading-container", - items: this._getLoadingTipItems(loadingAnimation), - element: BI.Layers.make(this.getName() + "-loading", this), - }); - } - BI.Layers.show(self.getName() + "-loading"); - } else if (BI.isNull(this._loading)) { - loadingAnimation.element.css("zIndex", 1); - BI.createWidget({ - type: "bi.center_adapt", - element: this, - cls: "loading-container", - items: this._getLoadingTipItems(loadingAnimation), - }); - } - self.fireEvent(BI.Pane.EVENT_LOADING); - this.element.addClass("loading-status"); - }, - - _getSize: function (v) { - return Math.ceil(v / (this.options.loadingSize === "small" ? 2 : 1)); - }, - - _getLoadingTipItems: function (loadingTip) { - var self = this, o = this.options; - var loadingTipItems = [{ - type: "bi.horizontal_adapt", - items: [loadingTip], - }]; - BI.isNotEmptyString(o.loadingText) && loadingTipItems.push({ - type: "bi.text", - text: o.loadingText, - tgap: this._getSize(10), - }); - - return [{ - type: "bi.vertical", - ref: function (_ref) { - self._loading = _ref; - }, - items: loadingTipItems, - }]; - }, - - loaded: function () { - var self = this, o = this.options; - BI.Layers.remove(self.getName() + "-loading"); - this._loading && this._loading.destroy(); - o.onLoaded(); - self.fireEvent(BI.Pane.EVENT_LOADED); - this.element.removeClass("loading-status"); - }, - - check: function () { - this.setTipVisible(BI.isEmpty(this.options.items)); - }, - - setTipVisible: function (b) { - if (b === true) { - this._assertTip(); - this._tipText && this._tipText.setVisible(true); - } else { - this._tipText && this._tipText.setVisible(false); - } - }, - - setTipText: function (text) { - this._assertTip(); - this._tipText.setText(text); - }, - - populate: function (items) { - this.options.items = items || []; - this.check(); - }, -}); -BI.Pane.EVENT_LOADED = "EVENT_LOADED"; -BI.Pane.EVENT_LOADING = "EVENT_LOADING"; - -BI.shortcut("bi.pane", BI.Pane); diff --git a/src/base/collection/collection.js b/src/base/collection/collection.js deleted file mode 100644 index cf561ab45..000000000 --- a/src/base/collection/collection.js +++ /dev/null @@ -1,430 +0,0 @@ -/** - * CollectionView - * - * Created by GUY on 2016/1/15. - * @class BI.CollectionView - * @extends BI.Widget - */ -BI.CollectionView = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-collection", - // width: 400, //必设 - // height: 300, //必设 - scrollable: true, - scrollx: false, - scrolly: false, - overflowX: true, - overflowY: true, - el: { - type: "bi.vertical" - }, - cellSizeAndPositionGetter: BI.emptyFn, - horizontalOverscanSize: 0, - verticalOverscanSize: 0, - scrollLeft: 0, - scrollTop: 0, - items: [], - itemFormatter: function (item, index) { - return item; - }, - }); - }, - - render: function () { - var self = this, o = this.options; - this.renderedCells = []; - this.renderedKeys = []; - this.renderRange = {}; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 1000 / 60); - this.container = BI._lazyCreateWidget({ - type: "bi.absolute", - }); - this.element.scroll(function () { - if (self._scrollLock === true) { - return; - } - o.scrollLeft = self.element.scrollLeft(); - o.scrollTop = self.element.scrollTop(); - self._calculateChildrenToRender(); - self.fireEvent(BI.CollectionView.EVENT_SCROLL, { - scrollLeft: o.scrollLeft, - scrollTop: o.scrollTop, - }); - }); - // 兼容一下 - var scrollable = o.scrollable, scrollx = o.scrollx, scrolly = o.scrolly; - if (o.overflowX === false) { - if (o.overflowY === false) { - scrollable = false; - } else { - scrollable = "y"; - } - } else { - if (o.overflowY === false) { - scrollable = "x"; - } - } - BI._lazyCreateWidget(o.el, { - type: "bi.vertical", - element: this, - scrollable: scrollable, - scrolly: scrolly, - scrollx: scrollx, - items: [this.container], - }); - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - if (o.items.length > 0) { - this._calculateSizeAndPositionData(); - this._populate(); - } - }, - - // mounted之后绑定事件 - mounted: function () { - var o = this.options; - if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } - }, - - _calculateSizeAndPositionData: function () { - var o = this.options; - var cellMetadata = []; - var sectionManager = new BI.SectionManager(); - var height = 0; - var width = 0; - - for (var index = 0, len = o.items.length; index < len; index++) { - var cellMetadatum = o.cellSizeAndPositionGetter(index); - - if (BI.isNull(cellMetadatum.height) || isNaN(cellMetadatum.height) || - BI.isNull(cellMetadatum.width) || isNaN(cellMetadatum.width) || - BI.isNull(cellMetadatum.x) || isNaN(cellMetadatum.x) || - BI.isNull(cellMetadatum.y) || isNaN(cellMetadatum.y)) { - throw Error(); - } - - height = Math.max(height, cellMetadatum.y + cellMetadatum.height); - width = Math.max(width, cellMetadatum.x + cellMetadatum.width); - - cellMetadatum.index = index; - cellMetadata[index] = cellMetadatum; - sectionManager.registerCell(cellMetadatum, index); - } - - this._cellMetadata = cellMetadata; - this._sectionManager = sectionManager; - this._height = height; - this._width = width; - }, - - _cellRenderers: function (height, width, x, y) { - this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y); - - return this._cellGroupRenderer(); - }, - - _cellGroupRenderer: function () { - var self = this; - var rendered = []; - BI.each(this._lastRenderedCellIndices, function (i, index) { - var cellMetadata = self._sectionManager.getCellMetadata(index); - rendered.push(cellMetadata); - }); - - return rendered; - }, - - _calculateChildrenToRender: function () { - var self = this, o = this.options; - var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()); - var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()); - var left = Math.max(0, scrollLeft - o.horizontalOverscanSize); - var top = Math.max(0, scrollTop - o.verticalOverscanSize); - var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize); - var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize); - if (right > 0 && bottom > 0) { - // 如果滚动的区间并没有超出渲染的范围 - if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) { - return; - } - var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); - var renderedCells = [], renderedKeys = {}, renderedWidgets = {}; - // 存储所有的left和top - var lefts = {}, tops = {}; - for (var i = 0, len = childrenToDisplay.length; i < len; i++) { - var datum = childrenToDisplay[i]; - lefts[datum.x] = datum.x; - lefts[datum.x + datum.width] = datum.x + datum.width; - tops[datum.y] = datum.y; - tops[datum.y + datum.height] = datum.y + datum.height; - } - lefts = BI.toArray(lefts); - tops = BI.toArray(tops); - var leftMap = BI.invert(lefts); - var topMap = BI.invert(tops); - // 存储上下左右四个边界 - var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {}; - function assertMinBorder(border, offset) { - if (BI.isNull(border[offset])) { - border[offset] = Number.MAX_VALUE; - } - } - function assertMaxBorder(border, offset) { - if (BI.isNull(border[offset])) { - border[offset] = 0; - } - } - for (var i = 0, len = childrenToDisplay.length; i < len; i++) { - var datum = childrenToDisplay[i]; - var index = this.renderedKeys[datum.index] && this.renderedKeys[datum.index][1]; - var child; - if (index >= 0) { - this.renderedCells[index].el.setWidth(datum.width); - this.renderedCells[index].el.setHeight(datum.height); - // 这里只使用px - this.renderedCells[index].el.element.css("left", datum.x + "px"); - this.renderedCells[index].el.element.css("top", datum.y + "px"); - renderedCells.push(child = this.renderedCells[index]); - } else { - var item = o.itemFormatter(o.items[datum.index], datum.index); - child = BI._lazyCreateWidget(BI.extend({ - type: "bi.label", - width: datum.width, - height: datum.height, - }, item, { - cls: (item.cls || "") + " collection-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : ""), - _left: datum.x, - _top: datum.y, - })); - renderedCells.push({ - el: child, - left: datum.x + "px", - top: datum.y + "px", - _left: datum.x, - _top: datum.y, - // _width: datum.width, - // _height: datum.height - }); - } - var startTopIndex = topMap[datum.y] | 0; - var endTopIndex = topMap[datum.y + datum.height] | 0; - for (var k = startTopIndex; k <= endTopIndex; k++) { - var t = tops[k]; - assertMinBorder(leftBorder, t); - assertMaxBorder(rightBorder, t); - leftBorder[t] = Math.min(leftBorder[t], datum.x); - rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width); - } - var startLeftIndex = leftMap[datum.x] | 0; - var endLeftIndex = leftMap[datum.x + datum.width] | 0; - for (var k = startLeftIndex; k <= endLeftIndex; k++) { - var l = lefts[k]; - assertMinBorder(topBorder, l); - assertMaxBorder(bottomBorder, l); - topBorder[l] = Math.min(topBorder[l], datum.y); - bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height); - } - - renderedKeys[datum.index] = [datum.index, i]; - renderedWidgets[i] = child; - } - // 已存在的, 需要添加的和需要删除的 - var existSet = {}, addSet = {}, deleteArray = []; - BI.each(renderedKeys, function (i, key) { - if (self.renderedKeys[i]) { - existSet[i] = key; - } else { - addSet[i] = key; - } - }); - BI.each(this.renderedKeys, function (i, key) { - if (existSet[i]) { - return; - } - if (addSet[i]) { - return; - } - deleteArray.push(key[1]); - }); - BI.each(deleteArray, function (i, index) { - // 性能优化,不调用destroy方法防止触发destroy事件 - self.renderedCells[index].el._destroy(); - }); - var addedItems = []; - BI.each(addSet, function (index, key) { - addedItems.push(renderedCells[key[1]]); - }); - this.container.addItems(addedItems); - // 拦截父子级关系 - this.container._children = renderedWidgets; - this.container.attr("items", renderedCells); - this.renderedCells = renderedCells; - this.renderedKeys = renderedKeys; - - // Todo 左右比较特殊 - var minX = BI.min(leftBorder); - var maxX = BI.max(rightBorder); - - var minY = BI.max(topBorder); - var maxY = BI.min(bottomBorder); - - this.renderRange = { minX: minX, minY: minY, maxX: maxX, maxY: maxY }; - } - }, - - _isOverflowX: function () { - var o = this.options; - // 兼容一下 - var scrollable = o.scrollable, scrollx = o.scrollx; - if (o.overflowX === false) { - return false; - } - if (scrollx) { - return true; - } - if (scrollable === true || scrollable === "xy" || scrollable === "x") { - return true; - } - return false; - }, - - _isOverflowY: function () { - var o = this.options; - // 兼容一下 - var scrollable = o.scrollable, scrolly = o.scrolly; - if (o.overflowY === false) { - return false; - } - if (scrolly) { - return true; - } - if (scrollable === true || scrollable === "xy" || scrollable === "y") { - return true; - } - return false; - }, - - _getMaxScrollLeft: function () { - return Math.max(0, this._width - this.options.width + (this._isOverflowX() ? BI.DOM.getScrollWidth() : 0)); - }, - - _getMaxScrollTop: function () { - return Math.max(0, this._height - this.options.height + (this._isOverflowY() ? BI.DOM.getScrollWidth() : 0)); - }, - - _populate: function (items) { - var o = this.options; - this._reRange(); - if (items && items !== this.options.items) { - this.options.items = items; - this._calculateSizeAndPositionData(); - } - this.container.setWidth(this._width); - this.container.setHeight(this._height); - - this._debounceRelease(); - // 元素未挂载时不能设置scrollTop - try { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } catch (e) { - } - this._calculateChildrenToRender(); - }, - - setScrollLeft: function (scrollLeft) { - if (this.options.scrollLeft === scrollLeft) { - return; - } - this._scrollLock = true; - this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft() || scrollLeft); - this._debounceRelease(); - this.element.scrollLeft(this.options.scrollLeft); - this._calculateChildrenToRender(); - }, - - setScrollTop: function (scrollTop) { - if (this.options.scrollTop === scrollTop) { - return; - } - this._scrollLock = true; - this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop() || scrollTop); - this._debounceRelease(); - this.element.scrollTop(this.options.scrollTop); - this._calculateChildrenToRender(); - }, - - setOverflowX: function (b) { - var self = this; - if (this.options.overflowX !== !!b) { - this.options.overflowX = !!b; - BI.nextTick(function () { - self.element.css({ overflowX: b ? "auto" : "hidden" }); - }); - } - }, - - setOverflowY: function (b) { - var self = this; - if (this.options.overflowY !== !!b) { - this.options.overflowY = !!b; - BI.nextTick(function () { - self.element.css({ overflowY: b ? "auto" : "hidden" }); - }); - } - }, - - getScrollLeft: function () { - return this.options.scrollLeft; - }, - - getScrollTop: function () { - return this.options.scrollTop; - }, - - getMaxScrollLeft: function () { - return this._getMaxScrollLeft(); - }, - - getMaxScrollTop: function () { - return this._getMaxScrollTop(); - }, - - // 重新计算children - _reRange: function () { - this.renderRange = {}; - }, - - _clearChildren: function () { - this.container._children = {}; - this.container.attr("items", []); - }, - - restore: function () { - BI.each(this.renderedCells, function (i, cell) { - cell.el._destroy(); - }); - this._clearChildren(); - this.renderedCells = []; - this.renderedKeys = []; - this.renderRange = {}; - this._scrollLock = false; - }, - - populate: function (items) { - if (items && items !== this.options.items) { - this.restore(); - } - this._populate(items); - }, -}); -BI.CollectionView.EVENT_SCROLL = "EVENT_SCROLL"; -BI.shortcut("bi.collection_view", BI.CollectionView); diff --git a/src/base/combination/bubble.js b/src/base/combination/bubble.js deleted file mode 100644 index 7b5f57736..000000000 --- a/src/base/combination/bubble.js +++ /dev/null @@ -1,513 +0,0 @@ -!(function () { - /** - * @class BI.Bubble - * @extends BI.Widget - */ - BI.Bubble = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.Bubble.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-popper", - attributes: { - tabIndex: -1, - }, - trigger: "click", // click || hover || click-hover || "hover-click" || "" - toggle: true, - direction: "", - placement: "bottom-start", // top-start/top/top-end/bottom-start/bottom/bottom-end/left-start/left/left-end/right-start/right/right-end - logic: { - dynamic: true, - }, - container: null, // popupview放置的容器,默认为this.element - isDefaultInit: false, - destroyWhenHide: false, - hideWhenClickOutside: true, - showArrow: true, - hideWhenBlur: false, - isNeedAdjustHeight: true, // 是否需要高度调整 - isNeedAdjustWidth: true, - stopEvent: false, - stopPropagation: false, - adjustLength: 0, // 调整的距离 - adjustXOffset: 0, - adjustYOffset: 0, - hideChecker: BI.emptyFn, - offsetStyle: "left", // left,right,center - el: {}, - popup: {}, - comboClass: "bi-combo-popup", - hoverClass: "bi-combo-hover", - }); - }, - - render: function () { - var self = this, o = this.options; - this._initCombo(); - // 延迟绑定事件,这样可以将自己绑定的事情优先执行 - BI.nextTick(() => { - !this.isDestroyed() && this._initPullDownAction(); - }); - this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self.isEnabled() && self.isValid()) { - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (type === BI.Events.EXPAND) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.Bubble.EVENT_EXPAND); - } - if (type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.isViewVisible() && self.fireEvent(BI.Bubble.EVENT_COLLAPSE); - } - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Bubble.EVENT_TRIGGER_CHANGE, obj); - } - } - }); - - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self.element.addClass(o.hoverClass); - } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self.element.removeClass(o.hoverClass); - } - }); - - BI.createWidget(BI.extend({ - element: this, - scrolly: false, - }, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { - items: [ - { el: this.combo } - ], - })))); - o.isDefaultInit && (this._assertPopupView()); - }, - - _toggle: function (e) { - this._assertPopupViewRender(); - if (this.popupView.isVisible()) { - this._hideView(e); - } else { - if (this.isEnabled()) { - this._popupView(e); - } - } - }, - - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = (this.options.trigger || "").split(","); - - function st(e) { - if (o.stopEvent) { - e.stopEvent(); - } - if (o.stopPropagation) { - e.stopPropagation(); - } - } - - var enterPopup = false; - - function hide(e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid() && o.toggle === true) { - self._hideView(e); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_COLLAPSE); - } - self.popupView && self.popupView.element.off("mouseenter." + self.getName()).off("mouseleave." + self.getName()); - enterPopup = false; - } - - BI.each(evs, function (i, ev) { - switch (ev) { - case "hover": - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self._popupView(e); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_EXPAND); - } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.popupView) { - self.popupView.element.on("mouseenter." + self.getName(), function (e) { - enterPopup = true; - self.popupView.element.on("mouseleave." + self.getName(), function (e) { - hide(e); - }); - self.popupView.element.off("mouseenter." + self.getName()); - }); - BI.defer(function () { - if (!enterPopup) { - hide(e); - } - }, 50); - } - }); - break; - case "click": - var debounce = BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - // if (!o.toggle && self.isViewVisible()) { - // return; - // } - o.toggle ? self._toggle(e) : self._popupView(e); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function (e) { - debounce(e); - st(e); - }); - break; - case "click-hover": - var debounce = BI.debounce(function (e) { - if (self.combo.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - // if (self.isViewVisible()) { - // return; - // } - self._popupView(e); - if (self.isViewVisible()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_EXPAND); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - self.element.off("click." + self.getName()).on("click." + self.getName(), function (e) { - debounce(e); - st(e); - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.popupView) { - self.popupView.element.on("mouseenter." + self.getName(), function (e) { - enterPopup = true; - self.popupView.element.on("mouseleave." + self.getName(), function (e) { - hide(e); - }); - self.popupView.element.off("mouseenter." + self.getName()); - }); - BI.delay(function () { - if (!enterPopup) { - hide(e); - } - }, 50); - } - }); - break; - case "hover-click": - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self._popupView(e); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); - self.fireEvent(BI.Bubble.EVENT_EXPAND); - } - }); - break; - default: - break; - } - }); - }, - - _initCombo: function () { - this.combo = BI.createWidget(this.options.el, { - value: this.options.value, - }); - }, - - _assertPopupView: function () { - var self = this, o = this.options; - if (BI.isNull(this.popupView)) { - this.popupView = BI.createWidget(BI.isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { - type: "bi.bubble_popup_view", - showArrow: o.showArrow, - value: o.value, - }, this); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - self.combo.setValue(self.getValue()); - self.fireEvent(BI.Bubble.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.popupView.setVisible(false); - BI.nextTick(function () { - self.fireEvent(BI.Bubble.EVENT_AFTER_INIT); - }); - } - }, - - _assertPopupViewRender: function () { - this._assertPopupView(); - if (!this._rendered) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: BI.isFunction(this.options.container) ? this.options.container() : (this.options.container || this), - items: [ - { el: this.popupView } - ], - }); - this._rendered = true; - } - }, - - _hideIf: function (e, skipTriggerChecker) { - // if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { - // return; - // } - // BI-10290 公式combo双击公式内容会收起 - if (e && ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) - || (this.popupView && this.popupView.element.find(e.target).length > 0) - || e.target.className === "CodeMirror-cursor" || BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0)) {// BI-9887 CodeMirror的公式弹框需要特殊处理下 - var directions = this.options.direction.split(","); - if (BI.contains(directions, "innerLeft") || BI.contains(directions, "innerRight")) { - // popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置 - this.adjustWidth(); - this.adjustHeight(); - } - - return; - } - var isHide = this.options.hideChecker.apply(this, [e]); - if (isHide === false) { - return; - } - this._hideView(e); - - return true; - }, - - _hideView: function (e) { - var o = this.options; - this.fireEvent(BI.Bubble.EVENT_BEFORE_HIDEVIEW); - if (this.options.destroyWhenHide === true) { - this.popupView && this.popupView.destroy(); - this.popupView = null; - this._rendered = false; - } else { - this.popupView && this.popupView.invisible(); - } - - if (!e || !this.combo.element.__isMouseInBounds__(e)) { - this.element.removeClass(this.options.hoverClass); - // 应对bi-focus-shadow在收起时不失焦 - this.element.blur(); - } - - if (this.popper) { - this.popper.destroy(); - this.popper = null; - } - - this.element.removeClass(this.options.comboClass); - - BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); - this.fireEvent(BI.Bubble.EVENT_AFTER_HIDEVIEW); - }, - - _popupView: function (e) { - var o = this.options; - this._assertPopupViewRender(); - this.fireEvent(BI.Bubble.EVENT_BEFORE_POPUPVIEW); - // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 - // this.popupView.css({left: -999999999, top: -99999999}); - this.popupView.visible(); - this.adjustWidth(e); - - if (this.popper) { - this.popper.destroy(); - } - var modifiers = [ - { - name: "offset", - options: { - offset: function () { - return [o.adjustXOffset, (o.showArrow ? 12 : 0) + (o.adjustYOffset + o.adjustLength)]; - }, - }, - } - ]; - if (this.options.showArrow) { - modifiers.push({ - name: "arrow", - options: { - padding: 4, - element: this.popupView.arrow.element[0], - }, - }); - } - this.popper = BI.Popper.createPopper(this.combo.element[0], this.popupView.element[0], { - placement: o.placement, - strategy: "fixed", - modifiers: modifiers, - }); - - // this.adjustHeight(e); - - this.element.addClass(this.options.comboClass); - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); - - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); - this.fireEvent(BI.Bubble.EVENT_AFTER_POPUPVIEW); - }, - - adjustWidth: function (e) { - var o = this.options; - if (!this.popupView) { - return; - } - if (o.isNeedAdjustWidth === true) { - this.resetListWidth(""); - var width = this.popupView.element.outerWidth(); - var maxW = this.element.outerWidth() || o.width; - // BI-93885 最大列宽算法调整 - if (maxW < 500) { - if (width >= 500) { - maxW = 500; - } else if (width > maxW) { - // 防止小数导致差那么一点 - maxW = width + 1; - } - } - - // if (width > maxW + 80) { - // maxW = maxW + 80; - // } else if (width > maxW) { - // maxW = width; - // } - this.resetListWidth(maxW < 100 ? 100 : maxW); - } - }, - - adjustHeight: function () { - - }, - - resetListHeight: function (h) { - this._assertPopupView(); - this.popupView.resetHeight && this.popupView.resetHeight(h); - }, - - resetListWidth: function (w) { - this._assertPopupView(); - this.popupView.resetWidth && this.popupView.resetWidth(w); - }, - - populate: function (items) { - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - this.combo.populate && this.combo.populate.apply(this.combo, arguments); - }, - - _setEnable: function (arg) { - BI.Bubble.superclass._setEnable.apply(this, arguments); - if (arg === true) { - this.element.removeClass("base-disabled disabled"); - } else if (arg === false) { - this.element.addClass("base-disabled disabled"); - } - !arg && this.element.removeClass(this.options.hoverClass); - !arg && this.isViewVisible() && this._hideView(); - }, - - setValue: function (v) { - this.combo.setValue(v); - if (BI.isNull(this.popupView)) { - this.options.popup.value = v; - } else { - this.popupView.setValue(v); - } - }, - - getValue: function () { - if (BI.isNull(this.popupView)) { - return this.options.popup.value; - } else { - return this.popupView.getValue(); - } - }, - - isViewVisible: function () { - return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); - }, - - showView: function (e) { - // 减少popup 调整宽高的次数 - if (this.isEnabled() && this.combo.isEnabled() && !this.isViewVisible()) { - this._popupView(e); - } - }, - - hideView: function (e) { - this._hideView(e); - }, - - getView: function () { - return this.popupView; - }, - - getPopupPosition: function () { - return this.position; - }, - - toggle: function () { - this._toggle(); - }, - - destroyed: function () { - BI.Widget._renderEngine.createElement(document) - .unbind("click." + this.getName()) - .unbind("mousedown." + this.getName()) - .unbind("mouseenter." + this.getName()) - .unbind("mouseleave." + this.getName()); - BI.Widget._renderEngine.createElement(window) - .unbind("blur." + this.getName()); - this.popper && this.popper.destroy(); - this.popper = null; - this.popupView && this.popupView._destroy(); - }, - }); - BI.Bubble.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; - BI.Bubble.EVENT_CHANGE = "EVENT_CHANGE"; - BI.Bubble.EVENT_EXPAND = "EVENT_EXPAND"; - BI.Bubble.EVENT_COLLAPSE = "EVENT_COLLAPSE"; - BI.Bubble.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - - BI.Bubble.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - BI.Bubble.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; - BI.Bubble.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; - BI.Bubble.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - - BI.shortcut("bi.bubble", BI.Bubble); -}()); diff --git a/src/base/combination/combo.js b/src/base/combination/combo.js deleted file mode 100644 index 75c45a4fe..000000000 --- a/src/base/combination/combo.js +++ /dev/null @@ -1,374 +0,0 @@ -!(function () { - var needHideWhenAnotherComboOpen = {}; - var currentOpenedCombos = {}; - - /** - * @class BI.Combo - * @extends BI.Widget - */ - BI.Combo = BI.inherit(BI.Bubble, { - _const: { - TRIANGLE_LENGTH: 12, - }, - _defaultConfig: function () { - var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), - attributes: { - tabIndex: -1, - }, - trigger: "click", // click || hover || click-hover || "" - toggle: true, - direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right||right,innerRight||right,innerLeft||innerRight||innerLeft - logic: { - dynamic: true, - }, - container: null, // popupview放置的容器,默认为this.element - isDefaultInit: false, - destroyWhenHide: false, - hideWhenBlur: true, - hideWhenAnotherComboOpen: false, - hideWhenClickOutside: true, - showArrow: false, - isNeedAdjustHeight: true, // 是否需要高度调整 - isNeedAdjustWidth: true, - stopEvent: false, - stopPropagation: false, - adjustLength: 0, // 调整的距离 - adjustXOffset: 0, - adjustYOffset: 0, - supportCSSTransform: true, - hideChecker: BI.emptyFn, - offsetStyle: "", // "",center,middle - el: {}, - popup: {}, - comboClass: "bi-combo-popup", - hoverClass: "bi-combo-hover", - belowMouse: false, - }); - }, - - render: function () { - var self = this, o = this.options; - this._initCombo(); - // 延迟绑定事件,这样可以将自己绑定的事情优先执行 - BI.nextTick(() => { - !this.isDestroyed() && this._initPullDownAction(); - }); - this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self.isEnabled() && self.isValid()) { - if (type === BI.Events.TOGGLE) { - self._toggle(); - } - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (type === BI.Events.EXPAND) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.Combo.EVENT_EXPAND); - } - if (type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.isViewVisible() && self.fireEvent(BI.Combo.EVENT_COLLAPSE); - } - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); - } - } - }); - - self.element.on("mouseenter." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self.element.addClass(o.hoverClass); - } - }); - self.element.on("mouseleave." + self.getName(), function (e) { - if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { - self.element.removeClass(o.hoverClass); - } - }); - - BI.createWidget(BI.extend({ - element: this, - scrolly: false, - }, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { - items: [ - { el: this.combo } - ], - })))); - o.isDefaultInit && (this._assertPopupView()); - BI.Resizers.add(this.getName(), BI.bind(function (e) { - // 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理 - if (this.isViewVisible()) { - BI.isNotNull(e) ? this._hideIf(e) : this._hideView(); - } - }, this)); - }, - - _assertPopupView: function () { - var self = this, o = this.options; - if (BI.isNull(this.popupView)) { - this.popupView = BI.createWidget(BI.isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { - type: "bi.popup_view", - showArrow: o.showArrow, - value: o.value, - }, this); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - self.combo.setValue(self.getValue()); - self.fireEvent(BI.Bubble.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.popupView.setVisible(false); - BI.nextTick(function () { - self.fireEvent(BI.Bubble.EVENT_AFTER_INIT); - }); - } - }, - - _hideView: function (e) { - var o = this.options; - this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); - if (this.options.destroyWhenHide === true) { - this.popupView && this.popupView.destroy(); - this.popupView = null; - this._rendered = false; - } else { - this.popupView && this.popupView.invisible(); - } - - if (!e || !this.combo.element.__isMouseInBounds__(e)) { - this.element.removeClass(this.options.hoverClass); - // 应对bi-focus-shadow在收起时不失焦 - this.element.blur(); - } - - this.element.removeClass(this.options.comboClass); - delete needHideWhenAnotherComboOpen[this.getName()]; - delete currentOpenedCombos[this.getName()]; - - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); - this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW, e); - }, - - _popupView: function (e) { - var self = this, o = this.options; - this._assertPopupViewRender(); - this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); - // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 - this.popupView.css({ left: -99999, top: -99999 }); - this.popupView.visible(); - BI.each(needHideWhenAnotherComboOpen, function (i, combo) { - if (i !== self.getName()) { - if (combo && combo._hideIf(e, true) === true) { - delete needHideWhenAnotherComboOpen[i]; - } - } - }); - currentOpenedCombos[this.getName()] = this; - this.options.hideWhenAnotherComboOpen && (needHideWhenAnotherComboOpen[this.getName()] = this); - this.adjustWidth(e); - this.adjustHeight(e); - - this.element.addClass(this.options.comboClass); - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousewheel." + this.getName()); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); - - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); - o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); - BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); - this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); - }, - - adjustHeight: function (e) { - var o = this.options, p = {}; - if (!this.popupView) { - return; - } - var isVisible = this.popupView.isVisible(); - this.popupView.visible(); - var combo = (o.belowMouse && BI.isNotNull(e)) ? { - element: { - 0: BI.extend({}, e.target, { - getBoundingClientRect: function () { - return { - left: e.pageX, - top: e.pageY, - width: 0, - height: 0, - }; - } - }), - offset: function () { - return { - left: e.pageX, - top: e.pageY, - }; - }, - }, - } : this.combo; - - var positionRelativeElement = BI.DOM.getPositionRelativeContainingBlock( - BI.isNull(o.container) - ? this.element[0] - : BI.isWidget(o.container) - ? o.container.element[0] - : BI.Widget._renderEngine.createElement(BI.isFunction(o.container) ? o.container() : o.container)[0] - ); - - switch (o.direction) { - case "bottom": - case "bottom,right": - p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "right", "left"], o.offsetStyle, positionRelativeElement); - break; - case "top": - case "top,right": - p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "right", "left"], o.offsetStyle, positionRelativeElement); - break; - case "left": - case "left,bottom": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "right": - case "right,bottom": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "top,left": - p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "left", "right"], o.offsetStyle, positionRelativeElement); - break; - case "bottom,left": - p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "left", "right"], o.offsetStyle, positionRelativeElement); - break; - case "left,top": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "top", "bottom"], o.offsetStyle, positionRelativeElement); - break; - case "right,top": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "top", "bottom"], o.offsetStyle, positionRelativeElement); - break; - case "right,innerRight": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "right,innerLeft": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "innerRight": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "innerLeft": - p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement); - break; - case "top,custom": - case "custom,top": - p = BI.DOM.getTopAdaptPosition(combo, this.popupView, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight); - p.dir = "top"; - break; - case "custom,bottom": - case "bottom,custom": - p = BI.DOM.getBottomAdaptPosition(combo, this.popupView, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight); - p.dir = "bottom"; - break; - case "left,custom": - case "custom,left": - p = BI.DOM.getLeftAdaptPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0)); - delete p.top; - delete p.adaptHeight; - p.dir = "left"; - break; - case "custom,right": - case "right,custom": - p = BI.DOM.getRightAdaptPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0)); - delete p.top; - delete p.adaptHeight; - p.dir = "right"; - break; - default: - break; - } - - var width = this.combo.element.outerWidth(); - var height = this.combo.element.outerHeight(); - this.popupView.setDirection && this.popupView.setDirection(p.dir, { - width: width, - height: height, - offsetStyle: o.offsetStyle, - adjustXOffset: o.adjustXOffset, - adjustYOffset: o.adjustYOffset, - offset: this.combo.element.offset(), - }); - - if (o.supportCSSTransform) { - - var positonedRect = positionRelativeElement.getBoundingClientRect(); - - var scaleX = positonedRect.width / positionRelativeElement.offsetWidth; - var scaleY = positonedRect.height / positionRelativeElement.offsetHeight; - - p.top && (p.top = Math.round(p.top / scaleY + positionRelativeElement.scrollTop)); - p.left && (p.left = Math.round(p.left / scaleX + positionRelativeElement.scrollLeft)); - - p.adaptHeight && (p.adaptHeight = Math.round(p.adaptHeight / scaleY)); - } - - if ("adaptHeight" in p) { - this.resetListHeight(p.adaptHeight); - } - - if ("left" in p) { - this.popupView.element.css({ - left: p.left, - }); - } - if ("top" in p) { - this.popupView.element.css({ - top: p.top, - }); - } - this.position = p; - this.popupView.setVisible(isVisible); - }, - - destroyed: function () { - BI.Widget._renderEngine.createElement(document) - .unbind("click." + this.getName()) - .unbind("mousedown." + this.getName()) - .unbind("mousewheel." + this.getName()) - .unbind("mouseenter." + this.getName()) - .unbind("mouseleave." + this.getName()); - BI.Widget._renderEngine.createElement(window) - .unbind("blur." + this.getName()); - BI.Resizers.remove(this.getName()); - this.popupView && this.popupView._destroy(); - delete needHideWhenAnotherComboOpen[this.getName()]; - delete currentOpenedCombos[this.getName()]; - }, - }); - BI.Combo.closeAll = function () { - BI.each(currentOpenedCombos, function (i, combo) { - if (combo) { - combo.hideView(); - } - }); - currentOpenedCombos = {}; - needHideWhenAnotherComboOpen = {}; - }; - BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; - BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; - BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; - BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; - BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - - BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; - BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; - BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - - BI.shortcut("bi.combo", BI.Combo); -}()); diff --git a/src/base/combination/expander.js b/src/base/combination/expander.js deleted file mode 100644 index 60b3dd471..000000000 --- a/src/base/combination/expander.js +++ /dev/null @@ -1,288 +0,0 @@ -/** - * - * 某个可以展开的节点 - * - * Created by GUY on 2015/9/10. - * @class BI.Expander - * @extends BI.Widget - */ -BI.Expander = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Expander.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-expander", - trigger: "click", - toggle: true, - // direction: "bottom", //top,bottom四个方向 - isDefaultInit: false, // 是否默认初始化子节点 - el: {}, - popup: {}, - expanderClass: "bi-expander-popup", - hoverClass: "bi-expander-hover", - }); - }, - - render: function () { - var self = this, o = this.options; - this._expanded = !!o.el.open; - this._initExpander(); - // 延迟绑定事件,这样可以将自己绑定的事情优先执行 - BI.nextTick(() => { - !this.isDestroyed() && this._initPullDownAction(); - }); - this.expander.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self.isEnabled() && self.isValid()) { - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (type === BI.Events.EXPAND) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.Expander.EVENT_EXPAND); - } - if (type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.isViewVisible() && self.fireEvent(BI.Expander.EVENT_COLLAPSE); - } - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Expander.EVENT_TRIGGER_CHANGE, value, obj); - } - } - }); - - this.element.hover(function () { - if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { - self.element.addClass(o.hoverClass); - } - }, function () { - if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { - self.element.removeClass(o.hoverClass); - } - }); - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - { el: this.expander } - ], - }); - o.isDefaultInit && this._assertPopupView(); - if (this.expander.isOpened() === true) { - this._popupView(); - } - }, - - _toggle: function () { - this._assertPopupViewRender(); - if (this.popupView.isVisible()) { - this._hideView(); - } else { - if (this.isEnabled()) { - this._popupView(); - } - } - }, - - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = this.options.trigger.split(","); - BI.each(evs, function (i, e) { - switch (e) { - case "hover": - self.element[e](function (e) { - if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { - self._popupView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); - self.fireEvent(BI.Expander.EVENT_EXPAND); - } - }, function () { - if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid() && o.toggle) { - self._hideView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.expander); - self.fireEvent(BI.Expander.EVENT_COLLAPSE); - } - }); - break; - case "click": - if (e) { - self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { - if (self.expander.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isExpanded()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); - self.fireEvent(BI.Expander.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.expander); - self.fireEvent(BI.Expander.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - })); - } - break; - default: - break; - } - }); - }, - - _initExpander: function () { - this.expander = BI.createWidget(this.options.el); - }, - - _assertPopupView: function () { - var self = this, o = this.options; - if (BI.isNull(this.popupView)) { - this.popupView = BI.createWidget(this.options.popup, { - type: "bi.button_group", - cls: "expander-popup", - layouts: [{ - type: "bi.vertical", - hgap: 0, - vgap: 0, - }], - value: o.value, - }, this); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - // self.setValue(self.getValue()); - self.fireEvent(BI.Expander.EVENT_CHANGE, value, obj); - } - }); - this.popupView.setVisible(this.isExpanded()); - BI.nextTick(function () { - self.fireEvent(BI.Expander.EVENT_AFTER_INIT); - }); - } - }, - - _assertPopupViewRender: function () { - this._assertPopupView(); - if (!this._rendered) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - { el: this.popupView } - ], - }); - this._rendered = true; - } - }, - - _hideView: function () { - this.fireEvent(BI.Expander.EVENT_BEFORE_HIDEVIEW); - this._expanded = false; - this.expander.setOpened(false); - this.popupView && this.popupView.invisible(); - this.element.removeClass(this.options.expanderClass); - - this.fireEvent(BI.Expander.EVENT_AFTER_HIDEVIEW); - }, - - _popupView: function () { - this._assertPopupViewRender(); - this.fireEvent(BI.Expander.EVENT_BEFORE_POPUPVIEW); - this._expanded = true; - this.expander.setOpened(true); - this.popupView.visible(); - this.element.addClass(this.options.expanderClass); - this.fireEvent(BI.Expander.EVENT_AFTER_POPUPVIEW); - }, - - populate: function (items) { - // this._assertPopupView(); - this.popupView && this.popupView.populate.apply(this.popupView, arguments); - this.expander.populate && this.expander.populate.apply(this.expander, arguments); - }, - - _setEnable: function (arg) { - BI.Expander.superclass._setEnable.apply(this, arguments); - !arg && this.element.removeClass(this.options.hoverClass); - !arg && this.isViewVisible() && this._hideView(); - }, - - setValue: function (v) { - this.expander.setValue(v); - if (BI.isNull(this.popupView)) { - this.options.popup.value = v; - } else { - this.popupView.setValue(v); - } - }, - - getValue: function () { - if (BI.isNull(this.popupView)) { - return this.options.popup.value; - } else { - return this.popupView.getValue(); - } - }, - - isViewVisible: function () { - return this.isEnabled() && this.expander.isEnabled() && !!this.popupView && this.popupView.isVisible(); - }, - - isExpanded: function () { - return this._expanded; - }, - - showView: function () { - if (this.isEnabled() && this.expander.isEnabled()) { - this._popupView(); - } - }, - - hideView: function () { - this._hideView(); - }, - - getView: function () { - return this.popupView; - }, - - getAllLeaves: function () { - return this.popupView && this.popupView.getAllLeaves(); - }, - - getNodeById: function (id) { - if (this.expander.options.id === id) { - return this.expander; - } - - return this.popupView && this.popupView.getNodeById(id); - }, - - getNodeByValue: function (value) { - if (this.expander.getValue() === value) { - return this.expander; - } - - return this.popupView && this.popupView.getNodeByValue(value); - }, - - destroy: function () { - BI.Expander.superclass.destroy.apply(this, arguments); - }, -}); -BI.Expander.EVENT_EXPAND = "EVENT_EXPAND"; -BI.Expander.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.Expander.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.Expander.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Expander.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.Expander.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.Expander.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.Expander.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.Expander.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - -BI.shortcut("bi.expander", BI.Expander); diff --git a/src/base/combination/group.button.js b/src/base/combination/group.button.js deleted file mode 100644 index 02b044b17..000000000 --- a/src/base/combination/group.button.js +++ /dev/null @@ -1,384 +0,0 @@ -/** - * Created by GUY on 2015/6/26. - * @class BI.ButtonGroup - * @extends BI.Widget - */ - -BI.ButtonGroup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ButtonGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-group", - behaviors: {}, - items: [], - value: "", - chooseType: BI.Selection.Single, - layouts: [{ - type: "bi.center", - hgap: 0, - vgap: 0, - }], - }); - }, - - render: function () { - var self = this, o = this.options; - var behaviors = {}; - BI.each(o.behaviors, function (key, rule) { - behaviors[key] = BI.BehaviorFactory.createBehavior(key, { - rule: rule, - }); - }); - this.behaviors = behaviors; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - if (BI.isKey(o.value) || BI.isNotEmptyArray(o.value)) { - this.setValue(o.value); - } - }, - - _createBtns: function (items) { - var btns; - BI.Widget.execWithContext(this, function () { - btns = BI.createWidgets(BI.createItems(items, { - type: "bi.text_button", - })); - }); - - return btns; - }, - - _btnsCreator: function (items) { - var self = this, args = Array.prototype.slice.call(arguments), o = this.options; - var buttons = this._createBtns(items); - args[0] = buttons; - - BI.each(this.behaviors, function (i, behavior) { - behavior.doBehavior.apply(behavior, args); - }); - BI.each(buttons, function (i, btn) { - btn.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - switch (o.chooseType) { - case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: - self.setValue(btn.getValue()); - break; - case BI.ButtonGroup.CHOOSE_TYPE_NONE: - self.setValue([]); - break; - default: - break; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.ButtonGroup.EVENT_CHANGE, value, obj); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }); - btn.on(BI.Events.DESTROY, function () { - BI.remove(self.buttons, btn); - }); - }); - - return buttons; - }, - - _packageBtns: function (btns) { - var o = this.options; - var layouts = BI.isArray(o.layouts) ? o.layouts : [o.layouts]; - for (var i = layouts.length - 1; i > 0; i--) { - btns = BI.map(btns, function (k, it) { - return BI.extend({}, layouts[i], { - items: [ - BI.extend({}, layouts[i].el, { - el: it, - }) - ], - }); - }); - } - - return btns; - }, - - _packageSimpleItems: function (btns) { - var o = this.options; - - return BI.map(o.items, function (i, item) { - if (BI.stripEL(item) === item) { - return btns[i]; - } - - return BI.extend({}, item, { - el: btns[i], - }); - }); - }, - - _packageItems: function (items, packBtns) { - return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); - }, - - _packageLayout: function (items) { - var o = this.options, layout = BI.deepClone(BI.isArray(o.layouts) ? o.layouts[0] : o.layouts); - - var lay = BI.formatEL(layout).el; - while (lay && lay.items && !BI.isEmpty(lay.items)) { - lay = BI.formatEL(lay.items[0]).el; - } - lay.items = items; - - return layout; - }, - - // 如果是一个简单的layout - _isSimpleLayout: function () { - var o = this.options; - - return BI.isArray(o.layouts) ? (o.layouts.length === 1 && !BI.isArray(o.items[0])) : true; - }, - - doBehavior: function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(this.buttons); - BI.each(this.behaviors, function (i, behavior) { - behavior.doBehavior.apply(behavior, args); - }); - }, - - prependItems: function (items) { - var btns = this._btnsCreator.apply(this, arguments); - this.buttons = BI.concat(btns, this.buttons); - - if (this._isSimpleLayout() && this.layouts && this.layouts.prependItems) { - this.layouts.prependItems(btns); - - return; - } - - items = this._packageItems(items, this._packageBtns(btns)); - this.layouts.prependItems(this._packageLayout(items).items); - }, - - addItems: function (items) { - var btns = this._btnsCreator.apply(this, arguments); - this.buttons = BI.concat(this.buttons, btns); - - // 如果是一个简单的layout - if (this._isSimpleLayout() && this.layouts && this.layouts.addItems) { - this.layouts.addItems(btns); - - return; - } - - items = this._packageItems(items, this._packageBtns(btns)); - this.layouts.addItems(this._packageLayout(items).items); - }, - - removeItemAt: function (indexes) { - BI.removeAt(this.buttons, indexes); - this.layouts.removeItemAt(indexes); - }, - - removeItems: function (values) { - values = BI.isArray(values) ? values : [values]; - var deleted = []; - BI.each(this.buttons, function (i, button) { - if (BI.deepContains(values, button.getValue())) { - deleted.push(i); - } - }); - BI.removeAt(this.buttons, deleted); - this.layouts.removeItemAt(deleted); - }, - - populate: function (items) { - items = items || []; - this.empty(); - this.options.items = items; - - this.buttons = this._btnsCreator.apply(this, arguments); - if (this._isSimpleLayout()) { - items = this._packageSimpleItems(this.buttons); - } else { - items = this._packageItems(items, this._packageBtns(this.buttons)); - } - - this.layouts = BI.createWidget(BI.extend({ element: this }, this._packageLayout(items))); - }, - - setNotSelectedValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); - }, - - setEnabledValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setEnable(true); - } else { - item.setEnable(false); - } - }); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.deepContains(v, item.getValue())) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); - }, - - setValueMap: function (map) { - map = map || {}; - BI.each(this.buttons, function (i, item) { - if (BI.has(map, item.getValue())) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); - }, - - setAllSelected: function (v) { - BI.each(this.getAllButtons(), function (i, btn) { - (btn.setSelected || btn.setAllSelected).apply(btn, [v]); - }); - }, - - getNotSelectedValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !(item.isSelected && item.isSelected())) { - v.push(item.getValue()); - } - }); - - return v; - }, - - getValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && item.isSelected && item.isSelected()) { - v.push(item.getValue()); - } - }); - - return v; - }, - - getAllButtons: function () { - return this.buttons; - }, - - getAllLeaves: function () { - return this.buttons; - }, - - getSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isSelected && item.isSelected()) { - btns.push(item); - } - }); - - return btns; - }, - - getNotSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isSelected && !item.isSelected()) { - btns.push(item); - } - }); - - return btns; - }, - - getIndexByValue: function (value) { - var index = -1; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.getValue() === value) { - index = i; - - return true; - } - }); - - return index; - }, - - getNodeById: function (id) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.options.id === id) { - node = item; - - return true; - } - }); - - return node; - }, - - getNodeByValue: function (value) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled() && item.getValue() === value) { - node = item; - - return true; - } - }); - - return node; - }, - - /** - * 滚动到指定的节点 - */ - scrollToValue: function (value, scrollIntoViewOptions) { - var node = this.getNodeByValue(value); - if (node) { - node.element[0].scrollIntoView(scrollIntoViewOptions); - } - }, - - empty: function () { - BI.ButtonGroup.superclass.empty.apply(this, arguments); - this.options.items = []; - }, - - destroy: function () { - BI.ButtonGroup.superclass.destroy.apply(this, arguments); - this.options.items = []; - }, -}); -BI.extend(BI.ButtonGroup, { - CHOOSE_TYPE_SINGLE: BI.Selection.Single, - CHOOSE_TYPE_MULTI: BI.Selection.Multi, - CHOOSE_TYPE_ALL: BI.Selection.All, - CHOOSE_TYPE_NONE: BI.Selection.None, - CHOOSE_TYPE_DEFAULT: BI.Selection.Default, -}); -BI.ButtonGroup.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.button_group", BI.ButtonGroup); diff --git a/src/base/combination/group.combo.js b/src/base/combination/group.combo.js deleted file mode 100644 index 12e11cad7..000000000 --- a/src/base/combination/group.combo.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Created by GUY on 2015/8/10. - */ - -BI.ComboGroup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ComboGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-combo-group bi-list-item", - - // 以下这些属性对每一个combo都是公用的 - trigger: "click,hover", - direction: "right", - adjustLength: 0, - isDefaultInit: false, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - - el: { type: "bi.text_button", text: "", value: "" }, - items: [], - - popup: { - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [ - { - type: "bi.vertical", - } - ], - }, - }, - }); - }, - - render: function () { - this._populate(this.options.el); - }, - - _populate: function (item) { - var self = this, o = this.options; - var children = o.items; - if (BI.isEmpty(children)) { - throw new Error("ComboGroup create items error"); - } - BI.each(children, function (i, ch) { - var son = BI.formatEL(ch).el.children; - ch = BI.formatEL(ch).el; - if (!BI.isEmpty(son)) { - ch.el = BI.clone(ch); - ch.items = son; - ch.type = "bi.combo_group"; - ch.action = o.action; - ch.height = o.height; - ch.direction = o.direction; - ch.isDefaultInit = o.isDefaultInit; - ch.isNeedAdjustHeight = o.isNeedAdjustHeight; - ch.isNeedAdjustWidth = o.isNeedAdjustWidth; - ch.adjustLength = o.adjustLength; - ch.popup = o.popup; - } - }); - this.combo = BI.createWidget({ - type: "bi.combo", - element: this, - container: o.container, - height: o.height, - trigger: o.trigger, - direction: o.direction, - isDefaultInit: o.isDefaultInit, - isNeedAdjustWidth: o.isNeedAdjustWidth, - isNeedAdjustHeight: o.isNeedAdjustHeight, - adjustLength: o.adjustLength, - el: item, - popup: BI.extend({}, o.popup, { - el: BI.extend({ - items: children, - }, o.popup.el), - }), - }); - this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.ComboGroup.EVENT_CHANGE, obj); - } - }); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - setValue: function (v) { - this.combo.setValue(v); - }, -}); -BI.ComboGroup.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.combo_group", BI.ComboGroup); diff --git a/src/base/combination/group.virtual.js b/src/base/combination/group.virtual.js deleted file mode 100644 index 40e7c09f4..000000000 --- a/src/base/combination/group.virtual.js +++ /dev/null @@ -1,145 +0,0 @@ -BI.VirtualGroup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.VirtualGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-virtual-group", - items: [], - layouts: [{ - type: "bi.center", - hgap: 0, - vgap: 0, - }], - }); - }, - - render: function () { - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - if (BI.isKey(o.value)) { - this.setValue(o.value); - } - }, - - _packageBtns: function (items) { - var o = this.options; - var map = this.buttonMap = {}; - var layouts = BI.isArray(o.layouts) ? o.layouts : [o.layouts]; - for (let i = layouts.length - 1; i > 0; i--) { - items = BI.map(items, function (k, it) { - var el = BI.stripEL(it); - - return BI.extend({}, layouts[i], { - items: [ - BI.extend({}, layouts[i].el, { - el: BI.extend({ - ref: function (_ref) { - if (BI.isKey(map[el.value])) { - map[el.value] = _ref; - } - }, - }, el), - }) - ], - }); - }); - } - - return items; - }, - - _packageLayout: function (items) { - var o = this.options; - var layouts = BI.isArray(o.layouts) ? o.layouts : [o.layouts]; - var layout = BI.deepClone(layouts[0]); - - var lay = BI.formatEL(layout).el; - while (lay && lay.items && !BI.isEmpty(lay.items)) { - lay = BI.formatEL(lay.items[0]).el; - } - lay.items = items; - - return layout; - }, - - addItems: function (items) { - this.layouts.addItems(items, this); - }, - - prependItems: function (items) { - this.layouts.prependItems(items, this); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttonMap, function (key, item) { - if (item) { - if (v.deepContains(key)) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - } - }); - }, - - getNotSelectedValue: function () { - var v = []; - BI.each(this.buttonMap, function (i, item) { - if (item) { - if (item.isEnabled() && !(item.isSelected && item.isSelected())) { - v.push(item.getValue()); - } - } - }); - - return v; - }, - - getNodeByValue: function (value) { - return this.buttonMap[value]; - }, - - /** - * 滚动到指定的节点 - */ - scrollToValue: function (value, scrollIntoViewOptions) { - var node = this.getNodeByValue(value); - if (node) { - node.element[0].scrollIntoView(scrollIntoViewOptions); - } - }, - - getValue: function () { - var v = []; - BI.each(this.buttonMap, function (i, item) { - if (item) { - if (item.isEnabled() && item.isSelected && item.isSelected()) { - v.push(item.getValue()); - } - } - }); - - return v; - }, - - populate: function (items) { - items = items || []; - this.options.items = items; - items = this._packageBtns(items); - if (!this.layouts) { - this.layouts = BI.createWidget(BI.extend({ element: this }, this._packageLayout(items))); - } else { - this.layouts.populate(items, { - context: this, - }); - } - }, -}); -BI.VirtualGroup.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.virtual_group", BI.VirtualGroup); diff --git a/src/base/combination/loader.js b/src/base/combination/loader.js deleted file mode 100644 index 686354c9e..000000000 --- a/src/base/combination/loader.js +++ /dev/null @@ -1,277 +0,0 @@ -/** - * 加载控件 - * - * Created by GUY on 2015/8/31. - * @class BI.Loader - * @extends BI.Widget - */ -BI.Loader = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Loader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-loader", - - direction: "top", - isDefaultInit: true, // 是否默认初始化数据 - logic: { - dynamic: true, - scrolly: true, - }, - - // 下面是button_group的属性 - el: { - type: "bi.button_group", - }, - - items: [], - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, - - // 下面是分页信息 - count: false, - prev: false, - next: {}, - hasPrev: BI.emptyFn, - hasNext: BI.emptyFn, - }); - }, - - _prevLoad: function () { - var self = this, o = this.options; - this.prev.setLoading(); - o.itemsCreator.apply(this, [ - { times: --this.times }, function () { - self.prev.setLoaded(); - self.prependItems.apply(self, arguments); - } - ]); - }, - - _nextLoad: function () { - var self = this, o = this.options; - this.next.setLoading(); - o.itemsCreator.apply(this, [ - { times: ++this.times }, function () { - self.next.setLoaded(); - self.addItems.apply(self, arguments); - } - ]); - }, - - render: function () { - var self = this, o = this.options; - if (o.itemsCreator === false) { - o.prev = false; - o.next = false; - } - if (o.prev !== false) { - this.prev = BI.createWidget(BI.extend({ - type: "bi.loading_bar", - }, o.prev)); - this.prev.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._prevLoad(); - } - }); - } - - this.button_group = BI.createWidget(o.el, { - type: "bi.button_group", - chooseType: 0, - items: o.items, - behaviors: {}, - layouts: [ - { - type: "bi.vertical", - } - ], - value: o.value, - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Loader.EVENT_CHANGE, obj); - } - }); - - if (o.next !== false) { - this.next = BI.createWidget(BI.extend({ - type: "bi.loading_bar", - }, o.next)); - this.next.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._nextLoad(); - } - }); - } - - BI.createWidget(BI.extend({ - element: this, - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ - scrolly: true, - }, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.prev, this.button_group, this.next), - })))); - - o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { - o.isDefaultInit && BI.isEmpty(o.items) && this._populate(); - }, this)); - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - if (BI.isNotEmptyArray(items)) { - this._populate(items); - } - }, - - hasPrev: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; - } - - return !!o.hasPrev.apply(this, [ - { - times: this.times, - count: this.count, - } - ]); - }, - - hasNext: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; - } - - return !!o.hasNext.apply(this, [ - { - times: this.times, - count: this.count, - } - ]); - }, - - prependItems: function (items) { - this.count += items.length; - if (this.next !== false) { - if (this.hasPrev()) { - this.options.items = this.options.items.concat(items); - this.prev.setLoaded(); - } else { - this.prev.setEnd(); - } - } - this.button_group.prependItems.apply(this.button_group, arguments); - }, - - addItems: function (items) { - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.options.items = this.options.items.concat(items); - this.next.setLoaded(); - } else { - this.next.setEnd(); - } - } - this.button_group.addItems.apply(this.button_group, arguments); - }, - - _populate: function (items) { - var self = this, o = this.options; - if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { - o.itemsCreator.apply(this, [ - { times: 1 }, function () { - if (arguments.length === 0) { - throw new Error("Parameter cannot be empty"); - } - self.populate.apply(self, arguments); - o.onLoaded(); - } - ]); - - return false; - } - this.options.items = items; - this.times = 1; - this.count = 0; - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.next.setLoaded(); - } else { - this.next.invisible(); - } - } - if (BI.isObject(this.prev)) { - if (this.hasPrev()) { - this.prev.setLoaded(); - } else { - this.prev.invisible(); - } - } - - return true; - }, - - populate: function () { - this._populate.apply(this, arguments) && this.button_group.populate.apply(this.button_group, arguments); - }, - - setNotSelectedValue: function () { - this.button_group.setNotSelectedValue.apply(this.button_group, arguments); - }, - - getNotSelectedValue: function () { - return this.button_group.getNotSelectedValue(); - }, - - setValue: function () { - this.button_group.setValue.apply(this.button_group, arguments); - }, - - getValue: function () { - return this.button_group.getValue.apply(this.button_group, arguments); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - getAllLeaves: function () { - return this.button_group.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.button_group.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.button_group.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.button_group.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.button_group.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.button_group.getNodeByValue(value); - }, - - empty: function () { - this.button_group.empty(); - BI.each([this.prev, this.next], function (i, ob) { - ob && ob.setVisible(false); - }); - }, - - destroy: function () { - BI.Loader.superclass.destroy.apply(this, arguments); - }, -}); -BI.Loader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.loader", BI.Loader); diff --git a/src/base/combination/navigation.js b/src/base/combination/navigation.js deleted file mode 100644 index 1b347298e..000000000 --- a/src/base/combination/navigation.js +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Created by GUY on 2015/6/26. - */ - -BI.Navigation = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Navigation.superclass._defaultConfig.apply(this, arguments), { - direction: "bottom", // top, bottom, left, right, custom - logic: { - dynamic: false, - }, - single: false, - showIndex: false, - tab: false, - cardCreator: function (v) { - return BI.createWidget(); - }, - - afterCardCreated: BI.emptyFn, - afterCardShow: BI.emptyFn, - }); - }, - - render: function () { - var self = this, o = this.options; - this.tab = BI.createWidget(this.options.tab, { type: "bi.button_group" }); - this.cardMap = {}; - this.showIndex = 0; - this.layout = BI.createWidget({ - type: "bi.card", - }); - BI.createWidget(BI.extend({ - element: this, - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout), - })))); - - - new BI.ShowListener({ - eventObj: this.tab, - cardLayout: this.layout, - cardNameCreator: function (v) { - return self.showIndex + v; - }, - cardCreator: function (v) { - BI.Widget.execWithContext(self, function () { - self.cardMap[v] = o.cardCreator(v); - }); - return self.cardMap[v]; - }, - afterCardCreated: BI.bind(this.afterCardCreated, this), - afterCardShow: BI.bind(this.afterCardShow, this), - }); - - if (BI.isFunction(o.showIndex)) { - this.__watch(o.showIndex, function (context, newValue) { - self.setSelect(newValue); - }); - } - }, - - created: function () { - var o = this.options; - if (o.showIndex !== false) { - this.setSelect(o.showIndex); - } - }, - - _deleteOtherCards: function (currCardName) { - var self = this, o = this.options; - if (o.single === true) { - BI.each(this.cardMap, function (name, card) { - if (name !== (currCardName + "")) { - self.layout.deleteCardByName(name); - delete self.cardMap[name]; - } - }); - } - }, - - afterCardCreated: function (v) { - var self = this; - this.cardMap[v].on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Navigation.EVENT_CHANGE, obj); - } - }); - this.options.afterCardCreated.apply(this, arguments); - }, - - afterCardShow: function (v) { - this.showIndex = v; - this._deleteOtherCards(v); - this.options.afterCardShow.apply(this, arguments); - }, - - populate: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.populate.apply(card, arguments); - } - }, - - _assertCard: function (v) { - var self = this, o = this.options; - if (!this.layout.isCardExisted(v)) { - BI.Widget.execWithContext(self, function () { - self.cardMap[v] = o.cardCreator(v); - }); - this.layout.addCardByName(v, this.cardMap[v]); - this.afterCardCreated(v); - } - }, - - setSelect: function (v) { - this._assertCard(v); - this.layout.showCardByName(v); - this._deleteOtherCards(v); - if (this.showIndex !== v) { - this.showIndex = v; - BI.nextTick(BI.bind(this.afterCardShow, this, v)); - } - }, - - getSelect: function () { - return this.showIndex; - }, - - getSelectedCard: function () { - if (BI.isKey(this.showIndex)) { - return this.cardMap[this.showIndex]; - } - }, - - getAllCard: function() { - return BI.values(this.cardMap); - }, - - /** - * @override - */ - setValue: function (v) { - var card = this.layout.getShowingCard(); - if (card) { - card.setValue(v); - } - }, - - /** - * @override - */ - getValue: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.getValue(); - } - }, - - empty: function () { - this.layout.deleteAllCard(); - this.cardMap = {}; - }, - - destroy: function () { - BI.Navigation.superclass.destroy.apply(this, arguments); - }, -}); -BI.Navigation.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.navigation", BI.Navigation); diff --git a/src/base/combination/searcher.js b/src/base/combination/searcher.js deleted file mode 100644 index 45d19488c..000000000 --- a/src/base/combination/searcher.js +++ /dev/null @@ -1,340 +0,0 @@ -/** - * 搜索逻辑控件 - * - * Created by GUY on 2015/9/28. - * @class BI.Searcher - * @extends BI.Widget - */ - -BI.Searcher = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Searcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-searcher", - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - vgap: 0, - hgap: 0, - - isDefaultInit: false, - isAutoSearch: true, // 是否自动搜索 - isAutoSync: true, // 是否自动同步数据, 即是否保持搜索面板和adapter面板状态值的统一 - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - - // isAutoSearch为false时启用 - onSearch: function (op, callback) { - callback([]); - }, - - el: { - type: "bi.search_editor", - }, - - popup: { - type: "bi.searcher_view", - }, - - adapter: null, - masker: { // masker层 - offset: {}, - }, - - simple: false, - }); - }, - - render: function () { - var self = this, o = this.options; - - this.editor = BI.createWidget(o.el, { - type: "bi.search_editor", - simple: o.simple, - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - hgap: o.hgap, - items: [this.editor], - }); - o.isDefaultInit && (this._assertPopupView()); - - var search = BI.debounce(BI.bind(this._search, this), BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function (type) { - switch (type) { - case BI.Events.STARTEDIT: - self._startSearch(); - break; - case BI.Events.EMPTY: - self._stopSearch(); - break; - case BI.Events.CHANGE: - search(); - break; - case BI.Events.PAUSE: - if (BI.endWith(this.getValue(), BI.BlankSplitChar)) { - self._pauseSearch(); - } - break; - default: - break; - } - }); - }, - - _assertPopupView: function () { - var self = this, o = this.options; - if ((o.masker && !BI.Maskers.has(this.getName())) || (o.masker === false && !this.popupView)) { - this.popupView = BI.createWidget(o.popup, { - type: "bi.searcher_view", - chooseType: o.chooseType, - }); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - if (o.isAutoSync) { - var values = o.adapter && o.adapter.getValue(); - switch (o.chooseType) { - case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: - o.adapter && o.adapter.setValue([obj.getValue()]); - break; - case BI.ButtonGroup.CHOOSE_TYPE_MULTI: - if (!obj.isSelected()) { - o.adapter && o.adapter.setValue(BI.deepWithout(values, obj.getValue())); - } - values.push(obj.getValue()); - o.adapter && o.adapter.setValue(values); - break; - default: - break; - } - } - self.fireEvent(BI.Searcher.EVENT_CHANGE, value, obj); - } - }); - BI.nextTick(function () { - self.fireEvent(BI.Searcher.EVENT_AFTER_INIT); - }); - } - if (o.masker && !BI.Maskers.has(this.getName())) { - BI.Maskers.create(this.getName(), o.adapter, BI.extend({ - container: this, - render: this.popupView, - }, o.masker), this); - } - }, - - _startSearch: function () { - this._assertPopupView(); - this._stop = false; - this._isSearching = true; - this.fireEvent(BI.Searcher.EVENT_START); - this.popupView.startSearch && this.popupView.startSearch(); - // 搜索前先清空dom - // BI.Maskers.get(this.getName()).empty(); - BI.nextTick(function (name) { - BI.Maskers.show(name); - }, this.getName()); - }, - - _pauseSearch: function () { - this._stop = true; - BI.nextTick(function (name) { - BI.Maskers.hide(name); - }, this.getName()); - if (this._isSearching === true) { - this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); - this.fireEvent(BI.Searcher.EVENT_PAUSE); - } - this._isSearching = false; - }, - - _stopSearch: function () { - var name = this.getName(); - this._stop = true; - BI.Maskers.hide(name); - if (this._isSearching === true) { - this.popupView && this.popupView.stopSearch && this.popupView.stopSearch(); - this.fireEvent(BI.Searcher.EVENT_STOP); - } - this._isSearching = false; - }, - - _search: function () { - var self = this, o = this.options, keyword = this.editor.getValue(); - if (keyword === "" || this._stop) { - return; - } - if (o.isAutoSearch) { - var items = (o.adapter && ((o.adapter.getItems && o.adapter.getItems()) || o.adapter.attr("items"))) || []; - var finding = BI.Func.getSearchResult(items, keyword); - var match = finding.match, find = finding.find; - this.popupView.populate(find, match, keyword); - o.isAutoSync && o.adapter && o.adapter.getValue && this.popupView.setValue(o.adapter.getValue()); - self.fireEvent(BI.Searcher.EVENT_SEARCHING); - - return; - } - this.popupView.loading && this.popupView.loading(); - o.onSearch({ - times: 1, - keyword: keyword, - selectedValues: o.adapter && o.adapter.getValue(), - }, function (searchResult, matchResult) { - if (!self._stop && keyword === self.editor.getValue()) { - var args = [].slice.call(arguments); - if (args.length > 0) { - args.push(keyword); - } - BI.Maskers.show(self.getName()); - self.popupView.populate.apply(self.popupView, args); - o.isAutoSync && o.adapter && o.adapter.getValue && self.popupView.setValue(o.adapter.getValue()); - self.popupView.loaded && self.popupView.loaded(); - self.fireEvent(BI.Searcher.EVENT_SEARCHING); - } - }); - }, - - _getLastSearchKeyword: function () { - if (this.isValid()) { - var res = this.editor.getValue().split(/\u200b\s\u200b/); - if (BI.isEmptyString(res[res.length - 1])) { - res = res.slice(0, res.length - 1); - } - - return BI.isNull(res) ? "" : res[res.length - 1]; - } - }, - - setAdapter: function (adapter) { - this.options.adapter = adapter; - BI.Maskers.remove(this.getName()); - }, - - doSearch: function () { - if (this.isSearching()) { - this._search(); - } - }, - - stopSearch: function () { - this._stopSearch();// 先停止搜索,然后再去设置editor为空 - // important:停止搜索必须退出编辑状态,这里必须加上try(input框不显示时blur会抛异常) - try { - this.editor.blur(); - } catch (e) { - if (!this.editor.blur) { - throw new Error("The editor does not implement the blur method "); - } - } finally { - this.editor.setValue(""); - } - }, - - isSearching: function () { - return this._isSearching; - }, - - isViewVisible: function () { - return this.editor.isEnabled() && BI.Maskers.isVisible(this.getName()); - }, - - getView: function () { - return this.popupView; - }, - - hasMatched: function () { - this._assertPopupView(); - - return this.popupView.hasMatched(); - }, - - adjustHeight: function () { - if (BI.Maskers.has(this.getName()) && BI.Maskers.get(this.getName()).isVisible()) { - BI.Maskers.show(this.getName()); - } - }, - - adjustView: function () { - this.isViewVisible() && BI.Maskers.show(this.getName()); - }, - - setValue: function (v) { - if (BI.isNull(this.popupView)) { - this.options.popup.value = v; - } else { - this.popupView.setValue(v); - } - }, - - getKeyword: function () { - return this._getLastSearchKeyword(); - }, - - getKeywords: function () { - return this.editor.getKeywords(); - }, - - getValue: function () { - var o = this.options; - if (o.isAutoSync && o.adapter && o.adapter.getValue) { - return o.adapter.getValue(); - } - if (this.isSearching()) { - return this.popupView.getValue(); - } else if (o.adapter && o.adapter.getValue) { - return o.adapter.getValue(); - } - if (BI.isNull(this.popupView)) { - return o.popup.value; - } - - return this.popupView.getValue(); - }, - - populate: function (result, searchResult, keyword) { - var o = this.options; - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - if (o.isAutoSync && o.adapter && o.adapter.getValue) { - this.popupView.setValue(o.adapter.getValue()); - } - }, - - empty: function () { - this.popupView && this.popupView.empty(); - }, - - destroyed: function () { - BI.Maskers.remove(this.getName()); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - }, -}); -BI.Searcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Searcher.EVENT_START = "EVENT_START"; -BI.Searcher.EVENT_STOP = "EVENT_STOP"; -BI.Searcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Searcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.Searcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - -BI.shortcut("bi.searcher", BI.Searcher); diff --git a/src/base/combination/switcher.js b/src/base/combination/switcher.js deleted file mode 100644 index 419711595..000000000 --- a/src/base/combination/switcher.js +++ /dev/null @@ -1,296 +0,0 @@ -/** - * - * 切换显示或隐藏面板 - * - * Created by GUY on 2015/11/2. - * @class BI.Switcher - * @extends BI.Widget - */ -BI.Switcher = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Switcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-switcher", - direction: BI.Direction.Top, - trigger: "click", - toggle: true, - el: {}, - popup: {}, - adapter: null, - masker: {}, - switcherClass: "bi-switcher-popup", - hoverClass: "bi-switcher-hover", - }); - }, - - render: function () { - var self = this, o = this.options; - this._initSwitcher(); - // 延迟绑定事件,这样可以将自己绑定的事情优先执行 - BI.nextTick(() => { - !this.isDestroyed() && this._initPullDownAction(); - }); - this.switcher.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self.isEnabled() && self.isValid()) { - if (type === BI.Events.EXPAND) { - self._popupView(); - } - if (type === BI.Events.COLLAPSE) { - self._hideView(); - } - if (type === BI.Events.EXPAND) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.Switcher.EVENT_EXPAND); - } - if (type === BI.Events.COLLAPSE) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.isViewVisible() && self.fireEvent(BI.Switcher.EVENT_COLLAPSE); - } - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Switcher.EVENT_TRIGGER_CHANGE, value, obj); - } - } - }); - - this.element.hover(function () { - if (self.isEnabled() && self.switcher.isEnabled()) { - self.element.addClass(o.hoverClass); - } - }, function () { - if (self.isEnabled() && self.switcher.isEnabled()) { - self.element.removeClass(o.hoverClass); - } - }); - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - { el: this.switcher } - ], - }); - o.isDefaultInit && (this._assertPopupView()); - }, - - _toggle: function () { - this._assertPopupView(); - if (this.isExpanded()) { - this._hideView(); - } else { - if (this.isEnabled()) { - this._popupView(); - } - } - }, - - _initPullDownAction: function () { - var self = this, o = this.options; - var evs = this.options.trigger.split(","); - BI.each(evs, function (i, e) { - switch (e) { - case "hover": - self.element[e](function (e) { - if (self.isEnabled() && self.switcher.isEnabled()) { - self._popupView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.switcher); - self.fireEvent(BI.Switcher.EVENT_EXPAND); - } - }, function () { - if (self.isEnabled() && self.switcher.isEnabled() && o.toggle) { - self._hideView(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.switcher); - self.fireEvent(BI.Switcher.EVENT_COLLAPSE); - } - }); - break; - default : - if (e) { - self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { - if (self.switcher.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && self.switcher.isEnabled()) { - o.toggle ? self._toggle() : self._popupView(); - if (self.isExpanded()) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.switcher); - self.fireEvent(BI.Switcher.EVENT_EXPAND); - } else { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.switcher); - self.fireEvent(BI.Switcher.EVENT_COLLAPSE); - } - } - } - }, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - })); - } - break; - } - }); - }, - - _initSwitcher: function () { - this.switcher = BI.createWidget(this.options.el, { - value: this.options.value, - }); - }, - - _assertPopupView: function () { - var self = this, o = this.options; - if (!this._created) { - this.popupView = BI.createWidget(o.popup, { - type: "bi.button_group", - element: o.adapter && BI.Maskers.create(this.getName(), o.adapter, BI.extend({ container: this }, o.masker)), - cls: "switcher-popup", - layouts: [{ - type: "bi.vertical", - hgap: 0, - vgap: 0, - }], - value: o.value, - }, this); - this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Switcher.EVENT_CHANGE, value, obj); - } - }); - if (o.direction !== BI.Direction.Custom && !o.adapter) { - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [ - { el: this.popupView } - ], - }); - } - this._created = true; - BI.nextTick(function () { - self.fireEvent(BI.Switcher.EVENT_AFTER_INIT); - }); - } - }, - - _hideView: function () { - this.fireEvent(BI.Switcher.EVENT_BEFORE_HIDEVIEW); - var self = this, o = this.options; - o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); - BI.nextTick(function () { - o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); - self.element.removeClass(o.switcherClass); - self.fireEvent(BI.Switcher.EVENT_AFTER_HIDEVIEW); - }); - }, - - _popupView: function () { - var self = this, o = this.options; - this._assertPopupView(); - this.fireEvent(BI.Switcher.EVENT_BEFORE_POPUPVIEW); - o.adapter ? BI.Maskers.show(this.getName()) : self.popupView.setVisible(true); - BI.nextTick(function (name) { - o.adapter ? BI.Maskers.show(name) : self.popupView.setVisible(true); - self.element.addClass(o.switcherClass); - self.fireEvent(BI.Switcher.EVENT_AFTER_POPUPVIEW); - }, this.getName()); - }, - - _populate: function () { - this._assertPopupView(); - this.popupView.populate.apply(this.popupView, arguments); - }, - - populate: function (items) { - this._populate.apply(this, arguments); - this.switcher.populate && this.switcher.populate.apply(this.switcher, arguments); - }, - - _setEnable: function (arg) { - BI.Switcher.superclass._setEnable.apply(this, arguments); - !arg && this.isViewVisible() && this._hideView(); - }, - - setValue: function (v) { - this.switcher.setValue(v); - if (BI.isNull(this.popupView)) { - this.options.popup.value = v; - } else { - this.popupView.setValue(v); - } - }, - - getValue: function () { - if (BI.isNull(this.popupView)) { - return this.options.popup.value; - } else { - return this.popupView.getValue(); - } - }, - - setAdapter: function (adapter) { - this.options.adapter = adapter; - BI.Maskers.remove(this.getName()); - }, - - isViewVisible: function () { - return this.isEnabled() && this.switcher.isEnabled() && - (this.options.adapter ? BI.Maskers.isVisible(this.getName()) : (this.popupView && this.popupView.isVisible())); - }, - - isExpanded: function () { - return this.isViewVisible(); - }, - - showView: function () { - if (this.isEnabled() && this.switcher.isEnabled()) { - this._popupView(); - } - }, - - hideView: function () { - this._hideView(); - }, - - getView: function () { - return this.popupView; - }, - - adjustView: function () { - this.isViewVisible() && BI.Maskers.show(this.getName()); - }, - - getAllLeaves: function () { - return this.popupView && this.popupView.getAllLeaves(); - }, - - getNodeById: function (id) { - if (this.switcher.attr("id") === id) { - return this.switcher; - } - - return this.popupView && this.popupView.getNodeById(id); - }, - - getNodeByValue: function (value) { - if (this.switcher.getValue() === value) { - return this.switcher; - } - - return this.popupView && this.popupView.getNodeByValue(value); - }, - - empty: function () { - this.popupView && this.popupView.empty(); - }, -}); -BI.Switcher.EVENT_EXPAND = "EVENT_EXPAND"; -BI.Switcher.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.Switcher.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.Switcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Switcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.Switcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.Switcher.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.Switcher.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.Switcher.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - -BI.shortcut("bi.switcher", BI.Switcher); diff --git a/src/base/combination/tab.js b/src/base/combination/tab.js deleted file mode 100644 index 933496004..000000000 --- a/src/base/combination/tab.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * Created by GUY on 2015/6/26. - */ - -BI.Tab = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Tab.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tab", - direction: "top", // top, bottom, left, right, custom - single: false, // 是不是单页面 - logic: { - dynamic: false, - }, - showIndex: false, - tab: false, - cardCreator: function (v) { - return BI.createWidget(); - }, - keepAlives: [], - }); - }, - - render: function () { - var self = this, o = this.options; - if (BI.isObject(o.tab)) { - this.tab = BI.createWidget(this.options.tab, { type: "bi.button_group" }); - this.tab.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - } - this.cardMap = {}; - this.layout = BI.createWidget({ - type: "bi.card", - }); - - BI.createWidget(BI.extend({ - element: this, - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout), - })))); - - var listener = new BI.ShowListener({ - eventObj: this.tab, - cardLayout: this.layout, - cardCreator: function (v) { - BI.Widget.execWithContext(self, function () { - self.cardMap[v] = o.cardCreator(v); - }); - - return self.cardMap[v]; - }, - afterCardShow: function (v) { - self._deleteOtherCards(v); - self.curr = v; - }, - }); - listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { - self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); - }); - }, - - _deleteOtherCards: function (currCardName) { - var self = this, o = this.options; - if (o.single === true) { - BI.each(this.cardMap, function (name, card) { - if (name !== (currCardName + "") && self._keepAlive(name) !== true) { - self.layout.deleteCardByName(name); - delete self.cardMap[name]; - } - }); - } - }, - - _assertCard: function (v) { - var self = this, o = this.options; - if (!this.layout.isCardExisted(v)) { - BI.Widget.execWithContext(this, function () { - self.cardMap[v] = o.cardCreator(v); - }); - this.layout.addCardByName(v, this.cardMap[v]); - } - }, - - _keepAlive: function (v) { - var o = this.options; - - return BI.isFunction(o.keepAlives) ? o.keepAlives(v) : BI.contains(o.keepAlives, v); - }, - - created: function () { - var self = this, o = this.options; - - var showIndex; - if (BI.isFunction(o.showIndex)) { - showIndex = this.__watch(o.showIndex, function (context, newValue) { - self.setSelect(newValue); - }); - } else { - showIndex = o.showIndex; - } - - if (showIndex !== false) { - this.setSelect(showIndex); - } - }, - - setSelect: function (v, action, callback) { - this.tab && this.tab.setValue(v); - this._assertCard(v); - this.layout.showCardByName(v, action, callback); - this._deleteOtherCards(v); - if (this.curr !== v) { - this.curr = v; - } - }, - - removeTab: function (cardname) { - var self = this; - BI.any(this.cardMap, function (name, card) { - if (BI.isEqual(name, (cardname + ""))) { - self.layout.deleteCardByName(name); - delete self.cardMap[name]; - - return true; - } - }); - }, - - isCardExisted: function (cardName) { - return this.layout.isCardExisted(cardName); - }, - - getSelect: function () { - return this.curr; - }, - - getSelectedTab: function () { - return this.layout.getShowingCard(); - }, - - getTab: function (v) { - this._assertCard(v); - - return this.layout.getCardByName(v); - }, - - setValue: function (v) { - var card = this.layout.getShowingCard(); - if (card) { - card.setValue(v); - } - }, - - getValue: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.getValue(); - } - }, - - populate: function () { - var card = this.layout.getShowingCard(); - if (card) { - return card.populate && card.populate.apply(card, arguments); - } - }, - - empty: function () { - this.layout.deleteAllCard(); - this.cardMap = {}; - }, - - destroy: function () { - this.cardMap = {}; - BI.Tab.superclass.destroy.apply(this, arguments); - }, -}); -BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.tab", BI.Tab); diff --git a/src/base/combination/tree.button.js b/src/base/combination/tree.button.js deleted file mode 100644 index cfa9a3c3b..000000000 --- a/src/base/combination/tree.button.js +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Created by GUY on 2015/8/10. - * @class BI.ButtonTree - * @extends BI.ButtonGroup - */ - -BI.ButtonTree = BI.inherit(BI.ButtonGroup, { - _defaultConfig: function () { - return BI.extend(BI.ButtonTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-tree", - }); - }, - - setNotSelectedValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - - return; - } - if (BI.deepContains(v, item.getValue())) { - item.setSelected(false); - } else { - item.setSelected(true); - } - }); - }, - - setEnabledValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (BI.isFunction(item.setEnabledValue)) { - item.setEnabledValue(v); - - return; - } - if (BI.deepContains(v, item.getValue())) { - item.setEnable(true); - } else { - item.setEnable(false); - } - }); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (i, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - - return; - } - if (BI.deepContains(v, item.getValue())) { - item.setSelected(true); - } else { - item.setSelected(false); - } - }); - }, - - getNotSelectedValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - v = BI.concat(v, item.getNotSelectedValue()); - - return; - } - if (item.isEnabled() && item.isSelected && !item.isSelected()) { - v.push(item.getValue()); - } - }); - - return v; - }, - - getValue: function () { - var v = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - v = BI.concat(v, item.getValue()); - - return; - } - if (item.isEnabled() && item.isSelected && item.isSelected()) { - v.push(item.getValue()); - } - }); - - return v; - }, - - getSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - btns = btns.concat(item.getSelectedButtons()); - - return; - } - if (item.isSelected && item.isSelected()) { - btns.push(item); - } - }); - - return btns; - }, - - getNotSelectedButtons: function () { - var btns = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - btns = btns.concat(item.getNotSelectedButtons()); - - return; - } - if (item.isSelected && !item.isSelected()) { - btns.push(item); - } - }); - - return btns; - }, - - // 获取所有的叶子节点 - getAllLeaves: function () { - var leaves = []; - BI.each(this.buttons, function (i, item) { - if (item.isEnabled() && !BI.isFunction(item.setSelected)) { - leaves = leaves.concat(item.getAllLeaves()); - - return; - } - if (item.isEnabled()) { - leaves.push(item); - } - }); - - return leaves; - }, - - getIndexByValue: function (value) { - var index = -1; - BI.any(this.buttons, function (i, item) { - var vs = item.getValue(); - if (item.isEnabled() && (vs === value || BI.contains(vs, value))) { - index = i; - - return true; - } - }); - - return index; - }, - - getNodeById: function (id) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled()) { - if (item.attr("id") === id) { - node = item; - - return true; - } else if (BI.isFunction(item.getNodeById)) { - node = item.getNodeById(id); - if (node) { - return true; - } - } - } - }); - - return node; - }, - - getNodeByValue: function (value) { - var node; - BI.any(this.buttons, function (i, item) { - if (item.isEnabled()) { - if (BI.isFunction(item.getNodeByValue)) { - node = item.getNodeByValue(value); - if (node) { - return true; - } - } else if (item.attr("value") === value) { - node = item; - - return true; - } - } - }); - - return node; - }, -}); -BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.button_tree", BI.ButtonTree); diff --git a/src/base/context.js b/src/base/context.js deleted file mode 100644 index 47fdd6c64..000000000 --- a/src/base/context.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * 表示当前对象 - * - * Created by GUY on 2015/9/7. - * @class BI.EL - * @extends BI.Widget - */ -BI.Context = BI.inherit(BI.Widget, { - props: { - context: "", - watch: {}, - el: {}, - items: [], - }, - - render: function () { - var self = this, o = this.options; - if (o.context) { - this.context = BI.useContext(o.context); - } - this.widget = BI.createWidget((o.items[0] || o.el)(this.context), { - element: this, - }); - this.widget.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - }, - - __initWatch: function () { - BI.Context.superclass.__initWatch.call(this); - var o = this.options; - BI.watch(this.context, o.context, o.watch); - }, - - setValue: function (v) { - this.widget.setValue(v); - }, - - getValue: function () { - return this.widget.getValue(); - }, - - populate: function () { - this.widget.populate.apply(this, arguments); - }, -}); -BI.shortcut("bi.context", BI.Context); diff --git a/src/base/el.js b/src/base/el.js deleted file mode 100644 index 885c04ac5..000000000 --- a/src/base/el.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * 表示当前对象 - * - * Created by GUY on 2015/9/7. - * @class BI.EL - * @extends BI.Widget - */ -BI.EL = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.EL.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-el", - el: {}, - }); - }, - - render: function () { - var self = this, o = this.options; - this.ele = BI.createWidget(o.el, { - element: this, - }); - this.ele.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - }, - - setValue: function (v) { - this.ele.setValue(v); - }, - - getValue: function () { - return this.ele.getValue(); - }, - - populate: function () { - this.ele.populate.apply(this, arguments); - }, -}); -BI.shortcut("bi.el", BI.EL); diff --git a/src/base/foundation/message.js b/src/base/foundation/message.js deleted file mode 100644 index b94dfbbcd..000000000 --- a/src/base/foundation/message.js +++ /dev/null @@ -1,240 +0,0 @@ -/** - * z-index在1亿层级 - * 弹出提示消息框,用于模拟阻塞操作(通过回调函数实现) - * @class BI.Msg - */ -BI.Msg = ((function () { - var $mask, $pop; - - var messageShows = []; - - var toastStack = []; - - var defaultConfig = { - buttonHeight: 24, - }; - - return { - alert: function (title, message, callback, config = defaultConfig) { - this._show(false, title, message, callback, config); - }, - confirm: function (title, message, callback, config = defaultConfig) { - this._show(true, title, message, callback, config); - }, - prompt: function (title, message, value, callback, min_width) { - // BI.Msg.prompt(title, message, value, callback, min_width); - }, - toast: function (message, options, context) { - BI.isString(options) && (options = { level: options }); - options = options || {}; - context = context || BI.Widget._renderEngine.createElement("body"); - var level = options.level || "common"; - var autoClose = BI.isNull(options.autoClose) ? true : options.autoClose; - var callback = BI.isFunction(options.callback) ? options.callback : BI.emptyFn; - var toast = BI.createWidget({ - type: "bi.toast", - cls: "bi-message-animate bi-message-leave", - level: level, - autoClose: autoClose, - closable: options.closable, - text: message, - listeners: [{ - eventName: BI.Toast.EVENT_DESTORY, - action: function () { - BI.remove(toastStack, toast.element); - var _height = BI.SIZE_CONSANTS.TOAST_TOP; - BI.each(toastStack, function (i, element) { - element.css({ "top": _height }); - _height += element.outerHeight() + 10; - }); - callback(); - }, - }], - }); - var height = BI.SIZE_CONSANTS.TOAST_TOP; - BI.each(toastStack, function (i, element) { - height += element.outerHeight() + 10; - }); - BI.createWidget({ - type: "bi.absolute", - element: context, - items: [{ - el: toast, - left: "50%", - top: height, - }], - }); - toastStack.push(toast.element); - toast.element.css({ "margin-left": -1 * toast.element.outerWidth() / 2 }); - toast.element.removeClass("bi-message-leave").addClass("bi-message-enter"); - - autoClose && BI.delay(function () { - toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); - toast.destroy?.(); - }, 5000); - - return function () { - toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); - toast.destroy?.(); - }; - }, - _show: function (hasCancel, title, message, callback, config) { - BI.isNull($mask) && ($mask = BI.Widget._renderEngine.createElement("
    ").css({ - position: "absolute", - zIndex: BI.zIndex_tip - 2, - top: 0, - left: 0, - right: 0, - bottom: 0, - opacity: 0.5, - }).appendTo("body")); - $pop = BI.Widget._renderEngine.createElement("
    ").css({ - position: "absolute", - zIndex: BI.zIndex_tip - 1, - top: 0, - left: 0, - right: 0, - bottom: 0, - }).appendTo("body"); - function close () { - messageShows[messageShows.length - 1].destroy(); - messageShows.pop(); - if (messageShows.length === 0) { - $mask.remove(); - $mask = null; - } - } - var controlItems = []; - if (hasCancel === true) { - controlItems.push({ - el: { - type: "bi.button", - height: config.buttonHeight, - text: BI.i18nText("BI-Basic_Cancel"), - light: true, - handler: function () { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [false]); - } - }, - }, - }); - } - controlItems.push({ - el: { - type: "bi.button", - height: config.buttonHeight, - text: BI.i18nText("BI-Basic_OK"), - handler: function () { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [true]); - } - }, - }, - }); - var conf = { - element: $pop, - type: "bi.center_adapt", - items: [ - { - type: "bi.border", - attributes: { - tabIndex: 1, - }, - mounted: function () { - this.element.keyup(function (e) { - if (e.keyCode === BI.KeyCode.ENTER) { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [true]); - } - } else if (e.keyCode === BI.KeyCode.ESCAPE) { - close(); - if (hasCancel === true) { - if (BI.isFunction(callback)) { - callback.apply(null, [false]); - } - } - } - }); - try { - this.element.focus(); - } catch (e) { - - } - }, - cls: "bi-card", - items: { - north: { - el: { - type: "bi.border", - cls: "bi-message-title bi-background", - items: { - center: { - el: { - type: "bi.label", - cls: "bi-font-bold", - text: title || BI.i18nText("BI-Basic_Prompt"), - textAlign: "left", - hgap: 20, - height: 40, - }, - }, - east: { - el: { - type: "bi.icon_button", - cls: "bi-message-close close-font", - // height: 50, - handler: function () { - close(); - if (BI.isFunction(callback)) { - callback.apply(null, [false]); - } - }, - }, - width: 56, - }, - }, - }, - height: 40, - }, - center: { - el: BI.isPlainObject(message) ? message : { - type: "bi.label", - vgap: 10, - hgap: 20, - whiteSpace: "normal", - text: message, - }, - }, - south: { - el: { - type: "bi.absolute", - items: [{ - el: { - type: "bi.right_vertical_adapt", - lgap: 10, - items: controlItems, - }, - top: 0, - left: 20, - right: 20, - bottom: 0, - }], - - }, - height: 44, - }, - }, - width: 450, - height: 200, - } - ], - }; - - messageShows[messageShows.length] = BI.createWidget(conf); - }, - }; -})()); diff --git a/src/base/grid/grid.js b/src/base/grid/grid.js deleted file mode 100644 index 944a82d4a..000000000 --- a/src/base/grid/grid.js +++ /dev/null @@ -1,436 +0,0 @@ -/** - * GridView - * - * Created by GUY on 2016/1/11. - * @class BI.GridView - * @extends BI.Widget - */ -BI.GridView = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-grid-view", - // width: 400, //必设 - // height: 300, //必设 - scrollable: true, - scrollx: false, - scrolly: false, - overflowX: true, - overflowY: true, - el: { - type: "bi.vertical" - }, - overscanColumnCount: 0, - overscanRowCount: 0, - rowHeightGetter: BI.emptyFn, // number类型或function类型 - columnWidthGetter: BI.emptyFn, // number类型或function类型 - // estimatedColumnSize: 100, //columnWidthGetter为function时必设 - // estimatedRowSize: 30, //rowHeightGetter为function时必设 - scrollLeft: 0, - scrollTop: 0, - items: [], - itemFormatter: function (item, row, col) { - return item; - }, - }); - }, - - render: function () { - var self = this, o = this.options; - this.renderedCells = []; - this.renderedKeys = []; - this.renderRange = {}; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 1000 / 60); - this.container = BI._lazyCreateWidget({ - type: "bi.absolute", - }); - this.element.scroll(function () { - if (self._scrollLock === true) { - return; - } - o.scrollLeft = self.element.scrollLeft(); - o.scrollTop = self.element.scrollTop(); - self._calculateChildrenToRender(); - self.fireEvent(BI.GridView.EVENT_SCROLL, { - scrollLeft: o.scrollLeft, - scrollTop: o.scrollTop, - }); - }); - // 兼容一下 - var scrollable = o.scrollable, scrollx = o.scrollx, scrolly = o.scrolly; - if (o.overflowX === false) { - if (o.overflowY === false) { - scrollable = false; - } else { - scrollable = "y"; - } - } else { - if (o.overflowY === false) { - scrollable = "x"; - } - } - BI._lazyCreateWidget(o.el, { - type: "bi.vertical", - element: this, - scrollable: scrollable, - scrolly: scrolly, - scrollx: scrollx, - items: [this.container], - }); - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - if (o.items.length > 0) { - this._calculateSizeAndPositionData(); - this._populate(); - } - }, - - // mounted之后绑定事件 - mounted: function () { - var o = this.options; - if (o.scrollLeft !== 0 || o.scrollTop !== 0) { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } - }, - - destroyed: function () { - BI.each(this.renderedCells, function(i, cell) { - cell.el._destroy(); - }) - }, - - _calculateSizeAndPositionData: function () { - var o = this.options; - this.rowCount = 0; - this.columnCount = 0; - if (BI.isNumber(o.columnCount)) { - this.columnCount = o.columnCount; - } else if (o.items.length > 0) { - this.columnCount = o.items[0].length; - } - if (BI.isNumber(o.rowCount)) { - this.rowCount = o.rowCount; - } else { - this.rowCount = o.items.length; - } - this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, o.columnWidthGetter, o.estimatedColumnSize); - this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, o.rowHeightGetter, o.estimatedRowSize); - }, - - _getOverscanIndices: function (cellCount, overscanCellsCount, startIndex, stopIndex) { - return { - overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), - overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount), - }; - }, - - _calculateChildrenToRender: function () { - var self = this, o = this.options; - - var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), - scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()), - overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount; - - if (height > 0 && width > 0) { - var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); - var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); - - var renderedCells = [], renderedKeys = {}, renderedWidgets = {}; - // 没有可见的单元格就干掉所有渲染过的 - if (!BI.isEmpty(visibleColumnIndices) && !BI.isEmpty(visibleRowIndices)) { - var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft); - var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); - - this._renderedColumnStartIndex = visibleColumnIndices.start; - this._renderedColumnStopIndex = visibleColumnIndices.stop; - this._renderedRowStartIndex = visibleRowIndices.start; - this._renderedRowStopIndex = visibleRowIndices.stop; - - var overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex); - - var overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex); - - var columnStartIndex = overscanColumnIndices.overscanStartIndex; - var columnStopIndex = overscanColumnIndices.overscanStopIndex; - var rowStartIndex = overscanRowIndices.overscanStartIndex; - var rowStopIndex = overscanRowIndices.overscanStopIndex; - - // 算区间size - var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex); - var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex); - var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex); - var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex); - var top = minRowDatum.offset + verticalOffsetAdjustment; - var left = minColumnDatum.offset + horizontalOffsetAdjustment; - var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size; - var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size; - // 如果滚动的区间并没有超出渲染的范围 - if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) { - return; - } - - var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0; - var count = 0; - for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { - var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); - - for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { - var key = rowIndex + "-" + columnIndex; - var columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); - - var index = this.renderedKeys[key] && this.renderedKeys[key][2]; - var child; - if (index >= 0) { - this.renderedCells[index].el.setWidth(columnDatum.size); - this.renderedCells[index].el.setHeight(rowDatum.size); - // 这里只使用px - this.renderedCells[index].el.element.css("left", columnDatum.offset + horizontalOffsetAdjustment + "px"); - this.renderedCells[index].el.element.css("top", rowDatum.offset + verticalOffsetAdjustment + "px"); - child = this.renderedCells[index].el; - renderedCells.push(this.renderedCells[index]); - } else { - var item = o.itemFormatter(o.items[rowIndex][columnIndex], rowIndex, columnIndex); - child = BI._lazyCreateWidget(BI.extend({ - type: "bi.label", - width: columnDatum.size, - height: rowDatum.size, - }, item, { - cls: (item.cls || "") + " grid-cell" + (rowIndex === 0 ? " first-row" : "") + (columnIndex === 0 ? " first-col" : ""), - _rowIndex: rowIndex, - _columnIndex: columnIndex, - _left: columnDatum.offset + horizontalOffsetAdjustment, - _top: rowDatum.offset + verticalOffsetAdjustment, - }), this); - renderedCells.push({ - el: child, - left: columnDatum.offset + horizontalOffsetAdjustment + "px", - top: rowDatum.offset + verticalOffsetAdjustment + "px", - _left: columnDatum.offset + horizontalOffsetAdjustment, - _top: rowDatum.offset + verticalOffsetAdjustment, - // _width: columnDatum.size, - // _height: rowDatum.size - }); - } - minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment); - maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size); - minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment); - maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size); - renderedKeys[key] = [rowIndex, columnIndex, count]; - renderedWidgets[count] = child; - count++; - } - } - } - // 已存在的, 需要添加的和需要删除的 - var existSet = {}, addSet = {}, deleteArray = []; - BI.each(renderedKeys, function (i, key) { - if (self.renderedKeys[i]) { - existSet[i] = key; - } else { - addSet[i] = key; - } - }); - BI.each(this.renderedKeys, function (i, key) { - if (existSet[i]) { - return; - } - if (addSet[i]) { - return; - } - deleteArray.push(key[2]); - }); - BI.each(deleteArray, function (i, index) { - // 性能优化,不调用destroy方法防止触发destroy事件 - self.renderedCells[index].el._destroy(); - }); - var addedItems = []; - BI.each(addSet, function (index, key) { - addedItems.push(renderedCells[key[2]]); - }); - // 与listview一样, 给上下文 - this.container.addItems(addedItems, this); - // 拦截父子级关系 - this.container._children = renderedWidgets; - this.container.attr("items", renderedCells); - this.renderedCells = renderedCells; - this.renderedKeys = renderedKeys; - this.renderRange = { minX: minX, minY: minY, maxX: maxX, maxY: maxY }; - } - }, - - _isOverflowX: function () { - var o = this.options; - // 兼容一下 - var scrollable = o.scrollable, scrollx = o.scrollx; - if (o.overflowX === false) { - return false; - } - if (scrollx) { - return true; - } - if (scrollable === true || scrollable === "xy" || scrollable === "x") { - return true; - } - return false; - }, - - _isOverflowY: function () { - var o = this.options; - // 兼容一下 - var scrollable = o.scrollable, scrolly = o.scrolly; - if (o.overflowX === false) { - return false; - } - if (scrolly) { - return true; - } - if (scrollable === true || scrollable === "xy" || scrollable === "y") { - return true; - } - return false; - }, - - _getMaxScrollLeft: function () { - return Math.max(0, this._getContainerWidth() - this.options.width + (this._isOverflowX() ? BI.DOM.getScrollWidth() : 0)); - }, - - _getMaxScrollTop: function () { - return Math.max(0, this._getContainerHeight() - this.options.height + (this._isOverflowY() ? BI.DOM.getScrollWidth() : 0)); - }, - - _getContainerWidth: function () { - return this.columnCount * this.options.estimatedColumnSize; - }, - - _getContainerHeight: function () { - return this.rowCount * this.options.estimatedRowSize; - }, - - _populate: function (items) { - var o = this.options; - this._reRange(); - if (items && items !== this.options.items) { - this.options.items = items; - this._calculateSizeAndPositionData(); - } - this.container.setWidth(this._getContainerWidth()); - this.container.setHeight(this._getContainerHeight()); - - // 元素未挂载时不能设置scrollTop - this._debounceRelease(); - try { - this.element.scrollTop(o.scrollTop); - this.element.scrollLeft(o.scrollLeft); - } catch (e) { - } - this._calculateChildrenToRender(); - }, - - setScrollLeft: function (scrollLeft) { - if (this.options.scrollLeft === scrollLeft) { - return; - } - this._scrollLock = true; - this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); - this._debounceRelease(); - this.element.scrollLeft(this.options.scrollLeft); - this._calculateChildrenToRender(); - }, - - setScrollTop: function (scrollTop) { - if (this.options.scrollTop === scrollTop) { - return; - } - this._scrollLock = true; - this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); - this._debounceRelease(); - this.element.scrollTop(this.options.scrollTop); - this._calculateChildrenToRender(); - }, - - setColumnCount: function (columnCount) { - this.options.columnCount = columnCount; - }, - - setRowCount: function (rowCount) { - this.options.rowCount = rowCount; - }, - - setOverflowX: function (b) { - var self = this; - if (this.options.overflowX !== !!b) { - this.options.overflowX = !!b; - BI.nextTick(function () { - self.element.css({ overflowX: b ? "auto" : "hidden" }); - }); - } - }, - - setOverflowY: function (b) { - var self = this; - if (this.options.overflowY !== !!b) { - this.options.overflowY = !!b; - BI.nextTick(function () { - self.element.css({ overflowY: b ? "auto" : "hidden" }); - }); - } - }, - - getScrollLeft: function () { - return this.options.scrollLeft; - }, - - getScrollTop: function () { - return this.options.scrollTop; - }, - - getMaxScrollLeft: function () { - return this._getMaxScrollLeft(); - }, - - getMaxScrollTop: function () { - return this._getMaxScrollTop(); - }, - - setEstimatedColumnSize: function (width) { - this.options.estimatedColumnSize = width; - }, - - setEstimatedRowSize: function (height) { - this.options.estimatedRowSize = height; - }, - - // 重新计算children - _reRange: function () { - this.renderRange = {}; - }, - - _clearChildren: function () { - this.container._children = {}; - this.container.attr("items", []); - }, - - restore: function () { - BI.each(this.renderedCells, function (i, cell) { - cell.el._destroy(); - }); - this._clearChildren(); - this.renderedCells = []; - this.renderedKeys = []; - this.renderRange = {}; - this._scrollLock = false; - }, - - populate: function (items) { - if (items && items !== this.options.items) { - this.restore(); - } - this._populate(items); - }, -}); -BI.GridView.EVENT_SCROLL = "EVENT_SCROLL"; -BI.shortcut("bi.grid_view", BI.GridView); diff --git a/src/base/layer/layer.drawer.js b/src/base/layer/layer.drawer.js deleted file mode 100644 index 23ef8b8c5..000000000 --- a/src/base/layer/layer.drawer.js +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Popover弹出层, - * @class BI.Popover - * @extends BI.Widget - */ -BI.Drawer = BI.inherit(BI.Widget, { - SIZE: { - SMALL: "small", - NORMAL: "normal", - BIG: "big", - }, - props: { - baseCls: "bi-drawer bi-card", - size: "normal", - placement: "right", // top/bottom/left/right - header: null, - headerHeight: 40, - body: null, - closable: true, // BI-40839 是否显示右上角的关闭按钮 - bodyHgap: 20, - bodyTgap: 10, - bodyBgap: 10, - }, - - render: function () { - var self = this; - var o = this.options; - var items = [{ - el: { - type: "bi.htape", - cls: "bi-message-title bi-header-background", - items: [{ - type: "bi.absolute", - items: [{ - el: BI.isPlainObject(o.header) ? BI.extend({}, o.header, { - extraCls: "bi-font-bold", - }) : { - type: "bi.label", - cls: "bi-font-bold", - height: o.headerHeight, - text: o.header, - title: o.header, - textAlign: "left", - }, - left: 20, - top: 0, - right: 0, - bottom: 0, - }], - }, { - el: o.closable ? { - type: "bi.icon_button", - cls: "bi-message-close close-font", - height: o.headerHeight, - handler: function () { - self.close(); - }, - } : { - type: "bi.layout", - }, - width: 56, - }], - height: o.headerHeight, - }, - height: o.headerHeight, - }, { - el: { - type: "bi.vertical", - scrolly: true, - cls: "drawer-body", - ref: function () { - self.body = this; - }, - items: [{ - el: o.body, - }], - }, - hgap: o.bodyHgap, - tgap: o.bodyTgap, - bgap: o.bodyBgap, - }]; - - return BI.extend({ - type: "bi.vtape", - items: items, - }, this._getSuitableSize()); - }, - - _getSuitableSize: function () { - var o = this.options; - var size = 0; - switch (o.size) { - case "big": - size = 736; - break; - case "small": - size = 200; - break; - case "normal": - default: - size = 378; - break; - } - if (o.placement === "top" || o.placement === "bottom") { - return { - height: o.height || size, - }; - } - if (o.placement === "left" || o.placement === "right") { - return { - width: o.width || size, - }; - } - }, - - mounted: function () { - var self = this, o = this.options; - switch (o.placement) { - case "right": - self.element.css({ - top: 0, - left: "100%", - bottom: 0, - }); - break; - case "left": - self.element.css({ - top: 0, - right: "100%", - bottom: 0, - }); - break; - case "top": - self.element.css({ - left: 0, - right: 0, - bottom: "100%", - }); - break; - case "bottom": - self.element.css({ - left: 0, - right: 0, - top: "100%", - }); - break; - default: - break; - } - }, - - show: function (callback) { - var self = this, o = this.options; - requestAnimationFrame(function () { - var size = self._getSuitableSize(); - switch (o.placement) { - case "right": - self.element.css({ - left: "calc(100% - " + size.width + "px)", - }); - break; - case "left": - self.element.css({ - right: "calc(100% - " + size.width + "px)", - }); - break; - case "top": - self.element.css({ - bottom: "calc(100% - " + size.height + "px)", - }); - break; - case "bottom": - self.element.css({ - top: "calc(100% - " + size.height + "px)", - }); - break; - default: - break; - } - callback && callback(); - }); - }, - - hide: function (callback) { - var self = this, o = this.options; - requestAnimationFrame(function () { - switch (o.placement) { - case "right": - self.element.css({ - left: "100%", - }); - break; - case "left": - self.element.css({ - right: "100%", - }); - break; - case "top": - self.element.css({ - bottom: "100%", - }); - break; - case "bottom": - self.element.css({ - top: "100%", - }); - break; - default: - break; - } - setTimeout(callback, 300); - }); - }, - - open: function () { - var self = this; - this.show(function () { - self.fireEvent(BI.Drawer.EVENT_OPEN); - }); - }, - - close: function () { - var self = this; - this.hide(function () { - self.fireEvent(BI.Drawer.EVENT_CLOSE); - }); - }, - - setZindex: function (zindex) { - this.element.css({ "z-index": zindex }); - }, - - destroyed: function () { - }, -}); - -BI.shortcut("bi.drawer", BI.Drawer); - -BI.Drawer.EVENT_CLOSE = "EVENT_CLOSE"; -BI.Drawer.EVENT_OPEN = "EVENT_OPEN"; diff --git a/src/base/layer/layer.popover.js b/src/base/layer/layer.popover.js deleted file mode 100644 index 063c2724c..000000000 --- a/src/base/layer/layer.popover.js +++ /dev/null @@ -1,281 +0,0 @@ -/** - * Popover弹出层, - * @class BI.Popover - * @extends BI.Widget - */ -BI.Popover = BI.inherit(BI.Widget, { - _constant: { - SIZE: { - SMALL: "small", - NORMAL: "normal", - BIG: "big", - }, - MAX_HEIGHT: 600, - }, - - props: function () { - return { - baseCls: "bi-popover bi-card bi-border-radius", - size: "normal", // small, normal, big - logic: { - dynamic: false, - }, - header: null, - headerHeight: 40, - body: null, - footer: null, - footerHeight: 44, - footerButtonHeight: 24, - closable: true, // BI-40839 是否显示右上角的关闭按钮 - bodyHgap: BI.SIZE_CONSANTS.H_GAP_SIZE, - bodyTgap: BI.SIZE_CONSANTS.V_GAP_SIZE, - }; - }, - - render: function () { - var self = this; - var o = this.options; - var c = this._constant; - this.startX = 0; - this.startY = 0; - var size = this._calculateSize(); - this.tracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { - var W = BI.Widget._renderEngine.createElement("body").width(); - var H = BI.Widget._renderEngine.createElement("body").height(); - self.startX += deltaX; - self.startY += deltaY; - self.element.css({ - left: BI.clamp(self.startX, 0, W - self.element.width()) + "px", - top: BI.clamp(self.startY, 0, H - self.element.height()) + "px", - }); - // BI-12134 没有什么特别好的方法 - BI.Resizers._resize({ - target: self.element[0], - }); - }, function () { - self.tracker.releaseMouseMoves(); - }, _global); - var items = [{ - el: { - type: "bi.htape", - cls: "bi-message-title bi-header-background", - items: [{ - el: { - type: "bi.absolute", - ref: function (_ref) { - self.dragger = _ref; - }, - items: [{ - el: BI.isPlainObject(o.header) ? BI.extend({}, o.header, { - extraCls: "bi-font-bold", - }) : { - type: "bi.label", - cls: "bi-font-bold", - height: o.headerHeight, - text: o.header, - title: o.header, - textAlign: "left", - }, - top: 0, - bottom: 0, - left: BI.SIZE_CONSANTS.H_GAP_SIZE, - right: o.closable ? 0 : BI.SIZE_CONSANTS.H_GAP_SIZE, - }], - }, - }, o.closable ? { - el: { - type: "bi.icon_button", - cls: "bi-message-close close-font", - height: o.headerHeight, - handler: function () { - self.close(); - }, - }, - width: 56, - } : null], - height: o.headerHeight, - }, - height: o.headerHeight, - }, o.logic.dynamic ? { - el: { - type: "bi.vertical", - scrolly: true, - cls: "popover-body", - ref: function () { - self.body = this; - }, - css: { - "max-height": this._getSuitableBodyHeight(c.MAX_HEIGHT - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap), - "min-height": this._getSuitableBodyHeight(size.height - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap), - }, - items: [{ - el: o.body, - }], - hgap: o.bodyHgap, - tgap: o.bodyTgap, - }, - } : { - el: { - type: "bi.absolute", - items: [{ - el: o.body, - left: o.bodyHgap, - top: o.bodyTgap, - right: o.bodyHgap, - bottom: 0, - }], - }, - }]; - if (o.footer) { - items.push({ - el: { - type: "bi.absolute", - items: [{ - el: o.footer, - left: BI.SIZE_CONSANTS.H_GAP_SIZE, - top: 0, - right: BI.SIZE_CONSANTS.H_GAP_SIZE, - bottom: 0, - }], - height: o.footerHeight, - }, - height: o.footerHeight, - }); - } - - return BI.extend({ - items: items, - width: this._getSuitableWidth(size.width), - }, o.logic.dynamic ? { - type: "bi.vertical", - scrolly: false, - } : { - type: "bi.vtape", - height: this._getSuitableHeight(size.height), - }); - }, - - // mounted之后绑定事件 - mounted: function () { - var self = this; - this.dragger.element.mousedown(function (e) { - if (self.options.draggable !== false) { - self.startX = self.element[0].offsetLeft; - self.startY = self.element[0].offsetTop; - self.tracker.captureMouseMoves(e); - } - }); - }, - - _getSuitableBodyHeight: function (height) { - var o = this.options; - - return BI.clamp(height, 0, BI.Widget._renderEngine.createElement("body")[0].clientHeight - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap); - }, - - _getSuitableHeight: function (height) { - return BI.clamp(height, 0, BI.Widget._renderEngine.createElement("body")[0].clientHeight); - }, - - _getSuitableWidth: function (width) { - return BI.clamp(width, 0, BI.Widget._renderEngine.createElement("body").width()); - }, - - _calculateSize: function () { - var o = this.options; - var size = {}; - if (BI.isNotNull(o.size)) { - switch (o.size) { - case this._constant.SIZE.SMALL: - size.width = 450; - size.height = 200; - size.type = "small"; - break; - case this._constant.SIZE.BIG: - size.width = 900; - size.height = 500; - size.type = "big"; - break; - default: - size.width = 550; - size.height = 500; - size.type = "default"; - } - } - - return { - width: o.width || size.width, - height: o.height || size.height, - type: size.type || "default", - }; - }, - - setDraggable: function (b) { - this.options.draggable = b; - }, - - hide: function () { - - }, - - open: function () { - this.show(); - this.fireEvent(BI.Popover.EVENT_OPEN, arguments); - }, - - close: function () { - this.hide(); - this.fireEvent(BI.Popover.EVENT_CLOSE, arguments); - }, - - setZindex: function (zindex) { - this.element.css({ "z-index": zindex }); - }, -}); - -BI.shortcut("bi.popover", BI.Popover); - -BI.BarPopover = BI.inherit(BI.Popover, { - _defaultConfig: function () { - return BI.extend(BI.BarPopover.superclass._defaultConfig.apply(this, arguments), { - btns: [BI.i18nText("BI-Basic_OK"), BI.i18nText("BI-Basic_Cancel")], - }); - }, - - beforeCreate: function () { - var self = this; - var o = this.options; - o.footer || (o.footer = { - type: "bi.right_vertical_adapt", - lgap: 10, - items: [{ - type: "bi.button", - height: o.footerButtonHeight, - text: this.options.btns[1], - value: 1, - light: true, - handler: function (v) { - self.fireEvent(BI.Popover.EVENT_CANCEL, v); - self.close(v); - }, - }, { - type: "bi.button", - height: o.footerButtonHeight, - text: this.options.btns[0], - warningTitle: o.warningTitle, - value: 0, - handler: function (v) { - self.fireEvent(BI.Popover.EVENT_CONFIRM, v); - self.close(v); - }, - }], - }); - }, -}); - -BI.shortcut("bi.bar_popover", BI.BarPopover); - -BI.Popover.EVENT_CLOSE = "EVENT_CLOSE"; -BI.Popover.EVENT_OPEN = "EVENT_OPEN"; -BI.Popover.EVENT_CANCEL = "EVENT_CANCEL"; -BI.Popover.EVENT_CONFIRM = "EVENT_CONFIRM"; diff --git a/src/base/layer/layer.popup.js b/src/base/layer/layer.popup.js deleted file mode 100644 index dbeb7e8fe..000000000 --- a/src/base/layer/layer.popup.js +++ /dev/null @@ -1,427 +0,0 @@ -/** - * 下拉框弹出层, zIndex在1000w - * @class BI.PopupView - * @extends BI.Widget - */ -BI.PopupView = BI.inherit(BI.Widget, { - _const: { - TRIANGLE_LENGTH: 12, - }, - _defaultConfig: function (props) { - return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { - _baseCls: "bi-popup-view" + (props.primary ? " bi-primary" : ""), - // 品牌色 - primary: false, - maxWidth: "auto", - minWidth: 100, - // maxHeight: 200, - minHeight: 24, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - vgap: 0, - hgap: 0, - innerVgap: 0, - innerHgap: 0, - showArrow: false, - direction: BI.Direction.Top, // 工具栏的方向 - stopEvent: false, // 是否停止mousedown、mouseup事件 - stopPropagation: false, // 是否停止mousedown、mouseup向上冒泡 - logic: { - dynamic: true, - }, - - tool: false, // 自定义工具栏 - tabs: [], // 导航栏 - buttons: [], // toolbar栏 - - el: { - type: "bi.button_group", - items: [], - chooseType: 0, - behaviors: {}, - layouts: [{ - type: "bi.vertical", - }], - }, - }); - }, - - render: function () { - var self = this, o = this.options; - function fn (e) { - e.stopPropagation(); - } - function stop (e) { - e.stopEvent(); - - return false; - } - this.element.css({ - "z-index": BI.zIndex_popup, - "min-width": BI.pixFormat(o.minWidth), - "max-width": BI.pixFormat(o.maxWidth), - }).bind({ click: fn }); - - this.element.bind("mousewheel", fn); - - o.stopPropagation && this.element.bind({ mousedown: fn, mouseup: fn, mouseover: fn }); - o.stopEvent && this.element.bind({ mousedown: stop, mouseup: stop, mouseover: stop }); - this.tool = this._createTool(); - this.tab = this._createTab(); - this.view = this._createView(); - this.toolbar = this._createToolBar(); - - this.view.on(BI.Controller.EVENT_CHANGE, function (type) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.PopupView.EVENT_CHANGE); - } - }); - - BI.createWidget(BI.extend({ - element: this, - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - scrolly: false, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - hgap: o.hgap, - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, BI.extend({ - cls: "list-view-outer bi-card list-view-shadow" + (o.primary ? " bi-primary" : ""), - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tool, this.tab, this.view, this.toolbar), - }))) - ), - })))); - if (o.showArrow) { - this.arrow = BI.createWidget({ - type: "bi.absolute", - cls: "bi-bubble-arrow", - items: [{ - type: "bi.layout", - cls: "bubble-arrow", - }], - }); - this.arrowWrapper = BI.createWidget({ - type: "bi.absolute", - cls: "bi-bubble-arrow-wrapper", - items: [{ - el: this.arrow, - }], - }); - // 因为三角符号的原因位置变大了,需要占位 - this.placeholder = BI.createWidget({ - type: "bi.layout", - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.arrowWrapper, - left: 0, - top: 0, - }, { - el: this.placeholder, - }], - }); - } - }, - - _createView: function () { - var o = this.options; - this.button_group = BI.createWidget(o.el, { type: "bi.button_group", value: o.value }); - this.button_group.element.css({ - "min-height": BI.pixFormat(o.minHeight), - "padding-top": BI.pixFormat(o.innerVgap), - "padding-bottom": BI.pixFormat(o.innerVgap), - "padding-left": BI.pixFormat(o.innerHgap), - "padding-right": BI.pixFormat(o.innerHgap), - }); - - return this.button_group; - }, - - _createTool: function () { - var o = this.options; - if (false === o.tool) { - return; - } - - return BI.createWidget(o.tool); - }, - - _createTab: function () { - var o = this.options; - if (o.tabs.length === 0) { - return; - } - - return BI.createWidget({ - type: "bi.center", - cls: "list-view-tab", - height: 25, - items: o.tabs, - value: o.value, - }); - }, - - _createToolBar: function () { - var o = this.options; - if (o.buttons.length === 0) { - return; - } - - return BI.createWidget({ - type: "bi.center", - cls: "list-view-toolbar bi-high-light bi-split-top", - height: 24, - items: BI.createItems(o.buttons, { - once: false, - shadow: true, - isShadowShowingOnSelected: true, - }), - }); - }, - - setDirection: function (direction, position) { - var o = this.options; - if (o.showArrow) { - var style = {}, wrapperStyle = {}, placeholderStyle = {}; - var adjustXOffset = position.adjustXOffset || 0; - var adjustYOffset = position.adjustYOffset || 0; - var bodyBounds = BI.Widget._renderEngine.createElement("body").bounds(); - var bodyWidth = bodyBounds.width; - var bodyHeight = bodyBounds.height; - var popupWidth = this.element.outerWidth(); - var popupHeight = this.element.outerHeight(); - var offset = position.offset; - var offsetStyle = position.offsetStyle; - var middle = offsetStyle === "center" || offsetStyle === "middle"; - - var minLeft = Math.max(4, offset.left + 4 + popupWidth - bodyWidth); - var minRight = Math.max(4, popupWidth - (offset.left + 4)); - var minTop = Math.max(4, offset.top + 4 + popupHeight - bodyHeight); - var minBottom = Math.max(4, popupHeight - (offset.top + 4)); - - var maxLeft = Math.min(popupWidth - 16 - 4, offset.left + position.width - 16 - 4); - var maxRight = Math.min(popupWidth - 16 - 4, bodyWidth - (offset.left + position.width - 16 - 4)); - var maxTop = Math.min(popupHeight - 16 - 4, offset.top + position.height - 16 - 4); - var maxBottom = Math.min(popupHeight - 16 - 4, bodyHeight - (offset.top + position.height - 16 - 4)); - switch (direction) { - case "bottom": - case "bottom,right": - direction = "bottom"; - style = { - // 5表示留出一定的空间 - left: BI.clamp(((middle ? popupWidth : position.width) - adjustXOffset) / 2 - 8, minLeft, maxLeft), - }; - wrapperStyle = { - top: o.tgap + o.vgap, - left: 0, - right: "", - bottom: "", - }; - placeholderStyle = { - left: 0, - right: 0, - height: this._const.TRIANGLE_LENGTH, - top: -this._const.TRIANGLE_LENGTH, - bottom: "", - }; - break; - case "bottom,left": - direction = "bottom"; - style = { - right: BI.clamp(((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, minRight, maxRight), - }; - wrapperStyle = { - top: o.bgap + o.vgap, - left: "", - right: 0, - bottom: "", - }; - placeholderStyle = { - left: 0, - right: 0, - height: this._const.TRIANGLE_LENGTH, - top: -this._const.TRIANGLE_LENGTH, - bottom: "", - }; - break; - case "top": - case "top,right": - direction = "top"; - style = { - left: BI.clamp(((middle ? popupWidth : position.width) - adjustXOffset) / 2 - 8, minLeft, maxLeft), - }; - wrapperStyle = { - bottom: o.bgap + o.vgap, - left: 0, - right: "", - top: "", - }; - placeholderStyle = { - left: 0, - right: 0, - height: this._const.TRIANGLE_LENGTH, - top: "", - bottom: -this._const.TRIANGLE_LENGTH, - }; - break; - case "top,left": - direction = "top"; - style = { - right: BI.clamp(((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, minRight, maxRight), - }; - wrapperStyle = { - bottom: o.bgap + o.vgap, - right: 0, - left: "", - top: "", - }; - placeholderStyle = { - left: 0, - right: 0, - height: this._const.TRIANGLE_LENGTH, - top: "", - bottom: -this._const.TRIANGLE_LENGTH, - }; - break; - case "left": - case "left,bottom": - direction = "left"; - style = { - top: BI.clamp(((middle ? popupHeight : position.height) - adjustYOffset) / 2 - 8, minTop, maxTop), - }; - wrapperStyle = { - right: o.rgap + o.hgap, - top: 0, - bottom: "", - left: "", - }; - placeholderStyle = { - top: 0, - bottom: 0, - width: this._const.TRIANGLE_LENGTH, - right: -this._const.TRIANGLE_LENGTH, - left: "", - }; - break; - case "left,top": - direction = "left"; - style = { - bottom: BI.clamp(((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, minBottom, maxBottom), - }; - wrapperStyle = { - right: o.rgap + o.hgap, - bottom: 0, - top: "", - left: "", - }; - placeholderStyle = { - top: 0, - bottom: 0, - width: this._const.TRIANGLE_LENGTH, - right: -this._const.TRIANGLE_LENGTH, - left: "", - }; - break; - case "right": - case "right,bottom": - direction = "right"; - style = { - top: BI.clamp(((middle ? popupHeight : position.height) - adjustYOffset) / 2 - 8, minTop, maxTop), - }; - wrapperStyle = { - left: o.lgap + o.hgap, - top: 0, - bottom: "", - right: "", - }; - placeholderStyle = { - top: 0, - bottom: 0, - width: this._const.TRIANGLE_LENGTH, - left: -this._const.TRIANGLE_LENGTH, - right: "", - }; - break; - case "right,top": - direction = "right"; - style = { - bottom: BI.clamp(((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, minBottom, maxBottom), - }; - wrapperStyle = { - left: o.lgap + o.hgap, - bottom: 0, - top: "", - right: "", - }; - placeholderStyle = { - top: 0, - bottom: 0, - width: this._const.TRIANGLE_LENGTH, - left: -this._const.TRIANGLE_LENGTH, - right: "", - }; - break; - case "right,innerRight": - break; - case "right,innerLeft": - break; - case "innerRight": - break; - case "innerLeft": - break; - default: - break; - } - this.element - .removeClass("left") - .removeClass("right") - .removeClass("top") - .removeClass("bottom") - .addClass(direction); - this.arrow.element.css(style); - this.arrowWrapper.element.css(wrapperStyle); - this.placeholder.element.css(placeholderStyle); - } - }, - - getView: function () { - return this.view; - }, - - populate: function (items) { - this.view.populate.apply(this.view, arguments); - }, - - resetWidth: function (w) { - this.options.width = w; - this.element.width(w); - }, - - resetHeight: function (h) { - var tbHeight = this.toolbar ? (this.toolbar.attr("height") || 24) : 0, - tabHeight = this.tab ? (this.tab.attr("height") || 24) : 0, - toolHeight = ((this.tool && this.tool.attr("height")) || 24) * ((this.tool && this.tool.isVisible()) ? 1 : 0); - var resetHeight = h - tbHeight - tabHeight - toolHeight - 2 * this.options.innerVgap; - this.view.resetHeight ? this.view.resetHeight(resetHeight) : - this.view.element.css({ "max-height": BI.pixFormat(resetHeight) }); - }, - - setValue: function (selectedValues) { - this.tab && this.tab.setValue(selectedValues); - this.view.setValue(selectedValues); - }, - - getValue: function () { - return this.view.getValue(); - }, -}); -BI.PopupView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.popup_view", BI.PopupView); diff --git a/src/base/layer/layer.searcher.js b/src/base/layer/layer.searcher.js deleted file mode 100644 index b9d8d2b41..000000000 --- a/src/base/layer/layer.searcher.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * 搜索面板 - * - * Created by GUY on 2015/9/28. - * @class BI.SearcherView - * @extends BI.Pane - */ - -BI.SearcherView = BI.inherit(BI.Pane, { - _defaultConfig: function () { - var conf = BI.SearcherView.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-searcher-view bi-card", - tipText: BI.i18nText("BI-No_Select"), - chooseType: BI.Selection.Single, - - matcher: { // 完全匹配的构造器 - type: "bi.button_group", - behaviors: { - redmark: function () { - return true; - }, - }, - items: [], - layouts: [{ - type: "bi.vertical", - }], - }, - searcher: { - type: "bi.button_group", - behaviors: { - redmark: function () { - return true; - }, - }, - items: [], - layouts: [{ - type: "bi.vertical", - }], - }, - }); - }, - - render: function () { - var self = this, o = this.options; - - this.matcher = BI.createWidget(o.matcher, { - type: "bi.button_group", - chooseType: o.chooseType, - behaviors: { - redmark: function () { - return true; - }, - }, - layouts: [{ - type: "bi.vertical", - }], - value: o.value, - }); - this.matcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); - } - }); - this.spliter = BI.createWidget({ - type: "bi.vertical", - height: 1, - hgap: 10, - items: [{ - type: "bi.layout", - height: 1, - cls: "searcher-view-spliter bi-background", - }], - }); - this.searcher = BI.createWidget(o.searcher, { - type: "bi.button_group", - chooseType: o.chooseType, - behaviors: { - redmark: function () { - return true; - }, - }, - layouts: [{ - type: "bi.vertical", - }], - value: o.value, - }); - this.searcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); - } - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.matcher, this.spliter, this.searcher], - }); - }, - - startSearch: function () { - - }, - - stopSearch: function () { - - }, - - setValue: function (v) { - this.matcher.setValue(v); - this.searcher.setValue(v); - }, - - getValue: function () { - return this.matcher.getValue().concat(this.searcher.getValue()); - }, - - populate: function (searchResult, matchResult, keyword) { - searchResult || (searchResult = []); - matchResult || (matchResult = []); - this.setTipVisible(searchResult.length + matchResult.length === 0); - this.spliter.setVisible(BI.isNotEmptyArray(matchResult) && BI.isNotEmptyArray(searchResult)); - this.matcher.populate(matchResult, keyword); - this.searcher.populate(searchResult, keyword); - }, - - empty: function () { - this.searcher.empty(); - this.matcher.empty(); - }, - - hasMatched: function () { - return this.matcher.getAllButtons().length > 0; - }, -}); -BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.searcher_view", BI.SearcherView); diff --git a/src/base/list/listview.js b/src/base/list/listview.js deleted file mode 100644 index 13a8895c7..000000000 --- a/src/base/list/listview.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * 边滚动边加载的列表控件 - * - * Created by GUY on 2017/5/23. - * @class BI.ListView - * @extends BI.Widget - */ -BI.ListView = BI.inherit(BI.Widget, { - props: function () { - return { - baseCls: "bi-list-view", - overscanHeight: 100, - blockSize: 10, - scrollTop: 0, - el: {}, - items: [], - itemFormatter: function (item, index) { - return item; - }, - }; - }, - - init: function () { - this.renderedIndex = -1; - this.cache = {}; - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical", - items: [BI.extend({ - type: "bi.vertical", - scrolly: false, - ref: function (_ref) { - self.container = _ref; - }, - }, o.el)], - element: this, - }; - }, - - // mounted之后绑定事件 - mounted: function () { - var self = this, o = this.options; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this._populate(); - this.element.scroll(function (e) { - o.scrollTop = self.element.scrollTop(); - self._calculateBlocksToRender(); - }); - var lastWidth = this.element.width(), - lastHeight = this.element.height(); - BI.ResizeDetector.addResizeListener(this, function () { - if (!self.element.is(":visible")) { - return; - } - var width = self.element.width(), - height = self.element.height(); - if (width !== lastWidth || height !== lastHeight) { - lastWidth = width; - lastHeight = height; - self._calculateBlocksToRender(); - } - }); - }, - - _renderMoreIf: function () { - var self = this, o = this.options; - var height = this.element.height(); - var minContentHeight = o.scrollTop + height + o.overscanHeight; - var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0; - var cnt = this.renderedIndex + 1; - var lastHeight; - - function getElementHeight() { - return self.container.element.height(); - } - - lastHeight = getElementHeight(); - while ((lastHeight) < minContentHeight && index < o.items.length) { - var items = o.items.slice(index, index + o.blockSize); - this.container.addItems(items.map(function (item, i) { - return o.itemFormatter(item, index + i); - }), this); - var addedHeight = getElementHeight() - lastHeight; - this.cache[cnt] = { - index: index, - scrollTop: lastHeight, - height: addedHeight, - }; - this.renderedIndex = cnt; - cnt++; - index += o.blockSize; - lastHeight = getElementHeight(); - } - }, - - _calculateBlocksToRender: function () { - // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 - // 这样从不可见状态变为可见状态能够重新触发线段树初始化 - if (!this.element.is(":visible")) { - return; - } - this._renderMoreIf(); - }, - - _populate: function (items) { - var o = this.options; - if (items && this.options.items !== items) { - this.options.items = items; - } - this._calculateBlocksToRender(); - this.element.scrollTop(o.scrollTop); - }, - - restore: function () { - this.renderedIndex = -1; - this.container.empty(); - this.cache = {}; - }, - - scrollTo: function (scrollTop) { - this.options.scrollTop = scrollTop; - this._calculateBlocksToRender(); - this.element.scrollTop(scrollTop); - }, - - populate: function (items) { - if (items && this.options.items !== items) { - this.restore(); - } - this._populate(items); - }, - - beforeDestroy: function () { - BI.ResizeDetector.removeResizeListener(this); - this.restore(); - }, -}); -BI.shortcut("bi.list_view", BI.ListView); - diff --git a/src/base/list/virtualgrouplist.js b/src/base/list/virtualgrouplist.js deleted file mode 100644 index 95b5276bd..000000000 --- a/src/base/list/virtualgrouplist.js +++ /dev/null @@ -1,198 +0,0 @@ -/** - * 同时用于virtualGroup和virtualList特性的虚拟列表 - * - * Created by GUY on 2017/5/22. - * @class BI.VirtualList - * @extends BI.Widget - */ -BI.VirtualGroupList = BI.inherit(BI.Widget, { - props: function () { - return { - baseCls: "bi-virtual-group-list", - overscanHeight: 100, - blockSize: 10, - scrollTop: 0, - rowHeight: "auto", - items: [], - el: {}, - itemFormatter: function (item, index) { - return item; - }, - }; - }, - - init: function () { - this.renderedIndex = -1; - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical", - items: [{ - type: "bi.layout", - ref: function () { - self.topBlank = this; - }, - }, { - type: "bi.virtual_group", - height: o.rowHeight * o.items.length, - ref: function () { - self.container = this; - }, - layouts: [BI.extend({ - type: "bi.vertical", - scrolly: false, - }, o.el)], - }, { - type: "bi.layout", - ref: function () { - self.bottomBlank = this; - }, - }], - element: this, - }; - }, - - // mounted之后绑定事件 - mounted: function () { - var self = this, o = this.options; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this._populate(); - this.ticking = false; - this.element.scroll(function () { - o.scrollTop = self.element.scrollTop(); - if (!self.ticking) { - requestAnimationFrame(function () { - self._calculateBlocksToRender(); - self.ticking = false; - }); - self.ticking = true; - } - }); - BI.ResizeDetector.addResizeListener(this, function () { - if (self.element.is(":visible")) { - self._calculateBlocksToRender(); - } - }); - }, - - _isAutoHeight: function () { - return !BI.isNumber(this.options.rowHeight); - }, - - _renderMoreIf: function () { - var self = this, o = this.options; - var height = this.element.height(); - var minContentHeight = o.scrollTop + height + o.overscanHeight; - var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1; - var lastHeight; - function getElementHeight () { - return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); - } - lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight(); - while (lastHeight < minContentHeight && index < o.items.length) { - var items = o.items.slice(index, index + o.blockSize); - this.container[self.renderedIndex === -1 ? "populate" : "addItems"](items.map(function (item, i) { - return o.itemFormatter(item, index + i); - }), this); - var elementHeight = getElementHeight(); - var addedHeight = elementHeight - lastHeight; - this.tree.set(cnt, addedHeight); - this.renderedIndex = cnt; - cnt++; - index += o.blockSize; - lastHeight = this.renderedIndex === -1 ? 0 : elementHeight; - } - }, - - _calculateBlocksToRender: function () { - // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 - // 这样从不可见状态变为可见状态能够重新触发线段树初始化 - if (!this.element.is(":visible")) { - return; - } - var o = this.options; - this._isAutoHeight() && this._renderMoreIf(); - var height = this.element.height(); - var minContentHeightFrom = o.scrollTop - o.overscanHeight; - var minContentHeightTo = o.scrollTop + height + o.overscanHeight; - var start = this.tree.greatestLowerBound(minContentHeightFrom); - var end = this.tree.leastUpperBound(minContentHeightTo); - var items = []; - var topHeight = this.tree.sumTo(Math.max(-1, start - 1)); - this.topBlank.setHeight(topHeight + "px"); - if (this._isAutoHeight()) { - for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { - var index = i * o.blockSize; - for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - items.push(o.items[j]); - } - } - this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px"); - this.container.populate(items.map(function (item, i) { - return o.itemFormatter(item, (start < 0 ? 0 : start) * o.blockSize + i); - })); - } else { - for (var i = (start < 0 ? 0 : start); i <= end; i++) { - var index = i * o.blockSize; - for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - items.push(o.items[j]); - } - } - this.container.element.height(o.rowHeight * o.items.length - topHeight); - this.container.populate(items.map(function (item, i) { - return o.itemFormatter(item, (start < 0 ? 0 : start) * o.blockSize + i); - })); - } - }, - - _populate: function (items) { - var o = this.options; - if (items && this.options.items !== items) { - // 重新populate一组items,需要重新对线段树分块 - this.options.items = items; - this._restore(); - } - this.tree = BI.PrefixIntervalTree.uniform(Math.ceil(o.items.length / o.blockSize), this._isAutoHeight() ? 0 : o.rowHeight * o.blockSize); - - this._calculateBlocksToRender(); - try { - this.element.scrollTop(o.scrollTop); - } catch (e) { - } - }, - - _restore: function () { - this.renderedIndex = -1; - // 依赖于cache的占位元素也要初始化 - this.topBlank.setHeight(0); - this.bottomBlank.setHeight(0); - }, - - // 暂时只支持固定行高的场景 - scrollTo: function (scrollTop) { - this.options.scrollTop = scrollTop; - this._calculateBlocksToRender(); - this.element.scrollTop(scrollTop); - }, - - restore: function () { - this.options.scrollTop = 0; - this._restore(); - }, - - populate: function (items) { - this._populate(items); - }, - - beforeDestroy: function () { - BI.ResizeDetector.removeResizeListener(this); - this.restore(); - } -}); -BI.shortcut("bi.virtual_group_list", BI.VirtualGroupList); - diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js deleted file mode 100644 index 618d66c2a..000000000 --- a/src/base/list/virtuallist.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * 虚拟列表 - * - * Created by GUY on 2017/5/22. - * @class BI.VirtualList - * @extends BI.Widget - */ -BI.VirtualList = BI.inherit(BI.Widget, { - props: function () { - return { - baseCls: "bi-virtual-list", - overscanHeight: 100, - blockSize: 10, - scrollTop: 0, - items: [], - itemFormatter: function (item, index) { - return item; - }, - }; - }, - - init: function () { - this.renderedIndex = -1; - this.cache = {}; - }, - - render: function () { - var self = this; - - return { - type: "bi.vertical", - items: [{ - type: "bi.layout", - ref: function () { - self.topBlank = this; - }, - }, { - type: "bi.vertical", - scrolly: false, - ref: function () { - self.container = this; - }, - }, { - type: "bi.layout", - ref: function () { - self.bottomBlank = this; - }, - }], - }; - }, - - // mounted之后绑定事件 - mounted: function () { - var self = this, o = this.options; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this._populate(); - this.element.scroll(function (e) { - o.scrollTop = self.element.scrollTop(); - self._calculateBlocksToRender(); - }); - BI.ResizeDetector.addResizeListener(this, function () { - if (self.element.is(":visible")) { - self._calculateBlocksToRender(); - } - }); - }, - - _renderMoreIf: function () { - var self = this, o = this.options; - var height = this.element.height(); - var minContentHeight = o.scrollTop + height + o.overscanHeight; - var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1; - var lastHeight; - function getElementHeight() { - return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); - } - lastHeight = getElementHeight(); - while (lastHeight < minContentHeight && index < o.items.length) { - var items = o.items.slice(index, index + o.blockSize); - this.container.addItems(items.map(function (item, i) { - return o.itemFormatter(item, index + i); - }), this); - var addedHeight = getElementHeight() - lastHeight; - this.tree.set(cnt, addedHeight); - this.renderedIndex = cnt; - cnt++; - index += o.blockSize; - lastHeight = getElementHeight(); - } - }, - - _calculateBlocksToRender: function () { - var o = this.options; - // BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。 - // 这样从不可见状态变为可见状态能够重新触发线段树初始化 - if (!this.element.is(":visible")) { - return; - } - this._renderMoreIf(); - var height = this.element.height(); - var minContentHeightFrom = o.scrollTop - o.overscanHeight; - var minContentHeightTo = o.scrollTop + height + o.overscanHeight; - var start = this.tree.greatestLowerBound(minContentHeightFrom); - var end = this.tree.leastUpperBound(minContentHeightTo); - var needDestroyed = [], needMount = []; - for (var i = 0; i < start; i++) { - var index = i * o.blockSize; - if (!this.cache[i]) { - this.cache[i] = {}; - } - if (!this.cache[i].destroyed) { - for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - needDestroyed.push(this.container._children[j]); - this.container._children[j] = null; - } - this.cache[i].destroyed = true; - } - } - for (var i = end + 1; i <= this.renderedIndex; i++) { - var index = i * o.blockSize; - if (!this.cache[i]) { - this.cache[i] = {}; - } - if (!this.cache[i].destroyed) { - for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - needDestroyed.push(this.container._children[j]); - this.container._children[j] = null; - } - this.cache[i].destroyed = true; - } - } - var firstFragment = BI.Widget._renderEngine.createFragment(), - lastFragment = BI.Widget._renderEngine.createFragment(); - var currentFragment = firstFragment; - for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { - var index = i * o.blockSize; - if (!this.cache[i]) { - this.cache[i] = {}; - } - if (!this.cache[i].destroyed) { - currentFragment = lastFragment; - } - if (this.cache[i].destroyed === true) { - for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - var w = this.container._addElement(j, o.itemFormatter(o.items[j], j), this); - needMount.push(w); - currentFragment.appendChild(w.element[0]); - } - this.cache[i].destroyed = false; - } - } - this.container.element.prepend(firstFragment); - this.container.element.append(lastFragment); - this.topBlank.setHeight(this.tree.sumTo(Math.max(-1, start - 1)) + "px"); - this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px"); - BI.each(needMount, function (i, child) { - child && child._mount(); - }); - BI.each(needDestroyed, function (i, child) { - child && child._destroy(); - }); - }, - - _populate: function (items) { - var o = this.options; - if (items && this.options.items !== items) { - this.options.items = items; - } - this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); - - this._calculateBlocksToRender(); - try { - this.element.scrollTop(o.scrollTop); - } catch (e) { - } - }, - - _clearChildren: function () { - BI.each(this.container._children, function (i, cell) { - cell && cell._destroy(); - }); - this.container._children = {}; - this.container.attr("items", []); - }, - - scrollTo: function (scrollTop) { - this.options.scrollTop = scrollTop; - this._calculateBlocksToRender(); - this.element.scrollTop(scrollTop); - }, - - restore: function () { - this.renderedIndex = -1; - this._clearChildren(); - this.cache = {}; - this.options.scrollTop = 0; - // 依赖于cache的占位元素也要初始化 - this.topBlank.setHeight(0); - this.bottomBlank.setHeight(0); - }, - - populate: function (items) { - if (items && this.options.items !== items) { - this.restore(); - } - this._populate(items); - }, - - beforeDestroy: function () { - BI.ResizeDetector.removeResizeListener(this); - this.restore(); - } -}); -BI.shortcut("bi.virtual_list", BI.VirtualList); - diff --git a/src/base/pager/pager.js b/src/base/pager/pager.js deleted file mode 100644 index ffce61a33..000000000 --- a/src/base/pager/pager.js +++ /dev/null @@ -1,304 +0,0 @@ -/** - * 分页控件 - * - * Created by GUY on 2015/8/31. - * @class BI.Pager - * @extends BI.Widget - */ -BI.Pager = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Pager.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-pager", - behaviors: {}, - layouts: [ - { - type: "bi.horizontal", - hgap: 10, - vgap: 0, - } - ], - - dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 - // dynamicShow为false时以下两个有用 - dynamicShowFirstLast: false, // 是否动态显示首页、尾页 - dynamicShowPrevNext: false, // 是否动态显示上一页、下一页 - pages: false, // 总页数 - curr: function () { - return 1; - }, // 初始化当前页 - groups: 0, // 连续显示分页数 - jump: BI.emptyFn, // 分页的回调函数 - first: false, // 是否显示首页 - last: false, // 是否显示尾页 - prev: BI.i18nText("BI-Previous_Page"), - next: BI.i18nText("BI-Next_Page"), - - firstPage: 1, - lastPage: function () { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 - return 1; - }, - hasPrev: BI.emptyFn, // pages不可用时有效 - hasNext: BI.emptyFn, // pages不可用时有效 - }); - }, - - render: function () { - this.currPage = BI.result(this.options, "curr"); - // 翻页太灵敏 - // this._lock = false; - // this._debouce = BI.debounce(function () { - // self._lock = false; - // }, 300); - this._populate(); - }, - - _populate: function () { - var self = this, o = this.options, view = [], dict = {}; - this.empty(); - var pages = BI.result(o, "pages"); - var curr = BI.result(this, "currPage"); - var groups = BI.result(o, "groups"); - var first = BI.result(o, "first"); - var last = BI.result(o, "last"); - var prev = BI.result(o, "prev"); - var next = BI.result(o, "next"); - - if (pages === false) { - groups = 0; - first = false; - last = false; - } else { - groups > pages && (groups = pages); - } - - // 计算当前组 - dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); - - // 当前页非首页,则输出上一页 - if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { - if (BI.isKey(prev)) { - view.push({ - text: prev, - value: "prev", - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false), - }); - } else { - view.push({ - el: BI.extend({ - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false), - }, prev), - }); - } - } - - // 当前组非首组,则输出首页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { - view.push({ - text: first, - value: "first", - disabled: !(dict.index > 1 && groups !== 0), - }); - if (dict.index > 1 && groups !== 0 && groups !== pages - 1) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026", - }); - } - } - - // 输出当前页组 - dict.poor = Math.floor((groups - 1) / 2); - dict.start = dict.index > 1 ? curr - dict.poor : 1; - dict.end = dict.index > 1 ? (function () { - var max = curr + (groups - dict.poor - 1); - - return max > pages ? pages : max; - }()) : groups; - if (dict.end - dict.start < groups - 1) { // 最后一组状态 - dict.start = dict.end - groups + 1; - } - var s = dict.start, e = dict.end; - if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { - s++; - e--; - } - for (; s <= e; s++) { - if (s === curr) { - view.push({ - text: s, - value: s, - selected: true, - }); - } else { - view.push({ - text: s, - value: s, - }); - } - } - - // 总页数大于连续分页数,且当前组最大页小于总页,输出尾页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { - if (pages > groups && dict.end < pages && groups !== 0 && groups !== pages - 1) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026", - }); - } - view.push({ - text: last, - value: "last", - disabled: !(pages > groups && dict.end < pages && groups !== 0), - }); - } - - // 当前页不为尾页时,输出下一页 - dict.flow = !prev && groups === 0; - if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { - view.push((function () { - if (BI.isKey(next)) { - if (pages === false) { - return { text: next, value: "next", disabled: o.hasNext(curr) === false }; - } - - return (dict.flow && curr === pages) - ? - { text: next, value: "next", disabled: true } - : - { text: next, value: "next", disabled: !(curr !== pages && next || dict.flow) }; - } - - return { - el: BI.extend({ - disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow), - }, next), - }; - }())); - } - - this.button_group = BI.createWidget({ - type: "bi.button_group", - element: this, - items: BI.map(view, function (idx, v) { - v = BI.extend({ - cls: "bi-list-item-select bi-border-radius", - height: 23, - hgap: v.el ? 0 : 10, - stopPropagation: true, - }, BI.stripEL(v)); - - return BI.formatEL(v); - }), - behaviors: o.behaviors, - layouts: o.layouts, - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - // if (self._lock === true) { - // return; - // } - // self._lock = true; - // self._debouce(); - if (type === BI.Events.CLICK) { - var v = self.button_group.getValue()[0]; - switch (v) { - case "first": - self.currPage = 1; - break; - case "last": - self.currPage = pages; - break; - case "prev": - self.currPage--; - break; - case "next": - self.currPage++; - break; - default: - self.currPage = v; - break; - } - o.jump.apply(self, [ - { - pages: pages, - curr: self.currPage, - } - ]); - self._populate(); - self.fireEvent(BI.Pager.EVENT_CHANGE, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.fireEvent(BI.Pager.EVENT_AFTER_POPULATE); - }, - - getCurrentPage: function () { - return this.currPage; - }, - - setAllPages: function (pages) { - this.options.pages = pages; - this._populate(); - }, - - hasPrev: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - - return pages === false ? o.hasPrev(v) : v > 1; - }, - - hasNext: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - - return pages === false ? o.hasNext(v) : v < pages; - }, - - setValue: function (v) { - var o = this.options; - v = v || 0; - v = v < 1 ? 1 : v; - if (o.pages === false) { - var lastPage = BI.result(o, "lastPage"), firstPage = 1; - this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); - } else { - v = v > o.pages ? o.pages : v; - this.currPage = v; - } - this._populate(); - }, - - getValue: function () { - var val = this.button_group.getValue()[0]; - switch (val) { - case "prev": - return -1; - case "next": - return 1; - case "first": - return BI.MIN; - case "last": - return BI.MAX; - default: - return val; - } - }, - - attr: function (key, value) { - BI.Pager.superclass.attr.apply(this, arguments); - if (key === "curr") { - this.currPage = BI.result(this.options, "curr"); - } - }, - - populate: function () { - this._populate(); - }, -}); -BI.Pager.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Pager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; -BI.shortcut("bi.pager", BI.Pager); diff --git a/src/base/single/0.single.js b/src/base/single/0.single.js deleted file mode 100644 index c13e02e81..000000000 --- a/src/base/single/0.single.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * guy - * 这仅仅只是一个超类, 所有简单控件的基类 - * 1、类的控制, - * 2、title的控制 - * 3、文字超过边界显示3个点 - * 4、cursor默认pointor - * @class BI.Single - * @extends BI.Widget - * @abstract - */ - -var delayingTooltips; - -BI.Single = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.Single.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - readonly: false, - title: null, - warningTitle: null, // deprecated - tipType: null, // deprecated success或warning - belowMouse: false, // title是否跟随鼠标 - enableHover: false, - }); - }, - - _showToolTip: function (e, opt) { - opt || (opt = {}); - var self = this; - var o = this.options; - var title = this.getTitle(); - - if (title instanceof Promise) { - this.requestingTitle = title; - title.then(resolvedTitle => { - // 由于是异步的,所以无法避免Promise resolve时机问题,所以设计为:鼠标移出了则不显示,并且只显示最后一次发起的查询结果 - this.mouseOver && this.requestingTitle === title && showToolTip(this._getTooltipOptions(resolvedTitle)); - }); - } else { - showToolTip(this._getTooltipOptions(title)); - } - - function showToolTip(tooltipOpt) { - if (BI.isKey(tooltipOpt.text) && !BI.Tooltips.has(self.getName())) { - BI.Tooltips.show(e, self.getName(), tooltipOpt, self, opt); - if (o.action) { - BI.Actions.runAction(o.action, "hover", o, self); - } - BI.Actions.runGlobalAction("hover", o, self); - } - } - }, - - _hideTooltip: function () { - var self = this; - var tooltip = BI.Tooltips.get(this.getName()); - if (BI.isNotNull(tooltip)) { - tooltip.element.fadeOut(200, function () { - BI.Tooltips.remove(self.getName()); - }); - } - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - BI.Single.superclass._init.apply(this, arguments); - }, - - _mounted: function () { - var o = this.options; - if (o.enableHover || BI.isKey(o.title) || BI.isKey(o.warningTitle) - || BI.isFunction(o.title) || BI.isFunction(o.warningTitle)) { - this.enableHover({ - belowMouse: o.belowMouse, - container: o.container, - }); - } - }, - - _clearTimeOut: function () { - if (BI.isNotNull(this.showTimeout)) { - clearTimeout(this.showTimeout); - this.showTimeout = null; - } - if (BI.isNotNull(this.hideTimeout)) { - clearTimeout(this.hideTimeout); - this.hideTimeout = null; - } - }, - - _getTooltipOptions: function (title) { - var o = this.options; - var tooltipOpt = {}; - if (BI.isPlainObject(title)) { - tooltipOpt = title; - } else { - tooltipOpt.level = this.getTipType() || "success"; - // 由于以前的用法,存在大量disabled:true搭配warningTitle的情况,所以这里做一个兼容,disabled:true的情况下,依然优先显示warningTitle,避免只设置了warningTitle而没有设置title的情况 - if (BI.isNull(o.tipType) && !this.isEnabled()) { - tooltipOpt.text = (this.getWarningTitle() || title); - } else { - tooltipOpt.text = tooltipOpt.level === "success" ? title : (this.getWarningTitle() || title); - } - } - return tooltipOpt; - }, - - enableHover: function (opt) { - opt || (opt = {}); - var self = this; - if (!this._hoverBinded) { - this.element.unbind("mouseenter.title").on("mouseenter.title", function (e) { - self._e = e; - self.mouseOver = true; - if (self.getTipType() === "warning" || (BI.isKey(self.getWarningTitle()) && !self.isEnabled())) { - delayingTooltips = self.getName(); - self.showTimeout = BI.delay(function () { - if (BI.isNotNull(self.showTimeout) && delayingTooltips === self.getName()) { - self._showToolTip(self._e || e, opt); - } - }, 200); - } else if (self.getTipType() === "success" || self.isEnabled()) { - delayingTooltips = self.getName(); - self.showTimeout = BI.delay(function () { - if (BI.isNotNull(self.showTimeout) && delayingTooltips === self.getName()) { - self._showToolTip(self._e || e, opt); - } - }, 500); - } - }); - this.element.unbind("mousemove.title").on("mousemove.title", function (e) { - self._e = e; - if (BI.isNotNull(self.showTimeout)) { - clearTimeout(self.showTimeout); - self.showTimeout = null; - } - if (BI.isNull(self.hideTimeout)) { - self.hideTimeout = BI.delay(function () { - if (BI.isNotNull(self.hideTimeout)) { - self._hideTooltip(); - } - }, 500); - } - - self.showTimeout = BI.delay(function () { - // DEC-5321 IE下如果回调已经进入事件队列,clearTimeout将不会起作用 - if (BI.isNotNull(self.showTimeout)) { - if (BI.isNotNull(self.hideTimeout)) { - clearTimeout(self.hideTimeout); - self.hideTimeout = null; - } - // CHART-10611 在拖拽的情况下, 鼠标拖拽着元素离开了拖拽元素的容器,但是子元素在dom结构上仍然属于容器 - // 这样会认为鼠标仍然在容器中, 500ms内放开的话,会在容器之外显示鼠标停留处显示容器的title - if (self.element.__isMouseInBounds__(self._e || e)) { - self._showToolTip(self._e || e, opt); - } - } - }, 500); - }); - this.element.unbind("mouseleave.title").on("mouseleave.title", function (e) { - self._e = null; - self.mouseOver = false; - self._clearTimeOut(); - self._hideTooltip(); - }); - this._hoverBinded = true; - } - }, - - disabledHover: function () { - // 取消hover事件 - this._clearTimeOut(); - this._hideTooltip(); - this.element.unbind("mouseenter.title") - .unbind("mousemove.title") - .unbind("mouseleave.title"); - this._hoverBinded = false; - }, - - // opt: {container: '', belowMouse: false} - setTitle: function (title, opt) { - this.options.title = title; - if (BI.isKey(title) || BI.isFunction(title)) { - this.enableHover(opt); - } else { - this.disabledHover(); - } - }, - - setWarningTitle: function (title, opt) { - this.options.warningTitle = title; - if (BI.isKey(title) || BI.isFunction(title)) { - this.enableHover(opt); - } else { - this.disabledHover(); - } - }, - - setTipType: function (type) { - this.options.tipType = type; - }, - - getTipType: function () { - return this.options.tipType; - }, - - isReadOnly: function () { - return !!this.options.readonly; - }, - - getTitle: function () { - var title = this.options.title; - if (BI.isFunction(title)) { - return title(); - } - - return title; - }, - - getWarningTitle: function () { - var title = this.options.warningTitle; - if (BI.isFunction(title)) { - return title(); - } - - return title; - }, - - setValue: function (val) { - if (!this.options.readonly) { - this.options.value = val; - this.options.setValue && this.options.setValue(val); - } - }, - - getValue: function () { - return this.options.value; - }, - - _destroyed: function () { - if (BI.isNotNull(this.showTimeout)) { - clearTimeout(this.showTimeout); - this.showTimeout = null; - } - BI.Tooltips.remove(this.getName()); - }, -}); -BI.shortcut("bi.single", BI.Single); diff --git a/src/base/single/1.text.js b/src/base/single/1.text.js deleted file mode 100644 index f31ebfe43..000000000 --- a/src/base/single/1.text.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * guy 表示一行数据,通过position来定位位置的数据 - * @class BI.Text - * @extends BI.Single - */ -!(function () { - BI.Text = BI.inherit(BI.Single, { - - props: { - baseCls: "bi-text", - textAlign: "left", - whiteSpace: "normal", - lineHeight: null, - handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的 - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - py: "", - highLight: false, - }, - - render: function () { - var self = this, o = this.options; - if (o.hgap + o.lgap > 0) { - this.element.css({ - "padding-left": BI.pixFormat(o.hgap + o.lgap), - }); - } - if (o.hgap + o.rgap > 0) { - this.element.css({ - "padding-right": BI.pixFormat(o.hgap + o.rgap), - }); - } - if (o.vgap + o.tgap > 0) { - this.element.css({ - "padding-top": BI.pixFormat(o.vgap + o.tgap), - }); - } - if (o.vgap + o.bgap > 0) { - this.element.css({ - "padding-bottom": BI.pixFormat(o.vgap + o.bgap), - }); - } - if (BI.isWidthOrHeight(o.height)) { - this.element.css({ lineHeight: BI.pixFormat(o.height) }); - } - if (BI.isWidthOrHeight(o.lineHeight)) { - this.element.css({ lineHeight: BI.pixFormat(o.lineHeight) }); - } - if (BI.isWidthOrHeight(o.maxWidth)) { - this.element.css({ maxWidth: BI.pixFormat(o.maxWidth) }); - } - this.element.css({ - textAlign: o.textAlign, - whiteSpace: this._getTextWrap(), - textOverflow: o.whiteSpace === "nowrap" ? "ellipsis" : "", - overflow: o.whiteSpace === "nowrap" ? "" : (BI.isWidthOrHeight(o.height) ? "auto" : ""), - }); - if (o.handler && o.handler !== BI.emptyFn) { - this.text = BI.createWidget({ - type: "bi.layout", - tagName: "span", - }); - this.text.element.click(function (e) { - !o.disabled && !o.invalid && o.handler.call(self, self.getValue(), self, e); - }); - BI.createWidget({ - type: "bi.default", - element: this, - items: [this.text], - }); - } else { - this.text = this; - } - - var text = BI.isFunction(o.text) ? this.__watch(o.text, function (context, newValue) { - self.setText(newValue); - }) : o.text; - // 只要不是undefined就可以显示text值,否则显示value - if (!BI.isUndefined(text)) { - this.setText(text); - } else if (BI.isKey(o.value)) { - this.setText(o.value); - } - if (BI.isKey(o.keyword)) { - this.doRedMark(o.keyword); - } - if (o.highLight) { - this.doHighLight(); - } - }, - - _getTextWrap: function () { - var o = this.options; - switch (o.whiteSpace) { - case "nowrap": - return "pre"; - case "normal": - return "pre-wrap"; - default: - return o.whiteSpace; - } - }, - - _getShowText: function () { - var o = this.options; - var text = BI.isFunction(o.text) ? o.text() : o.text; - - return BI.isKey(text) ? BI.Text.formatText(text + "") : text; - }, - - _doRedMark: function (keyword) { - var o = this.options; - // render之后做的doRedMark,这个时候虽然标红了,但是之后text mounted执行的时候并没有keyword - o.keyword = keyword; - this.text.element.__textKeywordMarked__(this._getShowText(), keyword, o.py); - }, - - doRedMark: function (keyword) { - if (BI.isKey(keyword)) { - this._doRedMark(keyword); - } - }, - - unRedMark: function () { - var o = this.options; - o.keyword = ""; - this.text.element.__textKeywordMarked__(this._getShowText(), "", o.py); - }, - - doHighLight: function () { - this.text.element.addClass("bi-high-light"); - }, - - unHighLight: function () { - this.text.element.removeClass("bi-high-light"); - }, - - setValue: function (text) { - BI.Text.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.setText(text); - } - }, - - setStyle: function (css) { - this.text.element.css(css); - }, - - setText: function (text) { - BI.Text.superclass.setText.apply(this, arguments); - this.options.text = text; - this._doRedMark(this.options.keyword); - }, - }); - var formatters = []; - BI.Text.addTextFormatter = function (formatter) { - formatters.push(formatter); - }; - BI.Text.formatText = function (text) { - if (formatters.length > 0) { - for (var i = 0, len = formatters.length; i < len; i++) { - text = formatters[i](text); - } - } - - return text; - }; - BI.shortcut("bi.text", BI.Text); -}()); - diff --git a/src/base/single/a/a.js b/src/base/single/a/a.js deleted file mode 100644 index 9159f0a46..000000000 --- a/src/base/single/a/a.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 超链接 - * - * Created by GUY on 2015/9/9. - * @class BI.A - * @extends BI.Text - * @abstract - */ -BI.A = BI.inherit(BI.Text, { - _defaultConfig: function () { - var conf = BI.A.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-a display-block", - href: "", - target: "_blank", - el: null, - tagName: "a", - }); - }, - - render: function () { - var o = this.options; - BI.A.superclass.render.apply(this, arguments); - this.element.attr({ href: o.href, target: o.target }); - if (o.el) { - BI.createWidget(o.el, { - element: this, - }); - } - }, -}); - -BI.shortcut("bi.a", BI.A); diff --git a/src/base/single/bar/bar.loading.js b/src/base/single/bar/bar.loading.js deleted file mode 100644 index 801331b15..000000000 --- a/src/base/single/bar/bar.loading.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * guy - * 加载条 - * @type {*|void|Object} - */ -BI.LoadingBar = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.LoadingBar.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-loading-bar bi-tips", - height: 30, - handler: BI.emptyFn, - }); - }, - - render: function () { - var self = this; - this.loaded = BI.createWidget({ - type: "bi.text_button", - cls: "loading-text bi-list-item-simple", - text: BI.i18nText("BI-Load_More"), - width: 120, - handler: this.options.handler, - }); - this.loaded.on(BI.Controller.EVENT_CHANGE, function (type) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.loading = BI.createWidget({ - type: "bi.layout", - width: this.options.height, - height: this.options.height, - cls: "loading-background cursor-default", - }); - var loaded = BI.createWidget({ - type: "bi.center_adapt", - items: [this.loaded], - }); - var loading = BI.createWidget({ - type: "bi.center_adapt", - items: [this.loading], - }); - this.cardLayout = BI.createWidget({ - type: "bi.card", - element: this, - items: [{ - el: loaded, - cardName: "loaded", - }, { - el: loading, - cardName: "loading", - }], - }); - this.invisible(); - }, - - _reset: function () { - this.visible(); - this.loaded.setText(BI.i18nText("BI-Load_More")); - this.loaded.enable(); - }, - - setLoaded: function () { - this._reset(); - this.cardLayout.showCardByName("loaded"); - }, - - setEnd: function () { - this.setLoaded(); - this.loaded.setText(BI.i18nText("BI-No_More_Data")); - this.loaded.disable(); - }, - - setLoading: function () { - this._reset(); - this.cardLayout.showCardByName("loading"); - }, -}); - -BI.shortcut("bi.loading_bar", BI.LoadingBar); diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js deleted file mode 100644 index 64865de8b..000000000 --- a/src/base/single/button/button.basic.js +++ /dev/null @@ -1,451 +0,0 @@ -/** - * guy - * @class BI.BasicButton - * @extends BI.Single - * - * 一般的button父级 - */ -BI.BasicButton = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.BasicButton.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-basic-button" + (conf.invalid ? "" : " cursor-pointer") + ((BI.isIE() && BI.getIEVersion() < 10) ? " hack" : ""), - // el: {} // 可以通过el来创建button元素 - value: "", - stopEvent: false, - stopPropagation: false, - selected: false, - once: false, // 点击一次选中有效,再点无效 - forceSelected: false, // 点击即选中, 选中了就不会被取消,与once的区别是forceSelected不影响事件的触发 - forceNotSelected: false, // 无论怎么点击都不会被选中 - disableSelected: false, // 使能选中 - - shadow: false, - isShadowShowingOnSelected: false, // 选中状态下是否显示阴影 - trigger: null, - handler: BI.emptyFn, - bubble: null, - debounce: true - }); - }, - - _init: function () { - var self = this; - var opts = this.options; - opts.selected = BI.isFunction(opts.selected) ? this.__watch(opts.selected, function (context, newValue) { - self.setSelected(newValue); - }) : opts.selected; - BI.BasicButton.superclass._init.apply(this, arguments); - - if (opts.shadow) { - this._createShadow(); - } - if (opts.level) { - this.element.addClass("button-" + opts.level); - } - }, - - _initRef: function () { - if (this.options.selected === true) { - this.setSelected(true); - } - // 延迟绑定事件,这样可以将自己绑定的事情优先执行 - BI.nextTick(() => { - !this.isDestroyed() && this.bindEvent(); - }); - BI.BasicButton.superclass._initRef.apply(this, arguments); - }, - - // 默认render方法 - render: function () { - return this.options.el; - }, - - _createShadow: function () { - var self = this, o = this.options; - - function assertMask() { - if (!self.$mask) { - self.$mask = BI.createWidget(BI.isObject(o.shadow) ? o.shadow : {}, { - type: "bi.layout", - cls: "bi-button-mask", - }); - self.$mask.invisible(); - BI.createWidget({ - type: "bi.absolute", - element: self, - items: [{ - el: self.$mask, - left: 0, - right: 0, - top: 0, - bottom: 0, - }], - }); - } - } - - this.element.mouseup(function () { - if (!self._hover && !o.isShadowShowingOnSelected) { - assertMask(); - self.$mask.invisible(); - } - }); - this.element.on("mouseenter." + this.getName(), function (e) { - if (self.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && !self._hover && (o.isShadowShowingOnSelected || !self.isSelected())) { - assertMask(); - self.$mask.visible(); - } - } - }); - this.element.on("mousemove." + this.getName(), function (e) { - if (!self.element.__isMouseInBounds__(e)) { - if (self.isEnabled() && !self._hover) { - assertMask(); - self.$mask.invisible(); - } - } - }); - this.element.on("mouseleave." + this.getName(), function () { - if (self.isEnabled() && !self._hover) { - assertMask(); - self.$mask.invisible(); - } - }); - }, - - bindEvent: function () { - var self = this; - var o = this.options, hand = this.handle(); - if (!hand) { - return; - } - hand = hand.element; - var triggerArr = (o.trigger || "").split(","); - BI.each(triggerArr, function (idx, trigger) { - switch (trigger) { - case "mouseup": - var mouseDown = false; - hand.mousedown(function () { - mouseDown = true; - }); - hand.mouseup(function (e) { - if (mouseDown === true) { - clk(e); - } - mouseDown = false; - ev(e); - }); - break; - case "mousedown": - var mouseDown = false; - var selected = false; - hand.mousedown(function (e) { - // if (e.button === 0) { - BI.Widget._renderEngine.createElement(document).bind("mouseup." + self.getName(), function (e) { - // if (e.button === 0) { - if (BI.DOM.isExist(self) && !hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { - // self.setSelected(!self.isSelected()); - self._trigger(); - } - mouseDown = false; - BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); - // } - }); - if (mouseDown === true) { - return; - } - if (self.isSelected()) { - selected = true; - } else { - clk(e); - } - mouseDown = true; - ev(e); - // } - }); - hand.mouseup(function (e) { - // if (e.button === 0) { - if (BI.DOM.isExist(self) && mouseDown === true && selected === true) { - clk(e); - } - mouseDown = false; - selected = false; - BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); - // } - }); - break; - case "dblclick": - hand.dblclick(clk); - break; - case "lclick": - var mouseDown = false; - var interval; - hand.mousedown(function (e) { - BI.Widget._renderEngine.createElement(document).bind("mouseup." + self.getName(), function () { - interval && clearInterval(interval); - interval = null; - mouseDown = false; - BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); - }); - if (mouseDown === true) { - return; - } - if (!self.isEnabled() || !self.isValid()) { - return; - } - if (self.isOnce() && self.isSelected()) { - return; - } - interval = setInterval(function () { - clk(e) - }, 180); - mouseDown = true; - ev(e); - }); - break; - default: - if (o.stopEvent || o.stopPropagation) { - hand.mousedown(function (e) { - ev(e); - }); - } - hand.click(clk); - // enter键等同于点击 - o.attributes && o.attributes.zIndex >= 0 && hand.keyup(function (e) { - if (e.keyCode === BI.KeyCode.ENTER) { - clk(e); - } - }); - break; - } - }); - - // 之后的300ms点击无效 - var onClick = o.debounce ? BI.debounce(this._doClick, BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }) : this._doClick; - - function ev(e) { - if (o.stopEvent) { - e.stopEvent(); - } - if (o.stopPropagation) { - e.stopPropagation(); - } - } - - function clk(e) { - ev(e); - if (!self.isEnabled() || !self.isValid()) { - return; - } - if (self.isOnce() && self.isSelected()) { - return; - } - if (BI.isKey(o.bubble) || BI.isFunction(o.bubble)) { - if (BI.isNull(self.combo)) { - var popup; - BI.createWidget({ - type: "bi.absolute", - element: self, - items: [{ - el: { - type: "bi.bubble_combo", - trigger: "", - // bubble的提示不需要一直存在在界面上 - destroyWhenHide: true, - ref: function () { - self.combo = this; - }, - el: { - type: "bi.layout", - height: "100%", - }, - popup: { - type: "bi.text_bubble_bar_popup_view", - text: getBubble(), - ref: function () { - popup = this; - }, - listeners: [{ - eventName: BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, - action: function (v) { - self.combo.hideView(); - if (v) { - onClick.apply(self, arguments); - } - }, - }], - }, - listeners: [{ - eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - popup.populate(getBubble()); - }, - }], - }, - left: 0, - right: 0, - bottom: 0, - top: 0, - }], - }); - } - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - - return; - } - onClick.apply(self, arguments); - } - - function getBubble() { - var bubble = self.options.bubble; - if (BI.isFunction(bubble)) { - return bubble(); - } - - return bubble; - } - }, - - _trigger: function (e) { - var o = this.options; - if (!this.isEnabled()) { - return; - } - if (!this.isDisableSelected()) { - this.isForceSelected() ? this.setSelected(true) : - (this.isForceNotSelected() ? this.setSelected(false) : - this.setSelected(!this.isSelected())); - } - if (this.isValid()) { - var v = this.getValue(); - o.handler.call(this, v, this, e); - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, v, this, e); - this.fireEvent(BI.BasicButton.EVENT_CHANGE, v, this); - if (o.action) { - BI.Actions.runAction(o.action, "click", o, this); - } - BI.Actions.runGlobalAction("click", o, this); - } - }, - - _doClick: function (e) { - if (!this.isEnabled() || !this.isValid()) { - return; - } - var isIntercepted = this.beforeClick(e); - // 如果事件已经被消费掉了,就不再触发点击事件 - if (isIntercepted) { - return; - } - - this._trigger(e); - if (this.isEnabled() && this.isValid()) { - this.doClick(e); - } - }, - - /** - * 子类可以得写这个方法,如果返回为 true,则可以阻止 handler 的触发 - */ - beforeClick: function () { - - }, - - doClick: function () { - - }, - - handle: function () { - return this; - }, - - hover: function () { - this._hover = true; - this.handle().element.addClass("hover"); - if (this.options.shadow) { - this.$mask && this.$mask.setVisible(true); - } - }, - - dishover: function () { - this._hover = false; - this.handle().element.removeClass("hover"); - if (this.options.shadow) { - this.$mask && this.$mask.setVisible(false); - } - }, - - setSelected: function (b) { - var o = this.options; - o.selected = b; - if (b) { - this.handle().element.addClass("active"); - } else { - this.handle().element.removeClass("active"); - } - if (o.shadow && !o.isShadowShowingOnSelected) { - this.$mask && this.$mask.setVisible(false); - } - this.options.setSelected && this.options.setSelected.call(this, b); - }, - - isSelected: function () { - return this.options.selected; - }, - - isOnce: function () { - return this.options.once; - }, - - isForceSelected: function () { - return this.options.forceSelected; - }, - - isForceNotSelected: function () { - return this.options.forceNotSelected; - }, - - isDisableSelected: function () { - return this.options.disableSelected; - }, - - setText: function (text) { - this.options.text = text; - this.options.setText && this.options.setText.call(this, text); - }, - - getText: function () { - return this.options.text; - }, - - _setEnable: function (enable) { - BI.BasicButton.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.removeClass("base-disabled disabled"); - } else if (enable === false) { - this.element.addClass("base-disabled disabled"); - } - if (!enable) { - if (this.options.shadow) { - this.$mask && this.$mask.setVisible(false); - } - } - }, - - empty: function () { - BI.Widget._renderEngine.createElement(document).unbind("mouseup." + this.getName()); - BI.BasicButton.superclass.empty.apply(this, arguments); - }, -}); -BI.BasicButton.EVENT_CHANGE = "BasicButton.EVENT_CHANGE"; -BI.shortcut("bi.basic_button", BI.BasicButton); diff --git a/src/base/single/button/button.node.js b/src/base/single/button/button.node.js deleted file mode 100644 index ae4bd9045..000000000 --- a/src/base/single/button/button.node.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * 表示一个可以展开的节点, 不仅有选中状态而且有展开状态 - * - * Created by GUY on 2015/9/9. - * @class BI.NodeButton - * @extends BI.BasicButton - * @abstract - */ -BI.NodeButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.NodeButton.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-node", - open: false, - once: false, - }); - }, - - _initRef: function () { - if (this.isOpened()) { - this.setOpened(this.isOpened()); - } - BI.NodeButton.superclass._initRef.apply(this, arguments); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - this.setOpened(!this.isOpened()); - }, - - isOpened: function () { - return !!this.options.open; - }, - - setOpened: function (b) { - this.options.open = !!b; - }, - - triggerCollapse: function () { - if (this.isOpened()) { - this.setOpened(false); - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, this.getValue(), this); - } - }, - - triggerExpand: function () { - if (!this.isOpened()) { - this.setOpened(true); - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, this.getValue(), this); - } - }, -}); -BI.shortcut("bi.node_button", BI.NodeButton); diff --git a/src/base/single/button/buttons/button.icon.js b/src/base/single/button/buttons/button.icon.js deleted file mode 100644 index 045126c38..000000000 --- a/src/base/single/button/buttons/button.icon.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @class BI.IconButton - * @extends BI.BasicButton - * 图标的button - */ -BI.IconButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.IconButton.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-icon-button horizon-center", - hgap: 0, - vgap: 0, - tgap: 0, - bgap: 0, - lgap: 0, - rgap: 0, - iconWidth: null, - iconHeight: null, - }); - }, - - render: function () { - var o = this.options; - this.element.css({ - textAlign: "center", - }); - this.icon = BI.createWidget({ - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight, - }); - if (BI.isNumber(o.height) && o.height > 0 && BI.isNull(o.iconWidth) && BI.isNull(o.iconHeight)) { - this.element.css("lineHeight", BI.pixFormat(o.height)); - BI.createWidget({ - type: "bi.default", - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - items: [this.icon], - }); - } else { - this.element.css("lineHeight", "1"); - BI.createWidget({ - element: this, - type: "bi.center_adapt", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - items: [this.icon], - }); - } - }, - - doClick: function () { - BI.IconButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconButton.EVENT_CHANGE, this); - } - }, -}); -BI.IconButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_button", BI.IconButton); diff --git a/src/base/single/button/buttons/button.image.js b/src/base/single/button/buttons/button.image.js deleted file mode 100644 index 6eeeffbf1..000000000 --- a/src/base/single/button/buttons/button.image.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 图片的button - * - * Created by GUY on 2016/1/27. - * @class BI.ImageButton - * @extends BI.BasicButton - */ -BI.ImageButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.ImageButton.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-image-button", - src: "", - iconWidth: "100%", - iconHeight: "100%", - }); - }, - - render: function () { - var o = this.options; - this.image = BI.createWidget({ - type: "bi.img", - width: o.iconWidth, - height: o.iconHeight, - src: o.src, - }); - if (BI.isNumber(o.iconWidth) || BI.isNumber(o.iconHeight)) { - BI.createWidget({ - type: "bi.center_adapt", - element: this, - items: [this.image], - }); - } else { - BI.createWidget({ - type: "bi.adaptive", - element: this, - items: [this.image], - scrollable: false, - }); - } - }, - - setWidth: function (w) { - BI.ImageButton.superclass.setWidth.apply(this, arguments); - this.options.width = w; - }, - - setHeight: function (h) { - BI.ImageButton.superclass.setHeight.apply(this, arguments); - this.options.height = h; - }, - - setImageWidth: function (w) { - this.image.setWidth(w); - }, - - setImageHeight: function (h) { - this.image.setHeight(h); - }, - - getImageWidth: function () { - return this.image.element.width(); - }, - - getImageHeight: function () { - return this.image.element.height(); - }, - - setSrc: function (src) { - this.options.src = src; - this.image.setSrc(src); - }, - - getSrc: function () { - return this.image.getSrc(); - }, - - doClick: function () { - BI.ImageButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.ImageButton.EVENT_CHANGE, this); - } - }, -}); -BI.ImageButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.image_button", BI.ImageButton); diff --git a/src/base/single/button/buttons/button.js b/src/base/single/button/buttons/button.js deleted file mode 100644 index bc1468450..000000000 --- a/src/base/single/button/buttons/button.js +++ /dev/null @@ -1,271 +0,0 @@ -(function () { - function isVertical(position) { - return position === "top" || position === "bottom"; - } - - var loadingCls = "button-loading-font anim-rotate"; - - /** - * 文字类型的按钮 - * @class BI.Button - * @extends BI.BasicButton - * - * @cfg {JSON} options 配置属性 - * @cfg {'common'/'success'/'warning'/'ignore'} [options.level='common'] 按钮类型,用不同颜色强调不同的场景 - */ - BI.Button = BI.inherit(BI.BasicButton, { - - _const: { - iconWidth: 18, - }, - - _defaultConfig: function (props) { - var conf = BI.Button.superclass._defaultConfig.apply(this, arguments); - - var adaptiveHeight = 0; - if (isVertical(props.iconPosition)) { - // 图标高度和文字高度默认相等 - adaptiveHeight += (props.textHeight || 16) * 2; - adaptiveHeight += props.iconGap || 0; - var tGap = props.tgap || props.vgap || 2; - var bGap = props.bgap || props.vgap || 2; - adaptiveHeight += (tGap + bGap); - } - - var clearMinWidth = props.block === true || props.clear === true || props.plain; - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-button" + ((BI.isIE() && BI.isIE9Below()) ? " hack" : ""), - attributes: { - tabIndex: 1, - }, - minWidth: clearMinWidth ? 0 : 80, - height: isVertical(props.iconPosition) ? adaptiveHeight : 24, - shadow: props.clear !== true, - isShadowShowingOnSelected: true, - readonly: true, - iconCls: "", - level: "common", - block: false, // 是否块状显示,即不显示边框,没有最小宽度的限制 - clear: false, // 是否去掉边框和背景 - ghost: false, // 是否幽灵显示, 即正常状态无背景 - loading: false, // 是否处于加载中 - light: false, // 是否使用浅色 - plain: false, // 是否是朴素按钮,和 clear 的区别是 plain 有悬浮效果 - textAlign: "center", - whiteSpace: "nowrap", - textWidth: null, - textHeight: null, - hgap: props.clear ? 0 : (props.plain && !props.text ? 4 : 10), - vgap: 0, - tgap: 0, - bgap: 0, - lgap: 0, - rgap: 0, - icon: "", - iconGap: 0, - iconPosition: "left", - }); - }, - - render: function () { - var o = this.options, self = this; - - // bi.center_adapt 作用:让 hgap 不影响 iconGap。 - BI.createWidget({ - type: "bi.center_adapt", - horizontalAlign: o.textAlign, - element: this, - ref: (ref) => { - self.containerRef = ref; - }, - hgap: o.hgap, - vgap: o.vgap, - items: self.generateItems(), - }); - - // 如果 options 对应的属性为 true 则给元素添加 class - var classArr = ["block", "clear", "ghost", "plain", "loading", "light"]; - BI.each(classArr, function (_, clz) { - if (BI.get(o, clz) === true) { - self.element.addClass(clz); - } - }); - - if (o.minWidth > 0) { - this.element.css({ "min-width": BI.pixFormat(o.minWidth) }); - } - }, - - generateItems(defaultRenderIcon) { - var o = this.options; - - // 由于button默认情况下有个边框,所以要主动算行高 - var lineHeight, textHeight = o.textHeight; - var hasBorder = false; - if (BI.isNumber(o.height)) { - if (!isVertical(o.iconPosition)) { - if (!(o.clear && o.block && o.light)) { - hasBorder = true; - } - lineHeight = o.height; - } else { - lineHeight = textHeight; - } - } - if (!textHeight) { - if (o.whiteSpace === "nowrap") { - textHeight = lineHeight; - } - } - - var iconInvisible = !(o.loading || o.iconCls || o.icon || defaultRenderIcon); - - var maxTextWidth = Math.max(o.minWidth, o.width); - maxTextWidth -= (o.hgap * 2 + o.iconGap); - // 减去图标水平占位宽度 - maxTextWidth -= iconInvisible || isVertical(o.iconPosition) ? 0 : this._const.iconWidth; - var textWidth = BI.isNull(o.textWidth) ? maxTextWidth : Math.min(o.textWidth, maxTextWidth); - - this.text = BI.createWidget({ - type: "bi.label", - text: o.text, - whiteSpace: o.whiteSpace, - textAlign: o.textAlign, - textWidth: textWidth, - textHeight: BI.toPix(textHeight, hasBorder ? 2 : 0), - height: BI.toPix(lineHeight, hasBorder ? 2 : 0), - value: o.value, - title: null, - }); - - if (iconInvisible) { - return [this.text]; - } - - this._iconRendered = true; - - if (BI.isPlainObject(o.icon) && !o.loading) { - this.icon = BI.createWidget(o.icon); - } else { - this.icon = BI.createWidget({ - type: "bi.icon_label", - cls: o.loading ? loadingCls : (o.iconCls || o.icon), - width: this._const.iconWidth, - height: BI.toPix(lineHeight, hasBorder ? 2 : 0), - lineHeight: BI.toPix(lineHeight, hasBorder ? 2 : 0), - // 不设置,自定义按钮无法居中 - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - invisible: iconInvisible, - }); - } - - var gapContainer = { - lgap: o.iconPosition === "left" && o.text ? o.iconGap : 0, - rgap: o.iconPosition === "right" ? o.iconGap : 0, - tgap: o.iconPosition === "top" ? o.iconGap : 0, - bgap: o.iconPosition === "bottom" ? o.iconGap : 0, - }; - - var items = [this.icon, BI.extend({ el: this.text }, gapContainer)]; - if (o.iconPosition === "right" || o.iconPosition === "bottom") { - items.reverse(); - } - - return [{ - type: isVertical(o.iconPosition) ? "bi.vertical" : "bi.horizontal", - horizontalAlign: "center", - verticalAlign: "middle", - items, - }]; - }, - - doClick: function () { - BI.Button.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.Button.EVENT_CHANGE, this); - } - }, - - _setEnable: function (enable) { - BI.Button.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("tabIndex", 1); - } else if (enable === false) { - this.element.removeAttr("tabIndex"); - } - }, - - beforeClick: function () { - return this.isLoading(); - }, - - isLoading: function () { - return this._loading === undefined ? this.options.loading : this._loading; - }, - - loading: function () { - this._loading = true; - this.element.addClass("loading"); - !this._iconRendered && this.containerRef.populate(this.generateItems(true)); - if (this.icon.loading) { - this.icon.loading(); - } else { - // loadingCls 可以覆盖 iconCls 所以不需要移除 iconCls - this.icon.element.addClass(loadingCls); - this.icon.setVisible(true); - } - }, - - loaded: function () { - this._loading = false; - this.element.removeClass("loading"); - if (this.icon.loaded) { - this.icon.loaded(); - } else { - this.icon.element.removeClass(loadingCls); - this.icon.setVisible(!!this.options.iconCls); - } - }, - - setText: function (text) { - BI.Button.superclass.setText.apply(this, arguments); - this.text.setText(text); - }, - - setValue: function (text) { - BI.Button.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.text.setValue(text); - } - }, - - setIcon: function (cls) { - var o = this.options; - !this._iconRendered && this.containerRef.populate(this.generateItems(true)); - if (this.icon && o.iconCls !== cls) { - this.icon.element.removeClass(o.iconCls).addClass(cls); - o.iconCls = cls; - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - }); - BI.shortcut("bi.button", BI.Button); - BI.Button.EVENT_CHANGE = "EVENT_CHANGE"; -}()); diff --git a/src/base/single/button/buttons/button.text.js b/src/base/single/button/buttons/button.text.js deleted file mode 100644 index 38470c291..000000000 --- a/src/base/single/button/buttons/button.text.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * guy - * 可以点击的一行文字 - * @class BI.TextButton - * @extends BI.BasicButton - * 文字button - */ -BI.TextButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.TextButton.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-button", - textAlign: "center", - whiteSpace: "nowrap", - textWidth: null, - textHeight: null, - hgap: 0, - lgap: 0, - rgap: 0, - vgap: 0, - py: "", - }); - }, - - render: function () { - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textWidth: o.textWidth, - textHeight: o.textHeight, - width: o.width, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - }); - }, - - doClick: function () { - BI.TextButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextButton.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setText: function (text) { - BI.TextButton.superclass.setText.apply(this, arguments); - text = BI.isArray(text) ? text.join(",") : text; - this.text.setText(text); - }, - - setStyle: function (style) { - this.text.setStyle(style); - }, - - setValue: function (text) { - BI.TextButton.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - text = BI.isArray(text) ? text.join(",") : text; - this.text.setValue(text); - } - }, -}); -BI.TextButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_button", BI.TextButton); diff --git a/src/base/single/button/listitem/blankiconicontextitem.js b/src/base/single/button/listitem/blankiconicontextitem.js deleted file mode 100644 index 1f6419008..000000000 --- a/src/base/single/button/listitem/blankiconicontextitem.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 带有一个占位 - * - * Created by GUY on 2015/9/11. - * @class BI.BlankIconIconTextItem - * @extends BI.BasicButton - */ -BI.BlankIconIconTextItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.BlankIconIconTextItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-blank-icon-icon-text-item", - iconCls1: "", - iconCls2: "", - blankWidth: 0, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, o.rightIconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.layout", - width: o.blankWidth, - }, { - type: "bi.icon_label", - cls: o.iconCls1, - width: o.leftIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - type: "bi.icon_label", - cls: o.iconCls2, - width: o.rightIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }], - }; - }, - - doClick: function () { - BI.BlankIconIconTextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.BlankIconIconTextItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - setSelected: function (b) { - BI.BlankIconIconTextItem.superclass.setSelected.apply(this, arguments); - this.icon1.setSelected(b); - this.icon2.setSelected(b); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, -}); -BI.BlankIconIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.blank_icon_icon_text_item", BI.BlankIconIconTextItem); diff --git a/src/base/single/button/listitem/blankicontexticonitem.js b/src/base/single/button/listitem/blankicontexticonitem.js deleted file mode 100644 index 34dc9e7d8..000000000 --- a/src/base/single/button/listitem/blankicontexticonitem.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * guy - * 一个占位符和两个icon和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/15. - * @class BI.BlankIconTextIconItem - * @extends BI.BasicButton - */ -BI.BlankIconTextIconItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.BlankIconTextIconItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-blank-icon-text-icon-item", - iconCls1: "", - iconCls2: "", - blankWidth: 0, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], - items: [{ - type: "bi.layout", - width: o.blankWidth, - }, { - type: "bi.icon_label", - cls: o.iconCls1, - width: o.leftIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }, { - type: "bi.icon_label", - cls: o.iconCls2, - width: o.rightIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.BlankIconTextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.BlankIconTextIconItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, -}); -BI.BlankIconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.blank_icon_text_icon_item", BI.BlankIconTextIconItem); diff --git a/src/base/single/button/listitem/blankicontextitem.js b/src/base/single/button/listitem/blankicontextitem.js deleted file mode 100644 index 08f13d22d..000000000 --- a/src/base/single/button/listitem/blankicontextitem.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 带有一个占位 - * - * Created by GUY on 2015/9/11. - * @class BI.BlankIconTextItem - * @extends BI.BasicButton - */ -BI.BlankIconTextItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.BlankIconTextItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", - blankWidth: 0, - iconHeight: null, - iconWidth: null, - iconCls: "", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.blankWidth, o.iconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.layout", - width: o.blankWidth, - }, { - type: "bi.icon_label", - cls: o.iconCls, - width: o.iconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }], - }; - }, - - doClick: function () { - BI.BlankIconTextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.BlankIconTextItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, -}); -BI.BlankIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.blank_icon_text_item", BI.BlankIconTextItem); diff --git a/src/base/single/button/listitem/icontexticonitem.js b/src/base/single/button/listitem/icontexticonitem.js deleted file mode 100644 index 425f47d90..000000000 --- a/src/base/single/button/listitem/icontexticonitem.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * guy - * 两个icon和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/9. - * @class BI.IconTextIconItem - * @extends BI.BasicButton - */ -BI.IconTextIconItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.IconTextIconItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-icon-item", - iconCls1: "", - iconCls2: "", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], - items: [{ - type: "bi.icon_label", - cls: o.iconCls1, - width: o.leftIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }, { - type: "bi.icon_label", - cls: o.iconCls2, - width: o.rightIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.IconTextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextIconItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, -}); -BI.IconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_icon_item", BI.IconTextIconItem); diff --git a/src/base/single/button/listitem/icontextitem.js b/src/base/single/button/listitem/icontextitem.js deleted file mode 100644 index 8fff16335..000000000 --- a/src/base/single/button/listitem/icontextitem.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * guy - * - * Created by GUY on 2015/9/9. - * @class BI.IconTextItem - * @extends BI.BasicButton - */ -BI.IconTextItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.IconTextItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-item", - direction: BI.Direction.Left, - iconWrapperWidth: null, - iconHeight: null, - iconWidth: null, - iconCls: "", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.icon_label", - cls: o.iconCls, - width: o.iconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }], - }; - }, - - doClick: function () { - BI.IconTextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, -}); -BI.IconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_item", BI.IconTextItem); diff --git a/src/base/single/button/listitem/texticonitem.js b/src/base/single/button/listitem/texticonitem.js deleted file mode 100644 index a0ece74e6..000000000 --- a/src/base/single/button/listitem/texticonitem.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * - * 图标的button - * - * Created by GUY on 2015/9/9. - * @class BI.TextIconItem - * @extends BI.BasicButton - */ -BI.TextIconItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.TextIconItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-icon-item", - iconWrapperWidth: null, - iconHeight: null, - iconWidth: null, - iconCls: "", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: ["fill", o.iconWrapperWidth || o.height], - items: [{ - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }, { - type: "bi.icon_label", - cls: o.iconCls, - width: o.iconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.TextIconItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextIconItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, -}); -BI.TextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_icon_item", BI.TextIconItem); diff --git a/src/base/single/button/listitem/textitem.js b/src/base/single/button/listitem/textitem.js deleted file mode 100644 index c4c810295..000000000 --- a/src/base/single/button/listitem/textitem.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * guy - * 一个button和一行数 组成的一行listitem - * - * Created by GUY on 2015/9/9. - * @class BI.TextItem - * @extends BI.BasicButton - */ -BI.TextItem = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.TextItem.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-item", - textAlign: "left", - whiteSpace: "nowrap", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textHeight: o.whiteSpace === "nowrap" ? o.height : o.textHeight, - height: o.height, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py, - }); - }, - - doClick: function () { - BI.TextItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, -}); -BI.TextItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_item", BI.TextItem); diff --git a/src/base/single/button/node/icontexticonnode.js b/src/base/single/button/node/icontexticonnode.js deleted file mode 100644 index 7569490eb..000000000 --- a/src/base/single/button/node/icontexticonnode.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * guy - * Created by GUY on 2015/9/9. - * @class BI.IconTextIconNode - * @extends BI.NodeButton - */ -BI.IconTextIconNode = BI.inherit(BI.NodeButton, { - - _defaultConfig: function () { - var conf = BI.IconTextIconNode.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-icon-node", - iconCls1: "close-ha-font", - iconCls2: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], - items: [{ - type: "bi.icon_label", - cls: o.iconCls1, - width: o.leftIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }, { - type: "bi.icon_label", - cls: o.iconCls2, - width: o.rightIconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.IconTextIconNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextIconNode.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, -}); -BI.IconTextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_icon_node", BI.IconTextIconNode); diff --git a/src/base/single/button/node/icontextnode.js b/src/base/single/button/node/icontextnode.js deleted file mode 100644 index 16383cc7d..000000000 --- a/src/base/single/button/node/icontextnode.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * guy - * Created by GUY on 2015/9/9. - * @class BI.IconTextNode - * @extends BI.NodeButton - */ -BI.IconTextNode = BI.inherit(BI.NodeButton, { - - _defaultConfig: function () { - var conf = BI.IconTextNode.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-text-node", - cls: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.icon_label", - cls: o.iconCls, - width: o.iconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }], - }; - }, - - doClick: function () { - BI.IconTextNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.IconTextNode.EVENT_CHANGE, this.getValue(), this); - } - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, -}); -BI.IconTextNode.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_node", BI.IconTextNode); diff --git a/src/base/single/button/node/texticonnode.js b/src/base/single/button/node/texticonnode.js deleted file mode 100644 index 01167b009..000000000 --- a/src/base/single/button/node/texticonnode.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Created by GUY on 2015/9/9. - * @class BI.TextIconNode - * @extends BI.NodeButton - */ -BI.TextIconNode = BI.inherit(BI.NodeButton, { - - _defaultConfig: function () { - var conf = BI.TextIconNode.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-icon-node", - cls: "close-ha-font", - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: ["fill", o.iconWrapperWidth || o.height], - items: [{ - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height, - }, - }, { - type: "bi.icon_label", - cls: o.iconCls, - width: o.iconWrapperWidth || o.height, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.TextIconNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextIconNode.EVENT_CHANGE, this.getValue(), this); - } - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, -}); -BI.TextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_icon_node", BI.TextIconNode); diff --git a/src/base/single/button/node/textnode.js b/src/base/single/button/node/textnode.js deleted file mode 100644 index 6ecaa3fbf..000000000 --- a/src/base/single/button/node/textnode.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * guy - * - * Created by GUY on 2015/9/9. - * @class BI.TextNode - * @extends BI.NodeButton - */ -BI.TextNode = BI.inherit(BI.NodeButton, { - - _defaultConfig: function () { - var conf = BI.TextNode.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-node", - textAlign: "left", - whiteSpace: "nowrap", - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0, - }); - }, - - render: function () { - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textHeight: o.whiteSpace === "nowrap" ? o.height : o.textHeight, - height: o.height, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py, - }); - }, - - doClick: function () { - BI.TextNode.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.TextNode.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, -}); -BI.TextNode.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_node", BI.TextNode); diff --git a/src/base/single/editor/editor.js b/src/base/single/editor/editor.js deleted file mode 100644 index 2dfcb8b6c..000000000 --- a/src/base/single/editor/editor.js +++ /dev/null @@ -1,380 +0,0 @@ -/** - * Created by GUY on 2015/4/15. - * @class BI.Editor - * @extends BI.Single - */ -BI.Editor = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Editor.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: "bi-editor bi-focus-shadow", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - // title,warningTitle这两个属性没用 - tipType: "warning", - inputType: "text", - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: false, - watermark: "", - errorText: "", - autoTrim: true, - }); - }, - - render: function () { - var self = this, o = this.options; - // 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码 - var autocomplete = o.autocomplete ? " autocomplete=" + o.autocomplete : ""; - this.editor = this.addWidget(BI.createWidget({ - type: "bi.input", - element: "", - root: true, - value: o.value, - watermark: o.watermark, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - })); - this.editor.element.css({ - width: "100%", - height: "100%", - border: "none", - outline: "none", - padding: "0", - margin: "0", - }); - - var items = [ - { - el: { - type: "bi.absolute", - ref: function (_ref) { - self.contentWrapper = _ref; - }, - items: [ - { - el: this.editor, - left: 0, - right: 0, - top: 0, - bottom: 0, - } - ], - }, - left: o.hgap + o.lgap, - right: o.hgap + o.rgap, - top: o.vgap + o.tgap, - bottom: o.vgap + o.bgap, - } - ]; - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: items, - }); - - this.setWaterMark(this.options.watermark); - - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Input.EVENT_FOCUS, function () { - self._checkError(); - self.element.addClass("bi-editor-focus"); - self.fireEvent(BI.Editor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Input.EVENT_BLUR, function () { - self._setErrorVisible(false); - self.element.removeClass("bi-editor-focus"); - self.fireEvent(BI.Editor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Input.EVENT_CLICK, function () { - self.fireEvent(BI.Editor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Input.EVENT_CHANGE, function () { - self.fireEvent(BI.Editor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Input.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.Editor.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.Input.EVENT_QUICK_DOWN, function (e) { - // tab键就不要隐藏了 - if (e.keyCode !== BI.KeyCode.TAB && self.watermark) { - self.watermark.invisible(); - } - self.fireEvent(BI.Editor.EVENT_QUICK_DOWN, arguments); - }); - - this.editor.on(BI.Input.EVENT_VALID, function () { - self._checkWaterMark(); - self._setErrorVisible(false); - self.element.removeClass("error"); - self.fireEvent(BI.Editor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Input.EVENT_ERROR, function () { - self._checkWaterMark(); - self.fireEvent(BI.Editor.EVENT_ERROR, arguments); - self._setErrorVisible(self.isEditing()); - self.element.addClass("error"); - }); - this.editor.on(BI.Input.EVENT_RESTRICT, function () { - self._checkWaterMark(); - var tip = self._setErrorVisible(true); - tip && tip.element.fadeOut(100, function () { - tip.element.fadeIn(100); - }); - self.fireEvent(BI.Editor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Input.EVENT_EMPTY, function () { - self._checkWaterMark(); - self.fireEvent(BI.Editor.EVENT_EMPTY, arguments); - }); - this.editor.on(BI.Input.EVENT_ENTER, function () { - self.fireEvent(BI.Editor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Input.EVENT_SPACE, function () { - self.fireEvent(BI.Editor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Input.EVENT_BACKSPACE, function () { - self.fireEvent(BI.Editor.EVENT_BACKSPACE, arguments); - }); - this.editor.on(BI.Input.EVENT_REMOVE, function () { - self.fireEvent(BI.Editor.EVENT_REMOVE, arguments); - }); - this.editor.on(BI.Input.EVENT_START, function () { - self.fireEvent(BI.Editor.EVENT_START, arguments); - }); - this.editor.on(BI.Input.EVENT_PAUSE, function () { - self.fireEvent(BI.Editor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Input.EVENT_STOP, function () { - self.fireEvent(BI.Editor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Input.EVENT_CONFIRM, function () { - self.fireEvent(BI.Editor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Input.EVENT_CHANGE_CONFIRM, function () { - self.fireEvent(BI.Editor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.element.click(function (e) { - e.stopPropagation(); - - return false; - }); - if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { - this._checkError(); - this._checkWaterMark(); - } else { - this._checkWaterMark(); - } - }, - - _checkToolTip: function () { - var o = this.options; - var errorText = o.errorText; - if (BI.isFunction(errorText)) { - errorText = errorText(this.editor.getValue()); - } - if (BI.isKey(errorText)) { - if (!this.isEnabled() || this.isValid() || BI.Bubbles.has(this.getName())) { - this.setTitle(""); - } else { - this.setTitle(errorText); - } - } - }, - - _assertWaterMark: function () { - var self = this, o = this.options; - if (BI.isNull(this.watermark)) { - this.watermark = BI.createWidget({ - type: "bi.label", - cls: "bi-water-mark", - text: this.options.watermark, - height: o.height - 2 * o.vgap - o.tgap, - hgap: 2, - whiteSpace: "nowrap", - textAlign: "left", - }); - this.watermark.element.bind({ - mousedown: function (e) { - if (self.isEnabled()) { - self.editor.isEditing() || self.editor.focus(); - } else { - self.editor.isEditing() && self.editor.blur(); - } - e.stopEvent(); - }, - }); - this.watermark.element.bind("click", function (e) { - if (self.isEnabled()) { - self.editor.isEditing() || self.editor.focus(); - } else { - self.editor.isEditing() && self.editor.blur(); - } - e.stopEvent(); - }); - } - }, - - _checkError: function () { - this._setErrorVisible(this.isEnabled() && !this.isValid()); - this._checkToolTip(); - }, - - _checkWaterMark: function () { - var o = this.options; - if (!this.disabledWaterMark && this.editor.getValue() === "" && BI.isKey(o.watermark)) { - this.watermark && this.watermark.visible(); - } else { - this.watermark && this.watermark.invisible(); - } - }, - - setErrorText: function (text) { - this.options.errorText = text; - }, - - getErrorText: function () { - return this.options.errorText; - }, - - setWaterMark: function (v) { - this.options.watermark = v; - - if (BI.isNull(this.watermark)) { - this._assertWaterMark(); - BI.createWidget({ - type: "bi.absolute", - element: this.contentWrapper, - items: [ - { - el: this.watermark, - left: 0, - right: 0, - top: 0, - bottom: 0, - } - ], - }); - } - this.watermark.setText(v); - this._checkWaterMark(); - }, - - _setErrorVisible: function (b) { - var o = this.options; - var errorText = o.errorText; - if (BI.isFunction(errorText)) { - errorText = errorText(o.autoTrim ? BI.trim(this.editor.getValue()) : this.editor.getValue()); - } - if (!this.disabledError && BI.isKey(errorText)) { - BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { - adjustYOffset: o.simple ? 1 : 2, - }); - this._checkToolTip(); - } - }, - - disableError: function () { - this.disabledError = true; - this._checkError(); - }, - - enableError: function () { - this.disabledError = false; - this._checkError(); - }, - - disableWaterMark: function () { - this.disabledWaterMark = true; - this._checkWaterMark(); - }, - - enableWaterMark: function () { - this.disabledWaterMark = false; - this._checkWaterMark(); - }, - - focus: function () { - this.element.addClass("text-editor-focus"); - this.editor.focus(); - }, - - blur: function () { - this.element.removeClass("text-editor-focus"); - this.editor.blur(); - }, - - selectAll: function () { - this.editor.selectAll(); - }, - - onKeyDown: function (k) { - this.editor.onKeyDown(k); - }, - - setValue: function (v) { - BI.Editor.superclass.setValue.apply(this, arguments); - this.editor.setValue(v); - this._checkError(); - this._checkWaterMark(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - getValue: function () { - if (!this.isValid()) { - return this.options.autoTrim ? BI.trim(this.editor.getLastValidValue()) : this.editor.getLastValidValue(); - } - - return this.options.autoTrim ? BI.trim(this.editor.getValue()) : this.editor.getValue(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - destroyed: function () { - BI.Bubbles.remove(this.getName()); - }, -}); -BI.Editor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.Editor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.Editor.EVENT_BLUR = "EVENT_BLUR"; -BI.Editor.EVENT_CLICK = "EVENT_CLICK"; -BI.Editor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.Editor.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; -BI.Editor.EVENT_SPACE = "EVENT_SPACE"; -BI.Editor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; - -BI.Editor.EVENT_START = "EVENT_START"; -BI.Editor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Editor.EVENT_STOP = "EVENT_STOP"; -BI.Editor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.Editor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.Editor.EVENT_VALID = "EVENT_VALID"; -BI.Editor.EVENT_ERROR = "EVENT_ERROR"; -BI.Editor.EVENT_ENTER = "EVENT_ENTER"; -BI.Editor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.Editor.EVENT_REMOVE = "EVENT_REMOVE"; -BI.Editor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.editor", BI.Editor); diff --git a/src/base/single/editor/editor.multifile.js b/src/base/single/editor/editor.multifile.js deleted file mode 100644 index 21765474d..000000000 --- a/src/base/single/editor/editor.multifile.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * 多文件 - * - * Created by GUY on 2016/4/13. - * @class BI.MultifileEditor - * @extends BI.Single - * @abstract - */ -BI.MultifileEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.MultifileEditor.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-multifile-editor", - multiple: false, - maxSize: -1, // 1024 * 1024 - accept: "", - url: "", - }); - }, - - render: function () { - var self = this, o = this.options; - this.file = BI.createWidget({ - type: "bi.file", - cls: "multifile-editor", - width: "100%", - height: "100%", - name: o.name, - url: o.url, - multiple: o.multiple, - accept: o.accept, - maxSize: o.maxSize, - maxLength: o.maxLength, - title: o.title, - errorText: o.errorText, - }); - this.file.on(BI.File.EVENT_CHANGE, function () { - self.fireEvent(BI.MultifileEditor.EVENT_CHANGE, arguments); - }); - this.file.on(BI.File.EVENT_UPLOADSTART, function () { - self.fireEvent(BI.MultifileEditor.EVENT_UPLOADSTART, arguments); - }); - this.file.on(BI.File.EVENT_ERROR, function () { - self.fireEvent(BI.MultifileEditor.EVENT_ERROR, arguments); - }); - this.file.on(BI.File.EVENT_PROGRESS, function () { - self.fireEvent(BI.MultifileEditor.EVENT_PROGRESS, arguments); - }); - this.file.on(BI.File.EVENT_UPLOADED, function () { - self.fireEvent(BI.MultifileEditor.EVENT_UPLOADED, arguments); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.adaptive", - scrollable: false, - items: [this.file], - }, - top: 0, - right: 0, - left: 0, - bottom: 0, - }], - }); - }, - - _reset: function () { - this.file.reset(); - }, - - setUrl: function (v) { - this.file.setUrl(v); - }, - - setMaxFileLength: function (v) { - this.file.setMaxFileLength(v); - }, - - select: function () { - this.file.select(); - }, - - getQueue: function () { - return this.file.getQueue(); - }, - - getValue: function () { - return this.file.getValue(); - }, - - upload: function () { - this._reset(); - this.file.upload(); - }, - - sendFiles: function (files) { - this._reset(); - - this.file.sendFiles(files); - }, - - reset: function () { - this._reset(); - }, -}); -BI.MultifileEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultifileEditor.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; -BI.MultifileEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.MultifileEditor.EVENT_PROGRESS = "EVENT_PROGRESS"; -BI.MultifileEditor.EVENT_UPLOADED = "EVENT_UPLOADED"; -BI.shortcut("bi.multifile_editor", BI.MultifileEditor); diff --git a/src/base/single/editor/editor.textarea.js b/src/base/single/editor/editor.textarea.js deleted file mode 100644 index d3838d29e..000000000 --- a/src/base/single/editor/editor.textarea.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * - * Created by GUY on 2016/1/18. - * @class BI.TextAreaEditor - * @extends BI.Single - */ -BI.TextAreaEditor = BI.inherit(BI.Single, { - _defaultConfig: function (conf) { - return BI.extend(BI.TextAreaEditor.superclass._defaultConfig.apply(), { - baseCls: "bi-textarea-editor", - value: "", - errorText: "", - adjustYOffset: conf.simple ? 0 : 2, - adjustXOffset: 0, - offsetStyle: "left", - validationChecker: function () { - return true; - }, - scrolly: true, - }); - }, - - render: function () { - var o = this.options, self = this; - this.content = BI.createWidget({ - type: "bi.layout", - tagName: "textarea", - width: "100%", - height: "100%", - cls: "bi-textarea textarea-editor-content display-block", - css: o.scrolly ? null : { - overflowY: "hidden", - }, - }); - this.content.element.css({ resize: "none" }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.adaptive", - items: [this.content], - }, - left: 4, - right: 4, - top: 2, - bottom: 2, - }], - }); - - this.content.element.on("input propertychange", function (e) { - self._checkError(); - self._checkWaterMark(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, self.getValue(), self); - self.fireEvent(BI.TextAreaEditor.EVENT_CHANGE); - if (BI.isEmptyString(self.getValue())) { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, self.getValue(), self); - } - }); - - this.content.element.focus(function () { - self._checkError(); - self._focus(); - self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); - BI.Widget._renderEngine.createElement(document).bind("mousedown." + self.getName(), function (e) { - if (BI.DOM.isExist(self) && !self.element.__isMouseInBounds__(e)) { - BI.Widget._renderEngine.createElement(document).unbind("mousedown." + self.getName()); - self.content.element.blur(); - } - }); - }); - this.content.element.blur(function () { - self._setErrorVisible(false); - self._blur(); - if (!self._isError()) { - self.fireEvent(BI.TextAreaEditor.EVENT_CONFIRM); - } - self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); - BI.Widget._renderEngine.createElement(document).unbind("mousedown." + self.getName()); - }); - this.content.element.keydown(function () { - // 水印快速消失 - self._checkWaterMark(); - }); - this.content.element.keyup(function (e) { - self.fireEvent(BI.TextAreaEditor.EVENT_KEY_DOWN, e.keyCode); - }); - this.content.element.click(function (e) { - e.stopPropagation(); - }); - if (BI.isKey(o.value)) { - this.setValue(o.value); - } - if (BI.isNotNull(o.style)) { - this.setStyle(o.style); - } - this._checkWaterMark(); - }, - - _checkWaterMark: function () { - var self = this, o = this.options; - var val = this.getValue(); - if (BI.isNotEmptyString(val)) { - this.watermark && this.watermark.destroy(); - this.watermark = null; - } else { - if (BI.isNotEmptyString(o.watermark)) { - if (!this.watermark) { - this.watermark = BI.createWidget({ - type: "bi.label", - cls: "bi-water-mark textarea-watermark", - textAlign: "left", - whiteSpace: o.scrolly ? "normal" : "nowrap", - text: o.watermark, - invalid: o.invalid, - disabled: o.disabled, - hgap: 6, - vgap: o.height > 24 ? 4 : 2, - height: o.height > 24 ? "" : o.height, - }); - this.watermark.element.bind({ - mousedown: function (e) { - if (self.isEnabled()) { - self.focus(); - } else { - self.blur(); - } - e.stopEvent(); - }, - click: function (e) { - e.stopPropagation(); - }, - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.watermark, - left: 0, - top: 0, - right: 0, - }], - }); - } else { - this.watermark.setText(o.watermark); - this.watermark.setValid(!o.invalid); - this.watermark.setEnable(!o.disabled); - } - } - } - }, - - _isError: function () { - return this.isEnabled() && !this.options.validationChecker(this.getValue()); - }, - - _checkError: function () { - var isError = this._isError(); - this._setErrorVisible(isError); - this.element[isError ? "addClass" : "removeClass"]("error"); - }, - - _focus: function () { - this.content.element.addClass("textarea-editor-focus"); - this._checkWaterMark(); - if (BI.isEmptyString(this.getValue())) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - } - }, - - _blur: function () { - this.content.element.removeClass("textarea-editor-focus"); - this._checkWaterMark(); - }, - - _setErrorVisible: function (b) { - var o = this.options; - var errorText = o.errorText; - if (BI.isFunction(errorText)) { - errorText = errorText(BI.trim(this.getValue())); - } - if (!this.disabledError && BI.isKey(errorText)) { - BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { - adjustYOffset: o.adjustYOffset, - adjustXOffset: o.adjustXOffset, - offsetStyle: o.offsetStyle, - }); - } - }, - - _defaultState: function () { - if (BI.isEmptyString(this.getValue())) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.TextAreaEditor.EVENT_EMPTY); - } - }, - - focus: function () { - this._focus(); - this.content.element.focus(); - }, - - blur: function () { - this._blur(); - this.content.element.blur(); - }, - - getValue: function () { - return this.content.element.val(); - }, - - setValue: function (value) { - this.content.element.val(value); - this._checkError(); - this._checkWaterMark(); - this._defaultState(); - }, - - setStyle: function (style) { - this.style = style; - this.element.css(style); - this.content.element.css(BI.extend({}, style, { - color: style.color || BI.DOM.getContrastColor(BI.DOM.isRGBColor(style.backgroundColor) ? BI.DOM.rgb2hex(style.backgroundColor) : style.backgroundColor), - })); - }, - - getStyle: function () { - return this.style; - }, - - setWatermark: function (v) { - this.options.watermark = v; - this._checkWaterMark(); - }, - - _setValid: function (b) { - BI.TextAreaEditor.superclass._setValid.apply(this, arguments); - // this.content.setValid(b); - // this.watermark && this.watermark.setValid(b); - }, - - _setEnable: function (b) { - BI.TextAreaEditor.superclass._setEnable.apply(this, [b]); - this.content && (this.content.element[0].disabled = !b); - }, -}); -BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.TextAreaEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.TextAreaEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.TextAreaEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.TextAreaEditor.EVENT_EMPTY = "EVENT_EMPTY"; -BI.TextAreaEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.shortcut("bi.textarea_editor", BI.TextAreaEditor); diff --git a/src/base/single/html/html.js b/src/base/single/html/html.js deleted file mode 100644 index 84c980427..000000000 --- a/src/base/single/html/html.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * guy 表示一行数据,通过position来定位位置的数据 - * @class BI.Html - * @extends BI.Single - */ -BI.Html = BI.inherit(BI.Single, { - - props: { - baseCls: "bi-html", - textAlign: "left", - whiteSpace: "normal", - lineHeight: null, - handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的 - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - text: "", - highLight: false, - }, - - render: function () { - var self = this, o = this.options; - if (o.hgap + o.lgap > 0) { - this.element.css({ - "padding-left": BI.pixFormat(o.hgap + o.lgap), - }); - } - if (o.hgap + o.rgap > 0) { - this.element.css({ - "padding-right": BI.pixFormat(o.hgap + o.rgap), - }); - } - if (o.vgap + o.tgap > 0) { - this.element.css({ - "padding-top": BI.pixFormat(o.vgap + o.tgap), - }); - } - if (o.vgap + o.bgap > 0) { - this.element.css({ - "padding-bottom": BI.pixFormat(o.vgap + o.bgap), - }); - } - if (BI.isNumber(o.height)) { - this.element.css({ lineHeight: BI.pixFormat(o.height) }); - } - if (BI.isNumber(o.lineHeight)) { - this.element.css({ lineHeight: BI.pixFormat(o.lineHeight) }); - } - if (BI.isWidthOrHeight(o.maxWidth)) { - this.element.css({ maxWidth: o.maxWidth }); - } - if (BI.isNumber(o.maxWidth)) { - this.element.css({ maxWidth: BI.pixFormat(o.maxWidth) }) - } - this.element.css({ - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textOverflow: o.whiteSpace === "nowrap" ? "ellipsis" : "", - overflow: o.whiteSpace === "nowrap" ? "" : "auto", - }); - if (o.handler) { - this.text = BI.createWidget({ - type: "bi.layout", - tagName: "span", - }); - this.text.element.click(function () { - o.handler(self.getValue()); - }); - BI.createWidget({ - type: "bi.default", - element: this, - items: [this.text], - }); - } else { - this.text = this; - } - - if (BI.isKey(o.text)) { - this.setText(o.text); - } else if (BI.isKey(o.value)) { - this.setText(o.value); - } - if (o.highLight) { - this.doHighLight(); - } - }, - - doHighLight: function () { - this.text.element.addClass("bi-high-light"); - }, - - unHighLight: function () { - this.text.element.removeClass("bi-high-light"); - }, - - setValue: function (text) { - BI.Html.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.setText(text); - } - }, - - setStyle: function (css) { - this.text.element.css(css); - }, - - setText: function (text) { - BI.Html.superclass.setText.apply(this, arguments); - this.options.text = text; - this.text.element.html(text); - }, -}); - -BI.shortcut("bi.html", BI.Html); diff --git a/src/base/single/icon/icon.js b/src/base/single/icon/icon.js deleted file mode 100644 index 916206bbd..000000000 --- a/src/base/single/icon/icon.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * guy 图标 - * @class BI.Icon - * @extends BI.Single - */ -BI.Icon = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Icon.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - tagName: "i", - baseCls: (conf.baseCls || "") + " x-icon b-font horizon-center display-block", - }); - }, - - render: function () { - if (BI.isIE9Below && BI.isIE9Below()) { - this.element.addClass("hack"); - } - }, -}); -BI.shortcut("bi.icon", BI.Icon); diff --git a/src/base/single/iframe/iframe.js b/src/base/single/iframe/iframe.js deleted file mode 100644 index e2df49e25..000000000 --- a/src/base/single/iframe/iframe.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @class BI.Iframe - * @extends BI.Single - * @abstract - * Created by GameJian on 2016/3/2. - */ -BI.Iframe = BI.inherit(BI.Single, { - _defaultConfig: function (config) { - var conf = BI.Iframe.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - tagName: "iframe", - baseCls: (conf.baseCls || "") + " bi-iframe", - src: "", - name: "", - attributes: {}, - width: "100%", - height: "100%", - }); - }, - - render: function () { - var self = this; - this.element.on("load", function () { - self.fireEvent("EVENT_LOADED"); - }); - }, - - _initProps: function () { - BI.Iframe.superclass._initProps.apply(this, arguments); - var o = this.options; - this.options.attributes = BI.extend({ - frameborder: 0, - src: o.src, - name: o.name, - }, this.options.attributes); - }, - - setSrc: function (src) { - this.options.src = src; - this.element.attr("src", src); - }, - - getSrc: function () { - return this.options.src; - }, - - setName: function (name) { - this.options.name = name; - this.element.attr("name", name); - }, - - getName: function () { - return this.options.name; - }, -}); - -BI.shortcut("bi.iframe", BI.Iframe); diff --git a/src/base/single/img/img.js b/src/base/single/img/img.js deleted file mode 100644 index ca715fb79..000000000 --- a/src/base/single/img/img.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * ͼƬ - * - * Created by GUY on 2016/1/26. - * @class BI.Img - * @extends BI.Single - * @abstract - */ -BI.Img = BI.inherit(BI.Single, { - _defaultConfig: function (config) { - var conf = BI.Img.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - tagName: "img", - baseCls: (conf.baseCls || "") + " bi-img display-block", - src: "", - attributes: config.src ? { src: config.src } : {}, - width: "100%", - height: "100%", - }); - }, - - _initProps: function () { - BI.Img.superclass._initProps.apply(this, arguments); - var o = this.options; - this.options.attributes = BI.extend({ - src: o.src, - }, this.options.attributes); - }, - - setSrc: function (src) { - this.options.src = src; - this.element.attr("src", src); - }, - - getSrc: function () { - return this.options.src; - }, -}); - -BI.shortcut("bi.img", BI.Img); diff --git a/src/base/single/input/checkbox/checkbox.image.js b/src/base/single/input/checkbox/checkbox.image.js deleted file mode 100644 index 0400f6530..000000000 --- a/src/base/single/input/checkbox/checkbox.image.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.ImageCheckbox = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - var conf = BI.ImageCheckbox.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-image-checkbox check-box-icon", - selected: false, - handler: BI.emptyFn, - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16, - }); - }, -}); -BI.ImageCheckbox.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; - -BI.shortcut("bi.image_checkbox", BI.ImageCheckbox); diff --git a/src/base/single/input/checkbox/checkbox.js b/src/base/single/input/checkbox/checkbox.js deleted file mode 100644 index b25d743e8..000000000 --- a/src/base/single/input/checkbox/checkbox.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.Checkbox = BI.inherit(BI.BasicButton, { - - props: { - baseCls: "bi-checkbox", - selected: false, - handler: BI.emptyFn, - width: 14, - height: 14, - iconWidth: 14, - iconHeight: 14, - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.center_adapt", - items: [{ - type: "bi.default", - ref: function (_ref) { - self.checkbox = _ref; - }, - cls: "checkbox-content", - width: o.iconWidth, - height: o.iconHeight, - }], - }; - }, - - _setEnable: function (enable) { - BI.Checkbox.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.checkbox.element.removeClass("base-disabled disabled"); - } else { - this.checkbox.element.addClass("base-disabled disabled"); - } - }, - - doClick: function () { - BI.Checkbox.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.Checkbox.EVENT_CHANGE); - } - }, - - setSelected: function (b) { - BI.Checkbox.superclass.setSelected.apply(this, arguments); - if (b) { - this.checkbox.element.addClass("bi-high-light-background"); - } else { - this.checkbox.element.removeClass("bi-high-light-background"); - } - }, -}); -BI.Checkbox.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.checkbox", BI.Checkbox); diff --git a/src/base/single/input/file.js b/src/base/single/input/file.js deleted file mode 100644 index 1769de9c5..000000000 --- a/src/base/single/input/file.js +++ /dev/null @@ -1,739 +0,0 @@ -/** - * 文件 - * - * Created by GUY on 2016/1/27. - * @class BI.File - * @extends BI.Single - * @abstract - */ -((function (document) { - /** - * @description normalize input.files. create if not present, add item method if not present - * @param Object generated wrap object - * @return Object the wrap object itself - */ - var F = ((function (item) { - return function (input) { - var files = input.files || [input]; - if (!files.item) { - files.item = item; - } - - return files; - }; - })(function (i) { - return this[i]; - })); - - var event = { - - /** - * @description add an event via addEventListener or attachEvent - * @param DOMElement the element to add event - * @param String event name without "on" (e.g. "mouseover") - * @param Function the callback to associate as event - * @return Object noswfupload.event - */ - add: document.addEventListener ? - function (node, name, callback) { - node.addEventListener(name, callback, false); - - return this; - } : - function (node, name, callback) { - node.attachEvent("on" + name, callback); - - return this; - }, - - /** - * @description remove an event via removeEventListener or detachEvent - * @param DOMElement the element to remove event - * @param String event name without "on" (e.g. "mouseover") - * @param Function the callback associated as event - * @return Object noswfupload.event - */ - del: document.removeEventListener ? - function (node, name, callback) { - node.removeEventListener(name, callback, false); - - return this; - } : - function (node, name, callback) { - node.detachEvent("on" + name, callback); - - return this; - }, - - /** - * @description to block event propagation and prevent event default - * @param void generated event or undefined - * @return Boolean false - */ - stop: function (e) { - if (!e) { - if (self.event) { - event.returnValue = !(event.cancelBubble = true); - } - } else { - e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; - e.preventDefault ? e.preventDefault() : e.returnValue = false; - } - - return false; - }, - }; - - var sendFile = (function (toString) { - var split = "onabort.onerror.onloadstart.onprogress".split("."), - length = split.length, - CRLF = "\r\n", - xhr = new XMLHttpRequest, - sendFile; - function multipart(boundary, name, file) { - return "--".concat( - boundary, CRLF, - "Content-Disposition: form-data; name=\"", name, "\"; filename=\"", _global.encodeURIComponent(file.fileName), "\"", CRLF, - "Content-Type: application/octet-stream", CRLF, - CRLF, - file.getAsBinary(), CRLF, - "--", boundary, "--", CRLF - ); - } - function isFunction (Function) { - return toString.call(Function) === "[object Function]"; - } - - - // FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work) - if (xhr.upload || xhr.sendAsBinary) { - sendFile = function (handler, maxSize, width, height) { - var current = handler.current; - if (-1 < maxSize && maxSize < handler.file.fileSize) { - if (isFunction(handler.onerror)) { - handler.onerror(); - } - - return; - } - for (var xhr = new XMLHttpRequest, - upload = xhr.upload || { - addEventListener: function (event, callback) { - this["on" + event] = callback; - }, - }, - i = 0; - i < length; - i++ - ) { - upload.addEventListener( - split[i].substring(2), - // eslint-disable-next-line no-loop-func - (function (event) { - return function (rpe) { - if (isFunction(handler[event])) { - handler[event](rpe, xhr); - } - }; - }(split[i])), - false - ); - } - upload.addEventListener( - "load", - function (rpe) { - if (handler.onreadystatechange === false) { - if (isFunction(handler.onload)) { - handler.onload(rpe, xhr); - } - } else { - setTimeout(function () { - if (xhr.readyState === 4) { - if (isFunction(handler.onload)) { - handler.onload(rpe, xhr); - } - } else { - setTimeout(arguments.callee, 15); - } - }, 15); - } - }, - false - ); - xhr.open("post", BI.appendQuery(handler.url, { - filename: _global.encodeURIComponent(handler.file.fileName), - }), true); - if (!xhr.upload) { - var rpe = { loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true }; - rpe.interval = setInterval(function () { - rpe.loaded += 1024 / 4; - if (rpe.total <= rpe.loaded) { - rpe.loaded = rpe.total; - } - upload.onprogress(rpe); - }, 100); - xhr.onabort = function () { - upload.onabort({}); - }; - xhr.onerror = function () { - upload.onerror({}); - }; - xhr.onreadystatechange = function () { - switch (xhr.readyState) { - case 2: - case 3: - if (rpe.total <= rpe.loaded) { - rpe.loaded = rpe.total; - } - upload.onprogress(rpe); - break; - case 4: - clearInterval(rpe.interval); - rpe.interval = 0; - rpe.loaded = rpe.total; - upload.onprogress(rpe); - if (199 < xhr.status && xhr.status < 400) { - upload.onload({}); - var attachO = BI.jsonDecode(xhr.responseText); - attachO.filename = handler.file.fileName; - if (handler.file.type.indexOf("image") !== -1) { - attachO.attach_type = "image"; - } - handler.attach_array[current] = attachO; - } else { - upload.onerror({}); - } - break; - default: - break; - } - }; - upload.onloadstart(rpe); - } else { - xhr.onreadystatechange = function () { - switch (xhr.readyState) { - case 4: - var attachO = BI.jsonDecode(xhr.responseText); - if (handler.file.type.indexOf("image") !== -1) { - attachO.attach_type = "image"; - } - attachO.filename = handler.file.fileName; - if (handler.maxLength === 1) { - handler.attach_array[0] = attachO; - // handler.attach_array.push(attachO); - } else { - handler.attach_array[current] = attachO; - } - break; - default: - break; - } - }; - if (isFunction(upload.onloadstart)) { - upload.onloadstart(); - } - } - var boundary = "AjaxUploadBoundary" + (new Date).getTime(); - xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); - if (handler.file.getAsBinary) { - xhr[xhr.sendAsBinary ? "sendAsBinary" : "send"](multipart(boundary, handler.name, handler.file)); - } else { - xhr.setRequestHeader("Content-Type", "multipart/form-data"); - // xhr.setRequestHeader("X-Name", handler.name); - // xhr.setRequestHeader("X-File-Name", handler.file.fileName); - var form = new FormData(); - form.append("FileData", handler.file); - xhr.send(form); - } - - return handler; - }; - } else { - // Internet Explorer, Opera, others - sendFile = function (handler, maxSize, width, height) { - var current = handler.current, iframe, form; - var url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"), - rpe = { - loaded: 1, total: 100, simulation: true, interval: setInterval(function () { - if (rpe.loaded < rpe.total) { - ++rpe.loaded; - } - if (isFunction(handler.onprogress)) { - handler.onprogress(rpe, {}); - } - }, 100), - }, - target = ["AjaxUpload", (new Date).getTime(), String(Math.random()).substring(2)].join("_"); - function onload() { - iframe.onreadystatechange = iframe.onload = iframe.onerror = null; - form.parentNode.removeChild(form); - form = null; - clearInterval(rpe.interval); - // rpe.loaded = rpe.total; - try { - var responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; - var attachO = BI.jsonDecode(responseText); - if (handler.file.type.indexOf("image") !== -1) { - attachO.attach_type = "image"; - } - - // attachO.fileSize = responseText.length; - try { - // decodeURIComponent特殊字符可能有问题, catch一下,保证能正常上传 - attachO.filename = _global.decodeURIComponent(handler.file.fileName); - } catch (e) { - attachO.filename = handler.file.fileName; - } - if (handler.maxLength === 1) { - handler.attach_array[0] = attachO; - } else { - handler.attach_array[current] = attachO; - } - } catch (e) { - if (isFunction(handler.onerror)) { - handler.onerror(rpe, event || _global.event); - } - } - if (isFunction(handler.onload)) { - handler.onload(rpe, { responseText: responseText }); - } - } - - try { // IE < 8 does not accept enctype attribute ... - var form = document.createElement("
    "), - iframe = handler.iframe || (handler.iframe = document.createElement("")); - } catch (e) { - var form = document.createElement("form"), - iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); - form.setAttribute("enctype", "multipart/form-data"); - iframe.setAttribute("name", iframe.id = target); - iframe.setAttribute("src", url); - } - iframe.style.position = "absolute"; - iframe.style.left = iframe.style.top = "-10000px"; - iframe.onload = onload; - iframe.onerror = function (event) { - if (isFunction(handler.onerror)) { - handler.onerror(rpe, event || _global.event); - } - }; - iframe.onreadystatechange = function () { - if (/loaded|complete/i.test(iframe.readyState)) { - onload(); - - // wei : todo,将附件信息放到handler.attach - } else if (isFunction(handler.onloadprogress)) { - if (rpe.loaded < rpe.total) { - ++rpe.loaded; - } - handler.onloadprogress(rpe, { - readyState: { - loading: 2, - interactive: 3, - loaded: 4, - complete: 4, - }[iframe.readyState] || 1, - }); - } - }; - form.setAttribute("action", handler.url + "&filename=" + _global.encodeURIComponent(handler.file.fileName)); - form.setAttribute("target", iframe.id); - form.setAttribute("method", "post"); - form.appendChild(handler.file); - form.style.display = "none"; - if (isFunction(handler.onloadstart)) { - handler.onloadstart(rpe, {}); - } - var d = document.body || document.documentElement; - d.appendChild(iframe); - d.appendChild(form); - form.submit(); - - return handler; - }; - } - xhr = null; - - return sendFile; - }(Object.prototype.toString)); - - function sendFiles(handler, maxSize, width, height) { - var length = handler.files.length, - onload = handler.onload, - onloadstart = handler.onloadstart; - handler.current = 0; - handler.total = 0; - handler.sent = 0; - while (handler.current < length) { - handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); - handler.current++; - } - handler.current = 0; - if (length && handler.files[0].fileSize !== -1) { - handler.file = handler.files[handler.current]; - - sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { - handler.onloadstart = null; - handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); - if (++handler.current < length) { - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = arguments.callee; - } else if (onload) { - handler.onloadstart = onloadstart; - handler.onload = onload; - handler.onload(rpe, xhr); - } - }; - } else if (length) { - handler.total = length * 100; - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { - var callee = arguments.callee; - handler.onloadstart = null; - handler.sent += 100; - if (++handler.current < length) { - if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { - handler.iframe.parentNode.removeChild(handler.iframe); - handler.iframe = null; - } - setTimeout(function () { - handler.file = handler.files[handler.current]; - sendFile(handler, maxSize, width, height).onload = callee; - }, 15); - } else if (onload) { - setTimeout(function () { - handler.iframe.parentNode.removeChild(handler.iframe); - handler.iframe = null; - handler.onloadstart = onloadstart; - handler.onload = onload; - handler.onload(rpe, xhr); - }, 15); - } - }; - } - - return handler; - } - - var r1 = /\.([^.]+)$/; // .png - var r2 = /\/([^/]+)$/; // image/png - - /** - * 校验文件类型是否合法,同时兼容旧版形式 - * @param fileName - * @param fileType - * @returns {boolean} - */ - function fileTypeValidate(fileName, fileType) { - if (!fileType) { - return true; - } - var mimes = fileType.split(","); - if (mimes[0] === fileType) { - mimes = (fileType + "").split(";"); - } - - return BI.some(mimes, function (index, mime) { - var matches; - matches = mime.match(r1); - if (matches) { - return fileName.toLowerCase().endsWith(matches[0]); - } - matches = mime.match(r2); - if (matches) { - return matches[1] === "*" ? true : fileName.toLowerCase().endsWith(`.${matches[1]}`); - } - }); - } - - BI.File = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.File.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-file display-block", - tagName: "input", - attributes: { - type: "file", - }, - name: "", - url: "", - multiple: true, - accept: "", // .png,.pdf,image/jpg,image/* 等 - maxSize: -1, // 1024 * 1024 单位b - maxLength: -1, // 无限制, 与multiple配合使用 - errorText: BI.emptyFn, - }); - }, - - render: function () { - var o = this.options; - if (o.multiple === true) { - this.element.attr("multiple", "multiple"); - } - this.element.attr("name", o.name || this.getName()); - this.element.attr("title", o.title || ""); - this.element.attr("accept", o.accept); - }, - - created: function () { - var self = this, o = this.options; - // create the noswfupload.wrap Object - // wrap.maxSize 文件大小限制 - // wrap.maxLength 文件个数限制 - var _wrap = this.wrap = this._wrap(this.element[0], o.maxSize); - // fileType could contain whatever text but filter checks *.{extension} - // if present - - // handlers - - _wrap.onloadstart = function (rpe, xhr) { - self.fireEvent(BI.File.EVENT_UPLOADSTART, arguments); - }; - - _wrap.onprogress = function (rpe, xhr) { - // percent for each bar - - // fileSize is -1 only if browser does not support file info access - // this if splits recent browsers from others - if (this.file.fileSize !== -1) { - // simulation property indicates when the progress event is fake - if (rpe.simulation) { - // empty - } else { - // empty - } - } else { - // if fileSIze is -1 browser is using an iframe because it does - // not support - // files sent via Ajax (XMLHttpRequest) - // We can still show some information - } - self.fireEvent(BI.File.EVENT_PROGRESS, { - file: this.file, - total: rpe.total, - loaded: rpe.loaded, - simulation: rpe.simulation, - }); - }; - - // generated if there is something wrong during upload - _wrap.onerror = function () { - // just inform the user something was wrong - self.fireEvent(BI.File.EVENT_ERROR); - }; - - // generated when every file has been sent (one or more, it does not - // matter) - _wrap.onload = function (rpe, xhr) { - var self_ = this; - // just show everything is fine ... - // ... and after a second reset the component - setTimeout(function () { - self_.clean(); // remove files from list - self_.hide(); // hide progress bars and enable input file - // enable again the submit button/element - }, 100); - if (200 > xhr.status || xhr.status > 399) { - BI.Msg.toast(BI.i18nText("BI-Upload_File_Error"), { level: "error" }); - self.fireEvent(BI.File.EVENT_ERROR); - - return; - } - var error = BI.some(_wrap.attach_array, function (index, attach) { - if (attach.errorCode) { - BI.Msg.toast(BI.i18nText(attach.errorMsg), { level: "error" }); - self.fireEvent(BI.File.EVENT_ERROR, attach); - - return true; - } - }); - !error && self.fireEvent(BI.File.EVENT_UPLOADED); - }; - _wrap.url = o.url; - _wrap.fileType = o.accept; // 文件类型限制 - _wrap.attach_array = []; - _wrap.attach_names = []; - _wrap.attachNum = 0; - }, - - _events: function (wrap) { - var self = this, o = this.options; - event.add(wrap.dom.input, "change", function () { - event.del(wrap.dom.input, "change", arguments.callee); - var input = wrap.dom.input.cloneNode(true); - var files = F(wrap.dom.input); - if (o.maxLength !== -1 && o.maxLength < files.length) { - self.fireEvent(BI.File.EVENT_ERROR, { - errorType: 2, - }); - } else { - for (var i = 0; i < files.length; i++) { - var item = files.item(i); - var tempFile = item.value || item.name; - var value = item.fileName || (item.fileName = tempFile.split("\\").pop()), - size = item.fileSize || item.size; - var validateFileType = fileTypeValidate(value, wrap.fileType); - if (!validateFileType) { - // 文件类型不支持 - BI.Msg.toast(o.errorText({ - errorType: 0, - file: item, - }) || BI.i18nText("BI-Upload_File_Type_Error", wrap.fileType), { level: "error" }); - self.fireEvent(BI.File.EVENT_ERROR, { - errorType: 0, - file: item, - }); - } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { - // 文件大小不支持 - BI.Msg.toast(o.errorText({ - errorType: 1, - file: item, - }) || BI.i18nText("BI-Upload_File_Size_Error", Math.ceil(wrap.maxSize / 1024 / 1024)), { level: "error" }); - self.fireEvent(BI.File.EVENT_ERROR, { - errorType: 1, - file: item, - }); - } else { - wrap.files.unshift(item); - } - } - } - wrap.files.length > 0 && self.fireEvent(BI.File.EVENT_CHANGE, { - files: wrap.files, - }); - input.value = ""; - wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); - wrap.dom.input = input; - event.add(wrap.dom.input, "change", arguments.callee); - }); - - return wrap; - }, - - _wrap: function () { - var o = this.options; - // be sure input accept multiple files - var input = this.element[0]; - if (o.multiple === true) { - this.element.attr("multiple", "multiple"); - } - input.value = ""; - - // wrap Object - return this._events({ - - // DOM namespace - dom: { - input: input, // input file - disabled: false, // internal use, checks input file state - }, - name: input.name, // name to send for each file ($_FILES[{name}] in the server) - // maxSize is the maximum amount of bytes for each file - maxSize: o.maxSize ? o.maxSize >> 0 : -1, - maxLength: o.maxLength, - files: [], // file list - - // remove every file from the noswfupload component - clean: function () { - this.files = []; - }, - - // upload one file a time (which make progress possible rather than all files in one shot) - // the handler is an object injected into the wrap one, could be the wrap itself or - // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} - upload: function (handler) { - if (handler) { - for (var key in handler) { - this[key] = handler[key]; - } - } - sendFiles(this, this.maxSize); - - return this; - }, - - // hide progress bar (total + current) and enable files selection - hide: function () { - if (this.dom.disabled) { - this.dom.disabled = false; - this.dom.input.removeAttribute("disabled"); - } - }, - - // show progress bar and disable file selection (used during upload) - // total and current are pixels used to style bars - // totalProp and currentProp are properties to change, "height" by default - show: function (total, current, totalProp, currentProp) { - if (!this.dom.disabled) { - this.dom.disabled = true; - this.dom.input.setAttribute("disabled", "disabled"); - } - }, - }); - }, - - setUrl: function(v) { - this.options.url = v; - if (this.wrap) { - this.wrap.url = v; - } - }, - - setMaxFileLength: function (v) { - this.options.maxLength = v; - if (this.wrap) { - this.wrap.maxLength = v; - } - }, - - select: function () { - this.wrap && BI.Widget._renderEngine.createElement(this.wrap.dom.input).click(); - }, - - upload: function (handler) { - this.wrap && this.wrap.upload(handler); - }, - - getValue: function () { - return this.wrap ? this.wrap.attach_array : []; - }, - - getQueue: function () { - return this.wrap.files; - }, - - reset: function () { - if (this.wrap) { - this.wrap.attach_array = []; - this.wrap.attach_names = []; - this.wrap.attachNum = 0; - } - }, - - sendFiles: function (files) { - if (!this.wrap) return; - - this.wrap.dom.input.files = files; - - var event = new CustomEvent("change"); - - this.wrap.dom.input.dispatchEvent(event); - }, - - _setEnable: function (enable) { - BI.File.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.removeAttr("disabled"); - } else { - this.element.attr("disabled", "disabled"); - } - }, - }); - BI.File.EVENT_CHANGE = "EVENT_CHANGE"; - BI.File.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; - BI.File.EVENT_ERROR = "EVENT_ERROR"; - BI.File.EVENT_PROGRESS = "EVENT_PROGRESS"; - BI.File.EVENT_UPLOADED = "EVENT_UPLOADED"; - BI.shortcut("bi.file", BI.File); -})(_global.document || {})); diff --git a/src/base/single/input/input.js b/src/base/single/input/input.js deleted file mode 100644 index 57cd580b5..000000000 --- a/src/base/single/input/input.js +++ /dev/null @@ -1,335 +0,0 @@ -/** - * guy - * @class BI.Input 一个button和一行数 组成的一行listitem - * @extends BI.Single - * @type {*|void|Object} - */ -BI.Input = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-input display-block overflow-dot", - tagName: "input", - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, // 按确定键能否退出编辑 - allowBlank: false, - }); - }, - - render: function () { - var self = this; - var ctrlKey = false; - var keyCode = null; - var inputEventValid = false; - var _keydown = BI.debounce(function (keyCode) { - self.onKeyDown(keyCode, ctrlKey); - self._keydown_ = false; - }, BI.EVENT_RESPONSE_TIME); - var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - this._focusDebounce = BI.debounce(BI.bind(this._focus, this), BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, { - "leading": true, - "trailing": false, - }); - this.element - .keydown(function (e) { - inputEventValid = false; - ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下 - keyCode = e.keyCode; - self.fireEvent(BI.Input.EVENT_QUICK_DOWN, arguments); - }) - .keyup(function (e) { - keyCode = null; - if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { - self._keydown_ = true; - _keydown(e.keyCode); - } - }) - .on("input propertychange", function (e) { - // 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了 - // 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8 - // 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓) - var originalEvent = e.originalEvent; - if (BI.isNull(originalEvent.propertyName) || originalEvent.propertyName === "value") { - inputEventValid = true; - self._keydown_ = true; - _keydown(keyCode); - keyCode = null; - } - }) - .click(function (e) { - e.stopPropagation(); - _clk(); - }) - .mousedown(function (e) { - self.element.val(self.element.val()); - }) - .focus(function (e) { // 可以不用冒泡 - self._focusDebounce(); - }) - .blur(function (e) { - // DEC-14919 IE11在浏览器重新获得焦点之后会先触发focusout再触发focus,要保持先获得焦点再失去焦点的顺序不变,因此采用blur - self._blurDebounce(); - }); - if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { - this.setValue(this.options.value); - } - }, - - _focus: function () { - this.element.addClass("bi-input-focus"); - this._checkValidationOnValueChange(); - this._isEditing = true; - if (this.getValue() === "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this.fireEvent(BI.Input.EVENT_FOCUS); - }, - - _blur: function () { - var self = this; - if (self._keydown_ === true) { - BI.delay(blur, BI.EVENT_RESPONSE_TIME); - } else { - blur(); - } - - function blur() { - if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { - self.element.val(self._lastValidValue ? self._lastValidValue : ""); - self._checkValidationOnValueChange(); - self._defaultState(); - } - self.element.removeClass("bi-input-focus"); - self._isEditing = false; - self._start = false; - if (self.isValid()) { - var lastValidValue = self._lastValidValue; - self._lastValidValue = self.getValue(); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); - self.fireEvent(BI.Input.EVENT_CONFIRM); - if (self._lastValidValue !== lastValidValue) { - self.fireEvent(BI.Input.EVENT_CHANGE_CONFIRM); - } - } - self.fireEvent(BI.Input.EVENT_BLUR); - } - }, - - _click: function () { - if (this._isEditing !== true) { - this.selectAll(); - this.fireEvent(BI.Input.EVENT_CLICK); - } - }, - - onClick: function () { - this._click(); - }, - - onKeyDown: function (keyCode, ctrlKey) { - if (!this.isValid() || BI.trim(this._lastChangedValue) !== BI.trim(this.getValue())) { - this._checkValidationOnValueChange(); - } - if (this.isValid() && BI.trim(this.getValue()) !== "") { - if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || BI.isNull(this._lastValue) || this._lastValue === "") - || (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { - this._start = true; - this._pause = false; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_START); - } - } - if (BI.isEqual(keyCode, BI.KeyCode.ENTER)) { - if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { - this.blur(); - this.fireEvent(BI.Input.EVENT_ENTER); - } else { - this.fireEvent(BI.Input.EVENT_RESTRICT); - } - } - if (BI.isEqual(keyCode, BI.KeyCode.SPACE)) { - this.fireEvent(BI.Input.EVENT_SPACE); - } - if (BI.isEqual(keyCode, BI.KeyCode.BACKSPACE) && this._lastValue === "") { - this.fireEvent(BI.Input.EVENT_REMOVE); - } - if (BI.isEqual(keyCode, BI.KeyCode.BACKSPACE) || BI.isEqual(keyCode, BI.KeyCode.DELETE)) { - this.fireEvent(BI.Input.EVENT_BACKSPACE); - } - this.fireEvent(BI.Input.EVENT_KEY_DOWN, arguments); - - // _valueChange中会更新_lastValue, 这边缓存用以后续STOP事件服务 - var lastValue = this._lastValue; - if (BI.trim(this.getValue()) !== BI.trim(this._lastValue || "")) { - this._valueChange(); - } - if (BI.isEndWithBlank(this.getValue())) { - this._pause = true; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); - this.fireEvent(BI.Input.EVENT_PAUSE); - this._defaultState(); - } else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && - BI.trim(this.getValue()) === "" && (lastValue !== null && BI.trim(lastValue) !== "")) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_STOP); - } - }, - - // 初始状态 - _defaultState: function () { - if (this.getValue() === "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this._lastValue = this.getValue(); - this._lastSubmitValue = null; - }, - - _valueChange: function () { - if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_CHANGE); - this._lastSubmitValue = BI.trim(this.getValue()); - } - if (this.getValue() === "") { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); - this.fireEvent(BI.Input.EVENT_EMPTY); - } - this._lastValue = this.getValue(); - }, - - _checkValidationOnValueChange: function (callback) { - var self = this, o = this.options; - var v = this.getValue(); - if (o.allowBlank === true && BI.trim(v) === "") { - this.setValid(true); - callback && callback(); - - return; - } - if (BI.trim(v) === "") { - this.setValid(false); - callback && callback(); - - return; - } - var checker = o.validationChecker.apply(this, [BI.trim(v)]); - if (checker instanceof Promise) { - checker.then(function (validate) { - self.setValid(validate !== false); - callback && callback(); - }); - } else { - this.setValid(checker !== false); - callback && callback(); - } - }, - - focus: function () { - if (!this.element.is(":visible")) { - throw new Error("input cannot be focus when it's invisible"); - } - if (!this._isEditing === true) { - this.element.focus(); - this.selectAll(); - } - }, - - blur: function () { - if (!this.element.is(":visible")) { - throw new Error("input cannot be blur when it's invisible"); - } - if (this._isEditing === true) { - this.element.blur(); - this._blurDebounce(); - } - }, - - selectAll: function () { - if (!this.element.is(":visible")) { - throw new Error("input cannot be select when it's invisible"); - } - this.element.select(); - this._isEditing = true; - }, - - setValue: function (textValue) { - var self = this; - this.element.val(textValue); - BI.nextTick(function () { - self._checkValidationOnValueChange(function () { - self._defaultState(); - if (self.isValid()) { - self._lastValidValue = self._lastSubmitValue = self.getValue(); - } - }); - }); - }, - - getValue: function () { - return this.element.val() || ""; - }, - - isEditing: function () { - return this._isEditing; - }, - - getLastValidValue: function () { - return this._lastValidValue; - }, - - getLastChangedValue: function () { - return this._lastChangedValue; - }, - - _setValid: function () { - BI.Input.superclass._setValid.apply(this, arguments); - if (this.isValid()) { - this._lastChangedValue = this.getValue(); - this.element.removeClass("bi-input-error"); - this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); - } else { - if (this._lastChangedValue === this.getValue()) { - this._lastChangedValue = null; - } - this.element.addClass("bi-input-error"); - this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); - } - }, - - _setEnable: function (b) { - BI.Input.superclass._setEnable.apply(this, [b]); - this.element[0].disabled = !b; - }, -}); -BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; -BI.Input.EVENT_CLICK = "EVENT_CLICK"; -BI.Input.EVENT_BLUR = "EVENT_BLUR"; -BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; -BI.Input.EVENT_SPACE = "EVENT_SPACE"; -BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; - -BI.Input.EVENT_START = "EVENT_START"; -BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; -BI.Input.EVENT_STOP = "EVENT_STOP"; -BI.Input.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; -BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; -BI.Input.EVENT_VALID = "EVENT_VALID"; -BI.Input.EVENT_ERROR = "EVENT_ERROR"; -BI.Input.EVENT_ENTER = "EVENT_ENTER"; -BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.shortcut("bi.input", BI.Input); diff --git a/src/base/single/input/radio/radio.image.js b/src/base/single/input/radio/radio.image.js deleted file mode 100644 index f9d870f63..000000000 --- a/src/base/single/input/radio/radio.image.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.ImageRadio = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - var conf = BI.ImageRadio.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-radio radio-icon", - selected: false, - handler: BI.emptyFn, - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16, - }); - }, - - doClick: function () { - BI.ImageRadio.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.ImageRadio.EVENT_CHANGE); - } - }, -}); -BI.ImageRadio.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; - -BI.shortcut("bi.image_radio", BI.ImageRadio); diff --git a/src/base/single/input/radio/radio.js b/src/base/single/input/radio/radio.js deleted file mode 100644 index f84cf4038..000000000 --- a/src/base/single/input/radio/radio.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.Radio = BI.inherit(BI.BasicButton, { - - props: { - baseCls: "bi-radio", - selected: false, - handler: BI.emptyFn, - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16 - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.center_adapt", - items: [{ - type: "bi.layout", - cls: "radio-content", - ref: function (_ref) { - self.radio = _ref; - }, - width: o.iconWidth, - height: o.iconHeight, - }], - }; - }, - - _setEnable: function (enable) { - BI.Radio.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.radio.element.removeClass("base-disabled disabled"); - } else { - this.radio.element.addClass("base-disabled disabled"); - } - }, - - doClick: function () { - BI.Radio.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.Radio.EVENT_CHANGE); - } - }, - - setSelected: function (b) { - BI.Radio.superclass.setSelected.apply(this, arguments); - if (b) { - this.radio.element.addClass("bi-high-light-background"); - } else { - this.radio.element.removeClass("bi-high-light-background"); - } - }, -}); -BI.Radio.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.radio", BI.Radio); diff --git a/src/base/single/instruction/instruction.js b/src/base/single/instruction/instruction.js deleted file mode 100644 index 71a61a6f3..000000000 --- a/src/base/single/instruction/instruction.js +++ /dev/null @@ -1,76 +0,0 @@ -BI.Instruction = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-instruction", - height: 20, - level: "error", - textAlign: "left", - whiteSpace: "nowrap", - hgap: 5 - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "instruction-" + o.level, - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - textHeight: o.height, - height: o.height, - hgap: o.hgap, - rgap: o.rgap, - lgap: o.lgap, - vgap: o.vgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - }; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setText: function (v) { - this.options.text = v; - this.text.setText(v); - }, - - getText: function () { - return this.options.text; - }, - - setStyle: function (css) { - this.text.setStyle(css); - }, - - setValue: function (v) { - this.text.setValue(v); - }, - - getValue: function () { - this.text.getValue(); - } -}); - -BI.shortcut("bi.instruction", BI.Instruction); diff --git a/src/base/single/label/abstract.label.js b/src/base/single/label/abstract.label.js deleted file mode 100644 index 19fc0322d..000000000 --- a/src/base/single/label/abstract.label.js +++ /dev/null @@ -1,399 +0,0 @@ -/** - * Created by dailer on 2019/6/19. - */ -!(function () { - BI.AbstractLabel = BI.inherit(BI.Single, { - - _defaultConfig: function (props) { - var conf = BI.AbstractLabel.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - textAlign: "center", - whiteSpace: "nowrap", // normal or nowrap - textWidth: null, - textHeight: null, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - highLight: false, - handler: null, - enableHover: props.title !== null, - }); - }, - - _createJson: function () { - var o = this.options; - - return { - type: "bi.text", - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - lineHeight: o.textHeight, - maxWidth: "100%", - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - highLight: o.highLight, - handler: o.handler, - }; - }, - - render: function () { - if (this.options.textAlign === "center") { - this._createCenterEl(); - } else { - this._createNotCenterEl(); - } - }, - - _createCenterEl: function () { - var o = this.options; - var json = this._createJson(); - json.textAlign = "left"; - if (BI.isNumber(o.width) && o.width > 0) { - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - json.maxWidth = o.textWidth; - if (BI.isNumber(o.height) && o.height > 0) { // 1.1 - BI.createWidget({ - type: "bi.center_adapt", - height: o.height, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - BI.createWidget({ // 1.2 - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - if (o.whiteSpace === "normal") { // 1.3 - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - }); - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - element: this, - items: [this.text], - }); - - return; - } - if (BI.isNumber(o.height) && o.height > 0) { // 1.4 - this.element.css({ - "line-height": BI.pixFormat(o.height), - }); - json.textAlign = o.textAlign; - delete json.maxWidth; - this.text = BI.createWidget(BI.extend(json, { - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - - return; - } - BI.extend(json, { // 1.5 - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - maxWidth: "100%", - }); - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - element: this, - items: [this.text], - }); - - return; - } - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { // 1.6 - json.maxWidth = o.textWidth; - BI.createWidget({ - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - if (o.whiteSpace === "normal") { // 1.7 - BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - }); - this.text = BI.createWidget(json); - BI.createWidget({ - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: true, - element: this, - items: [this.text], - }); - - return; - } - if (BI.isNumber(o.height) && o.height > 0) { // 1.8 - this.element.css({ - "line-height": BI.pixFormat(o.height), - }); - json.textAlign = o.textAlign; - delete json.maxWidth; - this.text = BI.createWidget(BI.extend(json, { - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - - return; - } - this.text = BI.createWidget(BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - BI.createWidget({ - type: "bi.center_adapt", - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - element: this, - items: [this.text], - }); - }, - - _createNotCenterEl: function () { - var o = this.options; - var adaptLayout = "bi.vertical_adapt"; - var json = this._createJson(); - if (BI.isNumber(o.width) && o.width > 0) { - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - json.maxWidth = o.textWidth; - if (BI.isNumber(o.height) && o.height > 0) { // 2.1 - BI.createWidget({ - type: adaptLayout, - horizontalAlign: o.textAlign, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - height: o.height, - scrollable: o.whiteSpace === "normal", - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - BI.createWidget({ // 2.2 - type: adaptLayout, - horizontalAlign: o.textAlign, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - if (BI.isNumber(o.height) && o.height > 0) { // 2.3 - if (o.whiteSpace !== "normal") { - this.element.css({ - "line-height": BI.pixFormat(o.height - (o.vgap * 2)), - }); - } - delete json.maxWidth; - this.text = BI.createWidget(BI.extend(json, { - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - - return; - } - json.maxWidth = o.width - 2 * o.hgap - o.lgap - o.rgap; - BI.createWidget({ // 2.4 - type: adaptLayout, - horizontalAlign: o.textAlign, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [{ - el: (this.text = BI.createWidget(json)), - }], - }); - - return; - } - if (BI.isNumber(o.textWidth) && o.textWidth > 0) { - json.maxWidth = o.textWidth; - BI.createWidget({ // 2.5 - type: adaptLayout, - horizontalAlign: o.textAlign, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - scrollable: o.whiteSpace === "normal", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - element: this, - items: [ - { - el: (this.text = BI.createWidget(json)), - } - ], - }); - - return; - } - if (BI.isNumber(o.height) && o.height > 0) { - if (o.whiteSpace !== "normal") { - this.element.css({ - "line-height": BI.pixFormat(o.height - (o.vgap * 2)), - }); - } - delete json.maxWidth; - this.text = BI.createWidget(BI.extend(json, { // 2.6 - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - - return; - } - this.text = BI.createWidget(BI.extend(json, { - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - })); - BI.createWidget({ - type: adaptLayout, - horizontalAlign: o.textAlign, - columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 - element: this, - scrollable: o.whiteSpace === "normal", - items: [this.text], - }); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setText: function (v) { - this.options.text = v; - this.text.setText(v); - }, - - getText: function () { - return this.options.text; - }, - - setStyle: function (css) { - this.text.setStyle(css); - }, - - setValue: function (v) { - BI.AbstractLabel.superclass.setValue.apply(this, arguments); - if (!this.isReadOnly()) { - this.options.text = v; - this.text.setValue(v); - } - }, - }); -}()); diff --git a/src/base/single/label/html.label.js b/src/base/single/label/html.label.js deleted file mode 100644 index e1ac76b66..000000000 --- a/src/base/single/label/html.label.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Created by GUY on 2015/6/26. - */ - -BI.HtmlLabel = BI.inherit(BI.AbstractLabel, { - - props: { - baseCls: "bi-html-label", - }, - - _createJson: function () { - var o = this.options; - - return { - type: "bi.html", - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - lineHeight: o.textHeight, - text: o.text, - value: o.value, - handler: o.handler, - }; - }, -}); - -BI.shortcut("bi.html_label", BI.HtmlLabel); diff --git a/src/base/single/label/icon.label.js b/src/base/single/label/icon.label.js deleted file mode 100644 index 53a400a05..000000000 --- a/src/base/single/label/icon.label.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @class BI.IconButton - * @extends BI.BasicButton - * 图标标签 - */ -BI.IconLabel = BI.inherit(BI.Single, { - - props: { - baseCls: "bi-icon-label horizon-center", - hgap: 0, - vgap: 0, - tgap: 0, - bgap: 0, - lgap: 0, - rgap: 0, - iconWidth: null, - iconHeight: null, - lineHeight: null, - }, - - render: function () { - var o = this.options; - this.element.css({ - textAlign: "center", - }); - this.icon = BI.createWidget({ - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight, - }); - if (BI.isNumber(o.height) && o.height > 0 && BI.isNull(o.iconWidth) && BI.isNull(o.iconHeight)) { - this.element.css("lineHeight", BI.pixFormat(o.lineHeight || o.height)); - BI.createWidget({ - type: "bi.default", - element: this, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - items: [this.icon], - }); - } else { - this.element.css("lineHeight", "1"); - BI.createWidget({ - element: this, - type: "bi.center_adapt", - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - items: [this.icon], - }); - } - }, -}); -BI.shortcut("bi.icon_label", BI.IconLabel); diff --git a/src/base/single/label/label.js b/src/base/single/label/label.js deleted file mode 100644 index 905efd29a..000000000 --- a/src/base/single/label/label.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Created by GUY on 2015/6/26. - */ - -BI.Label = BI.inherit(BI.AbstractLabel, { - - props: { - baseCls: "bi-label", - py: "", - keyword: "", - }, - - getTitle: function () { - var title = this.options.title; - var text = this.options.text; - if (BI.isFunction(title)) { - return title(); - } - if (BI.isNotNull(title)) { - return title; - } - - if (BI.isFunction(text)) { - return text(); - } - - return text; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, -}); - -BI.shortcut("bi.label", BI.Label); diff --git a/src/base/single/link/link.js b/src/base/single/link/link.js deleted file mode 100644 index 176389af5..000000000 --- a/src/base/single/link/link.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * guy a元素 - * @class BI.Link - * @extends BI.Text - */ -BI.Link = BI.inherit(BI.Label, { - _defaultConfig: function () { - var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-link display-block", - tagName: "a", - href: "", - target: "_blank", - }); - }, - - _createJson: function () { - var o = this.options; - - return { - type: "bi.a", - textAlign: o.textAlign, - whiteSpace: o.whiteSpace, - lineHeight: o.textHeight, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py, - href: o.href, - target: o.target, - }; - }, -}); - -BI.shortcut("bi.link", BI.Link); diff --git a/src/base/single/text.pure.js b/src/base/single/text.pure.js deleted file mode 100644 index 07a201369..000000000 --- a/src/base/single/text.pure.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 没有html标签的纯文本 - */ -!(function () { - BI.PureText = BI.inherit(BI.Widget, { - - props: { - tagName: null, - }, - - render: function () { - var self = this, o = this.options; - var text = BI.isFunction(o.text) ? this.__watch(o.text, function (context, newValue) { - self.setText(newValue); - }) : o.text; - if (BI.isKey(text)) { - this.setText(text); - } else if (BI.isKey(o.value)) { - this.setText(o.value); - } - }, - - _getShowText: function () { - var o = this.options; - var text = BI.isFunction(o.text) ? o.text() : o.text; - text = BI.isKey(text) ? text : o.value; - if (!BI.isKey(text)) { - return ""; - } - - return BI.Text.formatText(text + ""); - }, - - setValue: function (value) { - this.options.value = value; - this.setText(value); - }, - - setText: function (text) { - this.options.text = BI.isNotNull(text) ? text : ""; - this.element.__textKeywordMarked__(this._getShowText()); - }, - }); - BI.shortcut("bi.pure_text", BI.PureText); -}()); - diff --git a/src/base/single/tip/0.tip.js b/src/base/single/tip/0.tip.js deleted file mode 100644 index a13240d8b..000000000 --- a/src/base/single/tip/0.tip.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * guy - * tip提示 - * zIndex在10亿级别 - * @class BI.Tip - * @extends BI.Single - * @abstract - */ -BI.Tip = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Tip.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-tip", - zIndex: BI.zIndex_tip, - }); - }, - - _init: function () { - BI.Tip.superclass._init.apply(this, arguments); - this.element.css({ zIndex: this.options.zIndex }); - }, -}); diff --git a/src/base/single/tip/tip.toast.js b/src/base/single/tip/tip.toast.js deleted file mode 100644 index e347ae062..000000000 --- a/src/base/single/tip/tip.toast.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * toast提示 - * - * Created by GUY on 2015/9/7. - * @class BI.Toast - * @extends BI.Tip - */ -BI.Toast = BI.inherit(BI.Tip, { - _const: { - closableMinWidth: 146, - minWidth: 100, - closableMaxWidth: 410, - maxWidth: 400, - }, - - _defaultConfig: function () { - return BI.extend(BI.Toast.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-toast", - text: "", - level: "success", // success或warning - autoClose: true, - closable: null, - textHeight: 20, - vgap: 10, - innerHgap: 4, - hgap: 8, - }); - }, - - render: function () { - var self = this, o = this.options, c = this._const; - this.element.css({ - minWidth: BI.pixFormat(o.closable ? c.closableMinWidth : c.minWidth), - maxWidth: BI.pixFormat(o.closable ? c.closableMaxWidth : c.maxWidth), - }); - this.element.addClass("toast-" + o.level); - function fn(e) { - e.stopPropagation(); - e.stopEvent(); - - return false; - } - this.element.bind({ - click: fn, - mousedown: fn, - mouseup: fn, - mouseover: fn, - mouseenter: fn, - mouseleave: fn, - mousemove: fn, - }); - var cls; - switch (o.level) { - case "success": - cls = "toast-success-font"; - break; - case "error": - cls = "toast-error-font"; - break; - case "warning": - cls = "toast-warning-font"; - break; - case "loading": - cls = "toast-loading-font anim-rotate"; - break; - case "normal": - default: - cls = "toast-message-font"; - break; - } - - function hasCloseIcon() { - return o.closable === true || (o.closable === null && o.autoClose === false); - } - var items = [{ - type: "bi.icon_label", - cls: cls + " toast-icon", - height: o.textHeight, - }, { - el: BI.isPlainObject(o.text) ? o.text : { - type: "bi.label", - whiteSpace: "normal", - text: o.text, - textHeight: o.textHeight, - textAlign: "left", - }, - }]; - - var columnSize = ["", "fill"]; - - if (hasCloseIcon()) { - items.push({ - type: "bi.icon_button", - cls: "close-font toast-icon", - handler: function () { - self.destroy(); - }, - height: o.textHeight, - }); - columnSize.push(""); - } - - return { - type: "bi.horizontal", - horizontalAlign: BI.HorizontalAlign.Stretch, - items: items, - hgap: o.hgap, - vgap: o.vgap, - innerHgap: o.innerHgap, - columnSize: columnSize, - }; - }, - - beforeDestroy: function () { - this.fireEvent(BI.Toast.EVENT_DESTORY); - }, -}); -BI.Toast.EVENT_DESTORY = "EVENT_DESTORY"; -BI.shortcut("bi.toast", BI.Toast); diff --git a/src/base/single/tip/tip.tooltip.js b/src/base/single/tip/tip.tooltip.js deleted file mode 100644 index aae6d8e86..000000000 --- a/src/base/single/tip/tip.tooltip.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * title提示 - * - * Created by GUY on 2015/9/7. - * @class BI.Tooltip - * @extends BI.Tip - */ -BI.Tooltip = BI.inherit(BI.Tip, { - _const: { - hgap: 8, - vgap: 4, - }, - - _defaultConfig: function () { - return BI.extend(BI.Tooltip.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-tooltip", - text: "", - level: "success", // success或warning - stopEvent: false, - stopPropagation: false, - textAlign: "left", - }); - }, - - render: function () { - var o = this.options; - this.element.addClass("tooltip-" + o.level); - function fn(e) { - o.stopPropagation && e.stopPropagation(); - o.stopEvent && e.stopEvent(); - } - this.element.bind({ - click: fn, - mousedown: fn, - mouseup: fn, - mouseover: fn, - mouseenter: fn, - mouseleave: fn, - mousemove: fn, - }); - - var texts = (o.text + "").split("\n"); - if (texts.length > 1) { - BI.createWidget({ - type: "bi.vertical", - element: this, - hgap: this._const.hgap, - innerVgap: this._const.vgap, - items: BI.map(texts, function (i, text) { - return { - type: "bi.label", - textAlign: o.textAlign, - whiteSpace: "normal", - text: text, - textHeight: 18, - title: null, - }; - }), - }); - } else { - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: "normal", - text: o.text, - title: null, - textHeight: 18, - hgap: this._const.hgap, - vgap: this._const.vgap, - }); - } - }, - - setWidth: function (width) { - this.element.width(BI.pixFormat(width - 2 * this._const.hgap)); - }, - - setText: function (text) { - this.text && this.text.setText(text); - }, - - setLevel: function (level) { - this.element.removeClass("tooltip-success").removeClass("tooltip-warning"); - this.element.addClass("tooltip-" + level); - }, -}); - -BI.shortcut("bi.tooltip", BI.Tooltip); diff --git a/src/base/single/trigger/trigger.js b/src/base/single/trigger/trigger.js deleted file mode 100644 index 486ae898f..000000000 --- a/src/base/single/trigger/trigger.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * 下拉 - * @class BI.Trigger - * @extends BI.Single - * @abstract - */ -BI.Trigger = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.Trigger.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-trigger cursor-pointer", - height: 24, - }); - }, - - setKey: function () { - - }, - - getKey: function () { - - }, -}); diff --git a/src/base/tree/customtree.js b/src/base/tree/customtree.js deleted file mode 100644 index 3c32a80c0..000000000 --- a/src/base/tree/customtree.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * - * 自定义树 - * - * Created by GUY on 2015/9/7. - * @class BI.CustomTree - * @extends BI.Single - */ -BI.CustomTree = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.CustomTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-custom-tree", - expander: { - el: {}, - popup: { - type: "bi.custom_tree", - }, - }, - - items: [], - itemsCreator: BI.emptyFn, - - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical", - }], - }, - }); - }, - - _init: function () { - BI.CustomTree.superclass._init.apply(this, arguments); - this.initTree(this.options.items); - }, - - _formatItems: function (nodes) { - var self = this, o = this.options; - nodes = BI.Tree.transformToTreeFormat(nodes); - - var items = []; - BI.each(nodes, function (i, node) { - if (BI.isNotEmptyArray(node.children) || node.isParent === true) { - var item = BI.extend({ - type: "bi.expander", - el: { - value: node.value, - }, - popup: { type: "bi.custom_tree" }, - }, BI.deepClone(o.expander), { - id: node.id, - pId: node.pId, - key: node.key, - }); - var el = BI.stripEL(node); - if (!BI.isWidget(el)) { - el = BI.clone(el); - delete el.children; - BI.extend(item.el, el); - } else { - item.el = el; - } - item.popup.expander = BI.deepClone(o.expander); - item.items = item.popup.items = node.children; - item.itemsCreator = item.popup.itemsCreator = function (op) { - if (BI.isNotNull(op.node)) {// 从子节点传过来的itemsCreator直接向上传递 - return o.itemsCreator.apply(self, arguments); - } - var args = Array.prototype.slice.call(arguments, 0); - args[0].node = node; - - return o.itemsCreator.apply(self, args); - }; - BI.isNull(item.popup.el) && (item.popup.el = BI.deepClone(o.el)); - items.push(item); - } else { - items.push(node); - } - }); - - return items; - }, - - // 构造树结构, - initTree: function (nodes) { - var self = this, o = this.options; - this.tree = BI.createWidget(o.el, { - element: this, - items: this._formatItems(nodes), - itemsCreator: function (op, callback) { - o.itemsCreator.apply(this, [op, function (items) { - var args = Array.prototype.slice.call(arguments, 0); - args[0] = self._formatItems(items); - callback.apply(null, args); - }]); - }, - value: o.value, - }); - this.tree.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.CustomTree.EVENT_CHANGE, val, obj); - } - }); - }, - - // 生成树方法 - stroke: function (nodes) { - this.populate.apply(this, arguments); - }, - - populate: function (nodes) { - var args = Array.prototype.slice.call(arguments, 0); - if (arguments.length > 0) { - args[0] = this._formatItems(nodes); - } - this.tree.populate.apply(this.tree, args); - }, - - setValue: function (v) { - this.tree && this.tree.setValue(v); - }, - - getValue: function () { - return this.tree ? this.tree.getValue() : []; - }, - - getAllButtons: function () { - return this.tree ? this.tree.getAllButtons() : []; - }, - - getAllLeaves: function () { - return this.tree ? this.tree.getAllLeaves() : []; - }, - - getNodeById: function (id) { - return this.tree && this.tree.getNodeById(id); - }, - - getNodeByValue: function (id) { - return this.tree && this.tree.getNodeByValue(id); - }, - - empty: function () { - this.tree.empty(); - }, -}); -BI.CustomTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.custom_tree", BI.CustomTree); diff --git a/src/case/button/icon/icon.change.js b/src/case/button/icon/icon.change.js deleted file mode 100644 index e65160879..000000000 --- a/src/case/button/icon/icon.change.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 可以改变图标的button - * - * Created by GUY on 2016/2/2. - * - * @class BI.IconChangeButton - * @extends BI.Single - */ -BI.IconChangeButton = BI.inherit(BI.Single, { - _defaultConfig: function () { - var conf = BI.IconChangeButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-icon-change-button", - iconCls: "", - iconWidth: null, - iconHeight: null, - - stopEvent: false, - stopPropagation: false, - selected: false, - once: false, // 点击一次选中有效,再点无效 - forceSelected: false, // 点击即选中, 选中了就不会被取消 - forceNotSelected: false, // 无论怎么点击都不会被选中 - disableSelected: false, // 使能选中 - - shadow: false, - isShadowShowingOnSelected: false, // 选中状态下是否显示阴影 - trigger: null, - handler: BI.emptyFn - }); - }, - - _init: function () { - var self = this, o = this.options; - o.iconCls = BI.isFunction(o.iconCls) ? this.__watch(o.iconCls, function (context, newValue) { - self.setIcon(newValue); - }) : o.iconCls; - BI.IconChangeButton.superclass._init.apply(this, arguments); - this.button = BI.createWidget({ - type: "bi.icon_button", - element: this, - cls: o.iconCls, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - - stopEvent: o.stopEvent, - stopPropagation: o.stopPropagation, - selected: o.selected, - once: o.once, - forceSelected: o.forceSelected, - forceNotSelected: o.forceNotSelected, - disableSelected: o.disableSelected, - - shadow: o.shadow, - isShadowShowingOnSelected: o.isShadowShowingOnSelected, - trigger: o.trigger, - handler: o.handler - }); - - this.button.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button.on(BI.IconButton.EVENT_CHANGE, function () { - self.fireEvent(BI.IconChangeButton.EVENT_CHANGE, arguments); - }); - }, - - isSelected: function () { - return this.button.isSelected(); - }, - - setSelected: function (b) { - this.button.setSelected(b); - }, - - setIcon: function (cls) { - var o = this.options; - if (o.iconCls !== cls) { - this.element.removeClass(o.iconCls).addClass(cls); - o.iconCls = cls; - } - } -}); -BI.IconChangeButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_change_button", BI.IconChangeButton); diff --git a/src/case/button/icon/icon.trigger.js b/src/case/button/icon/icon.trigger.js deleted file mode 100644 index daa76b121..000000000 --- a/src/case/button/icon/icon.trigger.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * 统一的trigger图标按钮 - * - * Created by GUY on 2015/9/16. - * @class BI.TriggerIconButton - * @extends BI.IconButton - */ -BI.TriggerIconButton = BI.inherit(BI.IconButton, { - - _defaultConfig: function () { - var conf = BI.TriggerIconButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-trigger-icon-button overflow-hidden", - extraCls: "pull-down-font" - }); - } -}); -BI.TriggerIconButton.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; -BI.shortcut("bi.trigger_icon_button", BI.TriggerIconButton); diff --git a/src/case/button/icon/iconhalf/icon.half.image.js b/src/case/button/icon/iconhalf/icon.half.image.js deleted file mode 100644 index a9e9d0014..000000000 --- a/src/case/button/icon/iconhalf/icon.half.image.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.HalfIconButton = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - var conf = BI.HalfIconButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-half-icon-button check-half-select-icon", - height: 16, - width: 16, - iconWidth: 16, - iconHeight: 16, - selected: false - }); - } -}); -BI.HalfIconButton.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; - -BI.shortcut("bi.half_icon_button", BI.HalfIconButton); \ No newline at end of file diff --git a/src/case/button/icon/iconhalf/icon.half.js b/src/case/button/icon/iconhalf/icon.half.js deleted file mode 100644 index f8c23afc4..000000000 --- a/src/case/button/icon/iconhalf/icon.half.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * guy - * @extends BI.Single - * @type {*|void|Object} - */ -BI.HalfButton = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.HalfIconButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - selected: false, - width: 14, - height: 14, - iconWidth: 14, - iconHeight: 14, - }); - }, - - render: function () { - var o = this.options; - return { - type: "bi.center_adapt", - items: [{ - type: "bi.default", - cls: "bi-half-button bi-high-light-border", - width: o.iconWidth, - height: o.iconHeight, - }], - }; - }, - - doClick: function () { - BI.HalfButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.HalfButton.EVENT_CHANGE); - } - } -}); -BI.HalfButton.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.half_button", BI.HalfButton); diff --git a/src/case/button/item.multiselect.js b/src/case/button/item.multiselect.js deleted file mode 100644 index b90fafac5..000000000 --- a/src/case/button/item.multiselect.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * guy - * 复选框item - * @type {*|void|Object} - */ -BI.MultiSelectItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multi-select-item", - attributes: { - tabIndex: 1 - }, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - iconWrapperWidth: 26, - }); - }, - - render: function () { - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.checkbox" - }); - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.center_adapt", - items: [this.checkbox] - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.textHgap, - rgap: o.textRgap, - lgap: o.textLgap, - vgap: o.textVgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - } - }] - }; - }, - - // _setEnable: function (enable) { - // BI.MultiSelectItem.superclass._setEnable.apply(this, arguments); - // if (enable === true) { - // this.element.attr("tabIndex", 1); - // } else if (enable === false) { - // this.element.removeAttr("tabIndex"); - // } - // }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.MultiSelectItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.MultiSelectItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - setSelected: function (v) { - BI.MultiSelectItem.superclass.setSelected.apply(this, arguments); - this.checkbox.setSelected(v); - } -}); -BI.MultiSelectItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_item", BI.MultiSelectItem); diff --git a/src/case/button/item.singleselect.icontext.js b/src/case/button/item.singleselect.icontext.js deleted file mode 100644 index 47960e9fa..000000000 --- a/src/case/button/item.singleselect.icontext.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Created by GUY on 2016/2/2. - * - * @class BI.SingleSelectIconTextItem - * @extends BI.BasicButton - */ -BI.SingleSelectIconTextItem = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.SingleSelectIconTextItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-single-select-icon-text-item bi-list-item-active", - attributes: { - tabIndex: 1 - }, - iconCls: "", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT - }); - }, - - render: function () { - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.icon_text_item", - element: this, - cls: o.iconCls, - once: o.once, - iconWrapperWidth: o.iconWrapperWidth, - selected: o.selected, - height: o.height, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - textHgap: o.textHgap, - textVgap: o.textVgap, - textLgap: o.textLgap, - textRgap: o.textRgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - }); - this.text.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - }, - - _setEnable: function (enable) { - BI.SingleSelectIconTextItem.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("tabIndex", 1); - } else if (enable === false) { - this.element.removeAttr("tabIndex"); - } - }, - - isSelected: function () { - return this.text.isSelected(); - }, - - setSelected: function (b) { - this.text.setSelected(b); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - } -}); - -BI.shortcut("bi.single_select_icon_text_item", BI.SingleSelectIconTextItem); diff --git a/src/case/button/item.singleselect.js b/src/case/button/item.singleselect.js deleted file mode 100644 index 50a1cf6db..000000000 --- a/src/case/button/item.singleselect.js +++ /dev/null @@ -1,64 +0,0 @@ -BI.SingleSelectItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.SingleSelectItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-single-select-item bi-list-item-active", - attributes: { - tabIndex: 1 - }, - textHgap: 10, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - textAlign: "left" - }); - }, - - render: function () { - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textAlign: o.textAlign, - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - }); - }, - - _setEnable: function (enable) { - BI.SingleSelectItem.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("tabIndex", 1); - } else if (enable === false) { - this.element.removeAttr("tabIndex"); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.SingleSelectItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.SingleSelectItem.EVENT_CHANGE, this.isSelected(), this); - } - }, - - setSelected: function (v) { - BI.SingleSelectItem.superclass.setSelected.apply(this, arguments); - } -}); - -BI.SingleSelectItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_item", BI.SingleSelectItem); diff --git a/src/case/button/item.singleselect.radio.js b/src/case/button/item.singleselect.radio.js deleted file mode 100644 index 92058b476..000000000 --- a/src/case/button/item.singleselect.radio.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * guy - * 单选框item - * @type {*|void|Object} - */ -BI.SingleSelectRadioItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.SingleSelectRadioItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-single-select-radio-item", - attributes: { - tabIndex: 1 - }, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - iconWrapperWidth: 16, - textHgap: 10, - }); - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [{ - type: "bi.center_adapt", - items: [{ - type: "bi.radio", - once: o.once, - ref: function (_ref) { - self.radio = _ref; - }, - }] - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: "list-item-text", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - } - }] - }; - }, - - _setEnable: function (enable) { - BI.SingleSelectRadioItem.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("tabIndex", 1); - } else if (enable === false) { - this.element.removeAttr("tabIndex"); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.SingleSelectRadioItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.SingleSelectRadioItem.EVENT_CHANGE, this.isSelected(), this); - } - }, - - setSelected: function (v) { - BI.SingleSelectRadioItem.superclass.setSelected.apply(this, arguments); - this.radio.setSelected(v); - - } -}); - -BI.SingleSelectRadioItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_radio_item", BI.SingleSelectRadioItem); diff --git a/src/case/button/node/node.arrow.js b/src/case/button/node/node.arrow.js deleted file mode 100644 index d0b21ca7c..000000000 --- a/src/case/button/node/node.arrow.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Created by roy on 15/10/16. - */ -BI.ArrowNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.ArrowNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-arrow-group-node bi-list-item", - id: "", - pId: "", - open: false, - height: 24, - iconWrapperWidth: 16 - }); - }, - - render: function () { - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.arrow_group_node_checkbox", - expandIcon: o.expandIcon, - collapseIcon: o.collapseIcon, - }); - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [this.checkbox, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - } - }] - }; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.ArrowNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isOpened()); - }, - - setText: function (text) { - BI.ArrowNode.superclass.setText.apply(this, arguments); - this.text.setText(text); - }, - - setOpened: function (v) { - BI.ArrowNode.superclass.setOpened.apply(this, arguments); - this.checkbox.setSelected(v); - } -}); - -BI.shortcut("bi.arrow_group_node", BI.ArrowNode); diff --git a/src/case/button/node/node.first.plus.js b/src/case/button/node/node.first.plus.js deleted file mode 100644 index 989cdec0b..000000000 --- a/src/case/button/node/node.first.plus.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.FirstPlusGroupNode - * @extends BI.NodeButton - */ -BI.FirstPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.FirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-first-plus-group-node bi-list-item", - logic: { - dynamic: false - }, - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.FirstPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.first_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.FirstPlusGroupNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.FirstPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.first_plus_group_node", BI.FirstPlusGroupNode); diff --git a/src/case/button/node/node.icon.arrow.js b/src/case/button/node/node.icon.arrow.js deleted file mode 100644 index d641e655d..000000000 --- a/src/case/button/node/node.icon.arrow.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Created by User on 2016/3/31. - */ -/** - * > + icon + 文本 - * @class BI.IconArrowNode - * @extends BI.NodeButton - */ -BI.IconArrowNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.IconArrowNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-icon-arrow-node bi-list-item", - logic: { - dynamic: false - }, - id: "", - pId: "", - open: false, - height: 24, - iconHeight: 12, - iconWidth: 12, - iconCls: "", - iconWrapperWidth: 16 - }); - }, - _init: function () { - BI.IconArrowNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.arrow_group_node_checkbox", - expandIcon: o.expandIcon, - collapseIcon: o.collapseIcon, - width: 24, - stopPropagation: true - }); - - var icon = BI.createWidget({ - type: "bi.icon_label", - width: 24, - cls: o.iconCls, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight - }); - - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: o.iconWrapperWidth, - el: this.checkbox - }, { - width: 16, - el: icon - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items, - rgap: 5 - })))); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.IconArrowNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.IconArrowNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.icon_arrow_node", BI.IconArrowNode); diff --git a/src/case/button/node/node.last.plus.js b/src/case/button/node/node.last.plus.js deleted file mode 100644 index c1a949e3b..000000000 --- a/src/case/button/node/node.last.plus.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.LastPlusGroupNode - * @extends BI.NodeButton - */ -BI.LastPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.LastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-last-plus-group-node bi-list-item", - logic: { - dynamic: false - }, - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.LastPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.last_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if(type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.LastPlusGroupNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.LastPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.last_plus_group_node", BI.LastPlusGroupNode); \ No newline at end of file diff --git a/src/case/button/node/node.mid.plus.js b/src/case/button/node/node.mid.plus.js deleted file mode 100644 index 839565114..000000000 --- a/src/case/button/node/node.mid.plus.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.MidPlusGroupNode - * @extends BI.NodeButton - */ -BI.MidPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-mid-plus-group-node bi-list-item", - logic: { - dynamic: false - }, - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.MidPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.mid_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.MidPlusGroupNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MidPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.mid_plus_group_node", BI.MidPlusGroupNode); \ No newline at end of file diff --git a/src/case/button/node/node.multilayer.icon.arrow.js b/src/case/button/node/node.multilayer.icon.arrow.js deleted file mode 100644 index ffa9c50ea..000000000 --- a/src/case/button/node/node.multilayer.icon.arrow.js +++ /dev/null @@ -1,89 +0,0 @@ -BI.MultiLayerIconArrowNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerIconArrowNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-icon-arrow-node bi-list-item", - layer: 0, // 第几层级 - id: "", - pId: "", - open: false, - height: 24, - iconHeight: 16, - iconWidth: 16, - iconCls: "" - }); - }, - _init: function () { - BI.MultiLayerIconArrowNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = BI.createWidget({ - type: "bi.icon_arrow_node", - iconCls: o.iconCls, - cls: "bi-list-item-none", - id: o.id, - pId: o.pId, - open: o.open, - height: o.height, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.node.on(BI.Controller.EVENT_CHANGE, function (type) { - self.setSelected(self.isSelected()); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - BI.count(0, o.layer, function () { - items.push({ - type: "bi.layout", - width: 15, - height: o.height - }); - }); - items.push(this.node); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, 15), - items: items - }); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - isSelected: function () { - return this.node.isSelected(); - }, - - setSelected: function (b) { - BI.MultiLayerIconArrowNode.superclass.setSelected.apply(this, arguments); - this.node.setSelected(b); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerIconArrowNode.superclass.setOpened.apply(this, arguments); - this.node.setOpened(v); - } -}); - -BI.shortcut("bi.multilayer_icon_arrow_node", BI.MultiLayerIconArrowNode); diff --git a/src/case/button/node/node.plus.js b/src/case/button/node/node.plus.js deleted file mode 100644 index 4b9477ea7..000000000 --- a/src/case/button/node/node.plus.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.PlusGroupNode - * @extends BI.NodeButton - */ -BI.PlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.PlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-plus-group-node bi-list-item", - id: "", - pId: "", - open: false, - height: 24 - }); - }, - - render: function () { - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.tree_node_checkbox", - iconHeight: o.height, - iconWidth: o.iconWrapperWidth || o.height - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self.setSelected(self.isSelected()); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [this.checkbox, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - } - }] - }; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.PlusGroupNode.superclass.doClick.apply(this, arguments); - this.checkbox.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.PlusGroupNode.superclass.setOpened.apply(this, arguments); - if (this.checkbox) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.plus_group_node", BI.PlusGroupNode); diff --git a/src/case/button/node/siwtcher.tree.node.js b/src/case/button/node/siwtcher.tree.node.js deleted file mode 100644 index 8669f697b..000000000 --- a/src/case/button/node/siwtcher.tree.node.js +++ /dev/null @@ -1,59 +0,0 @@ -BI.TreeNodeSwitcher = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - return BI.extend(BI.TreeNodeSwitcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-node-switcher", - iconWidth: 24, - iconHeight: 24, - isFirstNode: false, - isLastNode: false, - layer: 0 - }); - }, - - render: function () { - - const [collapse, expand] = this.getIconCls(); - - return { - type: "bi.icon_label", - iconWidth: this.options.iconWidth, - iconHeight: this.options.iconHeight, - cls: this.options.open ? expand : collapse, - }; - }, - - getIconCls: function () { - var options = this.options; - if (options.layer === 0 && options.isFirstNode && options.isLastNode) { - // 只有一层,并且是第一个节点,并且是最后一个节点 - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] : ["tree-collapse-icon-type1", "tree-expand-icon-type1"]; - } else if (options.layer === 0 && options.isFirstNode) { - // 第一层,并且是第一个节点 - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] : ["tree-collapse-icon-type2", "tree-expand-icon-type2"]; - } else if (options.isLastNode) { - // 最后一个节点 - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] : ["tree-collapse-icon-type4", "tree-expand-icon-type4"]; - } else { - // 其他情况 - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? ["tree-solid-collapse-icon-type1", "tree-solid-expand-icon-type1"] : ["tree-collapse-icon-type3", "tree-expand-icon-type3"]; - } - }, - - setOpened: function (b) { - BI.TreeNodeSwitcher.superclass.setOpened.apply(this, arguments); - const [collapse, expand] = this.getIconCls(); - if (b) { - this.element.addClass(expand).removeClass(collapse); - } else { - this.element.addClass(collapse).removeClass(expand); - } - }, - - doClick: function () { - BI.TreeNodeSwitcher.superclass.doClick.apply(this, arguments); - this.fireEvent(BI.TreeNodeSwitcher.EVENT_CHANGE, this); - } -}); - -BI.TreeNodeSwitcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.tree_node_switcher", BI.TreeNodeSwitcher); diff --git a/src/case/button/node/treenode.js b/src/case/button/node/treenode.js deleted file mode 100644 index c557f791c..000000000 --- a/src/case/button/node/treenode.js +++ /dev/null @@ -1,106 +0,0 @@ -BI.BasicTreeNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function (props) { - var conf = BI.BasicTreeNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-tree-node " + (props.selectable ? "bi-list-item-active" : "bi-list-item"), - id: "", - pId: "", - open: false, - height: 24, - readonly: true, - isFirstNode: false, - isLastNode: false, - switcherIcon: {}, - selectable: true, - disabled: false, // disabled不会影响展开收起功能 - }); - }, - - render: function () { - var self = this, o = this.options; - - const checkbox = { - type: "bi.tree_node_switcher", - __ref: function (_ref) { - self.switcher = _ref; - }, - iconHeight: o.height, - iconWidth: o.iconWrapperWidth || o.height, - open: o.open, - isFirstNode: o.isFirstNode, - isLastNode: o.isLastNode, - layer: o.layer, - ...o.switcherIcon, - stopPropagation: o.selectable, - mounted: function () { - this.setEnable(true); - }, - listeners: [ - { - eventName: "EVENT_CHANGE", - action: () => { - if (!this.isEnabled() || o.selectable) { - this.isOpened() ? this.triggerCollapse() : this.triggerExpand(); - } - } - } - ] - }; - - return { - type: "bi.vertical_adapt", - columnSize: [o.iconWrapperWidth || o.height, "fill"], - items: [ - { - el: checkbox, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, // 偏移公式为每一层的偏移量为节点高度的一半 - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - } - } - ] - }; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - if (this.options.selectable) { - return; - } - BI.BasicTreeNode.superclass.doClick.apply(this, arguments); - }, - - setOpened: function (v) { - BI.BasicTreeNode.superclass.setOpened.apply(this, arguments); - this.switcher.setOpened(v); - }, - - setValue: function () { - BI.BasicTreeNode.superclass.setValue.apply(this, arguments); - } -}); - -BI.shortcut("bi.tree_node", BI.BasicTreeNode); diff --git a/src/case/button/switch.js b/src/case/button/switch.js deleted file mode 100644 index 1ca2bd2b6..000000000 --- a/src/case/button/switch.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Created by Windy on 2018/2/1. - */ -BI.Switch = BI.inherit(BI.BasicButton, { - - constants: { - CIRCLE_SIZE: 12 - }, - - props: { - extraCls: "bi-switch", - attributes: { - tabIndex: 1 - }, - height: 20, - width: 44, - showTip: false - }, - - render: function () { - var self = this, o = this.options, c = this.constants; - var tgap = (o.height - c.CIRCLE_SIZE) / 2; - return { - type: "bi.absolute", - ref: function () { - self.layout = this; - }, - items: [{ - el: { - type: "bi.text_button", - cls: "circle-button" - }, - width: 12, - height: 12, - top: tgap, - left: o.selected ? 28 : 4 - }, { - type: "bi.label", - text: BI.i18nText("BI-Basic_Simple_Open"), - cls: "content-tip", - left: 8, - top: tgap - 2, - invisible: !(o.showTip && o.selected), - ref: function (ref) { - self.openTip = ref; - } - }, { - type: "bi.label", - text: BI.i18nText("BI-Basic_Simple_Close"), - cls: "content-tip", - right: 8, - top: tgap - 2, - invisible: !(o.showTip && !o.selected), - ref: function (ref) { - self.closeTip = ref; - } - }] - }; - }, - - _setEnable: function (enable) { - BI.Switch.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.attr("tabIndex", 1); - } else if (enable === false) { - this.element.removeAttr("tabIndex"); - } - }, - - setSelected: function (v) { - BI.Switch.superclass.setSelected.apply(this, arguments); - this.layout.attr("items")[0].left = v ? 28 : 4; - this.layout.resize(); - this.options.showTip && this.openTip.setVisible(v); - this.options.showTip && this.closeTip.setVisible(!v); - }, - - doClick: function () { - BI.Switch.superclass.doClick.apply(this, arguments); - this.fireEvent(BI.Switch.EVENT_CHANGE, this.isSelected()); - } -}); -BI.Switch.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.switch", BI.Switch); diff --git a/src/case/button/treeitem/item.first.treeleaf.js b/src/case/button/treeitem/item.first.treeleaf.js deleted file mode 100644 index 52663de39..000000000 --- a/src/case/button/treeitem/item.first.treeleaf.js +++ /dev/null @@ -1,99 +0,0 @@ -BI.FirstTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.FirstTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-first-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - layer: 0, - height: 24 - }); - }, - _init: function () { - BI.FirstTreeLeafItem.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - el: { - type: "bi.layout", - cls: (o.pNode && o.pNode.isLastNode) ? "" : this._getBaseLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - height: o.height - } - }), { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: { - type: "bi.layout", - cls: this._getFirstLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: o.height - } - }, { - el: this.text - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - _getBaseLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "base-solid-line-conn-background"; - default: - return "base-line-conn-background"; - } - }, - - _getFirstLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "first-solid-line-conn-background"; - default: - return "first-line-conn-background"; - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.first_tree_leaf_item", BI.FirstTreeLeafItem); \ No newline at end of file diff --git a/src/case/button/treeitem/item.icon.treeleaf.js b/src/case/button/treeitem/item.icon.treeleaf.js deleted file mode 100644 index 92fd5e348..000000000 --- a/src/case/button/treeitem/item.icon.treeleaf.js +++ /dev/null @@ -1,82 +0,0 @@ -BI.IconTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.IconTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-icon-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - height: 24, - iconWidth: 16, - iconHeight: 16, - iconCls: "" - }); - }, - - _init: function () { - BI.IconTreeLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - var icon = BI.createWidget({ - type: "bi.center_adapt", - width: 24, - cls: o.iconCls, - items: [{ - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight - }] - }); - - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: 16, - el: icon - }, { - el: this.text - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items, - hgap: 5 - })))); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.icon_tree_leaf_item", BI.IconTreeLeafItem); \ No newline at end of file diff --git a/src/case/button/treeitem/item.last.treeleaf.js b/src/case/button/treeitem/item.last.treeleaf.js deleted file mode 100644 index 76449063e..000000000 --- a/src/case/button/treeitem/item.last.treeleaf.js +++ /dev/null @@ -1,99 +0,0 @@ -BI.LastTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.LastTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-last-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - layer: 0, - height: 24 - }); - }, - _init: function () { - BI.LastTreeLeafItem.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - el: { - type: "bi.layout", - cls: (o.pNode && o.pNode.isLastNode) ? "" : this._getBaseLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - height: o.height - } - }), { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: { - type: "bi.layout", - cls: this._getLastLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: o.height - } - }, { - el: this.text - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - _getBaseLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "base-solid-line-conn-background"; - default: - return "base-line-conn-background"; - } - }, - - _getLastLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "last-solid-line-conn-background"; - default: - return "last-line-conn-background"; - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.last_tree_leaf_item", BI.LastTreeLeafItem); \ No newline at end of file diff --git a/src/case/button/treeitem/item.mid.treeleaf.js b/src/case/button/treeitem/item.mid.treeleaf.js deleted file mode 100644 index 58af36e4e..000000000 --- a/src/case/button/treeitem/item.mid.treeleaf.js +++ /dev/null @@ -1,99 +0,0 @@ -BI.MidTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MidTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-mid-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - layer: 0, - height: 24 - }); - }, - _init: function () { - BI.MidTreeLeafItem.superclass._init.apply(this, arguments); - var o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - el: { - type: "bi.layout", - cls: (o.pNode && o.pNode.isLastNode) ? "" : this._getBaseLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, - height: o.height - } - }), { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: { - type: "bi.layout", - cls: this._getMidLineCls(), - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: o.height - } - }, { - el: this.text - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - _getBaseLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "base-solid-line-conn-background"; - default: - return "base-line-conn-background"; - } - }, - - _getMidLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "mid-solid-line-conn-background"; - default: - return "mid-line-conn-background"; - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.mid_tree_leaf_item", BI.MidTreeLeafItem); \ No newline at end of file diff --git a/src/case/button/treeitem/item.multilayer.icon.treeleaf.js b/src/case/button/treeitem/item.multilayer.icon.treeleaf.js deleted file mode 100644 index 363a348c0..000000000 --- a/src/case/button/treeitem/item.multilayer.icon.treeleaf.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @class BI.MultiLayerIconTreeLeafItem - * @extends BI.BasicButton - */ -BI.MultiLayerIconTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerIconTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multilayer-icon-tree-leaf-item bi-list-item-active", - layer: 0, - height: 24, - iconCls: "", - iconHeight: 16, - iconWidth: 16 - }); - }, - _init: function () { - BI.MultiLayerIconTreeLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.item = BI.createWidget({ - type: "bi.icon_tree_leaf_item", - cls: "bi-list-item-none", - iconCls: o.iconCls, - id: o.id, - pId: o.pId, - isFront: true, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight - }); - this.item.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - BI.count(0, o.layer, function () { - items.push({ - type: "bi.layout", - width: 15, - height: o.height - }); - }); - items.push(this.item); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, 15), - items: items - }); - }, - - doRedMark: function () { - this.item.doRedMark.apply(this.item, arguments); - }, - - unRedMark: function () { - this.item.unRedMark.apply(this.item, arguments); - }, - - doHighLight: function () { - this.item.doHighLight.apply(this.item, arguments); - }, - - unHighLight: function () { - this.item.unHighLight.apply(this.item, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - }, - - doClick: function () { - BI.MultiLayerIconTreeLeafItem.superclass.doClick.apply(this, arguments); - this.item.setSelected(this.isSelected()); - }, - - setSelected: function (v) { - BI.MultiLayerIconTreeLeafItem.superclass.setSelected.apply(this, arguments); - this.item.setSelected(v); - }, - - getValue: function () { - return this.options.value; - } -}); - -BI.shortcut("bi.multilayer_icon_tree_leaf_item", BI.MultiLayerIconTreeLeafItem); diff --git a/src/case/button/treeitem/item.root.treeleaf.js b/src/case/button/treeitem/item.root.treeleaf.js deleted file mode 100644 index f4637afdc..000000000 --- a/src/case/button/treeitem/item.root.treeleaf.js +++ /dev/null @@ -1,74 +0,0 @@ -BI.RootTreeLeafItem = BI.inherit(BI.BasicButton, { - props: { - baseCls: "bi-root-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - layer: 0, - height: 24 - }, - - render: function () { - var self = this; - var o = this.options; - var text = { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }; - - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: { - type: "bi.layout", - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: o.height - } - }, { - el: text - }); - - return BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.root_tree_leaf_item", BI.RootTreeLeafItem); diff --git a/src/case/button/treeitem/item.treetextleaf.js b/src/case/button/treeitem/item.treetextleaf.js deleted file mode 100644 index 872663fd0..000000000 --- a/src/case/button/treeitem/item.treetextleaf.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 树叶子节点 - * Created by GUY on 2015/9/6. - * @class BI.TreeTextLeafItem - * @extends BI.BasicButton - */ -BI.TreeTextLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.TreeTextLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-tree-text-leaf-item bi-list-item-active", - id: "", - pId: "", - height: 24, - hgap: 0, - lgap: 0, - rgap: 0 - }); - }, - _init: function () { - BI.TreeTextLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - lgap: o.lgap, - rgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - BI.createWidget({ - type: "bi.htape", - element: this, - items: [{ - el: this.text - }] - }); - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } -}); - -BI.shortcut("bi.tree_text_leaf_item", BI.TreeTextLeafItem); diff --git a/src/case/button/treeitem/treeitem.js b/src/case/button/treeitem/treeitem.js deleted file mode 100644 index 4ab512a29..000000000 --- a/src/case/button/treeitem/treeitem.js +++ /dev/null @@ -1,86 +0,0 @@ -BI.BasicTreeItem = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.BasicTreeItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-tree-item bi-list-item-active", - id: "", - pId: "", - height: 24, - readonly: true, - isFirstNode: false, - isLastNode: false, - }); - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical_adapt", - columnSize: ["", "fill"], - items: [ - { - el: { - type: "bi.layout", - height: o.height, - width: o.height, - cls: this.getLineCls(), - }, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2, // 偏移公式为每一层的偏移量为节点高度的一半 - }, - { - el: { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap || o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }, - } - ] - }; - }, - - getLineCls: function () { - var options = this.options; - if (options.layer === 0 && options.isFirstNode && options.isLastNode) { - return ""; - } else if (options.layer === 0 && options.isFirstNode) { - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-first-solid-line-conn-background" : "first-line-conn-background"; - } else if (options.isLastNode) { - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-last-solid-line-conn-background" : "last-line-conn-background"; - } else { - return BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-mid-solid-line-conn-background" : "mid-line-conn-background"; - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - } - -}); - -BI.shortcut("bi.tree_item", BI.BasicTreeItem); diff --git a/src/case/calendar/calendar.date.item.js b/src/case/calendar/calendar.date.item.js deleted file mode 100644 index 3b2d865a0..000000000 --- a/src/case/calendar/calendar.date.item.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 专门为calendar的视觉加的button,作为私有button,不能配置任何属性,也不要用这个玩意 - */ -BI.CalendarDateItem = BI.inherit(BI.BasicButton, { - props: function() { - return { - baseCls: "bi-calendar-date-item", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 8, - } - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.text_item", - cls: "bi-border-radius bi-list-item-select", - textAlign: "center", - text: o.text, - value: o.value, - ref: function () { - self.text = this; - } - }, - left: o.lgap, - right: o.rgap, - top: o.tgap, - bottom: o.bgap - }] - }; - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - setSelected: function (b) { - BI.CalendarDateItem.superclass.setSelected.apply(this, arguments); - this.text.setSelected(b); - }, - - getValue: function () { - return this.text.getValue(); - } -}); -BI.shortcut("bi.calendar_date_item", BI.CalendarDateItem); diff --git a/src/case/calendar/calendar.js b/src/case/calendar/calendar.js deleted file mode 100644 index 5645fb1f5..000000000 --- a/src/case/calendar/calendar.js +++ /dev/null @@ -1,245 +0,0 @@ -/** - * Created by GUY on 2015/8/28. - * @class BI.Calendar - * @extends BI.Widget - */ -BI.Calendar = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.Calendar.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-calendar", - logic: { - dynamic: false - }, - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - year: 2015, - month: 8, - day: 25 - }); - }, - - _dateCreator: function (Y, M, D) { - var self = this, o = this.options, log = {}, De = BI.getDate(); - var mins = o.min.match(/\d+/g); - var maxs = o.max.match(/\d+/g); - - De.setFullYear(Y, M, D); - log.ymd = [De.getFullYear(), De.getMonth(), De.getDate()]; - - var MD = BI.Date._MD.slice(0); - MD[1] = BI.isLeapYear(log.ymd[0]) ? 29 : 28; - - // 日期所在月第一天 - De.setFullYear(log.ymd[0], log.ymd[1], 1); - // 是周几 - log.FDay = De.getDay(); - - // 当前BI.StartOfWeek与周日对齐后的FDay是周几 - var offSetFDay = (7 - BI.StartOfWeek + log.FDay) % 7; - - // 当前月页第一天是几号 - log.PDay = MD[M === 0 ? 11 : M - 1] - offSetFDay + 1; - log.NDay = 1; - - var items = []; - BI.each(BI.range(42), function (i) { - var td = {}, YY = log.ymd[0], MM = log.ymd[1] + 1, DD; - // 上个月的日期 - if (i < offSetFDay) { - td.lastMonth = true; - DD = i + log.PDay; - // 上一年 - MM === 1 && (YY -= 1); - MM = MM === 1 ? 12 : MM - 1; - } else if (i >= offSetFDay && i < offSetFDay + MD[log.ymd[1]]) { - DD = i - offSetFDay + 1; - if (i - offSetFDay + 1 === log.ymd[2]) { - td.currentDay = true; - } - } else { - td.nextMonth = true; - DD = log.NDay++; - MM === 12 && (YY += 1); - MM = MM === 12 ? 1 : MM + 1; - } - if (BI.checkDateVoid(YY, MM, DD, mins, maxs)[0]) { - td.disabled = true; - } - td.text = DD; - items.push(td); - }); - return items; - }, - - _init: function () { - BI.Calendar.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var items = BI.map(this._getWeekLabel(), function (i, value) { - return { - type: "bi.label", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - text: value - }; - }); - var title = BI.createWidget({ - type: "bi.button_group", - height: 44, - items: items, - layouts: [{ - type: "bi.center", - hgap: 5, - vgap: 10 - }] - }); - - this.days = BI.createWidget({ - type: "bi.button_group", - items: BI.createItems(this._getItems(), {}), - value: o.year + "-" + o.month + "-" + o.day, - layouts: [BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { - columns: 7, - rows: 6, - columnSize: [1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7], - rowSize: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 8 - }))] - }); - this.days.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - BI.createWidget(BI.extend({ - element: this - - }, BI.LogicFactory.createLogic("vertical", BI.extend({}, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection("top", title, { - el: this.days, - tgap: -5 - }) - })))); - }, - - _getWeekLabel: function () { - return BI.map(BI.range(0, 7), function (idx, v) { - return BI.getShortDayName((v + BI.StartOfWeek) % 7); - }); - }, - - isFrontDate: function () { - var o = this.options, c = this._const; - var Y = o.year, M = o.month, De = BI.getDate(), day = De.getDay(); - Y = Y | 0; - De.setFullYear(Y, M, 1); - var newDate = BI.getOffsetDate(De, -1 * (day + 1)); - return !!BI.checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), o.min, o.max)[0]; - }, - - isFinalDate: function () { - var o = this.options, c = this._const; - var Y = o.year, M = o.month, De = BI.getDate(), day = De.getDay(); - Y = Y | 0; - De.setFullYear(Y, M, 1); - var newDate = BI.getOffsetDate(De, 42 - day); - return !!BI.checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), o.min, o.max)[0]; - }, - - _getItems: function () { - var o = this.options; - var days = this._dateCreator(o.year, o.month - 1, o.day); - var items = []; - items.push(days.slice(0, 7)); - items.push(days.slice(7, 14)); - items.push(days.slice(14, 21)); - items.push(days.slice(21, 28)); - items.push(days.slice(28, 35)); - items.push(days.slice(35, 42)); - - return BI.map(items, function (i, item) { - return BI.map(item, function (j, td) { - var month = td.lastMonth ? o.month - 1 : (td.nextMonth ? o.month + 1 : o.month); - var year = o.year; - if (month > 12) { - month = 1; - year++; - } else if (month < 1) { - month = 12; - year--; - } - return BI.extend(td, { - type: "bi.calendar_date_item", - once: false, - forceSelected: true, - value: year + "-" + month + "-" + td.text, - disabled: td.disabled, - cls: td.lastMonth || td.nextMonth ? "bi-tips" : "", - lgap: 2, - rgap: 2, - tgap: 4, - bgap: 4 - // selected: td.currentDay - }); - }); - }); - }, - - _populate: function() { - this.days.populate(this._getItems()); - }, - - setMinDate: function (minDate) { - var o = this.options; - if (BI.isNotEmptyString(o.min)) { - o.min = minDate; - this._populate(); - } - }, - - setMaxDate: function (maxDate) { - var o = this.options; - if (BI.isNotEmptyString(o.max)) { - o.max = maxDate; - this._populate(); - } - }, - - setValue: function (ob) { - this.days.setValue([ob.year + "-" + ob.month + "-" + ob.day]); - }, - - getValue: function () { - var date = this.days.getValue()[0].match(/\d+/g); - return { - year: date[0] | 0, - month: date[1] | 0, - day: date[2] | 0 - }; - } -}); - -BI.extend(BI.Calendar, { - getPageByDateJSON: function (json) { - var year = BI.getDate().getFullYear(); - var month = BI.getDate().getMonth(); - var page = (json.year - year) * 12; - page += json.month - 1 - month; - return page; - }, - getDateJSONByPage: function (v) { - var months = BI.getDate().getMonth(); - var page = v; - - // 对当前page做偏移,使到当前年初 - page = page + months; - - var year = BI.parseInt(page / 12); - if(page < 0 && page % 12 !== 0) { - year--; - } - var month = page >= 0 ? (page % 12) : ((12 + page % 12) % 12); - return { - year: BI.getDate().getFullYear() + year, - month: month + 1 - }; - } -}); - -BI.shortcut("bi.calendar", BI.Calendar); diff --git a/src/case/calendar/calendar.year.js b/src/case/calendar/calendar.year.js deleted file mode 100644 index 95fcaccdb..000000000 --- a/src/case/calendar/calendar.year.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Created by GUY on 2015/8/28. - * @class BI.YearCalendar - * @extends BI.Widget - */ -BI.YearCalendar = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - var conf = BI.YearCalendar.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-year-calendar", - behaviors: {}, - logic: { - dynamic: false - }, - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - year: null - }); - }, - - _yearCreator: function (Y) { - var o = this.options; - Y = Y | 0; - var start = BI.YearCalendar.getStartYear(Y); - var items = []; - // 对于年控件来说,只要传入的minDate和maxDate的year区间包含v就是合法的 - var startDate = BI.parseDateTime(o.min, "%Y-%X-%d"); - var endDate = BI.parseDateTime(o.max, "%Y-%X-%d"); - BI.each(BI.range(BI.YearCalendar.INTERVAL), function (i) { - var td = {}; - if (BI.checkDateVoid(start + i, 1, 1, BI.print(BI.getDate(startDate.getFullYear(), 0, 1), "%Y-%X-%d"), BI.print(BI.getDate(endDate.getFullYear(), 0, 1), "%Y-%X-%d"))[0]) { - td.disabled = true; - } - td.text = start + i; - items.push(td); - }); - return items; - }, - - _init: function () { - BI.YearCalendar.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.currentYear = BI.getDate().getFullYear(); - - this.years = BI.createWidget({ - type: "bi.button_group", - behaviors: o.behaviors, - items: BI.createItems(this._getItems(), {}), - layouts: [BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { - columns: 2, - rows: 6, - columnSize: [1 / 2, 1 / 2], - rowSize: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - })), { - type: "bi.center_adapt", - vgap: 2 - }] - }); - this.years.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic("vertical", BI.extend({}, o.logic, { - scrolly: true, - vgap: 5, - hgap: 6, - items: BI.LogicFactory.createLogicItemsByDirection("top", this.years) - })))); - }, - - isFrontYear: function () { - var o = this.options; - var Y = o.year; - Y = Y | 0; - return !!BI.checkDateVoid(BI.YearCalendar.getStartYear(Y) - 1, 1, 1, o.min, o.max)[0]; - }, - - isFinalYear: function () { - var o = this.options, c = this._const; - var Y = o.year; - Y = Y | 0; - return !!BI.checkDateVoid(BI.YearCalendar.getEndYear(Y) + 1, 1, 1, o.min, o.max)[0]; - }, - - _getItems: function () { - var o = this.options; - var years = this._yearCreator(o.year || this.currentYear); - - // 纵向排列年 - var len = years.length, tyears = BI.makeArray(len, ""); - var map = [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11]; - BI.each(years, function (i, y) { - tyears[i] = years[map[i]]; - }); - - var items = []; - items.push(tyears.slice(0, 2)); - items.push(tyears.slice(2, 4)); - items.push(tyears.slice(4, 6)); - items.push(tyears.slice(6, 8)); - items.push(tyears.slice(8, 10)); - items.push(tyears.slice(10, 12)); - - return BI.map(items, function (i, item) { - return BI.map(item, function (j, td) { - return BI.extend(td, { - type: "bi.text_item", - cls: "bi-list-item-select bi-border-radius", - textAlign: "center", - whiteSpace: "normal", - once: false, - forceSelected: true, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - width: 45, - value: td.text, - disabled: td.disabled - }); - }); - }); - }, - - _populate: function () { - this.years.populate(this._getItems()); - }, - - setMinDate: function (minDate) { - var o = this.options; - if (BI.isNotEmptyString(o.min)) { - o.min = minDate; - this._populate(); - } - }, - - setMaxDate: function (maxDate) { - var o = this.options; - if (BI.isNotEmptyString(this.options.max)) { - o.max = maxDate; - this._populate(); - } - }, - - setValue: function (val) { - this.years.setValue([val]); - }, - - getValue: function () { - return this.years.getValue()[0]; - } -}); -// 类方法 -BI.extend(BI.YearCalendar, { - INTERVAL: 12, - - // 获取显示的第一年 - getStartYear: function (year) { - var cur = BI.getDate().getFullYear(); - return year - ((year - cur + 3) % BI.YearCalendar.INTERVAL + 12) % BI.YearCalendar.INTERVAL; - }, - - getEndYear: function (year) { - return BI.YearCalendar.getStartYear(year) + BI.YearCalendar.INTERVAL - 1; - }, - - getPageByYear: function (year) { - var cur = BI.getDate().getFullYear(); - year = BI.YearCalendar.getStartYear(year); - return (year - cur + 3) / BI.YearCalendar.INTERVAL; - } -}); - -BI.shortcut("bi.year_calendar", BI.YearCalendar); diff --git a/src/case/checkbox/check.arrownode.js b/src/case/checkbox/check.arrownode.js deleted file mode 100644 index 3347f83d0..000000000 --- a/src/case/checkbox/check.arrownode.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Created by roy on 15/10/16. - * 右与下箭头切换的树节点 - */ -BI.ArrowTreeGroupNodeCheckbox = BI.inherit(BI.IconButton, { - - props: function (conf) { - return { - extraCls: "bi-arrow-group-node-checkbox " + (conf.collapseIcon || "expander-right-font"), - expandIcon: "expander-down-font", - collapseIcon: "expander-right-font" - }; - }, - - setSelected: function (v) { - var o = this.options; - BI.ArrowTreeGroupNodeCheckbox.superclass.setSelected.apply(this, arguments); - if(v) { - this.element.removeClass(o.collapseIcon).addClass(o.expandIcon); - } else { - this.element.removeClass(o.expandIcon).addClass(o.collapseIcon); - } - } -}); -BI.shortcut("bi.arrow_group_node_checkbox", BI.ArrowTreeGroupNodeCheckbox); diff --git a/src/case/checkbox/check.checkingmarknode.js b/src/case/checkbox/check.checkingmarknode.js deleted file mode 100644 index b3996691e..000000000 --- a/src/case/checkbox/check.checkingmarknode.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 十字型的树节点 - * @class BI.CheckingMarkNode - * @extends BI.IconButton - */ -BI.CheckingMarkNode = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - return BI.extend( BI.CheckingMarkNode.superclass._defaultConfig.apply(this, arguments), { - }); - }, - - setSelected: function (v) { - BI.CheckingMarkNode.superclass.setSelected.apply(this, arguments); - if(v === true) { - this.element.addClass("check-mark-font"); - } else { - this.element.removeClass("check-mark-font"); - } - } -}); -BI.shortcut("bi.checking_mark_node", BI.CheckingMarkNode); diff --git a/src/case/checkbox/check.first.treenode.js b/src/case/checkbox/check.first.treenode.js deleted file mode 100644 index aa808488f..000000000 --- a/src/case/checkbox/check.first.treenode.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 十字型的树节点 - * @class BI.FirstTreeNodeCheckbox - * @extends BI.IconButton - */ -BI.FirstTreeNodeCheckbox = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - return BI.extend( BI.FirstTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { - extraCls: BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-solid-collapse-icon-type2" : "tree-collapse-icon-type2", - iconWidth: 24, - iconHeight: 24 - }); - }, - - getLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "tree-solid-expand-icon-type2"; - default: - return "tree-expand-icon-type2"; - } - }, - - setSelected: function (v) { - BI.FirstTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); - if(v === true) { - this.element.addClass(this.getLineCls()); - } else { - this.element.removeClass(this.getLineCls()); - } - } -}); -BI.shortcut("bi.first_tree_node_checkbox", BI.FirstTreeNodeCheckbox); \ No newline at end of file diff --git a/src/case/checkbox/check.last.treenode.js b/src/case/checkbox/check.last.treenode.js deleted file mode 100644 index cb536f8cc..000000000 --- a/src/case/checkbox/check.last.treenode.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 十字型的树节点 - * @class BI.LastTreeNodeCheckbox - * @extends BI.IconButton - */ -BI.LastTreeNodeCheckbox = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - return BI.extend(BI.LastTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { - extraCls: BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-solid-collapse-icon-type4" : "tree-collapse-icon-type4", - iconWidth: 24, - iconHeight: 24 - }); - }, - - getLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "tree-solid-expand-icon-type4"; - default: - return "tree-expand-icon-type4"; - } - }, - - setSelected: function (v) { - BI.LastTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); - if (v === true) { - this.element.addClass(this.getLineCls()); - } else { - this.element.removeClass(this.getLineCls()); - } - } -}); -BI.shortcut("bi.last_tree_node_checkbox", BI.LastTreeNodeCheckbox); \ No newline at end of file diff --git a/src/case/checkbox/check.mid.treenode.js b/src/case/checkbox/check.mid.treenode.js deleted file mode 100644 index 7ec4e5230..000000000 --- a/src/case/checkbox/check.mid.treenode.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 十字型的树节点 - * @class BI.MidTreeNodeCheckbox - * @extends BI.IconButton - */ -BI.MidTreeNodeCheckbox = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - return BI.extend( BI.MidTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { - extraCls: BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-solid-collapse-icon-type3" : "tree-collapse-icon-type3", - iconWidth: 24, - iconHeight: 24 - }); - }, - - getLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "tree-solid-expand-icon-type3"; - default: - return "tree-expand-icon-type3"; - } - }, - - setSelected: function (v) { - BI.MidTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); - if(v === true) { - this.element.addClass(this.getLineCls()); - } else { - this.element.removeClass(this.getLineCls()); - } - } -}); -BI.shortcut("bi.mid_tree_node_checkbox", BI.MidTreeNodeCheckbox); \ No newline at end of file diff --git a/src/case/checkbox/check.treenode.js b/src/case/checkbox/check.treenode.js deleted file mode 100644 index 128bb73c6..000000000 --- a/src/case/checkbox/check.treenode.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 十字型的树节点 - * @class BI.TreeNodeCheckbox - * @extends BI.IconButton - */ -BI.TreeNodeCheckbox = BI.inherit(BI.IconButton, { - _defaultConfig: function () { - return BI.extend( BI.TreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { - extraCls: BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "tree-solid-collapse-icon-type1" : "tree-collapse-icon-type1", - iconWidth: 24, - iconHeight: 24 - }); - }, - - getLineCls: function () { - switch (BI.STYLE_CONSTANTS.LINK_LINE_TYPE) { - case "solid": - return "tree-solid-expand-icon-type1"; - default: - return "tree-expand-icon-type1"; - } - }, - - setSelected: function (v) { - BI.TreeNodeCheckbox.superclass.setSelected.apply(this, arguments); - if(v) { - this.element.addClass(this.getLineCls()); - } else { - this.element.removeClass(this.getLineCls()); - } - } -}); -BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox); \ No newline at end of file diff --git a/src/case/colorchooser/colorchooser.custom.js b/src/case/colorchooser/colorchooser.custom.js deleted file mode 100644 index c34d92500..000000000 --- a/src/case/colorchooser/colorchooser.custom.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 自定义选色 - * - * Created by GUY on 2015/11/17. - * @class BI.CustomColorChooser - * @extends BI.Widget - */ -BI.CustomColorChooser = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.CustomColorChooser.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-custom-color-chooser", - width: 292, - height: 265 - }); - }, - - _init: function () { - BI.CustomColorChooser.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.editor, { - type: "bi.simple_hex_color_picker_editor", - value: o.value - }); - this.editor.on(BI.ColorPickerEditor.EVENT_CHANGE, function () { - self.setValue(this.getValue()); - }); - this.farbtastic = BI.createWidget({ - type: "bi.farbtastic", - value: o.value - }); - this.farbtastic.on(BI.Farbtastic.EVENT_CHANGE, function () { - self.setValue(this.getValue()); - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - type: "bi.absolute", - items: [{ - el: this.editor, - left: 10, - top: 0, - right: 10 - }], - height: 50 - }, { - type: "bi.absolute", - items: [{ - el: this.farbtastic, - left: 46, - right: 46, - top: 7 - }], - height: 215 - }] - }); - }, - - setValue: function (color) { - this.editor.setValue(color); - this.farbtastic.setValue(color); - }, - - getValue: function () { - return this.editor.getValue(); - } -}); -BI.CustomColorChooser.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.custom_color_chooser", BI.CustomColorChooser); diff --git a/src/case/colorchooser/colorchooser.js b/src/case/colorchooser/colorchooser.js deleted file mode 100644 index 218ea56b0..000000000 --- a/src/case/colorchooser/colorchooser.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 选色控件 - * - * Created by GUY on 2015/11/17. - * @class BI.ColorChooser - * @extends BI.Widget - */ -BI.ColorChooser = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.ColorChooser.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-color-chooser", - value: "", - height: 24, - el: {}, - simple: false - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.ColorChooser.superclass._init.apply(this, arguments); - o.value = (o.value || "").toLowerCase(); - this.combo = BI.createWidget({ - type: "bi.combo", - element: this, - container: o.container, - adjustLength: 1, - destroyWhenHide: o.destroyWhenHide, - isNeedAdjustWidth: false, - isNeedAdjustHeight: false, - el: BI.extend({ - type: o.width <= 24 ? "bi.color_chooser_trigger" : "bi.long_color_chooser_trigger", - simple: o.simple, - ref: function (_ref) { - self.trigger = _ref; - }, - value: o.value, - width: o.el.type ? o.width : BI.toPix(o.width, 2), - height: o.el.type ? o.height : BI.toPix(o.height, 2) - }, o.el), - popup: () => ({ - el: BI.extend({ - type: "bi.hex_color_chooser_popup", - recommendColorsGetter: o.recommendColorsGetter, - ref: function (_ref) { - self.colorPicker = _ref; - }, - listeners: [{ - eventName: BI.ColorChooserPopup.EVENT_VALUE_CHANGE, - action: function () { - fn(); - if (!self._isRGBColor(self.colorPicker.getValue())) { - self.combo.hideView(); - } - } - }, { - eventName: BI.ColorChooserPopup.EVENT_CHANGE, - action: function () { - fn(); - self.combo.hideView(); - } - }] - }, o.popup), - value: o.value, - width: 300 - }), - value: o.value - }); - - var fn = function () { - var color = self.colorPicker.getValue(); - self.setValue(color); - }; - - this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { - self.fireEvent(BI.ColorChooser.EVENT_CHANGE, arguments); - }); - this.combo.on(BI.Combo.EVENT_AFTER_POPUPVIEW, function () { - self.fireEvent(BI.ColorChooser.EVENT_AFTER_POPUPVIEW, arguments); - }); - }, - - _isRGBColor: function (color) { - return BI.isNotEmptyString(color) && color !== "transparent"; - }, - - isViewVisible: function () { - return this.combo.isViewVisible(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - showView: function () { - this.combo.showView(); - }, - - setValue: function (color) { - this.options.value = (color || "").toLowerCase(); - this.combo.setValue(this.options.value); - }, - - getValue: function () { - return this.combo.getValue(); - } -}); -BI.ColorChooser.EVENT_CHANGE = "EVENT_CHANGE"; -BI.ColorChooser.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.shortcut("bi.color_chooser", BI.ColorChooser); diff --git a/src/case/colorchooser/colorchooser.popup.hex.js b/src/case/colorchooser/colorchooser.popup.hex.js deleted file mode 100644 index b8c98cb36..000000000 --- a/src/case/colorchooser/colorchooser.popup.hex.js +++ /dev/null @@ -1,281 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/11/10 - */ -BI.HexColorChooserPopup = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-color-chooser-popup", - width: 300, - recommendColorsGetter: BI.emptyFn, // 推荐色获取接口 - simple: false // 简单模式, popup中没有自动和透明 - }, - - render: function () { - var self = this, o = this.options; - var hasRecommendColors = BI.isNotNull(o.recommendColorsGetter()); - return [{ - type: "bi.vertical", - items: [{ - el: { - type: "bi.vertical", - hgap: 15, - items: [BI.extend({ - type: o.simple ? "bi.simple_hex_color_picker_editor" : "bi.hex_color_picker_editor", - value: o.value, - height: o.simple ? 36 : 70, - listeners: [{ - eventName: BI.ColorPickerEditor.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_VALUE_CHANGE, arguments); - } - }], - ref: function (_ref) { - self.colorEditor = _ref; - } - }, o.editor), { - el: { - type: "bi.hex_color_picker", - cls: "bi-border-bottom bi-border-right", - items: [this._digestStoreColors(this._getStoreColors())], - height: 22, - value: o.value, - listeners: [{ - eventName: BI.ColorPicker.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()[0]); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - } - }], - ref: function (_ref) { - self.storeColors = _ref; - } - }, - tgap: 10, - height: 22 - }, { - el: hasRecommendColors ? { - type: "bi.vertical", - items: [{ - type: "bi.label", - text: BI.i18nText("BI-Basic_Recommend_Color"), - textAlign: "left", - height: 24 - }, { - type: "bi.hex_color_picker", - cls: "bi-border-bottom bi-border-right", - items: [this._digestStoreColors(o.recommendColorsGetter())], - height: 22, - value: o.value, - listeners: [{ - eventName: BI.ColorPicker.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()[0]); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - } - }], - ref: function (_ref) { - self.recommendColors = _ref; - } - }] - } : {type: "bi.layout"}, - tgap: hasRecommendColors ? 10 : 0, - height: hasRecommendColors ? 47 : 0 - }, { - el: { - type: "bi.layout", - cls: "bi-border-top" - }, - vgap: 10, - height: 1 - }, { - type: "bi.absolute", - items: [{ - el: { - type: "bi.hex_color_picker", - space: true, - value: o.value, - listeners: [{ - eventName: BI.ColorPicker.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()[0]); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - } - }], - ref: function (_ref) { - self.colorPicker = _ref; - } - }, - top: 0, - left: 0, - right: 0, - bottom: 1 - }], - height: 80 - }] - } - }, { - el: { - type: "bi.combo", - cls: "bi-border-top", - container: null, - direction: "right,top", - isNeedAdjustHeight: false, - el: { - type: "bi.text_item", - cls: "color-chooser-popup-more bi-list-item", - textAlign: "center", - height: 24, - textLgap: 10, - text: BI.i18nText("BI-Basic_More") + "..." - }, - popup: { - type: "bi.popup_panel", - buttons: [BI.i18nText("BI-Basic_Cancel"), BI.i18nText("BI-Basic_Save")], - title: BI.i18nText("BI-Custom_Color"), - el: { - type: "bi.custom_color_chooser", - value: o.value, - editor: o.editor, - ref: function (_ref) { - self.customColorChooser = _ref; - } - }, - stopPropagation: false, - bgap: -1, - rgap: 1, - lgap: 1, - minWidth: 227, - listeners: [{ - eventName: BI.PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON, - action: function (index) { - switch (index) { - case 0: - self.more.hideView(); - break; - case 1: - var color = self.customColorChooser.getValue(); - // farbtastic选择器没有透明和自动选项,点击保存不应该设置透明 - if (BI.isNotEmptyString(color)) { - self.setValue(color); - self._dealStoreColors(); - } - self.more.hideView(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - break; - } - } - }] - }, - listeners: [{ - eventName: BI.Combo.EVENT_AFTER_POPUPVIEW, - action: function () { - self.customColorChooser.setValue(self.getValue()); - } - }], - ref: function (_ref) { - self.more = _ref; - } - }, - tgap: 10, - height: 24 - }] - }, { - type: "bi.absolute", - items: [{ - el: { - type: "bi.layout", - cls: "disable-mask", - invisible: !o.disabled, - ref: function () { - self.mask = this; - } - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }]; - }, - - // 这里就实现的不好了,setValue里面有个editor,editor的setValue会检测错误然后出bubble提示 - mounted: function () { - var o = this.options; - if (BI.isNotNull(o.value)) { - this.setValue(o.value); - } - }, - - _setEnable: function (enable) { - BI.ColorChooserPopup.superclass._setEnable.apply(this, arguments); - this.mask.setVisible(!enable); - }, - - _dealStoreColors: function () { - var color = this.getValue(); - var colors = this._getStoreColors(); - var que = new BI.Queue(12); - que.fromArray(colors); - que.remove(color); - que.unshift(color); - var array = que.toArray(); - BI.Cache.setItem("colors", BI.array2String(array)); - this.setStoreColors(array); - }, - - _digestStoreColors: function (colors) { - var items = BI.map(colors.slice(0, 12), function (i, color) { - return { - value: color - }; - }); - BI.count(colors.length, 12, function (i) { - items.push({ - value: "empty", - disabled: true - }); - }); - return items; - }, - - _getStoreColors: function () { - var self = this, o = this.options; - var colorsArray = BI.string2Array(BI.Cache.getItem("colors") || ""); - return BI.filter(colorsArray, function (idx, color) { - return o.simple ? self._isRGBColor(color) : true; - }); - }, - - _isRGBColor: function (color) { - return BI.isNotEmptyString(color) && color !== "transparent"; - }, - - setStoreColors: function (colors) { - if (BI.isArray(colors)) { - this.storeColors.populate([this._digestStoreColors(colors)]); - // BI-66973 选中颜色的同时选中历史 - this.storeColors.setValue(this.getValue()); - } - }, - - setValue: function (color) { - this.colorEditor.setValue(color); - this.colorPicker.setValue(color); - this.storeColors.setValue(color); - this.recommendColors && this.recommendColors.setValue(color); - }, - - getValue: function () { - return this.colorEditor.getValue(); - } -}); -BI.HexColorChooserPopup.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.HexColorChooserPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.hex_color_chooser_popup", BI.HexColorChooserPopup); diff --git a/src/case/colorchooser/colorchooser.popup.hex.simple.js b/src/case/colorchooser/colorchooser.popup.hex.simple.js deleted file mode 100644 index 628ad6f02..000000000 --- a/src/case/colorchooser/colorchooser.popup.hex.simple.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/11/10 - */ -BI.SimpleHexColorChooserPopup = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-color-chooser-popup", - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.hex_color_chooser_popup", - recommendColorsGetter: o.recommendColorsGetter, - value: o.value, - simple: true, // 是否有自动 - listeners: [{ - eventName: BI.ColorChooserPopup.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.SimpleColorChooserPopup.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.ColorChooserPopup.EVENT_VALUE_CHANGE, - action: function () { - self.fireEvent(BI.SimpleColorChooserPopup.EVENT_VALUE_CHANGE, arguments); - } - }], - ref: function (_ref) { - self.popup = _ref; - } - } - }, - - setStoreColors: function (colors) { - this.popup.setStoreColors(colors); - }, - - setValue: function (color) { - this.popup.setValue(color); - }, - - getValue: function () { - return this.popup.getValue(); - } -}); -BI.SimpleHexColorChooserPopup.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.SimpleHexColorChooserPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.simple_hex_color_chooser_popup", BI.SimpleHexColorChooserPopup); \ No newline at end of file diff --git a/src/case/colorchooser/colorchooser.popup.js b/src/case/colorchooser/colorchooser.popup.js deleted file mode 100644 index c73fd91fc..000000000 --- a/src/case/colorchooser/colorchooser.popup.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * 选色控件 - * - * Created by GUY on 2015/11/17. - * @class BI.ColorChooserPopup - * @extends BI.Widget - */ -BI.ColorChooserPopup = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-color-chooser-popup", - width: 230, - height: 145, - simple: false // 简单模式, popup中没有自动和透明 - }, - - render: function () { - var self = this, o = this.options; - this.colorEditor = BI.createWidget(o.editor, { - type: o.simple ? "bi.simple_color_picker_editor" : "bi.color_picker_editor", - value: o.value, - cls: "bi-header-background bi-border-bottom", - height: 30 - }); - - this.colorEditor.on(BI.ColorPickerEditor.EVENT_CHANGE, function () { - self.setValue(this.getValue()); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_VALUE_CHANGE, arguments); - }); - - this.storeColors = BI.createWidget({ - type: "bi.color_picker", - cls: "bi-border-bottom bi-border-right", - items: [this._digestStoreColors(this._getStoreColors())], - width: 210, - height: 24, - value: o.value - }); - this.storeColors.on(BI.ColorPicker.EVENT_CHANGE, function () { - self.setValue(this.getValue()[0]); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - }); - - this.colorPicker = BI.createWidget({ - type: "bi.color_picker", - width: 210, - height: 50, - value: o.value - }); - - this.colorPicker.on(BI.ColorPicker.EVENT_CHANGE, function () { - self.setValue(this.getValue()[0]); - self._dealStoreColors(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - }); - - this.customColorChooser = BI.createWidget({ - type: "bi.custom_color_chooser", - editor: o.editor - }); - - var panel = BI.createWidget({ - type: "bi.popup_panel", - buttons: [BI.i18nText("BI-Basic_Cancel"), BI.i18nText("BI-Basic_Save")], - title: BI.i18nText("BI-Custom_Color"), - el: this.customColorChooser, - stopPropagation: false, - bgap: -1, - rgap: 1, - lgap: 1, - minWidth: 227 - }); - - this.more = BI.createWidget({ - type: "bi.combo", - cls: "bi-border-top", - container: null, - direction: "right,top", - isNeedAdjustHeight: false, - el: { - type: "bi.text_item", - cls: "color-chooser-popup-more bi-list-item", - textAlign: "center", - height: 24, - textLgap: 10, - text: BI.i18nText("BI-Basic_More") + "..." - }, - popup: panel - }); - - this.more.on(BI.Combo.EVENT_AFTER_POPUPVIEW, function () { - self.customColorChooser.setValue(self.getValue()); - }); - panel.on(BI.PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.more.hideView(); - break; - case 1: - self.setValue(self.customColorChooser.getValue()); - self._dealStoreColors(); - self.more.hideView(); - self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); - break; - } - }); - - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.vtape", - items: [this.colorEditor, { - el: { - type: "bi.absolute", - items: [{ - el: this.storeColors, - left: 10, - right: 10, - top: 5 - }] - }, - height: 29 - }, { - el: { - type: "bi.absolute", - items: [{ - el: this.colorPicker, - left: 10, - right: 10, - top: 5, - bottom: 5 - }] - }, - height: 60 - }, { - el: this.more, - height: 24 - }] - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.layout", - cls: "disable-mask", - invisible: !o.disabled, - ref: function () { - self.mask = this; - } - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }; - }, - - // 这里就实现的不好了,setValue里面有个editor,editor的setValue会检测错误然后出bubble提示 - mounted: function () { - var self = this; - var o = this.options; - if (BI.isNotNull(o.value)) { - this.setValue(o.value); - } - }, - - _setEnable: function (enable) { - BI.ColorChooserPopup.superclass._setEnable.apply(this, arguments); - this.mask.setVisible(!enable); - }, - - _dealStoreColors: function () { - var color = this.getValue(); - var colors = this._getStoreColors(); - var que = new BI.Queue(8); - que.fromArray(colors); - que.remove(color); - que.unshift(color); - var array = que.toArray(); - BI.Cache.setItem("colors", BI.array2String(array)); - this.setStoreColors(array); - }, - - _digestStoreColors: function (colors) { - var items = BI.map(colors, function (i, color) { - return { - value: color - }; - }); - BI.count(colors.length, 8, function (i) { - items.push({ - value: "", - disabled: true - }); - }); - return items; - }, - - _getStoreColors: function() { - var self = this, o = this.options; - var colorsArray = BI.string2Array(BI.Cache.getItem("colors") || ""); - return BI.filter(colorsArray, function (idx, color) { - return o.simple ? self._isRGBColor(color) : true; - }); - }, - - _isRGBColor: function (color) { - return BI.isNotEmptyString(color) && color !== "transparent"; - }, - - setStoreColors: function (colors) { - if (BI.isArray(colors)) { - this.storeColors.populate([this._digestStoreColors(colors)]); - // BI-66973 选中颜色的同时选中历史 - this.storeColors.setValue(this.getValue()); - } - }, - - setValue: function (color) { - this.colorEditor.setValue(color); - this.colorPicker.setValue(color); - this.storeColors.setValue(color); - }, - - getValue: function () { - return this.colorEditor.getValue(); - } -}); -BI.ColorChooserPopup.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.ColorChooserPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_chooser_popup", BI.ColorChooserPopup); diff --git a/src/case/colorchooser/colorchooser.popup.simple.js b/src/case/colorchooser/colorchooser.popup.simple.js deleted file mode 100644 index 54b34cec4..000000000 --- a/src/case/colorchooser/colorchooser.popup.simple.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * 选色控件 - * - * Created by GUY on 2015/11/17. - * @class BI.SimpleColorChooserPopup - * @extends BI.Widget - */ -BI.SimpleColorChooserPopup = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SimpleColorChooserPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-color-chooser-popup" - }); - }, - - _init: function () { - BI.SimpleColorChooserPopup.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.popup = BI.createWidget({ - type: o.hex ? "bi.hex_color_chooser_popup" : "bi.color_chooser_popup", - value: o.value, - element: this, - simple: true // 是否有自动 - }); - this.popup.on(BI.ColorChooserPopup.EVENT_CHANGE, function () { - self.fireEvent(BI.SimpleColorChooserPopup.EVENT_CHANGE, arguments); - }); - this.popup.on(BI.ColorChooserPopup.EVENT_VALUE_CHANGE, function () { - self.fireEvent(BI.SimpleColorChooserPopup.EVENT_VALUE_CHANGE, arguments); - }); - }, - - setStoreColors: function (colors) { - this.popup.setStoreColors(colors); - }, - - setValue: function (color) { - this.popup.setValue(color); - }, - - getValue: function () { - return this.popup.getValue(); - } -}); -BI.SimpleColorChooserPopup.EVENT_VALUE_CHANGE = "EVENT_VALUE_CHANGE"; -BI.SimpleColorChooserPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.simple_color_chooser_popup", BI.SimpleColorChooserPopup); \ No newline at end of file diff --git a/src/case/colorchooser/colorchooser.simple.js b/src/case/colorchooser/colorchooser.simple.js deleted file mode 100644 index 28517ea6d..000000000 --- a/src/case/colorchooser/colorchooser.simple.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 简单选色控件,没有自动和透明 - * - * Created by GUY on 2015/11/17. - * @class BI.SimpleColorChooser - * @extends BI.Widget - */ -BI.SimpleColorChooser = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SimpleColorChooser.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-simple-color-chooser", - value: "#ffffff" - }); - }, - - _init: function () { - BI.SimpleColorChooser.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.combo = BI.createWidget({ - type: "bi.color_chooser", - simple: o.simple, - element: this, - container: o.container, - value: o.value, - width: o.width, - height: o.height, - destroyWhenHide: o.destroyWhenHide, - popup: { - type: "bi.simple_hex_color_chooser_popup", - recommendColorsGetter: o.recommendColorsGetter, - } - }); - this.combo.on(BI.ColorChooser.EVENT_CHANGE, function () { - self.fireEvent(BI.SimpleColorChooser.EVENT_CHANGE, arguments); - }); - this.combo.on(BI.ColorChooser.EVENT_AFTER_POPUPVIEW, function () { - self.fireEvent(BI.SimpleColorChooser.EVENT_AFTER_POPUPVIEW, arguments); - }); - }, - - isViewVisible: function () { - return this.combo.isViewVisible(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - showView: function () { - this.combo.showView(); - }, - - setValue: function (color) { - this.combo.setValue(color); - }, - - getValue: function () { - return this.combo.getValue(); - } -}); -BI.SimpleColorChooser.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SimpleColorChooser.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.shortcut("bi.simple_color_chooser", BI.SimpleColorChooser); diff --git a/src/case/colorchooser/colorchooser.trigger.js b/src/case/colorchooser/colorchooser.trigger.js deleted file mode 100644 index af2039226..000000000 --- a/src/case/colorchooser/colorchooser.trigger.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 选色控件 - * - * Created by GUY on 2015/11/17. - * @class BI.ColorChooserTrigger - * @extends BI.Trigger - */ -BI.ColorChooserTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function (config) { - var conf = BI.ColorChooserTrigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-color-chooser-trigger bi-focus-shadow " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 22 - }); - }, - - _init: function () { - BI.ColorChooserTrigger.superclass._init.apply(this, arguments); - this.colorContainer = BI.createWidget({ - type: "bi.layout", - cls: "color-chooser-trigger-content" + (BI.isIE9Below && BI.isIE9Below() ? " hack" : "") - }); - - var down = BI.createWidget({ - type: "bi.icon_button", - disableSelected: true, - cls: "icon-combo-down-icon trigger-triangle-font icon-size-12", - width: 12, - height: 8 - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.colorContainer, - left: 2, - right: 2, - top: 2, - bottom: 2 - }, { - el: down, - right: -1, - bottom: 1 - }] - }); - if (BI.isNotNull(this.options.value)) { - this.setValue(this.options.value); - } - }, - - setValue: function (color) { - BI.ColorChooserTrigger.superclass.setValue.apply(this, arguments); - if (color === "") { - this.colorContainer.element.css("background-color", "").removeClass("trans-color-background").addClass("auto-color-background"); - } else if (color === "transparent") { - this.colorContainer.element.css("background-color", "").removeClass("auto-color-background").addClass("trans-color-background"); - } else { - this.colorContainer.element.css({"background-color": color}).removeClass("auto-color-background").removeClass("trans-color-background"); - } - } -}); -BI.ColorChooserTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_chooser_trigger", BI.ColorChooserTrigger); diff --git a/src/case/colorchooser/colorchooser.trigger.long.js b/src/case/colorchooser/colorchooser.trigger.long.js deleted file mode 100644 index 773b3d326..000000000 --- a/src/case/colorchooser/colorchooser.trigger.long.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * 选色控件 - * - * Created by GUY on 2015/11/17. - * @class BI.LongColorChooserTrigger - * @extends BI.Trigger - */ -BI.LongColorChooserTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function (config) { - var conf = BI.LongColorChooserTrigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-color-chooser-trigger bi-focus-shadow " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24 - }); - }, - - _init: function () { - BI.LongColorChooserTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.colorContainer = BI.createWidget({ - type: "bi.htape", - cls: "color-chooser-trigger-content", - items: [{ - type: "bi.icon_change_button", - ref: function (_ref) { - self.changeIcon = _ref; - }, - disableSelected: true, - iconCls: "auto-color-icon", - width: 24, - iconWidth: 16, - iconHeight: 16 - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.label = _ref; - }, - textAlign: "left", - hgap: 5, - height: 18, - text: BI.i18nText("BI-Basic_Auto") - } - }] - }); - - var down = BI.createWidget({ - type: "bi.icon_button", - disableSelected: true, - cls: "icon-combo-down-icon trigger-triangle-font icon-size-12", - width: 12, - height: 8 - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.colorContainer, - left: 2, - right: 2, - top: 2, - bottom: 2 - }, { - el: down, - right: 3, - bottom: 3 - }] - }); - if (this.options.value) { - this.setValue(this.options.value); - } - }, - - setValue: function (color) { - BI.LongColorChooserTrigger.superclass.setValue.apply(this, arguments); - if (color === "") { - this.colorContainer.element.css("background-color", ""); - this.changeIcon.setVisible(true); - this.label.setVisible(true); - this.changeIcon.setIcon("auto-color-icon"); - this.label.setText(BI.i18nText("BI-Basic_Auto")); - } else if (color === "transparent") { - this.colorContainer.element.css("background-color", ""); - this.changeIcon.setVisible(true); - this.label.setVisible(true); - this.changeIcon.setIcon("trans-color-icon"); - this.label.setText(BI.i18nText("BI-Transparent_Color")); - } else { - this.colorContainer.element.css({"background-color": color}); - this.changeIcon.setVisible(false); - this.label.setVisible(false); - } - } -}); -BI.LongColorChooserTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.long_color_chooser_trigger", BI.LongColorChooserTrigger); diff --git a/src/case/colorchooser/colorpicker/button/button.colorpicker.js b/src/case/colorchooser/colorpicker/button/button.colorpicker.js deleted file mode 100644 index d3ebf5300..000000000 --- a/src/case/colorchooser/colorpicker/button/button.colorpicker.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 简单选色控件按钮 - * - * Created by GUY on 2015/11/16. - * @class BI.ColorPickerButton - * @extends BI.BasicButton - */ -BI.ColorPickerButton = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.ColorPickerButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-color-picker-button bi-background bi-border-top bi-border-left" - }); - }, - - _init: function () { - BI.ColorPickerButton.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.value)) { - if (o.value === '') { - this.element.addClass("auto-color-no-square-normal-background"); - } else if (o.value === "transparent") { - this.element.addClass("trans-color-background"); - } else { - this.element.css("background-color", o.value); - } - var name = this.getName(); - this.element.hover(function () { - self._createMask(); - if (self.isEnabled()) { - BI.Maskers.show(name); - } - }, function () { - if (!self.isSelected()) { - BI.Maskers.hide(name); - } - }); - } - }, - - _createMask: function () { - var o = this.options, name = this.getName(); - if (this.isEnabled() && !BI.Maskers.has(name)) { - var w = BI.Maskers.make(name, this, { - offset: { - left: -1, - top: -1, - right: -1, - bottom: -1 - } - }); - w.element.addClass("color-picker-button-mask").css("background-color", o.value); - } - }, - - setSelected: function (b) { - BI.ColorPickerButton.superclass.setSelected.apply(this, arguments); - if (b) { - this._createMask(); - } - BI.Maskers[b ? "show" : "hide"](this.getName()); - } -}); -BI.ColorPickerButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_picker_button", BI.ColorPickerButton); \ No newline at end of file diff --git a/src/case/colorchooser/colorpicker/button/button.colorshow.js b/src/case/colorchooser/colorpicker/button/button.colorshow.js deleted file mode 100644 index c9b2da438..000000000 --- a/src/case/colorchooser/colorpicker/button/button.colorshow.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/7/28 - */ -BI.ColorChooserShowButton = BI.inherit(BI.BasicButton, { - - props: { - baseCls: 'bi-color-chooser-show-button bi-border bi-list-item-effect bi-border-radius', - }, - - render: function () { - var self = this, o = this.options; - return { - type: 'bi.htape', - items: [ - { - el: { - type: "bi.icon_label", - ref: function (_ref) { - self.icon = _ref; - }, - iconWidth: 16, - iconHeight: 16, - }, - hgap: 20, - width: 16, - }, { - type: 'bi.label', - textAlign: 'left', - text: o.text, - } - ] - }; - }, - - doClick: function () { - BI.ColorChooserShowButton.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.ColorChooserShowButton.EVENT_CHANGE, this); - } - }, -}); -BI.ColorChooserShowButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_picker_show_button", BI.ColorChooserShowButton); diff --git a/src/case/colorchooser/colorpicker/colorpicker.hex.js b/src/case/colorchooser/colorpicker/colorpicker.hex.js deleted file mode 100644 index 8154b9c23..000000000 --- a/src/case/colorchooser/colorpicker/colorpicker.hex.js +++ /dev/null @@ -1,223 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/7/28 - */ -BI.HexColorPicker = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-hex-color-picker", - items: null, - }, - - _items: [ - [ - { - "value": "#999999" - }, - { - "value": "#FFFFFF" - }, - { - "value": "#FFE5E5" - }, - { - "value": "#FFF1E5" - }, - { - "value": "#FFF9E5" - }, - { - "value": "#E9F5E9" - }, - { - "value": "#EAEEFF" - }, - { - "value": "#EFEBF7" - }, - { - "value": "#FCE8EF" - } - ], - [ - { - "value": "#737373" - }, - { - "value": "#F2F2F2" - }, - { - "value": "#FFA6A6" - }, - { - "value": "#FFD0A6" - }, - { - "value": "#FFEDA6" - }, - { - "value": "#B3DCB2" - }, - { - "value": "#B9C6FF" - }, - { - "value": "#CABAE6" - }, - { - "value": "#F8B1C9" - } - ], - [ - { - "value": "#4C4C4C" - }, - { - "value": "#D9D9D9" - }, - { - "value": "#FF5959" - }, - { - "value": "#FFA759" - }, - { - "value": "#FFDD59" - }, - { - "value": "#7EBE70" - }, - { - "value": "#7B95FF" - }, - { - "value": "#9C7FD0" - }, - { - "value": "#F06D99" - } - ], - [ - { - "value": "#262626" - }, - { - "value": "#BFBFBF" - }, - { - "value": "#FF0000" - }, - { - "value": "#FF7800" - }, - { - "value": "#FFCB00" - }, - { - "value": "#259B23" - }, - { - "value": "#355CFF" - }, - { - "value": "#673AB7" - }, - { - "value": "#E91E63" - } - ], - [ - { - "value": "#000000" - }, - { - "value": "#A6A6A6" - }, - { - "value": "#A80000" - }, - { - "value": "#B65600" - }, - { - "value": "#CEB000" - }, - { - "value": "#0E550C" - }, - { - "value": "#09269C" - }, - { - "value": "#3A1A73" - }, - { - "value": "#B30072" - } - ] - ], - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.button_group", - items: this._digest(o.items || this._items), - layouts: [ - { - type: "bi.grid", - } - ], - value: o.value, - listeners: [ - { - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.HexColorPicker.EVENT_CHANGE, arguments); - } - } - ], - ref: function (_ref) { - self.colors = _ref; - } - }; - }, - - _digest: function (items) { - var o = this.options; - var blocks = []; - BI.each(items, function (idx, row) { - var bRow = []; - BI.each(row, function (idx, item) { - bRow.push(BI.extend({ - type: "bi.color_picker_button", - once: false, - cls: o.space ? 'bi-border-right' : '', - }, item)); - if (o.space && idx < row.length - 1) { - bRow.push({ type: 'bi.layout' }); - } - }); - blocks.push(bRow); - }); - - return blocks; - }, - - populate: function (items) { - var args = [].slice.call(arguments); - args[0] = this._digest(items); - this.colors.populate.apply(this.colors, args); - }, - - setValue: function (color) { - this.colors.setValue(color); - }, - - getValue: function () { - return this.colors.getValue(); - } -}); -BI.HexColorPicker.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.hex_color_picker", BI.HexColorPicker); diff --git a/src/case/colorchooser/colorpicker/colorpicker.js b/src/case/colorchooser/colorpicker/colorpicker.js deleted file mode 100644 index 54a827400..000000000 --- a/src/case/colorchooser/colorpicker/colorpicker.js +++ /dev/null @@ -1,190 +0,0 @@ -/** - * 简单选色控件 - * - * Created by GUY on 2015/11/16. - * @class BI.ColorPicker - * @extends BI.Widget - */ -BI.ColorPicker = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.ColorPicker.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-color-picker", - items: null - }); - }, - - _items: [ - [{ - value: "#ffffff" - }, { - value: "#f2f2f2" - }, { - value: "#e5e5e5" - }, { - value: "#d9d9d9" - }, { - value: "#cccccc" - }, { - value: "#bfbfbf" - }, { - value: "#b2b2b2" - }, { - value: "#a6a6a6" - }, { - value: "#999999" - }, { - value: "#8c8c8c" - }, { - value: "#808080" - }, { - value: "#737373" - }, { - value: "#666666" - }, { - value: "#4d4d4d" - }, { - value: "#333333" - }, { - value: "#000000" - }], - [{ - value: "#d8b5a6" - }, { - value: "#ff9e9a" - }, { - value: "#ffc17d" - }, { - value: "#f5e56b" - }, { - value: "#d8e698" - }, { - value: "#e0ebaf" - }, { - value: "#c3d825" - }, { - value: "#bbe2e7" - }, { - value: "#85d3cd" - }, { - value: "#bde1e6" - }, { - value: "#a0d8ef" - }, { - value: "#89c3eb" - }, { - value: "#bbc8e6" - }, { - value: "#bbbcde" - }, { - value: "#d6b4cc" - }, { - value: "#fbc0d3" - }], - [{ - value: "#bb9581" - }, { - value: "#f37d79" - }, { - value: "#fba74f" - }, { - value: "#ffdb4f" - }, { - value: "#c7dc68" - }, { - value: "#b0ca71" - }, { - value: "#99ab4e" - }, { - value: "#84b9cb" - }, { - value: "#00a3af" - }, { - value: "#2ca9e1" - }, { - value: "#0095d9" - }, { - value: "#4c6cb3" - }, { - value: "#8491c3" - }, { - value: "#a59aca" - }, { - value: "#cc7eb1" - }, { - value: "#e89bb4" - }], - [{ - value: "#9d775f" - }, { - value: "#dd4b4b" - }, { - value: "#ef8b07" - }, { - value: "#fcc800" - }, { - value: "#aacf53" - }, { - value: "#82ae46" - }, { - value: "#69821b" - }, { - value: "#59b9c6" - }, { - value: "#2a83a2" - }, { - value: "#007bbb" - }, { - value: "#19448e" - }, { - value: "#274a78" - }, { - value: "#4a488e" - }, { - value: "#7058a3" - }, { - value: "#884898" - }, { - value: "#d47596" - }] - ], - - _init: function () { - BI.ColorPicker.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.colors = BI.createWidget({ - type: "bi.button_group", - element: this, - items: BI.createItems(o.items || this._items, { - type: "bi.color_picker_button", - once: false - }), - layouts: [{ - type: "bi.grid" - }], - value: o.value - }); - this.colors.on(BI.ButtonGroup.EVENT_CHANGE, function () { - self.fireEvent(BI.ColorPicker.EVENT_CHANGE, arguments); - }); - }, - - populate: function (items) { - var args = [].slice.call(arguments); - args[0] = BI.createItems(items, { - type: "bi.color_picker_button", - once: false - }); - this.colors.populate.apply(this.colors, args); - }, - - setValue: function (color) { - this.colors.setValue(color); - }, - - getValue: function () { - return this.colors.getValue(); - } -}); -BI.ColorPicker.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_picker", BI.ColorPicker); \ No newline at end of file diff --git a/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js b/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js deleted file mode 100644 index 22c66a250..000000000 --- a/src/case/colorchooser/colorpicker/editor.colorpicker.hex.js +++ /dev/null @@ -1,303 +0,0 @@ -/** - * 简单选色控件 - * - * Created by GUY on 2015/11/16. - * @class BI.ColorPickerEditor - * @extends BI.Widget - */ -BI.HexColorPickerEditor = BI.inherit(BI.Widget, { - - constants: { - RGB_WIDTH: 32, - HEX_WIDTH: 70, - HEX_PREFIX_POSITION: 1 - }, - - props: { - baseCls: "bi-color-picker-editor", - height: 30 - }, - - render: function () { - var self = this, o = this.options, c = this.constants; - this.storeValue = {}; - var RGB = BI.createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { - type: "bi.label", - cls: "color-picker-editor-label", - height: 20 - }); - - var checker = function (v) { - return BI.isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; - }; - var Ws = BI.map(BI.range(0, 3), function () { - return { - type: "bi.small_text_editor", - cls: "color-picker-editor-input bi-border-radius", - validationChecker: checker, - errorText: BI.i18nText("BI-Color_Picker_Error_Text"), - allowBlank: true, - value: 255, - width: c.RGB_WIDTH, - height: 24, - listeners: [ - { - eventName: BI.TextEditor.EVENT_CHANGE, - action: function () { - self._checkEditors(); - if (checker(self.storeValue.r) && checker(self.storeValue.g) && checker(self.storeValue.b)) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - } - } - ] - }; - }); - - return { - type: "bi.absolute", - items: [ - { - el: { - type: "bi.vertical", - tgap: 10, - items: [ - { - type: 'bi.vertical_adapt', - columnSize: ["fill", 'fill'], - height: 24, - items: [ - { - type: "bi.color_picker_show_button", - cls: "trans-color-icon", - height: 22, - title: BI.i18nText("BI-Transparent_Color"), - text: BI.i18nText("BI-Transparent_Color"), - listeners: [ - { - eventName: BI.ColorChooserShowButton.EVENT_CHANGE, - action: function () { - self.setValue("transparent"); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - } - ], - ref: function (_ref) { - self.transparent = _ref; - } - }, { - el: { - type: "bi.color_picker_show_button", - cls: "auto-color-icon", - height: 22, - title: BI.i18nText("BI-Basic_Auto"), - text: BI.i18nText("BI-Basic_Auto"), - listeners: [ - { - eventName: BI.ColorChooserShowButton.EVENT_CHANGE, - action: function () { - self.setValue(""); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - } - ], - ref: function (_ref) { - self.none = _ref; - } - }, - lgap: 10, - } - ] - }, { - el: { - type: "bi.vertical_adapt", - columnSize: [22, 10, 'fill', 12, c.RGB_WIDTH, 12, c.RGB_WIDTH, 12, c.RGB_WIDTH], - - rgap: 5, - items: [ - { - el: { - type: "bi.layout", - cls: "color-picker-editor-display bi-card bi-border", - height: 22, - width: 22, - ref: function (_ref) { - self.colorShow = _ref; - } - }, - width: 18 - }, { - type: "bi.label", - text: "#", - width: 10 - }, { - type: "bi.small_text_editor", - ref: function (_ref) { - self.hexEditor = _ref; - }, - cls: "color-picker-editor-input bi-border-radius", - validationChecker: this._hexChecker, - allowBlank: true, - errorText: BI.i18nText("BI-Color_Picker_Error_Text_Hex"), - width: c.HEX_WIDTH, - height: 24, - listeners: [ - { - eventName: "EVENT_CHANGE", - action: function () { - self._checkHexEditor(); - if (checker(self.storeValue.r) && checker(self.storeValue.g) && checker(self.storeValue.b)) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - - } - } - ] - }, RGB[0], { - el: BI.extend(Ws[0], { - ref: function (_ref) { - self.R = _ref; - } - }), - width: c.RGB_WIDTH - }, RGB[1], { - el: BI.extend(Ws[1], { - ref: function (_ref) { - self.G = _ref; - } - }), - width: c.RGB_WIDTH - }, RGB[2], { - el: BI.extend(Ws[2], { - ref: function (_ref) { - self.B = _ref; - } - }), - rgap: -5, - width: c.RGB_WIDTH - } - ] - } - } - ] - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }; - }, - - _hexChecker: function (v) { - return /^[0-9a-fA-F]{6}$/.test(v); - }, - - _checkEditors: function () { - if (BI.isEmptyString(this.R.getValue())) { - this.R.setValue(0); - } - if (BI.isEmptyString(this.G.getValue())) { - this.G.setValue(0); - } - if (BI.isEmptyString(this.B.getValue())) { - this.B.setValue(0); - } - this.storeValue = { - r: this.R.getValue() || 0, - g: this.G.getValue() || 0, - b: this.B.getValue() || 0 - }; - this.hexEditor.setValue(this.getValue().slice(this.constants.HEX_PREFIX_POSITION)); - }, - - _isEmptyRGB: function () { - return BI.isEmptyString(this.storeValue.r) && BI.isEmptyString(this.storeValue.g) && BI.isEmptyString(this.storeValue.b); - }, - - _checkHexEditor: function () { - if (BI.isEmptyString(this.hexEditor.getValue())) { - this.hexEditor.setValue("000000"); - } - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb("#" + this.hexEditor.getValue())); - this.storeValue = { - r: json.r || 0, - g: json.g || 0, - b: json.b || 0, - }; - this.R.setValue(this.storeValue.r); - this.G.setValue(this.storeValue.g); - this.B.setValue(this.storeValue.b); - }, - - _showPreColor: function (color) { - if (color === "") { - this.colorShow.element.css("background-color", "").removeClass("trans-color-background").addClass("auto-color-square-normal-background"); - } else if (color === "transparent") { - this.colorShow.element.css("background-color", "").removeClass("auto-color-square-normal-background").addClass("trans-color-background"); - } else { - this.colorShow.element.css({ "background-color": color }).removeClass("auto-color-square-normal-background").removeClass("trans-color-background"); - } - }, - - _setEnable: function (enable) { - BI.ColorPickerEditor.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.removeClass("base-disabled disabled"); - } else if (enable === false) { - this.element.addClass("base-disabled disabled"); - } - }, - - setValue: function (color) { - if (color === "transparent") { - this.transparent.setSelected(true); - this.none.setSelected(false); - this._showPreColor("transparent"); - this.R.setValue(""); - this.G.setValue(""); - this.B.setValue(""); - this.hexEditor.setValue(""); - this.storeValue = { - r: "", - g: "", - b: "" - }; - return; - } - if (!color) { - color = ""; - this.none.setSelected(true); - } else { - this.none.setSelected(false); - } - this.transparent.setSelected(false); - this._showPreColor(color); - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb(color)); - this.storeValue = { - r: BI.isNull(json.r) ? "" : json.r, - g: BI.isNull(json.g) ? "" : json.g, - b: BI.isNull(json.b) ? "" : json.b - }; - this.R.setValue(this.storeValue.r); - this.G.setValue(this.storeValue.g); - this.B.setValue(this.storeValue.b); - this.hexEditor.setValue(color.slice(this.constants.HEX_PREFIX_POSITION)); - }, - - getValue: function () { - if (this._isEmptyRGB() && this.transparent.isSelected()) { - return "transparent"; - } - return BI.DOM.rgb2hex(BI.DOM.json2rgb({ - r: this.storeValue.r, - g: this.storeValue.g, - b: this.storeValue.b - })); - } -}); -BI.HexColorPickerEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.hex_color_picker_editor", BI.HexColorPickerEditor); diff --git a/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js b/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js deleted file mode 100644 index 749806355..000000000 --- a/src/case/colorchooser/colorpicker/editor.colorpicker.hex.simple.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/11/10 - */ -BI.SimpleHexColorPickerEditor = BI.inherit(BI.Widget, { - - constants: { - RGB_WIDTH: 32, - HEX_WIDTH: 70, - HEX_PREFIX_POSITION: 1 - }, - - props: { - baseCls: "bi-color-picker-editor", - height: 36 - }, - - render: function () { - var self = this, o = this.options, c = this.constants; - - var RGB = BI.createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { - type: "bi.label", - cls: "color-picker-editor-label", - height: 20 - }); - - var checker = function (v) { - return BI.isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; - }; - var Ws = BI.map(BI.range(0, 3), function () { - return { - type: "bi.small_text_editor", - cls: "color-picker-editor-input bi-border-radius", - validationChecker: checker, - errorText: BI.i18nText("BI-Color_Picker_Error_Text"), - allowBlank: true, - value: 255, - width: c.RGB_WIDTH, - height: 24, - listeners: [ - { - eventName: BI.TextEditor.EVENT_CHANGE, - action: function () { - self._checkEditors(); - if (self.R.isValid() && self.G.isValid() && self.B.isValid()) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.SimpleColorPickerEditor.EVENT_CHANGE); - } - } - } - ] - }; - }); - - return { - type: "bi.vertical", - tgap: 10, - items: [ - { - el: { - type: "bi.vertical_adapt", - rgap: 5, - columnSize: [22, 10, 'fill', 12, c.RGB_WIDTH, 12, c.RGB_WIDTH, 12, c.RGB_WIDTH], - items: [ - { - el: { - type: "bi.layout", - cls: "color-picker-editor-display bi-card bi-border", - height: 22, - width: 22, - ref: function (_ref) { - self.colorShow = _ref; - } - }, - width: 18, - }, { - type: "bi.label", - text: "#", - width: 10 - }, { - type: "bi.small_text_editor", - ref: function (_ref) { - self.hexEditor = _ref; - }, - cls: "color-picker-editor-input bi-border-radius", - validationChecker: this._hexChecker, - allowBlank: true, - errorText: BI.i18nText("BI-Color_Picker_Error_Text_Hex"), - width: c.HEX_WIDTH, - height: 24, - listeners: [ - { - eventName: "EVENT_CHANGE", - action: function () { - self._checkHexEditor(); - if (checker(self.storeValue.r) && checker(self.storeValue.g) && checker(self.storeValue.b)) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - } - } - ] - }, RGB[0], { - el: BI.extend(Ws[0], { - ref: function (_ref) { - self.R = _ref; - } - }), - width: c.RGB_WIDTH - }, RGB[1], { - el: BI.extend(Ws[1], { - ref: function (_ref) { - self.G = _ref; - } - }), - width: c.RGB_WIDTH - }, RGB[2], { - el: BI.extend(Ws[2], { - ref: function (_ref) { - self.B = _ref; - } - }), - rgap: -5, - width: c.RGB_WIDTH - } - ] - } - } - ] - - }; - }, - - _hexChecker: function (v) { - return /^[0-9a-fA-F]{6}$/.test(v); - }, - - _checkEditors: function () { - if (BI.isEmptyString(this.R.getValue())) { - this.R.setValue(0); - } - if (BI.isEmptyString(this.G.getValue())) { - this.G.setValue(0); - } - if (BI.isEmptyString(this.B.getValue())) { - this.B.setValue(0); - } - this.hexEditor.setValue(this.getValue().slice(this.constants.HEX_PREFIX_POSITION)); - }, - - _checkHexEditor: function () { - if (BI.isEmptyString(this.hexEditor.getValue())) { - this.hexEditor.setValue("000000"); - } - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb("#" + this.hexEditor.getValue())); - this.storeValue = { - r: json.r || 0, - g: json.g || 0, - b: json.b || 0, - }; - this.R.setValue(this.storeValue.r); - this.G.setValue(this.storeValue.g); - this.B.setValue(this.storeValue.b); - }, - - setValue: function (color) { - this.colorShow.element.css({ "background-color": color }); - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb(color)); - this.R.setValue(BI.isNull(json.r) ? "" : json.r); - this.G.setValue(BI.isNull(json.g) ? "" : json.g); - this.B.setValue(BI.isNull(json.b) ? "" : json.b); - this.hexEditor.setValue(BI.isEmptyObject(json) ? "" : color.slice(this.constants.HEX_PREFIX_POSITION)); - }, - - getValue: function () { - return BI.DOM.rgb2hex(BI.DOM.json2rgb({ - r: this.R.getValue(), - g: this.G.getValue(), - b: this.B.getValue() - })); - } -}); -BI.SimpleHexColorPickerEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.simple_hex_color_picker_editor", BI.SimpleHexColorPickerEditor); diff --git a/src/case/colorchooser/colorpicker/editor.colorpicker.js b/src/case/colorchooser/colorpicker/editor.colorpicker.js deleted file mode 100644 index 982d333c3..000000000 --- a/src/case/colorchooser/colorpicker/editor.colorpicker.js +++ /dev/null @@ -1,230 +0,0 @@ -/** - * 简单选色控件 - * - * Created by GUY on 2015/11/16. - * @class BI.ColorPickerEditor - * @extends BI.Widget - */ -BI.ColorPickerEditor = BI.inherit(BI.Widget, { - - constants: { - RGB_WIDTH: 32 - }, - - _defaultConfig: function () { - return BI.extend(BI.ColorPickerEditor.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-color-picker-editor", - // width: 200, - height: 30 - }); - }, - - _init: function () { - BI.ColorPickerEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this.constants; - this.storeValue = {}; - this.colorShow = BI.createWidget({ - type: "bi.layout", - cls: "color-picker-editor-display bi-card bi-border", - height: 16, - width: 16 - }); - var RGB = BI.createWidgets(BI.createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { - type: "bi.label", - cls: "color-picker-editor-label", - width: 20, - height: 20 - })); - - var checker = function (v) { - return BI.isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; - }; - var Ws = BI.createWidgets([{}, {}, {}], { - type: "bi.small_text_editor", - cls: "color-picker-editor-input bi-border-radius", - validationChecker: checker, - errorText: BI.i18nText("BI-Color_Picker_Error_Text"), - allowBlank: true, - value: 255, - width: c.RGB_WIDTH, - height: 20 - }); - BI.each(Ws, function (i, w) { - w.on(BI.TextEditor.EVENT_CHANGE, function () { - self._checkEditors(); - if (checker(self.storeValue.r) && checker(self.storeValue.g) && checker(self.storeValue.b)) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - } - }); - }); - this.R = Ws[0]; - this.G = Ws[1]; - this.B = Ws[2]; - - this.none = BI.createWidget({ - type: "bi.icon_button", - cls: "auto-color-icon", - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16, - title: BI.i18nText("BI-Basic_Auto") - }); - this.none.on(BI.IconButton.EVENT_CHANGE, function () { - var value = self.getValue(); - self.setValue(""); - (value !== "") && self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - }); - - this.transparent = BI.createWidget({ - type: "bi.icon_button", - cls: "trans-color-icon", - width: 16, - height: 16, - iconWidth: 16, - iconHeight: 16, - title: BI.i18nText("BI-Transparent_Color") - }); - this.transparent.on(BI.IconButton.EVENT_CHANGE, function () { - var value = self.getValue(); - self.setValue("transparent"); - (value !== "transparent") && self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: { - type: "bi.vertical_adapt", - items: [ - { - el: this.colorShow, - width: 16 - }, { - el: RGB[0], - width: 20 - }, { - el: this.R, - width: c.RGB_WIDTH - }, { - el: RGB[1], - width: 20 - }, { - el: this.G, - width: c.RGB_WIDTH - }, { - el: RGB[2], - width: 20 - }, { - el: this.B, - width: c.RGB_WIDTH - }, { - el: this.transparent, - width: 16, - lgap: 5 - }, { - el: this.none, - width: 16, - lgap: 5 - } - ] - }, - left: 10, - right: 10, - top: 0, - bottom: 0 - } - ] - }); - }, - - _checkEditors: function () { - if (BI.isEmptyString(this.R.getValue())) { - this.R.setValue(0); - } - if (BI.isEmptyString(this.G.getValue())) { - this.G.setValue(0); - } - if (BI.isEmptyString(this.B.getValue())) { - this.B.setValue(0); - } - this.storeValue = { - r: this.R.getValue() || 0, - g: this.G.getValue() || 0, - b: this.B.getValue() || 0 - }; - }, - - _isEmptyRGB: function () { - return BI.isEmptyString(this.storeValue.r) && BI.isEmptyString(this.storeValue.g) && BI.isEmptyString(this.storeValue.b); - }, - - _showPreColor: function (color) { - if (color === "") { - this.colorShow.element.css("background-color", "").removeClass("trans-color-background").addClass("auto-color-normal-background"); - } else if (color === "transparent") { - this.colorShow.element.css("background-color", "").removeClass("auto-color-normal-background").addClass("trans-color-background"); - } else { - this.colorShow.element.css({ "background-color": color }).removeClass("auto-color-normal-background").removeClass("trans-color-background"); - } - }, - - _setEnable: function (enable) { - BI.ColorPickerEditor.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.removeClass("base-disabled disabled"); - } else if (enable === false) { - this.element.addClass("base-disabled disabled"); - } - }, - - setValue: function (color) { - if (color === "transparent") { - this.transparent.setSelected(true); - this.none.setSelected(false); - this._showPreColor("transparent"); - this.R.setValue(""); - this.G.setValue(""); - this.B.setValue(""); - this.storeValue = { - r: "", - g: "", - b: "" - }; - return; - } - if (!color) { - color = ""; - this.none.setSelected(true); - } else { - this.none.setSelected(false); - } - this.transparent.setSelected(false); - this._showPreColor(color); - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb(color)); - this.storeValue = { - r: BI.isNull(json.r) ? "" : json.r, - g: BI.isNull(json.g) ? "" : json.g, - b: BI.isNull(json.b) ? "" : json.b - }; - this.R.setValue(this.storeValue.r); - this.G.setValue(this.storeValue.g); - this.B.setValue(this.storeValue.b); - }, - - getValue: function () { - if (this._isEmptyRGB() && this.transparent.isSelected()) { - return "transparent"; - } - return BI.DOM.rgb2hex(BI.DOM.json2rgb({ - r: this.storeValue.r, - g: this.storeValue.g, - b: this.storeValue.b - })); - } -}); -BI.ColorPickerEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.color_picker_editor", BI.ColorPickerEditor); diff --git a/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js b/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js deleted file mode 100644 index 63b7576b4..000000000 --- a/src/case/colorchooser/colorpicker/editor.colorpicker.simple.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * 简单选色控件 - * - * Created by GUY on 2015/11/16. - * @class BI.SimpleColorPickerEditor - * @extends BI.Widget - */ -BI.SimpleColorPickerEditor = BI.inherit(BI.Widget, { - - constants: { - RGB_WIDTH: 32 - }, - - _defaultConfig: function () { - return BI.extend(BI.SimpleColorPickerEditor.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-color-picker-editor", - // width: 200, - height: 30 - }); - }, - - _init: function () { - BI.SimpleColorPickerEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this.constants; - this.colorShow = BI.createWidget({ - type: "bi.layout", - cls: "color-picker-editor-display bi-card bi-border", - height: 16, - width: 16 - }); - var RGB = BI.createWidgets(BI.createItems([{ text: "R" }, { text: "G" }, { text: "B" }], { - type: "bi.label", - cls: "color-picker-editor-label", - width: 20, - height: 20 - })); - - var checker = function (v) { - return BI.isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; - }; - var Ws = BI.createWidgets([{}, {}, {}], { - type: "bi.small_text_editor", - cls: "color-picker-editor-input bi-border-radius", - validationChecker: checker, - errorText: BI.i18nText("BI-Color_Picker_Error_Text"), - allowBlank: true, - value: 255, - width: c.RGB_WIDTH, - height: 20 - }); - BI.each(Ws, function (i, w) { - w.on(BI.TextEditor.EVENT_CHANGE, function () { - self._checkEditors(); - if (self.R.isValid() && self.G.isValid() && self.B.isValid()) { - self.colorShow.element.css("background-color", self.getValue()); - self.fireEvent(BI.SimpleColorPickerEditor.EVENT_CHANGE); - } - }); - }); - this.R = Ws[0]; - this.G = Ws[1]; - this.B = Ws[2]; - - BI.createWidget({ - type: "bi.vertical_adapt", - element: this, - items: [ - { - el: this.colorShow, - width: 16, - lgap: 20, - rgap: 15 - }, { - el: RGB[0], - width: 20 - }, { - el: this.R, - width: c.RGB_WIDTH - }, { - el: RGB[1], - width: 20 - }, { - el: this.G, - width: c.RGB_WIDTH - }, { - el: RGB[2], - width: 20 - }, { - el: this.B, - width: c.RGB_WIDTH - } - ] - }); - }, - - _checkEditors: function () { - if (BI.isEmptyString(this.R.getValue())) { - this.R.setValue(0); - } - if (BI.isEmptyString(this.G.getValue())) { - this.G.setValue(0); - } - if (BI.isEmptyString(this.B.getValue())) { - this.B.setValue(0); - } - }, - - setValue: function (color) { - this.colorShow.element.css({ "background-color": color }); - var json = BI.DOM.rgb2json(BI.DOM.hex2rgb(color)); - this.R.setValue(BI.isNull(json.r) ? "" : json.r); - this.G.setValue(BI.isNull(json.g) ? "" : json.g); - this.B.setValue(BI.isNull(json.b) ? "" : json.b); - }, - - getValue: function () { - return BI.DOM.rgb2hex(BI.DOM.json2rgb({ - r: this.R.getValue(), - g: this.G.getValue(), - b: this.B.getValue() - })); - } -}); -BI.SimpleColorPickerEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.simple_color_picker_editor", BI.SimpleColorPickerEditor); diff --git a/src/case/colorchooser/farbtastic/farbtastic.js b/src/case/colorchooser/farbtastic/farbtastic.js deleted file mode 100644 index 0bf1061b0..000000000 --- a/src/case/colorchooser/farbtastic/farbtastic.js +++ /dev/null @@ -1,253 +0,0 @@ -BI.Farbtastic = BI.inherit(BI.BasicButton, { - - constants: { - RADIUS: 84, - SQUARE: 100, - WIDTH: 194 - }, - - props: { - baseCls: "bi-farbtastic", - width: 195, - height: 195, - stopPropagation: true, - value: "#000000" - }, - - render: function () { - var self = this; - this._defaultState(); - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.layout", - cls: "", - ref: function (_ref) { - self.colorWrapper = _ref; - } - }, - top: 47, - left: 47, - width: 101, - height: 101 - }, { - el: { - type: "bi.layout", - cls: "wheel", - ref: function (_ref) { - self.wheel = _ref; - } - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.layout", - cls: "overlay", - ref: function (_ref) { - self.overlay = _ref; - } - }, - top: 47, - left: 47, - width: 101, - height: 101 - }, { - el: { - type: "bi.layout", - cls: "marker", - ref: function (_ref) { - self.hMarker = _ref; - }, - scrollable: false, - width: 17, - height: 17 - } - }, { - el: { - type: "bi.layout", - cls: "marker", - ref: function (_ref) { - self.slMarker = _ref; - }, - scrollable: false, - width: 17, - height: 17 - } - }] - }; - }, - - created: function () { - var o = this.options; - if (BI.isKey(o.value)) { - this.setValue(o.value); - } - }, - - _defaultState: function () { - this.hsl = [0, 0, 0]; - }, - - _unpack: function (color) { - if (color.length === 7) { - return [parseInt("0x" + color.substring(1, 3)) / 255, - parseInt("0x" + color.substring(3, 5)) / 255, - parseInt("0x" + color.substring(5, 7)) / 255]; - } else if (color.length === 4) { - return [parseInt("0x" + color.substring(1, 2)) / 15, - parseInt("0x" + color.substring(2, 3)) / 15, - parseInt("0x" + color.substring(3, 4)) / 15]; - } - }, - - _pack: function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - return "#" + (r < 16 ? "0" : "") + r.toString(16) + - (g < 16 ? "0" : "") + g.toString(16) + - (b < 16 ? "0" : "") + b.toString(16); - }, - - _setColor: function (color) { - var unpack = this._unpack(color); - if (this.value !== color && unpack) { - this.value = color; - this.rgb = unpack; - this.hsl = this._RGBToHSL(this.rgb); - this._updateDisplay(); - } - }, - - _setHSL: function (hsl) { - this.hsl = hsl; - this.rgb = this._HSLToRGB(hsl); - this.value = this._pack(this.rgb); - this._updateDisplay(); - return this; - }, - - _HSLToRGB: function (hsl) { - return BI.DOM.hsl2rgb(hsl); - }, - - _RGBToHSL: function (rgb) { - return BI.DOM.rgb2hsl(rgb); - }, - - _updateDisplay: function () { - var angle = this.hsl[0] * 6.28; - this.hMarker.element.css({ - left: Math.round(Math.sin(angle) * this.constants.RADIUS + this.constants.WIDTH / 2) + "px", - top: Math.round(-Math.cos(angle) * this.constants.RADIUS + this.constants.WIDTH / 2) + "px" - }); - - this.slMarker.element.css({ - left: Math.round(this.constants.SQUARE * (.5 - this.hsl[1]) + this.constants.WIDTH / 2) + "px", - top: Math.round(this.constants.SQUARE * (.5 - this.hsl[2]) + this.constants.WIDTH / 2) + "px" - }); - - // Saturation/Luminance gradient - this.colorWrapper.element.css("backgroundColor", this._pack(this._HSLToRGB([this.hsl[0], 1, 0.5]))); - }, - - _absolutePosition: function (el) { - var r = {x: el.offsetLeft, y: el.offsetTop}; - // Resolve relative to offsetParent - if (el.offsetParent) { - var tmp = this._absolutePosition(el.offsetParent); - r.x += tmp.x; - r.y += tmp.y; - } - return r; - }, - - _widgetCoords: function (event) { - var x, y; - var el = event.target || event.srcElement; - var reference = this.wheel.element[0]; - - if (typeof event.offsetX !== "undefined") { - // Use offset coordinates and find common offsetParent - var pos = {x: event.offsetX, y: event.offsetY}; - - // Send the coordinates upwards through the offsetParent chain. - var e = el; - while (e) { - e.mouseX = pos.x; - e.mouseY = pos.y; - pos.x += e.offsetLeft; - pos.y += e.offsetTop; - e = e.offsetParent; - } - - // Look for the coordinates starting from the wheel widget. - var e = reference; - var offset = {x: 0, y: 0}; - while (e) { - if (typeof e.mouseX !== "undefined") { - x = e.mouseX - offset.x; - y = e.mouseY - offset.y; - break; - } - offset.x += e.offsetLeft; - offset.y += e.offsetTop; - e = e.offsetParent; - } - - // Reset stored coordinates - e = el; - while (e) { - e.mouseX = undefined; - e.mouseY = undefined; - e = e.offsetParent; - } - } else { - // Use absolute coordinates - var pos = this._absolutePosition(reference); - x = (event.pageX || 0) - pos.x; - y = (event.pageY || 0) - pos.y; - } - // Subtract distance to middle - return {x: x - this.constants.WIDTH / 2, y: y - this.constants.WIDTH / 2}; - }, - - _doMouseMove: function (event) { - var pos = this._widgetCoords(event); - - // Set new HSL parameters - if (this.circleDrag) { - var hue = Math.atan2(pos.x, -pos.y) / 6.28; - if (hue < 0) hue += 1; - this._setHSL([hue, this.hsl[1], this.hsl[2]]); - } else { - var sat = Math.max(0, Math.min(1, -(pos.x / this.constants.SQUARE) + .5)); - var lum = Math.max(0, Math.min(1, -(pos.y / this.constants.SQUARE) + .5)); - this._setHSL([this.hsl[0], sat, lum]); - } - this.fireEvent(BI.Farbtastic.EVENT_CHANGE, this.getValue(), this); - }, - - doClick: function (event) { - var pos = this._widgetCoords(event); - this.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > this.constants.SQUARE; - - // Process - this._doMouseMove(event); - return false; - }, - - setValue: function (color) { - this._setColor(color); - }, - - getValue: function () { - return this.value; - } -}); -BI.Farbtastic.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.farbtastic", BI.Farbtastic); diff --git a/src/case/combo/bubblecombo/combo.bubble.js b/src/case/combo/bubblecombo/combo.bubble.js deleted file mode 100644 index 7f2448ac0..000000000 --- a/src/case/combo/bubblecombo/combo.bubble.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Created by GUY on 2017/2/8. - * - * @class BI.BubbleCombo - * @extends BI.Widget - */ -BI.BubbleCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.BubbleCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-bubble-combo", - trigger: "click", - toggle: true, - primary: false, - direction: "bottom,left", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right - isDefaultInit: false, - destroyWhenHide: false, - hideWhenClickOutside: true, - hideWhenBlur: true, - isNeedAdjustHeight: true, // 是否需要高度调整 - isNeedAdjustWidth: true, - stopPropagation: false, - adjustLength: 0, // 调整的距离 - adjustXOffset: 0, - adjustYOffset: 0, - hideChecker: BI.emptyFn, - offsetStyle: "left", // left,right,center - el: {}, - popup: {} - }); - }, - _init: function () { - BI.BubbleCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.combo = BI.createWidget({ - type: "bi.combo", - element: this, - trigger: o.trigger, - toggle: o.toggle, - logic: o.logic, - container: o.container, - direction: o.direction, - isDefaultInit: o.isDefaultInit, - hideWhenBlur: o.hideWhenBlur, - hideWhenClickOutside: o.hideWhenClickOutside, - destroyWhenHide: o.destroyWhenHide, - hideWhenAnotherComboOpen: o.hideWhenAnotherComboOpen, - isNeedAdjustHeight: o.isNeedAdjustHeight, - isNeedAdjustWidth: o.isNeedAdjustWidth, - stopPropagation: o.stopPropagation, - adjustXOffset: o.adjustXOffset, - adjustYOffset: o.adjustYOffset, - hideChecker: o.hideChecker, - offsetStyle: o.offsetStyle, - showArrow: true, - comboClass: o.comboClass, - supportCSSTransform: o.supportCSSTransform, - el: o.el, - popup: () => BI.extend({ - type: "bi.bubble_popup_view", - animation: "bi-zoom-big", - animationDuring: 200, - primary: o.primary - }, BI.isFunction(this.options.popup) ? this.options.popup() : this.options.popup) - }); - this.combo.on(BI.Combo.EVENT_TRIGGER_CHANGE, function () { - self.fireEvent(BI.BubbleCombo.EVENT_TRIGGER_CHANGE, arguments); - }); - this.combo.on(BI.Combo.EVENT_CHANGE, function () { - self.fireEvent(BI.BubbleCombo.EVENT_CHANGE, arguments); - }); - this.combo.on(BI.Combo.EVENT_EXPAND, function () { - self.fireEvent(BI.BubbleCombo.EVENT_EXPAND, arguments); - }); - this.combo.on(BI.Combo.EVENT_COLLAPSE, function () { - self.fireEvent(BI.BubbleCombo.EVENT_COLLAPSE, arguments); - }); - this.combo.on(BI.Combo.EVENT_AFTER_INIT, function () { - self.fireEvent(BI.BubbleCombo.EVENT_AFTER_INIT, arguments); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, arguments); - }); - this.combo.on(BI.Combo.EVENT_AFTER_POPUPVIEW, function () { - self.fireEvent(BI.BubbleCombo.EVENT_AFTER_POPUPVIEW, arguments); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { - self.fireEvent(BI.BubbleCombo.EVENT_BEFORE_HIDEVIEW, arguments); - }); - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - self.fireEvent(BI.BubbleCombo.EVENT_AFTER_HIDEVIEW, arguments); - }); - }, - - hideView: function () { - this.combo && this.combo.hideView(); - }, - - showView: function () { - this.combo && this.combo.showView(); - }, - - isViewVisible: function () { - return this.combo.isViewVisible(); - }, - - adjustWidth: function () { - this.combo.adjustWidth(); - }, - - adjustHeight: function () { - this.combo.adjustHeight(); - } -}); - -BI.BubbleCombo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.BubbleCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.BubbleCombo.EVENT_EXPAND = "EVENT_EXPAND"; -BI.BubbleCombo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; -BI.BubbleCombo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; - - -BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.BubbleCombo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; -BI.BubbleCombo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; -BI.BubbleCombo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; -BI.shortcut("bi.bubble_combo", BI.BubbleCombo); diff --git a/src/case/combo/bubblecombo/popup.bubble.js b/src/case/combo/bubblecombo/popup.bubble.js deleted file mode 100644 index 26cff20b6..000000000 --- a/src/case/combo/bubblecombo/popup.bubble.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Created by GUY on 2017/2/8. - * - * @class BI.BubblePopupView - * @extends BI.PopupView - */ -BI.BubblePopupView = BI.inherit(BI.PopupView, { - _defaultConfig: function () { - var config = BI.BubblePopupView.superclass._defaultConfig.apply(this, arguments); - return BI.extend(config, { - baseCls: config.baseCls + " bi-bubble-popup-view", - minWidth: 70, - maxWidth: 300, - // minHeight: 50, - showArrow: true, - }); - } -}); - -BI.shortcut("bi.bubble_popup_view", BI.BubblePopupView); - -/** - * Created by GUY on 2017/2/8. - * - * @class BI.BubblePopupBarView - * @extends BI.BubblePopupView - */ -BI.BubblePopupBarView = BI.inherit(BI.BubblePopupView, { - _defaultConfig: function () { - return BI.extend(BI.BubblePopupBarView.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-bubble-bar-popup-view", - buttons: [{ - value: false, - text: BI.i18nText("BI-Basic_Cancel"), - light: true, - }, { - text: BI.i18nText(BI.i18nText("BI-Basic_OK")), - value: true - }], - innerVgap: 16, - innerHgap: 16, - }); - }, - - _createToolBar: function () { - var o = this.options, self = this; - - var items = []; - BI.each(o.buttons, function (i, buttonOpt) { - if (BI.isWidget(buttonOpt)) { - items.push({ - el: buttonOpt, - lgap: 12, - }); - } else { - items.push({ - el: BI.extend({ - type: "bi.button", - height: 24, - handler: function (v) { - self.fireEvent(BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, v); - } - }, buttonOpt), - lgap: 12, - }); - } - }); - return BI.createWidget({ - type: "bi.right_vertical_adapt", - innerVgap: o.innerVgap, - innerHgap: o.innerHgap, - items: items - }); - }, - - _createContent: function () { - return this.options.el; - }, - - _createView: function () { - var o = this.options; - - var view = BI.createWidget({ - type: "bi.vertical", - items: [this._createContent()], - cls: "bar-popup-container", - hgap: o.innerHgap, - tgap: o.innerVgap, - }); - - view.element.css("min-height", o.minHeight); - - return view; - } -}); -BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; -BI.shortcut("bi.bubble_bar_popup_view", BI.BubblePopupBarView); - -/** - * Created by Windy on 2018/2/2. - * - * @class BI.TextBubblePopupBarView - * @extends BI.BubblePopupView - */ -BI.TextBubblePopupBarView = BI.inherit(BI.BubblePopupBarView, { - - _defaultConfig: function () { - var config = BI.TextBubblePopupBarView.superclass._defaultConfig.apply(this, arguments); - return BI.extend(config, { - baseCls: config.baseCls + " bi-text-bubble-bar-popup-view", - text: "", - }); - }, - - _createContent: function () { - var self = this, o = this.options; - return { - type: "bi.label", - text: o.text, - whiteSpace: "normal", - textAlign: "left", - ref: function () { - self.text = this; - } - }; - }, - - populate: function (v) { - this.text.setText(v || this.options.text); - } -}); -BI.TextBubblePopupBarView.EVENT_CHANGE = "EVENT_CLICK_TOOLBAR_BUTTON"; -BI.shortcut("bi.text_bubble_bar_popup_view", BI.TextBubblePopupBarView); diff --git a/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js b/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js deleted file mode 100644 index 28c57a2e9..000000000 --- a/src/case/combo/editoriconcheckcombo/combo.editiconcheck.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Created by Young's on 2016/4/28. - */ -BI.EditorIconCheckCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.EditorIconCheckCombo.superclass._defaultConfig.apply(this, arguments), { - baseClass: "bi-check-editor-combo", - width: 100, - height: 24, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: true, - watermark: "", - errorText: "" - }); - }, - - _init: function () { - BI.EditorIconCheckCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.trigger = BI.createWidget({ - type: "bi.editor_trigger", - items: o.items, - height: o.height, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - value: o.value - }); - this.trigger.on(BI.EditorTrigger.EVENT_CHANGE, function () { - self.popup.setValue(this.getValue()); - self.fireEvent(BI.EditorIconCheckCombo.EVENT_CHANGE, arguments); - }); - this.trigger.on(BI.EditorTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.EditorIconCheckCombo.EVENT_FOCUS, arguments); - }); - this.trigger.on(BI.EditorTrigger.EVENT_EMPTY, function () { - self.fireEvent(BI.EditorIconCheckCombo.EVENT_EMPTY, arguments); - }); - this.trigger.on(BI.EditorTrigger.EVENT_VALID, function () { - self.fireEvent(BI.EditorIconCheckCombo.EVENT_VALID, arguments); - }); - this.trigger.on(BI.EditorTrigger.EVENT_ERROR, function () { - self.fireEvent(BI.EditorIconCheckCombo.EVENT_ERROR, arguments); - }); - - this.popup = BI.createWidget({ - type: "bi.text_value_check_combo_popup", - chooseType: o.chooseType, - items: o.items, - value: o.value - }); - this.popup.on(BI.TextValueCheckComboPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.editorIconCheckCombo.hideView(); - self.fireEvent(BI.EditorIconCheckCombo.EVENT_CHANGE); - }); - this.popup.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editorIconCheckCombo = BI.createWidget({ - type: "bi.combo", - container: o.container, - direction: o.direction, - element: this, - adjustLength: 2, - el: this.trigger, - popup: { - el: this.popup, - maxHeight: 300 - } - }); - }, - - setValue: function (v) { - this.editorIconCheckCombo.setValue(v); - }, - - getValue: function () { - return this.trigger.getValue(); - }, - - populate: function (items) { - this.options.items = items; - this.editorIconCheckCombo.populate(items); - } -}); -BI.EditorIconCheckCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.EditorIconCheckCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.EditorIconCheckCombo.EVENT_EMPTY = "EVENT_EMPTY"; -BI.EditorIconCheckCombo.EVENT_VALID = "EVENT_VALID"; -BI.EditorIconCheckCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.shortcut("bi.editor_icon_check_combo", BI.EditorIconCheckCombo); diff --git a/src/case/combo/iconcombo/combo.icon.js b/src/case/combo/iconcombo/combo.icon.js deleted file mode 100644 index 6c0f45c51..000000000 --- a/src/case/combo/iconcombo/combo.icon.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Created by GUY on 2016/2/2. - * - * @class BI.IconCombo - * @extend BI.Widget - */ -BI.IconCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.IconCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-icon-combo", - width: 24, - height: 24, - el: {}, - popup: {}, - minWidth: 100, - maxWidth: "auto", - maxHeight: 300, - direction: "bottom", - adjustLength: 3, // 调整的距离 - adjustXOffset: 0, - adjustYOffset: 0, - offsetStyle: "left", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - isShowDown: true, - hideWhenAnotherComboOpen: false - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - BI.IconCombo.superclass._init.apply(this, arguments); - this.trigger = BI.createWidget(o.el, { - type: "bi.icon_combo_trigger", - iconCls: o.iconCls, - title: o.title, - items: o.items, - width: o.width, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - value: o.value, - isShowDown: o.isShowDown - }); - this.popup = BI.createWidget(o.popup, { - type: "bi.icon_combo_popup", - chooseType: o.chooseType, - items: o.items, - value: o.value - }); - this.popup.on(BI.IconComboPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.iconCombo.hideView(); - self.fireEvent(BI.IconCombo.EVENT_CHANGE); - }); - this.popup.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.iconCombo = BI.createWidget({ - type: "bi.combo", - element: this, - direction: o.direction, - trigger: o.trigger, - container: o.container, - adjustLength: o.adjustLength, - adjustXOffset: o.adjustXOffset, - adjustYOffset: o.adjustYOffset, - offsetStyle: o.offsetStyle, - el: this.trigger, - hideWhenAnotherComboOpen: o.hideWhenAnotherComboOpen, - popup: { - el: this.popup, - maxWidth: o.maxWidth, - maxHeight: o.maxHeight, - minWidth: o.minWidth - } - }); - }, - - showView: function () { - this.iconCombo.showView(); - }, - - hideView: function () { - this.iconCombo.hideView(); - }, - - setValue: function (v) { - this.trigger.setValue(v); - this.popup.setValue(v); - }, - - getValue: function () { - var value = this.popup.getValue(); - return BI.isNull(value) ? [] : (BI.isArray(value) ? value : [value]); - }, - - populate: function (items) { - this.options.items = items; - this.iconCombo.populate(items); - } -}); -BI.IconCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_combo", BI.IconCombo); \ No newline at end of file diff --git a/src/case/combo/iconcombo/popup.iconcombo.js b/src/case/combo/iconcombo/popup.iconcombo.js deleted file mode 100644 index 9b0f4cc80..000000000 --- a/src/case/combo/iconcombo/popup.iconcombo.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Created by GUY on 2016/2/2. - * - * @class BI.IconComboPopup - * @extend BI.Pane - */ -BI.IconComboPopup = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.IconComboPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi.icon-combo-popup", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE - }); - }, - - _init: function () { - BI.IconComboPopup.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.popup = BI.createWidget({ - type: "bi.button_group", - items: BI.createItems(o.items, { - type: "bi.single_select_icon_text_item", - }), - chooseType: o.chooseType, - layouts: [{ - type: "bi.vertical" - }], - value: o.value - }); - - this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.IconComboPopup.EVENT_CHANGE, val, obj); - } - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - vgap: 5, - items: [this.popup] - }); - }, - - populate: function (items) { - BI.IconComboPopup.superclass.populate.apply(this, arguments); - items = BI.createItems(items, { - type: "bi.single_select_icon_text_item", - }); - this.popup.populate(items); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - setValue: function (v) { - this.popup.setValue(v); - } - -}); -BI.IconComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_combo_popup", BI.IconComboPopup); \ No newline at end of file diff --git a/src/case/combo/iconcombo/trigger.iconcombo.js b/src/case/combo/iconcombo/trigger.iconcombo.js deleted file mode 100644 index 65c353504..000000000 --- a/src/case/combo/iconcombo/trigger.iconcombo.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Created by GUY on 2016/2/2. - * - * @class BI.IconComboTrigger - * @extend BI.Widget - */ -BI.IconComboTrigger = BI.inherit(BI.Trigger, { - _defaultConfig: function () { - return BI.extend(BI.IconComboTrigger.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-icon-combo-trigger", - el: {}, - items: [], - iconCls: "", - width: 24, - height: 24, - isShowDown: true, - value: "" - }); - }, - - _init: function () { - BI.IconComboTrigger.superclass._init.apply(this, arguments); - var o = this.options, self = this; - var iconCls = ""; - if(BI.isKey(o.value)){ - iconCls = this._digest(o.value, o.items); - } - this.button = BI.createWidget(o.el, { - type: "bi.icon_change_button", - cls: "icon-combo-trigger-icon", - iconCls: iconCls, - disableSelected: true, - width: o.isShowDown ? o.width - 12 : o.width, - height: o.height, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight, - selected: BI.isNotEmptyString(iconCls) - }); - this.down = BI.createWidget({ - type: "bi.icon_button", - disableSelected: true, - cls: "icon-combo-down-icon trigger-triangle-font font-size-12", - width: 12, - height: 8, - selected: BI.isNotEmptyString(iconCls), - invisible: !o.isShowDown - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.button, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: this.down, - right: 3, - bottom: 0 - }] - }); - }, - - _digest: function (v, items) { - var iconCls = ""; - v = BI.isArray(v) ? v[0] : v; - BI.any(items, function (i, item) { - if (v === item.value) { - iconCls = item.iconCls; - return true; - } - }); - return iconCls; - }, - - populate: function (items) { - var o = this.options; - this.options.items = items || []; - this.button.setIcon(o.iconCls); - this.button.setSelected(false); - this.down.setSelected(false); - }, - - setValue: function (v) { - BI.IconComboTrigger.superclass.setValue.apply(this, arguments); - var o = this.options; - var iconCls = this._digest(v, this.options.items); - v = BI.isArray(v) ? v[0] : v; - if (BI.isNotEmptyString(iconCls)) { - this.button.setIcon(iconCls); - this.button.setSelected(true); - this.down.setSelected(true); - } else { - this.button.setIcon(o.iconCls); - this.button.setSelected(false); - this.down.setSelected(false); - } - } -}); -BI.IconComboTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_combo_trigger", BI.IconComboTrigger); diff --git a/src/case/combo/icontextvaluecombo/combo.icontextvalue.js b/src/case/combo/icontextvaluecombo/combo.icontextvalue.js deleted file mode 100644 index 9a920240a..000000000 --- a/src/case/combo/icontextvaluecombo/combo.icontextvalue.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Created by Windy on 2017/12/12. - * combo : icon + text + icon, popup : icon + text - */ -BI.IconTextValueCombo = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - return BI.extend(BI.IconTextValueCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-icon-text-value-combo " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24, - iconHeight: null, - iconWidth: null, - value: "", - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - BI.IconTextValueCombo.superclass._init.apply(this, arguments); - this.trigger = BI.createWidget({ - type: "bi.select_icon_text_trigger", - cls: "icon-text-value-trigger", - items: o.items, - height: BI.toPix(o.height, 2), - text: o.text, - iconCls: o.iconCls, - value: o.value, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - iconWrapperWidth: o.iconWrapperWidth, - title: o.title, - warningTitle: o.warningTitle - }); - this.popup = BI.createWidget({ - type: "bi.icon_text_value_combo_popup", - items: o.items, - value: o.value, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - iconWrapperWidth: o.iconWrapperWidth - }); - this.popup.on(BI.IconTextValueComboPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.textIconCombo.hideView(); - self.fireEvent(BI.IconTextValueCombo.EVENT_CHANGE, arguments); - }); - this.popup.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.textIconCombo = BI.createWidget({ - type: "bi.combo", - height: BI.toPix(o.height, 2), - width: BI.toPix(o.width, 2), - element: this, - container: o.container, - direction: o.direction, - adjustLength: 2, - el: this.trigger, - popup: { - el: this.popup, - maxHeight: 240, - minHeight: 25 - } - }); - if (BI.isKey(o.value)) { - this.setValue(o.value); - } - }, - - _checkError: function (v) { - if(BI.isNull(v) || BI.isEmptyArray(v) || BI.isEmptyString(v)) { - this.trigger.options.tipType = "success"; - this.element.removeClass("combo-error"); - } else { - v = BI.isArray(v) ? v : [v]; - var result = BI.find(this.options.items, function (idx, item) { - return BI.contains(v, item.value); - }); - if (BI.isNull(result)) { - this.trigger.options.tipType = "warning"; - this.element.removeClass("combo-error").addClass("combo-error"); - } else { - this.trigger.options.tipType = "success"; - this.element.removeClass("combo-error"); - } - } - }, - - setValue: function (v) { - this.trigger.setValue(v); - this.popup.setValue(v); - this._checkError(v); - }, - - getValue: function () { - var value = this.popup.getValue(); - return BI.isNull(value) ? [] : (BI.isArray(value) ? value : [value]); - }, - - populate: function (items) { - this.options.items = items; - this.textIconCombo.populate(items); - } -}); -BI.IconTextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_value_combo", BI.IconTextValueCombo); diff --git a/src/case/combo/icontextvaluecombo/popup.icontextvalue.js b/src/case/combo/icontextvaluecombo/popup.icontextvalue.js deleted file mode 100644 index 88db08e67..000000000 --- a/src/case/combo/icontextvaluecombo/popup.icontextvalue.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Created by Windy on 2017/12/12. - */ -BI.IconTextValueComboPopup = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.IconTextValueComboPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-icon-text-icon-popup", - behaviors: { - redmark: function () { - return true; - } - } - }); - }, - - _init: function () { - BI.IconTextValueComboPopup.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.popup = BI.createWidget({ - type: "bi.button_group", - items: BI.createItems(o.items, { - type: "bi.single_select_icon_text_item", - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - iconWrapperWidth: o.iconWrapperWidth - }), - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - layouts: [{ - type: "bi.vertical" - }], - behaviors: o.behaviors, - value: o.value - }); - - this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.IconTextValueComboPopup.EVENT_CHANGE, val, obj); - } - }); - - this.check(); - - BI.createWidget({ - type: "bi.vertical", - element: this, - vgap: 5, - items: [this.popup] - }); - }, - - populate: function (items, keyword) { - BI.IconTextValueComboPopup.superclass.populate.apply(this, arguments); - var o = this.options; - items = BI.createItems(items, { - type: "bi.single_select_icon_text_item", - iconWrapperWidth: o.iconWrapperWidth, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - }); - this.popup.populate(items, keyword); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - setValue: function (v) { - this.popup.setValue(v); - } - -}); -BI.IconTextValueComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.icon_text_value_combo_popup", BI.IconTextValueComboPopup); diff --git a/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js b/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js deleted file mode 100644 index baa653207..000000000 --- a/src/case/combo/searchtextvaluecombo/combo.searchtextvalue.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Created by Windy on 2018/2/2. - */ -BI.SearchTextValueCombo = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-search-text-value-combo", - height: 24, - text: "", - defaultText: "", - items: [], - tipType: "", - warningTitle: "", - allowClear: false, - }, - - render: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - - return { - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - container: o.container, - adjustLength: 2, - height: BI.toPix(o.height, o.simple ? 1 : 2), - width: BI.toPix(o.width, 2), - ref: function () { - self.combo = this; - }, - el: { - type: "bi.search_text_value_trigger", - cls: "search-text-value-trigger", - watermark: o.watermark, - ref: function () { - self.trigger = this; - }, - items: o.items, - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - defaultText: o.defaultText, - value: o.value, - tipType: o.tipType, - warningTitle: o.warningTitle, - title: o.title, - allowClear: o.allowClear, - listeners: [{ - eventName: BI.SearchTextValueTrigger.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()[0]); - self.combo.hideView(); - self.fireEvent(BI.SearchTextValueCombo.EVENT_CHANGE); - } - }, { - eventName: BI.SearchTextValueTrigger.EVENT_CLEAR, - action: function () { - self._clear(); - self.fireEvent(BI.SearchTextValueCombo.EVENT_CHANGE); - } - }] - }, - popup: { - el: { - type: "bi.text_value_combo_popup", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - value: o.value, - items: o.items, - ref: function () { - self.popup = this; - self.trigger.getSearcher().setAdapter(self.popup); - }, - listeners: [{ - eventName: BI.TextValueComboPopup.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()[0]); - self.combo.hideView(); - self.fireEvent(BI.SearchTextValueCombo.EVENT_CHANGE); - } - }] - }, - value: o.value, - maxHeight: 252, - minHeight: 25 - }, - listeners: [{ - eventName: BI.Combo.EVENT_AFTER_HIDEVIEW, - action: function () { - self.trigger.stopEditing(); - self.fireEvent(BI.SearchTextValueCombo.EVENT_AFTER_HIDEVIEW); - } - }, { - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.SearchTextValueCombo.EVENT_BEFORE_POPUPVIEW); - } - }], - }; - }, - - created: function () { - var o = this.options; - if (BI.isKey(o.value)) { - this._checkError(o.value); - } - }, - - _clear: function () { - this.setValue(); - }, - - _checkError: function (v) { - if (BI.isNull(v) || BI.isEmptyArray(v) || BI.isEmptyString(v)) { - this.trigger.options.tipType = "success"; - this.element.removeClass("combo-error"); - } else { - v = BI.isArray(v) ? v : [v]; - var result = BI.find(this.options.items, function (idx, item) { - return BI.contains(v, item.value); - }); - if (BI.isNull(result)) { - this.element.removeClass("combo-error").addClass("combo-error"); - this.trigger.attr("tipType", "warning"); - } else { - this.element.removeClass("combo-error"); - this.trigger.attr("tipType", "success"); - } - } - }, - - populate: function (items) { - this.options.items = items; - this.combo.populate(items); - }, - - setValue: function (v) { - this.combo.setValue(v); - this._checkError(v); - }, - - getValue: function () { - var value = this.combo.getValue(); - return BI.isNull(value) ? [] : (BI.isArray(value) ? value : [value]); - } -}); -BI.SearchTextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchTextValueCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.SearchTextValueCombo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW" -BI.shortcut("bi.search_text_value_combo", BI.SearchTextValueCombo); diff --git a/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js b/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js deleted file mode 100644 index dc1107fb1..000000000 --- a/src/case/combo/searchtextvaluecombo/popup.searchtextvalue.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Created by Windy on 2018/2/5. - */ -BI.SearchTextValueComboPopup = BI.inherit(BI.Pane, { - - props: { - baseCls: "bi-search-text-value-popup" - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vertical", - vgap: 5, - items: [{ - type: "bi.button_group", - ref: function () { - self.popup = this; - }, - items: this._formatItems(o.items), - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - layouts: [{ - type: "bi.vertical" - }], - behaviors: { - redmark: function () { - return true; - } - }, - value: o.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SearchTextValueComboPopup.EVENT_CHANGE, val, obj); - } - } - }] - }] - }; - }, - - _formatItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return BI.extend({ - type: "bi.single_select_item", - textAlign: o.textAlign, - title: item.title || item.text - }, item); - }); - }, - - // mounted之后做check - mounted: function() { - this.check(); - }, - - populate: function (find, match, keyword) { - var items = BI.concat(find, match); - BI.SearchTextValueComboPopup.superclass.populate.apply(this, items); - this.popup.populate(this._formatItems(items), keyword); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - setValue: function (v) { - this.popup.setValue(v); - } - -}); -BI.SearchTextValueComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.search_text_value_combo_popup", BI.SearchTextValueComboPopup); diff --git a/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js b/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js deleted file mode 100644 index 7f6f7925d..000000000 --- a/src/case/combo/searchtextvaluecombo/trigger.searchtextvalue.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - * Created by Windy on 2018/2/2. - */ -BI.SearchTextValueTrigger = BI.inherit(BI.Trigger, { - - props: function () { - return { - baseCls: "bi-search-text-value-trigger", - height: 24, - watermark: BI.i18nText("BI-Basic_Search"), - allowClear: false, - title: () => this.editor.getText(), - }; - }, - - render: function () { - var self = this, o = this.options; - - var triggerButton = { - type: "bi.trigger_icon_button", - cls: "trigger-icon-button", - ref: function () { - self.triggerBtn = this; - }, - width: o.height, - height: o.height, - }; - - var stateText = this._digest(o.value, o.items) || o.text; - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", 24], - items: [ - { - el: { - type: "bi.searcher", - ref: function () { - self.searcher = this; - }, - isAutoSearch: false, - el: { - type: "bi.default_text_editor", - ref: function () { - self.editor = this; - }, - watermark: o.watermark, - defaultText: o.defaultText, - text: stateText, - value: o.value, - height: o.height, - }, - popup: { - type: "bi.search_text_value_combo_popup", - cls: "bi-card", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - tipText: BI.i18nText("BI-No_Select"), - }, - onSearch: function (obj, callback) { - var keyword = obj.keyword; - var finding = BI.Func.getSearchResult(o.items, keyword); - var matched = finding.match, find = finding.find; - callback(matched, find); - }, - listeners: [{ - eventName: BI.Searcher.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.SearchTextValueTrigger.EVENT_CHANGE); - } - }] - } - }, { - el: o.allowClear ? { - type: "bi.vertical_adapt", - horizontalAlign: "left", - scrollable: false, - items: [ - { - el: { - type: "bi.icon_button", - ref: function (_ref) { - self.clearBtn = _ref; - }, - cls: "close-h-font " + (o.allowClear ? "clear-button" : ""), - stopPropagation: true, - invisible: !BI.isNotEmptyString(stateText), - width: o.height, - height: o.height, - handler: function () { - self.fireEvent(BI.SearchTextValueTrigger.EVENT_CLEAR); - }, - }, - }, { - el: triggerButton, - } - ] - } : triggerButton, - width: 24 - } - ] - }; - }, - - _setState: function (v) { - this.editor.setState(v); - }, - - _digest: function (value, items) { - var result = BI.find(items, function (i, item) { - return item.value === value; - }); - return result?.text; - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - getSearcher: function () { - return this.searcher; - }, - - populate: function (items) { - this.options.items = items; - }, - - setValue: function (vals) { - var digestText = this._digest(vals, this.options.items); - this._setState(digestText); - this.options.allowClear && this.clearBtn.setVisible(BI.isNotEmptyString(digestText)); - }, - - getValue: function () { - return this.searcher.getValue(); - } -}); -BI.SearchTextValueTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.SearchTextValueTrigger.EVENT_STOP = "EVENT_STOP"; -BI.SearchTextValueTrigger.EVENT_START = "EVENT_START"; -BI.SearchTextValueTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchTextValueTrigger.EVENT_CLEAR = "EVENT_CLEAR"; -BI.shortcut("bi.search_text_value_trigger", BI.SearchTextValueTrigger); diff --git a/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js b/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js deleted file mode 100644 index dd5013eba..000000000 --- a/src/case/combo/textvaluecheckcombo/combo.textvaluecheck.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @class BI.TextValueCheckCombo - * @extend BI.Widget - * combo : text + icon, popup : check + text - */ -BI.TextValueCheckCombo = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - return BI.extend(BI.TextValueCheckCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-text-value-check-combo " + (config.simple ? "bi-border-bottom" : "bi-border"), - width: 100, - height: 24, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - value: "", - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - BI.TextValueCheckCombo.superclass._init.apply(this, arguments); - this.trigger = BI.createWidget({ - type: "bi.select_text_trigger", - cls: "text-value-trigger", - items: o.items, - height: BI.toPix(o.height, 2), - text: o.text, - value: o.value, - defaultText: o.defaultText - }); - this.popup = BI.createWidget({ - type: "bi.text_value_check_combo_popup", - chooseType: o.chooseType, - items: o.items, - value: o.value - }); - this.popup.on(BI.TextValueCheckComboPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.textIconCheckCombo.hideView(); - self.fireEvent(BI.TextValueCheckCombo.EVENT_CHANGE); - }); - this.popup.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.textIconCheckCombo = BI.createWidget({ - type: "bi.combo", - container: o.container, - direction: o.direction, - element: this, - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - adjustLength: 2, - el: this.trigger, - popup: { - el: this.popup, - maxHeight: 300 - } - }); - - if (BI.isKey(o.value)) { - this.setValue(o.value); - } - }, - - setTitle: function (title) { - this.trigger.setTitle(title); - }, - - setValue: function (v) { - this.trigger.setValue(v); - this.popup.setValue(v); - }, - - setWarningTitle: function (title) { - this.trigger.setWarningTitle(title); - }, - - getValue: function () { - var value = this.popup.getValue(); - return BI.isNull(value) ? [] : (BI.isArray(value) ? value : [value]); - }, - - populate: function (items) { - this.options.items = items; - this.textIconCheckCombo.populate(items); - } -}); -BI.TextValueCheckCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_value_check_combo", BI.TextValueCheckCombo); diff --git a/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js b/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js deleted file mode 100644 index b25ccc141..000000000 --- a/src/case/combo/textvaluecheckcombo/popup.textvaluecheck.js +++ /dev/null @@ -1,64 +0,0 @@ -BI.TextValueCheckComboPopup = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.TextValueCheckComboPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-text-icon-popup", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE - }); - }, - - _init: function () { - BI.TextValueCheckComboPopup.superclass._init.apply(this, arguments); - var o = this.options, self = this; - this.popup = BI.createWidget({ - type: "bi.button_group", - items: this._formatItems(o.items), - chooseType: o.chooseType, - layouts: [{ - type: "bi.vertical" - }], - value: o.value - }); - - this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.TextValueCheckComboPopup.EVENT_CHANGE, val, obj); - } - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - vgap: 5, - items: [this.popup] - }); - }, - - _formatItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return BI.extend({ - type: "bi.single_select_item", - cls: "bi-list-item", - textAlign: o.textAlign, - title: item.title || item.text - }, item); - }); - }, - - populate: function (items) { - BI.TextValueCheckComboPopup.superclass.populate.apply(this, arguments); - this.popup.populate(this._formatItems(items)); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - setValue: function (v) { - this.popup.setValue(v); - } - -}); -BI.TextValueCheckComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_value_check_combo_popup", BI.TextValueCheckComboPopup); diff --git a/src/case/combo/textvaluecombo/combo.textvalue.js b/src/case/combo/textvaluecombo/combo.textvalue.js deleted file mode 100644 index bc43fce64..000000000 --- a/src/case/combo/textvaluecombo/combo.textvalue.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @class BI.TextValueCombo - * @extend BI.Widget - * combo : text + icon, popup : text - * 参见场景dashboard布局方式选择 - */ -BI.TextValueCombo = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - return BI.extend(BI.TextValueCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-text-value-combo " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - text: "", - value: "", - defaultText: "", - el: {}, - allowClear: false, - status: "success", // success | warning | error, - title: null, - allowSelectAll: true, - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - BI.TextValueCombo.superclass._init.apply(this, arguments); - }, - - render: function () { - - const o = this.options; - - const title = () => { - if (BI.isFunction(o.title)) { - return o.title(); - } - if (this.options.status === "error") { - return { - level: "warning", - text: o.warningTitle - }; - } - return { - level: "success" - }; - }; - - const trigger = { - type: "bi.select_text_trigger", - ref: ref => this.trigger = ref, - cls: "text-value-trigger", - items: o.items, - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - value: o.value, - title, - allowClear: o.allowClear, - defaultText: o.defaultText, - listeners: [ - { - eventName: BI.SelectTextTrigger.EVENT_CLEAR, - action: () => { - this._clear(); - this.fireEvent(BI.TextValueCombo.EVENT_CHANGE); - } - } - ], - ...o.el - }; - let changeTag = false; - const popup = { - type: "bi.text_value_combo_popup", - ref: ref => this.popup = ref, - chooseType: o.chooseType, - items: o.items, - allowSelectAll: o.allowSelectAll, - listeners: [ - { - eventName: BI.TextValueComboPopup.EVENT_CHANGE, - action: (...args) => { - changeTag = true; - const value = this.popup.getValue(); - this.setValue(value); - if (o.chooseType === BI.ButtonGroup.CHOOSE_TYPE_SINGLE) { - this.combo.hideView(...args); - this.fireEvent(BI.TextValueCombo.EVENT_CHANGE, ...args); - } - if (o.chooseType === BI.ButtonGroup.CHOOSE_TYPE_MULTI && BI.isEmptyArray(value)) { - this._clear(); - } - } - }, { - eventName: BI.Controller.EVENT_CHANGE, - action: (...args) => { - this.fireEvent(BI.Controller.EVENT_CHANGE, ...args); - } - }, { - eventName: BI.TextValueComboPopup.EVENT_CLEAR, - action: (...args) => { - changeTag = true; - this._clear(); - this.combo.hideView(); - } - }, { - eventName: BI.TextValueComboPopup.EVENT_CONFIRM, - action: (...args) => { - this.combo.hideView(); - } - } - ] - }; - - return { - type: "bi.combo", - height: BI.toPix(o.height, 2), - width: BI.toPix(o.width, 2), - ref: ref => this.combo = ref, - container: o.container, - direction: o.direction, - adjustLength: 2, - el: trigger, - listeners: [ - { - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: () => { - changeTag = false; - this.fireEvent(BI.TextValueCombo.EVENT_BEFORE_POPUPVIEW); - } - }, { - eventName: BI.Combo.EVENT_AFTER_HIDEVIEW, - action: (...args) => { - if (o.chooseType !== BI.ButtonGroup.CHOOSE_TYPE_SINGLE && changeTag) { - this.fireEvent(BI.TextValueCombo.EVENT_CHANGE, ...args); - } - } - } - ], - popup: { - el: popup, - value: o.value, - maxHeight: 240, - minHeight: (o.chooseType === BI.ButtonGroup.CHOOSE_TYPE_MULTI && o.allowSelectAll) ? 55 : 25 - } - }; - }, - - mounted: function () { - const o = this.options; - if (BI.isKey(o.value) || BI.isObject(o.value)) { - this._checkError(o.value); - } - }, - - _clear: function () { - this.trigger.setText(""); - this.combo.setValue(); - this.setStatus("success"); - }, - - _checkError: function (v) { - - if (BI.isNull(v)) { - this.setStatus("success"); - return; - } - - var vals = BI.isArray(v) ? v : [v]; - - var result = BI.intersection(BI.map(this.options.items, "value"), vals); - - if (result.length !== vals.length) { - this.setStatus("error"); - } else { - this.setStatus("success"); - } - }, - - clear: function () { - this._clear(); - }, - - setText: function (text) { - this.trigger.setText(text); - }, - - setValue: function (v) { - this.combo.setValue(v); - this._checkError(v); - }, - - setStatus: function (status) { - this.element.removeClass(`bi-status-${this.options.status}`); - this.element.addClass(`bi-status-${status}`); - this.options.status = status; - }, - - getValue: function () { - var value = this.combo.getValue(); - return BI.isNull(value) ? [] : (BI.isArray(value) ? value : [value]); - }, - - populate: function (items) { - this.options.items = items; - this.combo.populate(items); - } -}); -BI.TextValueCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.TextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_value_combo", BI.TextValueCombo); diff --git a/src/case/combo/textvaluecombo/combo.textvaluesmall.js b/src/case/combo/textvaluecombo/combo.textvaluesmall.js deleted file mode 100644 index 96678c736..000000000 --- a/src/case/combo/textvaluecombo/combo.textvaluesmall.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @class BI.SmallTextValueCombo - * @extend BI.Widget - * combo : text + icon, popup : text - * 参见场景dashboard布局方式选择 - */ -BI.SmallTextValueCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.SmallTextValueCombo.superclass._defaultConfig.apply(this, arguments), { - width: 100, - height: 20, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - el: {}, - text: "" - }); - }, - - render: function () { - var o = this.options; - return { - type: "bi.text_value_combo", - ref: (_ref) => { - this.combo = _ref; - }, - height: o.height, - chooseType: o.chooseType, - el: { - type: "bi.small_select_text_trigger", - ...o.el - }, - items: o.items, - text: o.text, - value: o.value, - defaultText: o.defaultText, - allowClear: o.allowClear, - status: o.status, - title: o.title, - listeners: [{ - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: (...args) => { - this.fireEvent(BI.SmallTextValueCombo.EVENT_CHANGE, ...args); - } - }] - } - }, - - setValue: function (v) { - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - populate: function (items) { - this.combo.populate(items); - } -}); -BI.SmallTextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.small_text_value_combo", BI.SmallTextValueCombo); diff --git a/src/case/combo/textvaluecombo/popup.textvalue.js b/src/case/combo/textvaluecombo/popup.textvalue.js deleted file mode 100644 index 9d3e3d004..000000000 --- a/src/case/combo/textvaluecombo/popup.textvalue.js +++ /dev/null @@ -1,186 +0,0 @@ -BI.TextValueComboPopup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.TextValueComboPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-text-icon-popup", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - allowSelectAll: true, - }); - }, - - render() { - var o = this.options, self = this; - if (o.chooseType !== BI.ButtonGroup.CHOOSE_TYPE_MULTI) { - return { - type: "bi.vertical", - vgap: 5, - items: [ - { - type: "bi.list_pane", - ref: (_ref) => { - this.popup = _ref; - }, - items: this._formatItems(o.items), - el: { - type: "bi.button_group", - chooseType: o.chooseType, - layouts: [ - { - type: "bi.vertical" - } - ], - }, - value: o.value, - listeners: [ - { - eventName: BI.Controller.EVENT_CHANGE, - action: function (type, val, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.TextValueComboPopup.EVENT_CHANGE, val, obj); - } - } - } - ] - } - ] - }; - } - return { - type: "bi.vertical", - verticalAlign: BI.VerticalAlign.Stretch, - items: o.allowSelectAll ? [ - { - type: "bi.select_list", - logic: { - dynamic: true, - innerVgap: 5, - rowSize: ["", "fill"], - verticalAlign: BI.VerticalAlign.Stretch - }, - ref: (_ref) => { - this.popup = _ref; - }, - el: { - el: { - chooseType: o.chooseType, - } - }, - items: this._formatItems(o.items), - value: { - type: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - value: o.value - }, - height: "fill", - listeners: [ - { - eventName: BI.SelectList.EVENT_CHANGE, - action: function (val) { - self.fireEvent(BI.TextValueComboPopup.EVENT_CHANGE, val); - } - } - ] - }, { - type: "bi.center", - cls: "list-view-toolbar bi-high-light bi-split-top", - height: 24, - items: BI.createItems([ - { - type: "bi.text_button", - text: BI.i18nText("BI-Basic_Clears"), - handler: function () { - self.fireEvent(BI.TextValueComboPopup.EVENT_CLEAR); - } - }, { - type: "bi.text_button", - text: BI.i18nText("BI-Basic_OK"), - handler: function () { - self.fireEvent(BI.TextValueComboPopup.EVENT_CONFIRM); - } - } - ], { - once: false, - shadow: true, - isShadowShowingOnSelected: true - }) - } - ] : [ - { - type: "bi.list_pane", - logic: { - dynamic: true, - innerVgap: 5, - rowSize: ["", "fill"], - verticalAlign: BI.VerticalAlign.Stretch - }, - ref: (_ref) => { - this.popup = _ref; - }, - el: { - chooseType: o.chooseType, - }, - items: this._formatItems(o.items), - value: o.value, - height: "fill", - listeners: [ - { - eventName: BI.ListPane.EVENT_CHANGE, - action: function (val) { - self.fireEvent(BI.TextValueComboPopup.EVENT_CHANGE, val); - } - } - ] - } - ], - }; - }, - - _formatItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return BI.extend({ - type: o.chooseType !== BI.ButtonGroup.CHOOSE_TYPE_MULTI ? "bi.single_select_item" : "bi.multi_select_item", - iconWrapperWidth: 36, - textAlign: o.textAlign, - title: item.title || item.text - }, item); - }); - }, - - populate: function (items) { - this.popup.populate(this._formatItems(items)); - }, - - getValue: function () { - if (this.options.chooseType !== BI.ButtonGroup.CHOOSE_TYPE_MULTI) { - return this.popup.getValue(); - } - var val = this.popup.getValue(); - if (!this.options.allowSelectAll) { - return val; - } - if (val.type === BI.ButtonGroup.CHOOSE_TYPE_MULTI) { - return val.value; - } else { - return val.assist; - } - }, - - setValue: function (v) { - if (this.options.chooseType !== BI.ButtonGroup.CHOOSE_TYPE_MULTI) { - return this.popup.setValue(v); - } - if (!this.options.allowSelectAll) { - this.popup.setValue(v); - return; - } - this.popup.setValue({ - type: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - value: v - }); - } - -}); -BI.TextValueComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.TextValueComboPopup.EVENT_CLEAR = "EVENT_CLEAR"; -BI.TextValueComboPopup.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.text_value_combo_popup", BI.TextValueComboPopup); diff --git a/src/case/editor/editor.clear.js b/src/case/editor/editor.clear.js deleted file mode 100644 index e18ab9599..000000000 --- a/src/case/editor/editor.clear.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * 有清楚按钮的文本框 - * Created by GUY on 2015/9/29. - * @class BI.SmallTextEditor - * @extends BI.SearchEditor - */ -BI.ClearEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.ClearEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-clear-editor", - height: 24, - errorText: "", - watermark: "", - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn - }); - }, - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - BI.ClearEditor.superclass._init.apply(this, arguments); - this.editor = BI.createWidget({ - type: "bi.editor", - simple: o.simple, - height: o.height, - watermark: o.watermark, - allowBlank: true, - errorText: o.errorText, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - value: o.value, - autoTrim: o.autoTrim, - }); - this.clear = BI.createWidget({ - type: "bi.icon_button", - stopEvent: true, - invisible: !BI.isKey(o.value), - cls: "search-close-h-font" - }); - this.clear.on(BI.IconButton.EVENT_CHANGE, function () { - self.setValue(""); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT); - self.fireEvent(BI.ClearEditor.EVENT_CLEAR); - }); - BI.createWidget({ - element: this, - type: "bi.htape", - items: [ - { - el: this.editor - }, - { - el: this.clear, - width: 24 - } - ] - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.ClearEditor.EVENT_FOCUS); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.ClearEditor.EVENT_BLUR); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.ClearEditor.EVENT_CLICK); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self._checkClear(); - self.fireEvent(BI.ClearEditor.EVENT_CHANGE); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.ClearEditor.EVENT_KEY_DOWN, v); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.ClearEditor.EVENT_SPACE); - }); - this.editor.on(BI.Editor.EVENT_BACKSPACE, function () { - self.fireEvent(BI.ClearEditor.EVENT_BACKSPACE); - }); - - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.ClearEditor.EVENT_VALID); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.fireEvent(BI.ClearEditor.EVENT_ERROR); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.ClearEditor.EVENT_ENTER); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.ClearEditor.EVENT_RESTRICT); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self._checkClear(); - self.fireEvent(BI.ClearEditor.EVENT_EMPTY); - }); - this.editor.on(BI.Editor.EVENT_REMOVE, function () { - self.fireEvent(BI.ClearEditor.EVENT_REMOVE); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self.fireEvent(BI.ClearEditor.EVENT_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self.fireEvent(BI.ClearEditor.EVENT_CHANGE_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.ClearEditor.EVENT_START); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.ClearEditor.EVENT_PAUSE); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.ClearEditor.EVENT_STOP); - }); - }, - - _checkClear: function () { - if (!this.getValue()) { - this.clear.invisible(); - } else { - this.clear.visible(); - } - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - getValue: function () { - if (this.isValid()) { - return this.editor.getValue(); - } - }, - - setValue: function (v) { - this.editor.setValue(v); - if (BI.isKey(v)) { - this.clear.visible(); - } - }, - - isValid: function () { - return this.editor.isValid(); - } -}); -BI.ClearEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.ClearEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ClearEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.ClearEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.ClearEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.ClearEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.ClearEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; -BI.ClearEditor.EVENT_CLEAR = "EVENT_CLEAR"; - -BI.ClearEditor.EVENT_START = "EVENT_START"; -BI.ClearEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.ClearEditor.EVENT_STOP = "EVENT_STOP"; -BI.ClearEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.ClearEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.ClearEditor.EVENT_VALID = "EVENT_VALID"; -BI.ClearEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.ClearEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.ClearEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.ClearEditor.EVENT_REMOVE = "EVENT_REMOVE"; -BI.ClearEditor.EVENT_EMPTY = "EVENT_EMPTY"; -BI.shortcut("bi.clear_editor", BI.ClearEditor); diff --git a/src/case/editor/editor.defaulttext.js b/src/case/editor/editor.defaulttext.js deleted file mode 100644 index fe88d27bb..000000000 --- a/src/case/editor/editor.defaulttext.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * dailer - * 有默认提示文字的输入框 - * @class BI.DefaultTextEditor - * @extends BI.Widget - */ -BI.DefaultTextEditor = BI.inherit(BI.Widget, { - props: function () { - return { - baseCls: "bi-default-text-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: true, - watermark: "", - errorText: "", - height: 24, - defaultText: "", // 默认显示值,默认显示值与显示值的区别是默认显示值标记灰色 - text: "", // 显示值 - el: {} - }; - }, - - render: function () { - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - invisible: true, - autoTrim: o.autoTrim, - }); - - var showText = BI.isFunction(o.text) ? o.text() : o.text; - - this.text = BI.createWidget({ - type: "bi.text_button", - cls: BI.isKey(showText) ? "tip-text-style" : "bi-water-mark tip-text-style", - textAlign: "left", - height: o.height, - text: showText || o.defaultText, - hgap: o.hgap + 2, - handler: function () { - self._showInput(); - self.editor.focus(); - self.editor.setValue(""); - }, - title: o.title, - warningTitle: o.warningTitle, - tipType: o.tipType - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - BI.nextTick(function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_CLICK_LABEL); - }); - }); - - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.DefaultTextEditor.EVENT_KEY_DOWN, arguments); - }); - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.DefaultTextEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.DefaultTextEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_START, arguments); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.DefaultTextEditor.EVENT_EMPTY, arguments); - }); - - return { - type: "bi.absolute", - items: [ - { - el: this.editor, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: this.text, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }; - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - setTitle: function (title) { - this.text.setTitle(title); - }, - - setWarningTitle: function (title) { - this.text.setWarningTitle(title); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - focus: function () { - if (this.options.disabled === false) { - this._showInput(); - this.editor.focus(); - } - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - _setText: function (v) { - this.text.setText(v); - this.text.setTitle(v); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (k) { - this.editor.setValue(k); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.text.getValue(); - }, - - setState: function (v) { - var o = this.options; - if (BI.isKey(v)) { - this.text.setText(v); - this.text.element.removeClass("bi-water-mark"); - return; - } - this.text.setText(o.defaultText); - this.text.element.addClass("bi-water-mark"); - }, - - setTipType: function (v) { - this.text.options.tipType = v; - }, - - getText: function () { - return this.text.getText(); - } -}); -BI.DefaultTextEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DefaultTextEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DefaultTextEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.DefaultTextEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.DefaultTextEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.DefaultTextEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.DefaultTextEditor.EVENT_START = "EVENT_START"; -BI.DefaultTextEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.DefaultTextEditor.EVENT_STOP = "EVENT_STOP"; -BI.DefaultTextEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DefaultTextEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.DefaultTextEditor.EVENT_VALID = "EVENT_VALID"; -BI.DefaultTextEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.DefaultTextEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.DefaultTextEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.DefaultTextEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.DefaultTextEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.default_text_editor", BI.DefaultTextEditor); diff --git a/src/case/editor/editor.shelter.js b/src/case/editor/editor.shelter.js deleted file mode 100644 index 4cb8e4d75..000000000 --- a/src/case/editor/editor.shelter.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * 带标记的文本框 - * Created by GUY on 2016/1/25. - * @class BI.ShelterEditor - * @extends BI.Widget - */ -BI.ShelterEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.ShelterEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-shelter-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: true, - watermark: "", - errorText: "", - height: 24, - textAlign: "left" - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - BI.ShelterEditor.superclass._init.apply(this, arguments); - this.editor = BI.createWidget({ - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - autoTrim: o.autoTrim, - }); - this.text = BI.createWidget({ - type: "bi.text_button", - cls: "shelter-editor-text", - title: o.title, - warningTitle: o.warningTitle, - tipType: o.tipType, - textAlign: o.textAlign, - height: o.height, - hgap: o.hgap + 2 - }); - this.text.on(BI.Controller.EVENT_CHANGE, function () { - arguments[2] = self; - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - self.fireEvent(BI.ShelterEditor.EVENT_CLICK_LABEL); - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.ShelterEditor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.ShelterEditor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.ShelterEditor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.ShelterEditor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.ShelterEditor.EVENT_KEY_DOWN, arguments); - }); - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.ShelterEditor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.ShelterEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.ShelterEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.ShelterEditor.EVENT_START, arguments); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.ShelterEditor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.ShelterEditor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.ShelterEditor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self._checkText(); - self.fireEvent(BI.ShelterEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.ShelterEditor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.ShelterEditor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.ShelterEditor.EVENT_EMPTY, arguments); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.text, - inset: 0, - }, { - el: this.editor, - inset: 0, - } - ] - }); - this._showHint(); - self._checkText(); - }, - - _checkText: function () { - var o = this.options; - BI.nextTick(BI.bind(function () { - if (this.editor.getValue() === "") { - this.text.setValue(o.watermark || ""); - this.text.element.addClass("bi-water-mark"); - } else { - this.text.setValue(this.editor.getValue()); - this.text.element.removeClass("bi-water-mark"); - } - BI.isKey(o.keyword) && this.text.doRedMark(o.keyword); - }, this)); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - setTitle: function (title) { - this.text.setTitle(title); - }, - - setWarningTitle: function (title) { - this.text.setWarningTitle(title); - }, - - focus: function () { - this._showInput(); - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - this._checkText(); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setTextStyle: function (style) { - this.text.setStyle(style); - }, - - setValue: function (k) { - var o = this.options; - this.editor.setValue(k); - this._checkText(); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.text.getValue(); - }, - - setState: function (v) { - this._showHint(); - this.text.setValue(v); - } -}); -BI.ShelterEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.ShelterEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ShelterEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.ShelterEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.ShelterEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.ShelterEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.ShelterEditor.EVENT_START = "EVENT_START"; -BI.ShelterEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.ShelterEditor.EVENT_STOP = "EVENT_STOP"; -BI.ShelterEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.ShelterEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.ShelterEditor.EVENT_VALID = "EVENT_VALID"; -BI.ShelterEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.ShelterEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.ShelterEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.ShelterEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.ShelterEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.shelter_editor", BI.ShelterEditor); diff --git a/src/case/editor/editor.sign.js b/src/case/editor/editor.sign.js deleted file mode 100644 index a624d78a2..000000000 --- a/src/case/editor/editor.sign.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * 带标记的文本框 - * Created by GUY on 2015/8/28. - * @class BI.SignEditor - * @extends BI.Widget - */ -BI.SignEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.SignEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-sign-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: true, - watermark: "", - errorText: "", - textAlign: "left", - height: 24 - }); - }, - - _init: function () { - var self = this, o = this.options; - o.value = BI.isFunction(o.value) ? this.__watch(o.value, function (context, newValue) { - self.setValue(newValue); - }) : o.value; - BI.SignEditor.superclass._init.apply(this, arguments); - this.editor = BI.createWidget({ - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - autoTrim: o.autoTrim, - }); - this.text = BI.createWidget({ - type: "bi.text_button", - cls: "sign-editor-text", - title: o.title, - warningTitle: o.warningTitle, - tipType: o.tipType, - textAlign: o.textAlign, - height: o.height, - hgap: o.hgap + 2, - handler: function () { - self._showInput(); - self.editor.focus(); - self.editor.selectAll(); - } - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - BI.nextTick(function () { - self.fireEvent(BI.SignEditor.EVENT_CLICK_LABEL); - }); - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.SignEditor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.SignEditor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.SignEditor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.SignEditor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.SignEditor.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.Editor.EVENT_QUICK_DOWN, function () { - self.fireEvent(BI.SignEditor.EVENT_QUICK_DOWN, arguments); - }); - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.SignEditor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.SignEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.SignEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.SignEditor.EVENT_START, arguments); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.SignEditor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.SignEditor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.SignEditor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self._checkText(); - self.fireEvent(BI.SignEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.SignEditor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.SignEditor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.SignEditor.EVENT_EMPTY, arguments); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.text, - inset: 0, - }, { - el: this.editor, - inset: 0, - } - ] - }); - this._showHint(); - self._checkText(); - }, - - _checkText: function () { - var o = this.options; - BI.nextTick(BI.bind(function () { - if (this.editor.getValue() === "") { - this.text.setValue(o.watermark || ""); - this.text.element.addClass("bi-water-mark"); - } else { - this.text.setValue(this.editor.getValue()); - this.text.element.removeClass("bi-water-mark"); - BI.isKey(o.keyword) && this.text.doRedMark(o.keyword); - } - }, this)); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - setTitle: function (title) { - this.text.setTitle(title); - }, - - setTipType: function (v) { - this.text.setTipType(v); - }, - - setWarningTitle: function (title) { - this.text.setWarningTitle(title); - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this._checkText(); - this.editor.setWaterMark(v); - }, - - focus: function () { - this._showInput(); - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - this._checkText(); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (k) { - this.editor.setValue(k); - this._checkText(); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.text.getValue(); - }, - - setState: function (v) { - this._showHint(); - this.text.setValue(v); - } -}); -BI.SignEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SignEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SignEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.SignEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.SignEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.SignEditor.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; -BI.SignEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.SignEditor.EVENT_START = "EVENT_START"; -BI.SignEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SignEditor.EVENT_STOP = "EVENT_STOP"; -BI.SignEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.SignEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.SignEditor.EVENT_VALID = "EVENT_VALID"; -BI.SignEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.SignEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.SignEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.SignEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.SignEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.sign_editor", BI.SignEditor); diff --git a/src/case/editor/editor.state.js b/src/case/editor/editor.state.js deleted file mode 100644 index 9c3f340f9..000000000 --- a/src/case/editor/editor.state.js +++ /dev/null @@ -1,309 +0,0 @@ -/** - * guy - * 记录状态的输入框 - * @class BI.StateEditor - * @extends BI.Single - */ -BI.StateEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.StateEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-state-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: true, - watermark: "", - errorText: "", - height: 24, - defaultText: BI.i18nText("BI-Basic_Unrestricted"), // 默认显示值,默认显示值与显示值的区别是默认显示值标记灰色 - text: "", // 显示值 - el: {} - }); - }, - - _init: function () { - BI.StateEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - autoTrim: o.autoTrim, - }); - this.text = BI.createWidget({ - type: "bi.text_button", - cls: "bi-water-mark tip-text-style", - textAlign: "left", - height: o.height, - text: o.text, - hgap: o.hgap + 2, - handler: function () { - self._showInput(); - self.editor.focus(); - self.editor.setValue(""); - }, - title: BI.isNotNull(o.tipText) ? o.tipText : function () { - var title = ""; - if (BI.isString(self.stateValue)) { - title = self.stateValue; - } - if (BI.isArray(self.stateValue) && self.stateValue.length === 1) { - title = self.stateValue[0]; - } - return title; - }, - warningTitle: o.warningTitle, - tipType: o.tipType - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - BI.nextTick(function () { - self.fireEvent(BI.StateEditor.EVENT_CLICK_LABEL); - }); - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.StateEditor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.StateEditor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.StateEditor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.StateEditor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.StateEditor.EVENT_KEY_DOWN, arguments); - }); - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.StateEditor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.StateEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.StateEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.StateEditor.EVENT_START, arguments); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.StateEditor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.StateEditor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.StateEditor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.fireEvent(BI.StateEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.StateEditor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.StateEditor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.StateEditor.EVENT_EMPTY, arguments); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.text, - inset: 0, - }, { - el: this.editor, - inset: 0, - } - ] - }); - this._showHint(); - if (BI.isNotNull(o.text)) { - this.setState(o.text); - } - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - focus: function () { - if (this.options.disabled === false) { - this._showInput(); - this.editor.focus(); - } - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - _setText: function (v) { - this.text.setText(v); - this.text.setTitle(v); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (k) { - this.editor.setValue(k); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.editor.getValue().match(/[^\s]+/g); - }, - - setState: function (v) { - var o = this.options; - var defaultText = BI.isFunction(o.defaultText) ? o.defaultText() : o.defaultText; - BI.StateEditor.superclass.setValue.apply(this, arguments); - this.stateValue = v; - if (BI.isNumber(v)) { - if (v === BI.Selection.All) { - this._setText(BI.i18nText("BI-Select_All")); - this.text.element.removeClass("bi-water-mark"); - } else if (v === BI.Selection.Multi) { - this._setText(BI.i18nText("BI-Select_Part")); - this.text.element.removeClass("bi-water-mark"); - } else { - this._setText(BI.isKey(defaultText) ? defaultText : o.text); - BI.isKey(defaultText) ? this.text.element.addClass("bi-water-mark") : this.text.element.removeClass("bi-water-mark"); - } - return; - } - if (BI.isString(v)) { - this._setText(v); - // 配置了defaultText才判断标灰,其他情况不标灰 - (BI.isKey(defaultText) && defaultText === v) ? this.text.element.addClass("bi-water-mark") : this.text.element.removeClass("bi-water-mark"); - return; - } - if (BI.isArray(v)) { - if (BI.isEmpty(v)) { - this._setText(BI.isKey(defaultText) ? defaultText : o.text); - BI.isKey(defaultText) ? this.text.element.addClass("bi-water-mark") : this.text.element.removeClass("bi-water-mark"); - } else if (v.length === 1) { - this._setText(v[0]); - this.text.element.removeClass("bi-water-mark"); - } else { - this._setText(BI.i18nText("BI-Select_Part")); - this.text.element.removeClass("bi-water-mark"); - } - } - }, - - setTipType: function (v) { - this.text.options.tipType = v; - }, - - getText: function () { - return this.text.getText(); - } -}); -BI.StateEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.StateEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.StateEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.StateEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.StateEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.StateEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.StateEditor.EVENT_START = "EVENT_START"; -BI.StateEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.StateEditor.EVENT_STOP = "EVENT_STOP"; -BI.StateEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.StateEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.StateEditor.EVENT_VALID = "EVENT_VALID"; -BI.StateEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.StateEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.StateEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.StateEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.StateEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.state_editor", BI.StateEditor); diff --git a/src/case/editor/editor.state.simple.js b/src/case/editor/editor.state.simple.js deleted file mode 100644 index 96be87aa1..000000000 --- a/src/case/editor/editor.state.simple.js +++ /dev/null @@ -1,288 +0,0 @@ -/** - * 无限制-已选择状态输入框 - * Created by GUY on 2016/5/18. - * @class BI.SimpleStateEditor - * @extends BI.Single - */ -BI.SimpleStateEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.SimpleStateEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-simple-state-editor", - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - mouseOut: false, - allowBlank: true, - watermark: "", - errorText: "", - height: 24, - text: "", - defaultText: BI.i18nText("BI-Basic_Unrestricted"), - }); - }, - - _init: function () { - BI.SimpleStateEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - autoTrim: o.autoTrim, - }); - this.text = BI.createWidget({ - type: "bi.text_button", - cls: "bi-water-mark", - textAlign: "left", - text: o.text, - height: o.height, - hgap: o.hgap + 2, - handler: function () { - self._showInput(); - self.editor.focus(); - self.editor.setValue(""); - } - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - BI.nextTick(function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_CLICK_LABEL); - }); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.text, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_BLUR, arguments); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_CLICK, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.SimpleStateEditor.EVENT_KEY_DOWN, arguments); - }); - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_VALID, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.SimpleStateEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self.fireEvent(BI.SimpleStateEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_START, arguments); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_PAUSE, arguments); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_STOP, arguments); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_SPACE, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_ENTER, arguments); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_RESTRICT, arguments); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.SimpleStateEditor.EVENT_EMPTY, arguments); - }); - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [this.editor] - }); - this._showHint(); - if (BI.isNotNull(o.text)) { - this.setState(o.text); - } - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - focus: function () { - this._showInput(); - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - _setText: function (v) { - this.text.setText(v); - this.text.setTitle(v); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (k) { - this.editor.setValue(k); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.editor.getValue().match(/[^\s]+/g); - }, - - setState: function (v) { - var o = this.options; - BI.SimpleStateEditor.superclass.setValue.apply(this, arguments); - var defaultText = BI.isFunction(o.defaultText) ? o.defaultText() : o.defaultText; - if (BI.isNumber(v)) { - if (v === BI.Selection.All) { - this._setText(BI.i18nText("BI-Already_Selected")); - this.text.element.removeClass("bi-water-mark"); - } else if (v === BI.Selection.Multi) { - this._setText(BI.i18nText("BI-Already_Selected")); - this.text.element.removeClass("bi-water-mark"); - } else { - this._setText(BI.isKey(defaultText) ? defaultText : o.text); - this.text.element.addClass("bi-water-mark"); - } - return; - } - if (!BI.isArray(v) || v.length === 1) { - this._setText(v); - this.text.element.removeClass("bi-water-mark"); - } else if (BI.isEmpty(v)) { - this._setText(o.text); - this.text.element.addClass("bi-water-mark"); - } else { - this._setText(BI.i18nText("BI-Already_Selected")); - this.text.element.removeClass("bi-water-mark"); - } - }, - - getText: function () { - return this.text.getText(); - } -}); -BI.SimpleStateEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SimpleStateEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SimpleStateEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.SimpleStateEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.SimpleStateEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.SimpleStateEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.SimpleStateEditor.EVENT_START = "EVENT_START"; -BI.SimpleStateEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SimpleStateEditor.EVENT_STOP = "EVENT_STOP"; -BI.SimpleStateEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.SimpleStateEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.SimpleStateEditor.EVENT_VALID = "EVENT_VALID"; -BI.SimpleStateEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.SimpleStateEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.SimpleStateEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.SimpleStateEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.SimpleStateEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.simple_state_editor", BI.SimpleStateEditor); diff --git a/src/case/layer/layer.multipopup.js b/src/case/layer/layer.multipopup.js deleted file mode 100644 index 5b69dabe3..000000000 --- a/src/case/layer/layer.multipopup.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 下拉框弹出层的多选版本,toolbar带有若干按钮, zIndex在1000w - * @class BI.MultiPopupView - * @extends BI.Widget - */ - -BI.MultiPopupView = BI.inherit(BI.PopupView, { - - _defaultConfig: function () { - var conf = BI.MultiPopupView.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - _baseCls: (conf._baseCls || "") + " bi-multi-list-view", - buttons: [BI.i18nText("BI-Basic_OK")] - }); - }, - - _createToolBar: function () { - var o = this.options, self = this; - if (o.buttons.length === 0) { - return; - } - - var text = []; // 构造[{text:content},……] - BI.each(o.buttons, function (idx, item) { - text.push({ - text: item, - value: idx - }); - }); - - this.buttongroup = BI.createWidget({ - type: "bi.button_group", - cls: "list-view-toolbar bi-high-light bi-split-top", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - items: BI.createItems(text, { - type: "bi.text_button", - once: false, - shadow: true, - isShadowShowingOnSelected: true - }), - layouts: [{ - type: "bi.center", - hgap: 0, - vgap: 0 - }] - }); - - this.buttongroup.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { - self.fireEvent(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, value, obj); - }); - - return this.buttongroup; - } - -}); - -BI.MultiPopupView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; - -BI.shortcut("bi.multi_popup_view", BI.MultiPopupView); diff --git a/src/case/layer/layer.panel.js b/src/case/layer/layer.panel.js deleted file mode 100644 index c136cc0e9..000000000 --- a/src/case/layer/layer.panel.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * 可以理解为MultiPopupView和Panel两个面板的结合体 - * @class BI.PopupPanel - * @extends BI.MultiPopupView - */ - -BI.PopupPanel = BI.inherit(BI.MultiPopupView, { - - _defaultConfig: function () { - var conf = BI.PopupPanel.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-popup-panel", - title: "" - }); - }, - - _createTool: function () { - var self = this, o = this.options; - var close = BI.createWidget({ - type: "bi.icon_button", - cls: "close-h-font", - width: 25, - height: 25 - }); - close.on(BI.IconButton.EVENT_CHANGE, function () { - self.setVisible(false); - self.fireEvent(BI.PopupPanel.EVENT_CLOSE); - }); - return BI.createWidget({ - type: "bi.htape", - cls: "popup-panel-title bi-header-background", - height: 25, - items: [{ - el: { - type: "bi.label", - textAlign: "left", - text: o.title, - height: 25, - lgap: 10 - } - }, { - el: close, - width: 25 - }] - }); - } -}); - -BI.PopupPanel.EVENT_CHANGE = "EVENT_CHANGE"; -BI.PopupPanel.EVENT_CLOSE = "EVENT_CLOSE"; -BI.PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; - -BI.shortcut("bi.popup_panel", BI.PopupPanel); diff --git a/src/case/layer/pane.list.js b/src/case/layer/pane.list.js deleted file mode 100644 index 01b24e7ae..000000000 --- a/src/case/layer/pane.list.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * list面板 - * - * Created by GUY on 2015/10/30. - * @class BI.ListPane - * @extends BI.Pane - */ -BI.ListPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - var conf = BI.ListPane.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-list-pane", - logic: { - dynamic: true - }, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - vgap: 0, - hgap: 0, - items: [], - itemsCreator: BI.emptyFn, - hasNext: BI.emptyFn, - onLoaded: BI.emptyFn, - el: { - type: "bi.button_group" - } - }); - }, - _init: function () { - BI.ListPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.button_group = BI.createWidget(o.el, { - type: "bi.button_group", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - behaviors: {}, - items: o.items, - value: o.value, - itemsCreator: function (op, calback) { - if (op.times === 1) { - self.empty(); - BI.nextTick(function () { - self.loading(); - }); - } - o.itemsCreator(op, function () { - calback.apply(self, arguments); - o.items = BI.concat(o.items, BI.get(arguments, [0], [])); - if (op.times === 1) { - o.items = BI.get(arguments, [0], []); - BI.nextTick(function () { - self.loaded(); - // callback可能在loading之前执行, check保证显示正确 - self.check(); - }); - } - }); - }, - hasNext: o.hasNext, - layouts: [ - { - type: "bi.vertical" - } - ] - }); - - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.ListPane.EVENT_CHANGE, value, obj); - } - }); - this.check(); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Top), BI.extend({ - scrolly: true, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - hgap: o.hgap - }, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Top, this.button_group) - })))); - }, - - hasPrev: function () { - return this.button_group.hasPrev && this.button_group.hasPrev(); - }, - - hasNext: function () { - return this.button_group.hasNext && this.button_group.hasNext(); - }, - - prependItems: function (items) { - this.options.items = items.concat(this.options.items); - this.button_group.prependItems.apply(this.button_group, arguments); - this.check(); - }, - - addItems: function (items) { - this.options.items = this.options.items.concat(items); - this.button_group.addItems.apply(this.button_group, arguments); - this.check(); - }, - - removeItemAt: function (indexes) { - indexes = BI.isNull(indexes) ? [] : indexes; - BI.removeAt(this.options.items, indexes); - this.button_group.removeItemAt.apply(this.button_group, arguments); - this.check(); - }, - - populate: function (items) { - var self = this, o = this.options; - if (arguments.length === 0 && (BI.isFunction(this.button_group.attr("itemsCreator")))) {// 接管loader的populate方法 - this.button_group.attr("itemsCreator").apply(this, [ - { times: 1 }, function () { - if (arguments.length === 0) { - throw new Error("Parameter cannot be empty"); - } - self.populate.apply(self, arguments); - } - ]); - return; - } - - var context = BI.get(arguments, [2], {}); - var tipText = context.tipText || ''; - if (BI.isNotEmptyString(tipText)) { - BI.ListPane.superclass.populate.apply(this, []); - this.setTipText(tipText); - } else { - BI.ListPane.superclass.populate.apply(this, arguments); - this.button_group.populate.apply(this.button_group, arguments); - BI.isEmptyArray(BI.get(arguments, [0], [])) && this.setTipText(o.tipText); - } - }, - - empty: function () { - this.button_group.empty(); - }, - - setNotSelectedValue: function () { - this.button_group.setNotSelectedValue.apply(this.button_group, arguments); - }, - - getNotSelectedValue: function () { - return this.button_group.getNotSelectedValue(); - }, - - setValue: function () { - this.button_group.setValue.apply(this.button_group, arguments); - }, - - setAllSelected: function (v) { - if (this.button_group.setAllSelected) { - this.button_group.setAllSelected(v); - } else { - BI.each(this.getAllButtons(), function (i, btn) { - (btn.setSelected || btn.setAllSelected).apply(btn, [v]); - }); - } - }, - - getValue: function () { - return this.button_group.getValue.apply(this.button_group, arguments); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - getAllLeaves: function () { - return this.button_group.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.button_group.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.button_group.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.button_group.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.button_group.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.button_group.getNodeByValue(value); - } -}); -BI.ListPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.list_pane", BI.ListPane); diff --git a/src/case/layer/panel.js b/src/case/layer/panel.js deleted file mode 100644 index 4ec115b51..000000000 --- a/src/case/layer/panel.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * 带有标题栏的pane - * @class BI.Panel - * @extends BI.Widget - */ -BI.Panel = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Panel.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-panel bi-border", - title: "", - titleHeight: 30, - titleButtons: [], - el: {}, - // logic: { - // dynamic: false - // } - }); - }, - - render: function () { - return { - type: "bi.vertical_fill", - rowSize: ["", "fill"], - items: [this._createTitle(), this.options.el] - }; - }, - - _createTitle: function () { - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - cls: "panel-title-text", - text: o.title, - height: o.titleHeight - }); - - this.button_group = BI.createWidget({ - type: "bi.button_group", - items: o.titleButtons, - layouts: [{ - type: "bi.center_adapt", - lgap: 10 - }] - }); - - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.button_group.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { - self.fireEvent(BI.Panel.EVENT_CHANGE, value, obj); - }); - - return { - // el: { - type: "bi.left_right_vertical_adapt", - cls: "panel-title bi-header-background bi-border-bottom", - height: BI.toPix(o.titleHeight, 1), - items: { - left: [this.text], - right: [this.button_group] - }, - lhgap: 10, - rhgap: 10 - // }, - // height: BI.toPix(o.titleHeight, 1) - }; - }, - - setTitle: function (title) { - this.text.setValue(title); - } -}); -BI.Panel.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.panel", BI.Panel); diff --git a/src/case/linearsegment/button.linear.segment.js b/src/case/linearsegment/button.linear.segment.js deleted file mode 100644 index c9954925c..000000000 --- a/src/case/linearsegment/button.linear.segment.js +++ /dev/null @@ -1,55 +0,0 @@ -BI.LinearSegmentButton = BI.inherit(BI.BasicButton, { - - props: { - extraCls: "bi-line-segment-button bi-list-item-effect", - once: true, - readonly: true, - hgap: 10, - height: 24 - }, - - render: function () { - var self = this, o = this.options; - - return [{ - type: "bi.label", - text: o.text, - height: o.height, - textHeight: BI.toPix(o.height, 2), - value: o.value, - hgap: o.hgap, - ref: function () { - self.text = this; - } - }, { - type: "bi.absolute", - items: [{ - el: { - type: "bi.layout", - cls: "line-segment-button-line", - height: 2, - ref: function () { - self.line = this; - } - }, - left: 0, - right: 0, - bottom: 0 - }] - }]; - }, - - setSelected: function (v) { - BI.LinearSegmentButton.superclass.setSelected.apply(this, arguments); - if (v) { - this.line.element.addClass("bi-high-light-background"); - } else { - this.line.element.removeClass("bi-high-light-background"); - } - }, - - setText: function (text) { - this.text.setText(text); - } -}); -BI.shortcut("bi.linear_segment_button", BI.LinearSegmentButton); diff --git a/src/case/linearsegment/linear.segment.js b/src/case/linearsegment/linear.segment.js deleted file mode 100644 index 41d282263..000000000 --- a/src/case/linearsegment/linear.segment.js +++ /dev/null @@ -1,60 +0,0 @@ -BI.LinearSegment = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-linear-segment", - items: [], - height: 30 - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.button_group", - items: [BI.createItems(o.items, { - type: "bi.linear_segment_button", - height: o.height - })], - layouts: [{ - type: "bi.table", - columnSize: BI.makeArrayByArray(o.items, "fill"), - }], - value: o.value, - listeners: [{ - eventName: "__EVENT_CHANGE__", - action: function () { - self.fireEvent("__EVENT_CHANGE__", arguments); - } - }, { - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }], - ref: function () { - self.buttonGroup = this; - } - }; - }, - - setValue: function (v) { - this.buttonGroup.setValue(v); - }, - - setEnabledValue: function (v) { - this.buttonGroup.setEnabledValue(v); - }, - - - getValue: function () { - return this.buttonGroup.getValue(); - }, - - populate: function (buttons) { - var o = this.options; - this.buttonGroup.populate([BI.createItems(buttons, { - type: "bi.linear_segment_button", - height: o.height - })]) - }, -}); -BI.shortcut("bi.linear_segment", BI.LinearSegment); diff --git a/src/case/list/list.select.js b/src/case/list/list.select.js deleted file mode 100644 index dfb3d7c1a..000000000 --- a/src/case/list/list.select.js +++ /dev/null @@ -1,236 +0,0 @@ -/** - * 选择列表 - * - * Created by GUY on 2015/11/1. - * @class BI.SelectList - * @extends BI.Widget - */ -BI.SelectList = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SelectList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-list", - direction: BI.Direction.Top, // toolbar的位置 - logic: { - dynamic: true - }, - items: [], - itemsCreator: BI.emptyFn, - hasNext: BI.emptyFn, - onLoaded: BI.emptyFn, - toolbar: { - type: "bi.multi_select_bar", - iconWrapperWidth: 36 - }, - el: { - type: "bi.list_pane" - } - }); - }, - _init: function () { - BI.SelectList.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - // 全选 - this.toolbar = BI.createWidget(o.toolbar); - this.allSelected = false; - this.toolbar.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.allSelected = this.isSelected(); - if (type === BI.Events.CLICK) { - self.setAllSelected(self.allSelected); - self.fireEvent(BI.SelectList.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.list = BI.createWidget(o.el, { - type: "bi.list_pane", - items: o.items, - itemsCreator: function (op, callback) { - op.times === 1 && self.toolbar.setVisible(false); - o.itemsCreator(op, function (items, keywords, context) { - callback.apply(self, arguments); - if (op.times === 1) { - var tipText = BI.get(context, 'tipText', ''); - var visible = BI.isEmptyString(tipText) && items && items.length > 0; - self.toolbar.setVisible(visible); - self.toolbar.setEnable(self.isEnabled() && visible); - } - self._checkAllSelected(); - }); - }, - onLoaded: o.onLoaded, - hasNext: o.hasNext - }); - - this.list.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - self._checkAllSelected(); - self.fireEvent(BI.SelectList.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ - scrolly: true - }, o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.toolbar, this.list) - })))); - - if (o.items.length <= 0) { - this.toolbar.setVisible(false); - this.toolbar.setEnable(false); - } - if(BI.isNotNull(o.value)){ - this.setValue(o.value); - } - }, - - _checkAllSelected: function () { - var selectLength = this.list.getValue().length; - var notSelectLength = this.getAllLeaves().length - selectLength; - var hasNext = this.list.hasNext(); - var isAlreadyAllSelected = this.toolbar.isSelected(); - var isHalf = selectLength > 0 && notSelectLength > 0; - var allSelected = selectLength > 0 && notSelectLength <= 0 && (!hasNext || isAlreadyAllSelected); - - if (this.isAllSelected() === false) { - hasNext && (isHalf = selectLength > 0); - if (!isAlreadyAllSelected && notSelectLength === 0 && !hasNext) { - allSelected = true; - } - } else { - hasNext && (isHalf = notSelectLength > 0); - if (!isAlreadyAllSelected && notSelectLength === 0) { - allSelected = true; - } - } - - this.toolbar.setHalfSelected(isHalf); - !isHalf && this.toolbar.setSelected(allSelected); - }, - - setAllSelected: function (v) { - if (this.list.setAllSelected) { - this.list.setAllSelected(v); - } else { - BI.each(this.getAllButtons(), function (i, btn) { - (btn.setSelected || btn.setAllSelected).apply(btn, [v]); - }); - } - this.allSelected = !!v; - this.toolbar.setSelected(v); - this.toolbar.setHalfSelected(false); - }, - - setToolBarVisible: function (b) { - this.toolbar.setVisible(b); - }, - - isAllSelected: function () { - return this.allSelected; - // return this.toolbar.isSelected(); - }, - - hasPrev: function () { - return this.list.hasPrev(); - }, - - hasNext: function () { - return this.list.hasNext(); - }, - - prependItems: function (items) { - this.list.prependItems.apply(this.list, arguments); - }, - - addItems: function (items) { - this.list.addItems.apply(this.list, arguments); - }, - - setValue: function (data) { - var selectAll = data.type === BI.ButtonGroup.CHOOSE_TYPE_ALL; - this.setAllSelected(selectAll); - this.list[selectAll ? "setNotSelectedValue" : "setValue"](data.value); - this._checkAllSelected(); - }, - - getValue: function () { - if (this.isAllSelected() === false) { - return { - type: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - value: this.list.getValue(), - assist: this.list.getNotSelectedValue() - }; - } - return { - type: BI.ButtonGroup.CHOOSE_TYPE_ALL, - value: this.list.getNotSelectedValue(), - assist: this.list.getValue() - }; - - }, - - empty: function () { - this.list.empty(); - }, - - populate: function (items) { - this.toolbar.setVisible(!BI.isEmptyArray(items)); - this.toolbar.setEnable(this.isEnabled() && !BI.isEmptyArray(items)); - this.list.populate.apply(this.list, arguments); - this._checkAllSelected(); - }, - - _setEnable: function (enable) { - BI.SelectList.superclass._setEnable.apply(this, arguments); - this.toolbar.setEnable(enable); - }, - - resetHeight: function (h) { - var toolHeight = ( this.toolbar.element.outerHeight() || 25) * ( this.toolbar.isVisible() ? 1 : 0); - this.list.resetHeight ? this.list.resetHeight(h - toolHeight) : - this.list.element.css({"max-height": BI.pixFormat(h - toolHeight)}); - }, - - setNotSelectedValue: function () { - this.list.setNotSelectedValue.apply(this.list, arguments); - this._checkAllSelected(); - }, - - getNotSelectedValue: function () { - return this.list.getNotSelectedValue(); - }, - - getAllButtons: function () { - return this.list.getAllButtons(); - }, - - getAllLeaves: function () { - return this.list.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.list.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.list.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.list.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.list.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.list.getNodeByValue(value); - } -}); -BI.SelectList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.select_list", BI.SelectList); diff --git a/src/case/loader/loader.lazy.js b/src/case/loader/loader.lazy.js deleted file mode 100644 index 339940077..000000000 --- a/src/case/loader/loader.lazy.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Created by roy on 15/11/6. - */ -BI.LazyLoader = BI.inherit(BI.Widget, { - _const: { - PAGE: 100 - }, - _defaultConfig: function () { - return BI.extend(BI.LazyLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-lazy-loader", - el: {}, - items: [] - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.LazyLoader.superclass._init.apply(this, arguments); - var all = o.items.length; - this.loader = BI.createWidget({ - type: "bi.loader", - element: this, - // 下面是button_group的属性 - el: o.el, - - itemsCreator: function (options, populate) { - populate(self._getNextItems(options)); - }, - hasNext: function (option) { - return option.count < all; - } - }); - - this.loader.on(BI.Loader.EVENT_CHANGE, function (obj) { - self.fireEvent(BI.LazyLoader.EVENT_CHANGE, obj); - }); - }, - _getNextItems: function (options) { - var self = this, o = this.options; - var lastNum = o.items.length - this._const.PAGE * (options.times - 1); - var lastItems = BI.takeRight(o.items, lastNum); - var nextItems = BI.take(lastItems, this._const.PAGE); - return nextItems; - }, - - populate: function (items) { - this.loader.populate(items); - }, - - addItems: function (items) { - this.loader.addItems(items); - }, - - empty: function () { - this.loader.empty(); - }, - - setNotSelectedValue: function () { - this.loader.setNotSelectedValue.apply(this.loader, arguments); - }, - - getNotSelectedValue: function () { - return this.loader.getNotSelectedValue(); - }, - - setValue: function () { - this.loader.setValue.apply(this.loader, arguments); - }, - - getValue: function () { - return this.loader.getValue.apply(this.loader, arguments); - }, - - getAllButtons: function () { - return this.loader.getAllButtons(); - }, - - getAllLeaves: function () { - return this.loader.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.loader.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.loader.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.loader.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.loader.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.loader.getNodeByValue(value); - } -}); -BI.LazyLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.lazy_loader", BI.LazyLoader); \ No newline at end of file diff --git a/src/case/loader/loader.list.js b/src/case/loader/loader.list.js deleted file mode 100644 index 4339aac21..000000000 --- a/src/case/loader/loader.list.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * 恶心的加载控件, 为解决排序问题引入的控件 - * - * Created by GUY on 2015/11/12. - * @class BI.ListLoader - * @extends BI.Widget - */ -BI.ListLoader = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.ListLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-loader", - - isDefaultInit: true, // 是否默认初始化数据 - - // 下面是button_group的属性 - el: { - type: "bi.button_group" - }, - - items: [], - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, - - // 下面是分页信息 - count: false, - next: {}, - hasNext: BI.emptyFn - }); - }, - - _nextLoad: function () { - var self = this, o = this.options; - this.next.setLoading(); - o.itemsCreator.apply(this, [ - { times: ++this.times }, function () { - self.next.setLoaded(); - self.addItems.apply(self, arguments); - } - ]); - }, - - _init: function () { - BI.ListLoader.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (o.itemsCreator === false) { - o.next = false; - } - - this.button_group = BI.createWidget(o.el, { - type: "bi.button_group", - element: this, - chooseType: 0, - items: o.items, - behaviors: {}, - layouts: [ - { - type: "bi.vertical" - } - ] - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.ListLoader.EVENT_CHANGE, obj); - } - }); - - if (o.next !== false) { - this.next = BI.createWidget(BI.extend({ - type: "bi.loading_bar" - }, o.next)); - this.next.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._nextLoad(); - } - }); - } - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.next] - }); - - o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { - this.populate(); - }, this)); - if (BI.isNotEmptyArray(o.items)) { - this.populate(o.items); - } - }, - - hasNext: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; - } - return !!o.hasNext.apply(this, [ - { - times: this.times, - count: this.count - } - ]); - }, - - addItems: function (items) { - this.count += items.length; - if (BI.isObject(this.next)) { - this.options.items = this.options.items.concat(items); - if (this.hasNext()) { - this.next.setLoaded(); - } else { - this.next.setEnd(); - } - } - this.button_group.addItems.apply(this.button_group, arguments); - this.next.element.appendTo(this.element); - }, - - populate: function (items) { - var self = this, o = this.options; - if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { - o.itemsCreator.apply(this, [ - { times: 1 }, function () { - if (arguments.length === 0) { - throw new Error("Parameter cannot be empty"); - } - self.populate.apply(self, arguments); - o.onLoaded(); - } - ]); - return; - } - this.options.items = items; - this.times = 1; - this.count = 0; - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.next.setLoaded(); - } else { - this.next.invisible(); - } - } - BI.DOM.hang([this.next]); - this.button_group.populate.apply(this.button_group, arguments); - this.next.element.appendTo(this.element); - }, - - empty: function () { - BI.DOM.hang([this.next]); - this.button_group.empty(); - this.next.element.appendTo(this.element); - BI.each([this.next], function (i, ob) { - ob && ob.setVisible(false); - }); - }, - - setNotSelectedValue: function () { - this.button_group.setNotSelectedValue.apply(this.button_group, arguments); - }, - - getNotSelectedValue: function () { - return this.button_group.getNotSelectedValue(); - }, - - setValue: function () { - this.button_group.setValue.apply(this.button_group, arguments); - }, - - getValue: function () { - return this.button_group.getValue.apply(this.button_group, arguments); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - getAllLeaves: function () { - return this.button_group.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.button_group.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.button_group.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.button_group.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.button_group.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.button_group.getNodeByValue(value); - } -}); -BI.ListLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.list_loader", BI.ListLoader); diff --git a/src/case/loader/sort.list.js b/src/case/loader/sort.list.js deleted file mode 100644 index c4606a7cb..000000000 --- a/src/case/loader/sort.list.js +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Created by GUY on 2016/4/29. - * - * @class BI.SortList - * @extends BI.Widget - */ -BI.SortList = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.SortList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-sort-list", - - isDefaultInit: true, // 是否默认初始化数据 - - // 下面是button_group的属性 - el: { - type: "bi.button_group" - }, - - items: [], - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, - - // 下面是分页信息 - count: false, - next: {}, - hasNext: BI.emptyFn - - // containment: this.element, - // connectWith: ".bi-sort-list", - }); - }, - - _init: function () { - BI.SortList.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.loader = BI.createWidget({ - type: "bi.list_loader", - element: this, - isDefaultInit: o.isDefaultInit, - el: o.el, - items: this._formatItems(o.items), - itemsCreator: function (op, callback) { - o.itemsCreator(op, function (items) { - callback(self._formatItems(items)); - }); - }, - onLoaded: o.onLoaded, - count: o.count, - next: o.next, - hasNext: o.hasNext - }); - this.loader.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SortList.EVENT_CHANGE, value, obj); - } - }); - - this.loader.element.sortable({ - containment: o.containment || this.element, - connectWith: o.connectWith || ".bi-sort-list", - items: ".sort-item", - cursor: o.cursor || "drag", - tolerance: o.tolerance || "intersect", - placeholder: { - element: function ($currentItem) { - var holder = BI.createWidget({ - type: "bi.layout", - cls: "bi-sortable-holder", - height: $currentItem.outerHeight() - }); - holder.element.css({ - "margin-left": $currentItem.css("margin-left"), - "margin-right": $currentItem.css("margin-right"), - "margin-top": $currentItem.css("margin-top"), - "margin-bottom": $currentItem.css("margin-bottom"), - margin: $currentItem.css("margin") - }); - return holder.element; - }, - update: function () { - - } - }, - start: function (event, ui) { - - }, - stop: function (event, ui) { - self.fireEvent(BI.SortList.EVENT_CHANGE); - }, - over: function (event, ui) { - - } - }); - }, - - _formatItems: function (items) { - BI.each(items, function (i, item) { - item = BI.stripEL(item); - item.cls = item.cls ? item.cls + " sort-item" : "sort-item"; - item.attributes = { - sorted: item.value - }; - }); - return items; - }, - - hasNext: function () { - return this.loader.hasNext(); - }, - - addItems: function (items) { - this.loader.addItems(items); - }, - - populate: function (items) { - if (items) { - arguments[0] = this._formatItems(items); - } - this.loader.populate.apply(this.loader, arguments); - }, - - empty: function () { - this.loader.empty(); - }, - - setNotSelectedValue: function () { - this.loader.setNotSelectedValue.apply(this.loader, arguments); - }, - - getNotSelectedValue: function () { - return this.loader.getNotSelectedValue(); - }, - - setValue: function () { - this.loader.setValue.apply(this.loader, arguments); - }, - - getValue: function () { - return this.loader.getValue(); - }, - - getAllButtons: function () { - return this.loader.getAllButtons(); - }, - - getAllLeaves: function () { - return this.loader.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.loader.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.loader.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.loader.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.loader.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.loader.getNodeByValue(value); - }, - - getSortedValues: function () { - return this.loader.element.sortable("toArray", {attribute: "sorted"}); - } -}); -BI.SortList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.sort_list", BI.SortList); diff --git a/src/case/pager/pager.all.count.js b/src/case/pager/pager.all.count.js deleted file mode 100644 index 8e03d57ca..000000000 --- a/src/case/pager/pager.all.count.js +++ /dev/null @@ -1,234 +0,0 @@ -/** - * 有总页数和总行数的分页控件 - * Created by Young's on 2016/10/13. - */ -BI.AllCountPager = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.AllCountPager.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-all-count-pager", - pagerDirection: "vertical", // 翻页按钮方向,可选值:vertical/horizontal - height: 24, - pages: 1, // 必选项 - curr: 1, // 初始化当前页, pages为数字时可用, - count: 1, // 总行数 - rowInfoObject: null, - showRowCount: true, - showRowInfo: true, - }); - }, - _init: function () { - BI.AllCountPager.superclass._init.apply(this, arguments); - var self = this, o = this.options, pagerIconCls = this._getPagerIconCls(); - this.editor = BI.createWidget({ - type: "bi.small_text_editor", - cls: "pager-editor bi-border-radius", - validationChecker: function (v) { - return (o.pages === 0 && v === "0") || BI.isPositiveInteger(v); - }, - hgap: 4, - vgap: 0, - value: o.curr, - errorText: BI.i18nText("BI-Please_Input_Positive_Integer"), - width: 40, - height: 24, - invisible: o.pages <= 1 - }); - - this.pager = BI.createWidget({ - type: "bi.pager", - width: 58, - layouts: [{ - type: "bi.horizontal", - lgap: 5 - }], - - dynamicShow: false, - pages: o.pages, - curr: o.curr, - groups: 0, - - first: false, - last: false, - prev: { - type: "bi.icon_button", - value: "prev", - title: BI.i18nText("BI-Previous_Page"), - warningTitle: BI.i18nText("BI-Current_Is_First_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius all-pager-prev bi-list-item-select2 " + pagerIconCls.preCls - }, - next: { - type: "bi.icon_button", - value: "next", - title: BI.i18nText("BI-Next_Page"), - warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius all-pager-next bi-list-item-select2 " + pagerIconCls.nextCls - }, - - hasPrev: o.hasPrev, - hasNext: o.hasNext, - firstPage: o.firstPage, - lastPage: o.lastPage, - invisible: o.pages <= 1 - }); - - this.editor.on(BI.TextEditor.EVENT_CONFIRM, function () { - self.pager.setValue(BI.parseInt(self.editor.getValue())); - self.fireEvent(BI.AllCountPager.EVENT_CHANGE); - }); - this.pager.on(BI.Pager.EVENT_CHANGE, function () { - self.fireEvent(BI.AllCountPager.EVENT_CHANGE); - }); - this.pager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { - self.editor.setValue(self.pager.getCurrentPage()); - }); - - this.allPages = BI.createWidget({ - type: "bi.label", - title: o.pages, - height: o.height, - text: "/" + o.pages, - lgap: 5, - invisible: o.pages <= 1 - }); - - BI.createWidget(o.showRowCount ? { - type: "bi.vertical_adapt", - element: this, - scrollx: false, - columnSize: ["fill", ""], - horizontalAlign: BI.HorizontalAlign.Right, - items: [ - this._getRowCountObject(), - this.editor, this.allPages, this.pager - ], - } : { - type: "bi.vertical_adapt", - element: this, - items: [this.editor, this.allPages, this.pager] - }); - }, - - _getPagerIconCls: function () { - var o = this.options; - switch (o.pagerDirection) { - case "horizontal": - return { - preCls: "row-pre-page-h-font ", - nextCls: "row-next-page-h-font " - }; - case "vertical": - default: - return { - preCls: "column-pre-page-h-font ", - nextCls: "column-next-page-h-font " - }; - } - }, - - _getRowCountObject: function() { - var self = this, o = this.options; - - return { - type: "bi.left", - height: o.height, - scrollable: false, - ref: function (_ref) { - self.rowCountObject = _ref; - }, - items: [{ - type: "bi.label", - height: o.height, - text: BI.i18nText("BI-Basic_Total"), - ref: function (_ref) { - self.prevText = _ref; - } - }, { - el: { - type: "bi.label", - ref: function (_ref) { - self.rowCount = _ref; - }, - cls: "row-count", - height: o.height, - text: o.count, - title: o.count - }, - hgap: 5, - }, { - type: "bi.label", - height: o.height, - text: BI.i18nText("BI-Tiao_Data"), - textAlign: "left" - }, BI.isNotEmptyObject(o.rowInfoObject) ? o.rowInfoObject : null] - }; - }, - - setAllPages: function (v) { - this.allPages.setText("/" + v); - this.allPages.setTitle(v); - this.options.pages = v; - this.pager.setAllPages(v); - this.editor.setEnable(v >= 1); - this.setPagerVisible(v > 1); - }, - - setShowRowInfo: function (b) { - this.options.showRowInfo = b; - this.rowCountObject.setVisible(b); - }, - - setValue: function (v) { - this.pager.setValue(v); - }, - - setVPage: function (v) { - this.pager.setValue(v); - }, - - setCount: function (count) { - if (this.options.showRowCount) { - this.rowCount.setText(count); - this.rowCount.setTitle(count); - } - }, - - setCountPrevText: function (text) { - if (this.options.showRowCount) { - this.prevText.setText(text); - } - }, - - getCurrentPage: function () { - return this.pager.getCurrentPage(); - }, - - hasPrev: function () { - return this.pager.hasPrev(); - }, - - hasNext: function () { - return this.pager.hasNext(); - }, - - isShowPager: function () { - return this.options.showRowInfo || this.options.pages > 1; - }, - - setPagerVisible: function (b) { - this.editor.setVisible(b); - this.allPages.setVisible(b); - this.pager.setVisible(b); - }, - - populate: function () { - this.pager.populate(); - this.setPagerVisible(this.options.pages > 1); - } -}); -BI.AllCountPager.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.all_count_pager", BI.AllCountPager); \ No newline at end of file diff --git a/src/case/pager/pager.detail.js b/src/case/pager/pager.detail.js deleted file mode 100644 index 36e8392f6..000000000 --- a/src/case/pager/pager.detail.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * 分页控件 - * - * Created by GUY on 2015/8/31. - * @class BI.DetailPager - * @extends BI.Widget - */ -BI.DetailPager = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.DetailPager.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-detail-pager", - behaviors: {}, - layouts: [{ - type: "bi.horizontal", - }], - - dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 - // dynamicShow为false时以下两个有用 - dynamicShowFirstLast: false, // 是否动态显示首页、尾页 - dynamicShowPrevNext: false, // 是否动态显示上一页、下一页 - pages: false, // 总页数 - curr: function () { - return 1; - }, // 初始化当前页 - groups: 0, // 连续显示分页数 - jump: BI.emptyFn, // 分页的回调函数 - - first: false, // 是否显示首页 - last: false, // 是否显示尾页 - prev: "上一页", - next: "下一页", - - firstPage: 1, - lastPage: function () { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 - return 1; - }, - hasPrev: BI.emptyFn, // pages不可用时有效 - hasNext: BI.emptyFn // pages不可用时有效 - }); - }, - _init: function () { - BI.DetailPager.superclass._init.apply(this, arguments); - var self = this; - this.currPage = BI.result(this.options, "curr"); - // 翻页太灵敏 - this._lock = false; - this._debouce = BI.debounce(function () { - self._lock = false; - }, 300); - this._populate(); - }, - - _populate: function () { - var self = this, o = this.options, view = [], dict = {}; - this.empty(); - var pages = BI.result(o, "pages"); - var curr = BI.result(this, "currPage"); - var groups = BI.result(o, "groups"); - var first = BI.result(o, "first"); - var last = BI.result(o, "last"); - var prev = BI.result(o, "prev"); - var next = BI.result(o, "next"); - - if (pages === false) { - groups = 0; - first = false; - last = false; - } else { - groups > pages && (groups = pages); - } - - // 计算当前组 - dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); - - // 当前页非首页,则输出上一页 - if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { - if (BI.isKey(prev)) { - view.push({ - text: prev, - value: "prev", - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) - }); - } else { - view.push(BI.extend({ - disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) - }, prev)); - } - } - - // 当前组非首组,则输出首页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { - view.push({ - text: first, - value: "first", - disabled: !(dict.index > 1 && groups !== 0) - }); - if (dict.index > 1 && groups !== 0) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026" - }); - } - } - - // 输出当前页组 - dict.poor = Math.floor((groups - 1) / 2); - dict.start = dict.index > 1 ? curr - dict.poor : 1; - dict.end = dict.index > 1 ? (function () { - var max = curr + (groups - dict.poor - 1); - return max > pages ? pages : max; - }()) : groups; - if (dict.end - dict.start < groups - 1) { // 最后一组状态 - dict.start = dict.end - groups + 1; - } - var s = dict.start, e = dict.end; - if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { - s++; - e--; - } - for (; s <= e; s++) { - if (s === curr) { - view.push({ - text: s, - value: s, - selected: true - }); - } else { - view.push({ - text: s, - value: s - }); - } - } - - // 总页数大于连续分页数,且当前组最大页小于总页,输出尾页 - if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { - if (pages > groups && dict.end < pages && groups !== 0) { - view.push({ - type: "bi.label", - cls: "page-ellipsis", - text: "\u2026" - }); - } - view.push({ - text: last, - value: "last", - disabled: !(pages > groups && dict.end < pages && groups !== 0) - }); - } - - // 当前页不为尾页时,输出下一页 - dict.flow = !prev && groups === 0; - if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { - view.push((function () { - if (BI.isKey(next)) { - if (pages === false) { - return {text: next, value: "next", disabled: o.hasNext(curr) === false}; - } - return (dict.flow && curr === pages) - ? - {text: next, value: "next", disabled: true} - : - {text: next, value: "next", disabled: !(curr !== pages && next || dict.flow)}; - } - return BI.extend({ - disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow) - }, next); - - }())); - } - - this.button_group = BI.createWidget({ - type: "bi.button_group", - element: this, - items: BI.createItems(view, { - cls: "page-item bi-border bi-list-item-active", - height: 23 - }), - behaviors: o.behaviors, - layouts: o.layouts - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (self._lock === true) { - return; - } - self._lock = true; - self._debouce(); - if (type === BI.Events.CLICK) { - var v = self.button_group.getValue()[0]; - switch (v) { - case "first": - self.currPage = 1; - break; - case "last": - self.currPage = pages; - break; - case "prev": - self.currPage--; - break; - case "next": - self.currPage++; - break; - default: - self.currPage = v; - break; - } - o.jump.apply(self, [{ - pages: pages, - curr: self.currPage - }]); - self._populate(); - self.fireEvent(BI.DetailPager.EVENT_CHANGE, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.fireEvent(BI.DetailPager.EVENT_AFTER_POPULATE); - }, - - getCurrentPage: function () { - return this.currPage; - }, - - setAllPages: function (pages) { - this.options.pages = pages; - this._populate(); - }, - - hasPrev: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - return pages === false ? o.hasPrev(v) : v > 1; - }, - - hasNext: function (v) { - v || (v = 1); - var o = this.options; - var pages = this.options.pages; - return pages === false ? o.hasNext(v) : v < pages; - }, - - setValue: function (v) { - var o = this.options; - v = v || 0; - v = v < 1 ? 1 : v; - if (o.pages === false) { - var lastPage = BI.result(o, "lastPage"), firstPage = 1; - this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); - } else { - v = v > o.pages ? o.pages : v; - this.currPage = v; - } - this._populate(); - }, - - getValue: function () { - var val = this.button_group.getValue()[0]; - switch (val) { - case "prev": - return -1; - case "next": - return 1; - case "first": - return BI.MIN; - case "last": - return BI.MAX; - default : - return val; - } - }, - - attr: function (key, value) { - BI.DetailPager.superclass.attr.apply(this, arguments); - if (key === "curr") { - this.currPage = BI.result(this.options, "curr"); - } - }, - - populate: function () { - this._populate(); - } -}); -BI.DetailPager.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DetailPager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; -BI.shortcut("bi.detail_pager", BI.DetailPager); diff --git a/src/case/pager/pager.direction.js b/src/case/pager/pager.direction.js deleted file mode 100644 index dcc0ab96b..000000000 --- a/src/case/pager/pager.direction.js +++ /dev/null @@ -1,276 +0,0 @@ -/** - * 显示页码的分页控件 - * - * Created by GUY on 2016/6/30. - * @class BI.DirectionPager - * @extends BI.Widget - */ -BI.DirectionPager = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.DirectionPager.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-direction-pager", - height: 24, - horizontal: { - pages: false, // 总页数 - curr: 1, // 初始化当前页, pages为数字时可用 - - hasPrev: BI.emptyFn, - hasNext: BI.emptyFn, - firstPage: 1, - lastPage: BI.emptyFn - }, - vertical: { - pages: false, // 总页数 - curr: 1, // 初始化当前页, pages为数字时可用 - - hasPrev: BI.emptyFn, - hasNext: BI.emptyFn, - firstPage: 1, - lastPage: BI.emptyFn - } - }); - }, - _init: function () { - BI.DirectionPager.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var v = o.vertical, h = o.horizontal; - this._createVPager(); - this._createHPager(); - this.layout = BI.createWidget({ - type: "bi.absolute", - scrollable: false, - element: this, - items: [{ - el: this.vpager, - top: 0, - right: 86 - }, { - el: this.vlabel, - top: 0, - right: 110 - }, { - el: this.hpager, - top: 0, - right: 0 - }, { - el: this.hlabel, - top: 0, - right: 24 - }] - }); - }, - - _createVPager: function () { - var self = this, o = this.options; - var v = o.vertical; - this.vlabel = BI.createWidget({ - type: "bi.label", - width: 24, - height: 24, - value: v.curr, - title: v.curr, - invisible: true - }); - this.vpager = BI.createWidget({ - type: "bi.pager", - width: 72, - layouts: [{ - type: "bi.horizontal", - scrollx: false, - rgap: 24 - }], - invisible: true, - - dynamicShow: false, - pages: v.pages, - curr: v.curr, - groups: 0, - - first: false, - last: false, - prev: { - type: "bi.icon_button", - value: "prev", - title: BI.i18nText("BI-Up_Page"), - warningTitle: BI.i18nText("BI-Current_Is_First_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius direction-pager-prev column-pre-page-h-font bi-list-item-select2" - }, - next: { - type: "bi.icon_button", - value: "next", - title: BI.i18nText("BI-Down_Page"), - warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius direction-pager-next column-next-page-h-font bi-list-item-select2" - }, - - hasPrev: v.hasPrev, - hasNext: v.hasNext, - firstPage: v.firstPage, - lastPage: v.lastPage - }); - - this.vpager.on(BI.Pager.EVENT_CHANGE, function () { - self.fireEvent(BI.DirectionPager.EVENT_CHANGE); - }); - this.vpager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { - self.vlabel.setValue(this.getCurrentPage()); - self.vlabel.setTitle(this.getCurrentPage()); - }); - }, - - _createHPager: function () { - var self = this, o = this.options; - var h = o.horizontal; - this.hlabel = BI.createWidget({ - type: "bi.label", - width: 24, - height: 24, - value: h.curr, - title: h.curr, - invisible: true - }); - this.hpager = BI.createWidget({ - type: "bi.pager", - width: 72, - layouts: [{ - type: "bi.horizontal", - scrollx: false, - rgap: 24 - }], - invisible: true, - - dynamicShow: false, - pages: h.pages, - curr: h.curr, - groups: 0, - - first: false, - last: false, - prev: { - type: "bi.icon_button", - value: "prev", - title: BI.i18nText("BI-Left_Page"), - warningTitle: BI.i18nText("BI-Current_Is_First_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius direction-pager-prev row-pre-page-h-font bi-list-item-select2" - }, - next: { - type: "bi.icon_button", - value: "next", - title: BI.i18nText("BI-Right_Page"), - warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), - height: 22, - width: 22, - cls: "bi-border bi-border-radius direction-pager-next row-next-page-h-font bi-list-item-select2" - }, - - hasPrev: h.hasPrev, - hasNext: h.hasNext, - firstPage: h.firstPage, - lastPage: h.lastPage - }); - - this.hpager.on(BI.Pager.EVENT_CHANGE, function () { - self.fireEvent(BI.DirectionPager.EVENT_CHANGE); - }); - this.hpager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { - self.hlabel.setValue(this.getCurrentPage()); - self.hlabel.setTitle(this.getCurrentPage()); - }); - }, - - getVPage: function () { - return this.vpager.getCurrentPage(); - }, - - getHPage: function () { - return this.hpager.getCurrentPage(); - }, - - setVPage: function (v) { - this.vpager.setValue(v); - this.vlabel.setValue(v); - this.vlabel.setTitle(v); - }, - - setHPage: function (v) { - this.hpager.setValue(v); - this.hlabel.setValue(v); - this.hlabel.setTitle(v); - }, - - hasVNext: function () { - return this.vpager.hasNext(); - }, - - hasHNext: function () { - return this.hpager.hasNext(); - }, - - hasVPrev: function () { - return this.vpager.hasPrev(); - }, - - hasHPrev: function () { - return this.hpager.hasPrev(); - }, - - setHPagerVisible: function (b) { - this.hpager.setVisible(b); - this.hlabel.setVisible(b); - }, - - setVPagerVisible: function (b) { - this.vpager.setVisible(b); - this.vlabel.setVisible(b); - }, - - populate: function () { - this.vpager.populate(); - this.hpager.populate(); - var vShow = false, hShow = false; - if (!this.hasHNext() && !this.hasHPrev()) { - this.setHPagerVisible(false); - } else { - this.setHPagerVisible(true); - hShow = true; - } - if (!this.hasVNext() && !this.hasVPrev()) { - this.setVPagerVisible(false); - } else { - this.setVPagerVisible(true); - vShow = true; - } - this.setVisible(hShow || vShow); - var num = [86, 110, 0, 24]; - var items = this.layout.attr("items"); - - if (vShow === true && hShow === true) { - items[0].right = num[0]; - items[1].right = num[1]; - items[2].right = num[2]; - items[3].right = num[3]; - } else if (vShow === true) { - items[0].right = num[2]; - items[1].right = num[3]; - } else if (hShow === true) { - items[2].right = num[2]; - items[3].right = num[3]; - } - this.layout.attr("items", items); - this.layout.resize(); - }, - - clear: function () { - this.vpager.attr("curr", 1); - this.hpager.attr("curr", 1); - } -}); -BI.DirectionPager.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.direction_pager", BI.DirectionPager); \ No newline at end of file diff --git a/src/case/segment/button.segment.js b/src/case/segment/button.segment.js deleted file mode 100644 index 05d0a3d83..000000000 --- a/src/case/segment/button.segment.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 分段控件使用的button - * - * Created by GUY on 2015/9/7. - * @class BI.SegmentButton - * @extends BI.BasicButton - */ -BI.SegmentButton = BI.inherit(BI.BasicButton, { - - _defaultConfig: function () { - var conf = BI.SegmentButton.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-segment-button bi-list-item-select bi-card", - shadow: true, - readonly: true, - hgap: 5 - }); - }, - - _init: function () { - BI.SegmentButton.superclass._init.apply(this, arguments); - var opts = this.options, self = this; - this.text = BI.createWidget({ - type: "bi.label", - element: this, - textHeight: opts.height, - whiteSpace: opts.whiteSpace, - text: opts.text, - value: opts.value, - hgap: opts.hgap - }); - }, - - setSelected: function () { - BI.SegmentButton.superclass.setSelected.apply(this, arguments); - }, - - setText: function (text) { - BI.SegmentButton.superclass.setText.apply(this, arguments); - this.text.setText(text); - } -}); -BI.shortcut("bi.segment_button", BI.SegmentButton); diff --git a/src/case/segment/segment.js b/src/case/segment/segment.js deleted file mode 100644 index 2c1dda918..000000000 --- a/src/case/segment/segment.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * 单选按钮组 - * - * Created by GUY on 2015/9/7. - * @class BI.Segment - * @extends BI.Widget - */ -BI.Segment = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.Segment.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-segment", - items: [], - height: 24, - }); - }, - _init: function () { - BI.Segment.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.buttonGroup = BI.createWidget({ - element: this, - type: "bi.button_group", - value: o.value, - items: [BI.createItems(o.items, { - type: "bi.segment_button", - height: BI.toPix(o.height, 2), - whiteSpace: o.whiteSpace, - })], - layouts: [{ - type: "bi.table", - columnSize: BI.makeArrayByArray(o.items, "fill"), - }], - }); - this.buttonGroup.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.buttonGroup.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { - self.fireEvent(BI.Segment.EVENT_CHANGE, value, obj); - }); - }, - - _setEnable: function (enable) { - BI.Segment.superclass._setEnable.apply(this, arguments); - if (enable === true) { - this.element.removeClass("base-disabled disabled"); - } else if (enable === false) { - this.element.addClass("base-disabled disabled"); - } - }, - - setValue: function (v) { - this.buttonGroup.setValue(v); - }, - - setEnabledValue: function (v) { - this.buttonGroup.setEnabledValue(v); - }, - - getValue: function () { - return this.buttonGroup.getValue(); - }, - - populate: function (buttons) { - var o = this.options; - this.buttonGroup.populate([BI.createItems(buttons, { - type: "bi.segment_button", - height: BI.toPix(o.height, 2), - whiteSpace: o.whiteSpace, - })]); - }, -}); -BI.Segment.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.segment", BI.Segment); diff --git a/src/case/toolbar/toolbar.multiselect.js b/src/case/toolbar/toolbar.multiselect.js deleted file mode 100644 index f18677b85..000000000 --- a/src/case/toolbar/toolbar.multiselect.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * guy - * 复选导航条 - * Created by GUY on 2015/8/25. - * @class BI.MultiSelectBar - * @extends BI.BasicButton - */ -BI.MultiSelectBar = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectBar.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multi-select-bar", - height: 25, - text: BI.i18nText("BI-Select_All"), - isAllCheckedBySelectedValue: BI.emptyFn, - // 手动控制选中 - disableSelected: true, - isHalfCheckedBySelectedValue: function (selectedValues) { - return selectedValues.length > 0; - }, - halfSelected: false, - iconWrapperWidth: 26, - iconWidth: 14, - iconHeight: 14, - }); - }, - _init: function () { - BI.MultiSelectBar.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var isSelect = o.selected === true; - var isHalfSelect = !o.selected && o.halfSelected; - this.checkbox = BI.createWidget({ - type: "bi.checkbox", - stopPropagation: true, - handler: function () { - self.setSelected(self.isSelected()); - }, - selected: isSelect, - invisible: isHalfSelect, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight - }); - this.half = BI.createWidget({ - type: "bi.half_icon_button", - stopPropagation: true, - handler: function () { - self.setSelected(true); - }, - invisible: isSelect || !isHalfSelect, - iconWidth: o.iconWidth, - iconHeight: o.iconHeight - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, self.isSelected(), self); - }); - this.checkbox.on(BI.Checkbox.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, self.isSelected(), self); - }); - this.half.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, self.isSelected(), self); - }); - this.half.on(BI.HalfIconButton.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, self.isSelected(), self); - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - keyword: o.keyword, - value: o.value, - py: o.py - }); - BI.createWidget({ - type: "bi.htape", - element: this, - items: [{ - width: o.iconWrapperWidth, - el: { - type: "bi.center_adapt", - items: [this.checkbox, this.half] - } - }, { - el: this.text - }] - }); - }, - - _setSelected: function (v) { - this.checkbox.setSelected(!!v); - }, - - // 自己手动控制选中 - beforeClick: function () { - var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); - if (isHalf === true) { - this.setSelected(true); - } else { - this.setSelected(!isSelected); - } - }, - - setSelected: function (v) { - this.checkbox.setSelected(v); - this.setHalfSelected(false); - }, - - setHalfSelected: function (b) { - this.halfSelected = !!b; - if (b === true) { - this.checkbox.setSelected(false); - this.half.visible(); - this.checkbox.invisible(); - } else { - this.half.invisible(); - this.checkbox.visible(); - } - }, - - isHalfSelected: function () { - return !this.isSelected() && !!this.halfSelected; - }, - - isSelected: function () { - return this.checkbox.isSelected(); - }, - - setValue: function (selectedValues) { - BI.MultiSelectBar.superclass.setValue.apply(this, arguments); - var isAllChecked = this.options.isAllCheckedBySelectedValue.apply(this, arguments); - this.setSelected(isAllChecked); - !isAllChecked && this.setHalfSelected(this.options.isHalfCheckedBySelectedValue.apply(this, arguments)); - }, - - doClick: function () { - BI.MultiSelectBar.superclass.doClick.apply(this, arguments); - if(this.isValid()) { - this.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); - } - } -}); -BI.MultiSelectBar.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_bar", BI.MultiSelectBar); diff --git a/src/case/tree/tree.level.js b/src/case/tree/tree.level.js deleted file mode 100644 index 81609217e..000000000 --- a/src/case/tree/tree.level.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * guy - * 二级树 - * @class BI.LevelTree - * @extends BI.Single - */ -BI.LevelTree = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.LevelTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-level-tree", - el: { - chooseType: 0 - }, - expander: {}, - items: [], - value: "" - }); - }, - - _init: function () { - BI.LevelTree.superclass._init.apply(this, arguments); - - this.initTree(this.options.items); - }, - - _formatItems: function (nodes, layer, pNode) { - var self = this; - BI.each(nodes, function (i, node) { - var extend = { - layer: layer, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - isFirstNode: i === 0, - isLastNode: i === nodes.length - 1, - }; - if (!BI.isKey(node.id)) { - node.id = BI.UUID(); - } - extend.pNode = pNode; - if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) { - extend.type = "bi.tree_node"; - extend.selectable = false; - - BI.defaults(node, extend); - self._formatItems(node.children, layer + 1, node); - } else { - extend.type = "bi.tree_item"; - BI.defaults(node, extend); - } - }); - return nodes; - }, - - _assertId: function (sNodes) { - BI.each(sNodes, function (i, node) { - if (!BI.isKey(node.id)) { - node.id = BI.UUID(); - } - }); - }, - - // 构造树结构, - initTree: function (nodes) { - var self = this, o = this.options; - this.empty(); - this._assertId(nodes); - this.tree = BI.createWidget({ - type: "bi.custom_tree", - element: this, - expander: BI.extend({ - type: "bi.tree_expander", - el: {}, - isDefaultInit: false, - selectable: false, - popup: { - type: "bi.custom_tree" - } - }, o.expander), - items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), - value: o.value, - - el: BI.extend({ - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical" - }] - }, o.el) - }); - this.tree.on(BI.Controller.EVENT_CHANGE, function (type, value, ob) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.LevelTree.EVENT_CHANGE, value, ob); - self.setValue(value); - } - }); - }, - - // 生成树方法 - stroke: function (nodes) { - this.tree.stroke.apply(this.tree, arguments); - }, - - populate: function (items, keyword) { - items = this._formatItems(BI.Tree.transformToTreeFormat(items), 0); - this.tree.populate(items, keyword); - }, - - setValue: function (v) { - this.tree.setValue(v); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - getAllLeaves: function () { - return this.tree.getAllLeaves(); - }, - - getNodeById: function (id) { - return this.tree.getNodeById(id); - }, - - getNodeByValue: function (id) { - return this.tree.getNodeByValue(id); - } -}); -BI.LevelTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.level_tree", BI.LevelTree); diff --git a/src/case/tree/treeexpander/tree.expander.js b/src/case/tree/treeexpander/tree.expander.js deleted file mode 100644 index 8dde0807b..000000000 --- a/src/case/tree/treeexpander/tree.expander.js +++ /dev/null @@ -1,80 +0,0 @@ -!(function () { - var Widget = BI.inherit(BI.Widget, { - props: { - baseCls: "bi-tree-expander", - layer: 0, // 第几层级 - isLastNode: false, // 是不是最后一个 - isFirstNode: false, // 是不是第一个 - selectable: false, - showLine: true, - }, - - render: function () { - - var self = this; - var o = this.options; - - this.trigger = BI.createWidget(o.el, { - forceNotSelected: !o.selectable, - }); - this.trigger.on(BI.Controller.EVENT_CHANGE, function (type) { - o.selectable && self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - return { - type: "bi.expander", - ref: function (_ref) { - self.expander = _ref; - }, - trigger: o.selectable ? "" : "click", - el: this.trigger, - isDefaultInit: o.isDefaultInit, - popup: { - type: "bi.tree_expander.popup", - layer: o.layer || o.el.layer, - isLastNode: o.isLastNode || o.el.isLastNode, - isFirstNode: o.isFirstNode || o.el.isFirstNode, - showLine: o.showLine, - el: o.popup, - }, - value: o.value, - listeners: [ - { - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }, - }, - ], - }; - }, - - setValue: function (v) { - if (BI.contains(v, this.trigger.getValue())) { - this.trigger.setSelected(true); - this.expander.setValue([]); - } else { - this.trigger.setSelected(false); - this.expander.setValue(v); - } - }, - - getValue: function () { - if (this.trigger.isSelected()) { - var value = this.trigger.getValue(); - return BI.isArray(value) ? value : [value]; - } - return this.expander.getValue(); - }, - - populate: function (items) { - this.expander.populate(items); - }, - - getAllLeaves: function () { - return this.expander && this.expander.getAllLeaves(); - } - }); - - BI.shortcut("bi.tree_expander", Widget); -}()); diff --git a/src/case/tree/treeexpander/tree.expander.popup.js b/src/case/tree/treeexpander/tree.expander.popup.js deleted file mode 100644 index ada979b0e..000000000 --- a/src/case/tree/treeexpander/tree.expander.popup.js +++ /dev/null @@ -1,60 +0,0 @@ -!(function () { - var Widget = BI.inherit(BI.Widget, { - props: function () { - return { - baseCls: "bi-tree-expander-popup", - layer: 0, // 第几层级 - el: {}, - isLastNode: false, - showLine: true, - }; - }, - - render: function () { - - var self = this; - var o = this.options; - var offset = BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2; - - this.popupView = BI.createWidget(BI.extend(o.el, { - value: o.value - }), this); - - this.popupView.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - if (o.showLine) { - this.popupView.element.css("margin-left", BI.pixFormat(-offset * (o.layer + 1))); - this.element.css("margin-left", BI.pixFormat(offset * (o.layer + 1))); - } - - return { - type: "bi.vertical", - cls: (o.showLine && !o.isLastNode) ? (BI.STYLE_CONSTANTS.LINK_LINE_TYPE === "solid" ? "line solid" : "line") : "", - scrolly: null, - items: [ - this.popupView, - ], - }; - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - populate: function (items) { - this.popupView.populate(items); - }, - - getAllLeaves: function () { - return this.popupView && this.popupView.getAllLeaves(); - } - }); - - BI.shortcut("bi.tree_expander.popup", Widget); -}()); diff --git a/src/case/trigger/trigger.editor.js b/src/case/trigger/trigger.editor.js deleted file mode 100644 index 1c87c612c..000000000 --- a/src/case/trigger/trigger.editor.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * 文本输入框trigger - * - * Created by GUY on 2015/9/15. - * @class BI.EditorTrigger - * @extends BI.Trigger - */ -BI.EditorTrigger = BI.inherit(BI.Trigger, { - _defaultConfig: function (config) { - var conf = BI.EditorTrigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-editor-trigger " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: false, - watermark: "", - errorText: "" - }); - }, - - _init: function () { - BI.EditorTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.editor = BI.createWidget({ - type: "bi.sign_editor", - height: BI.toPix(o.height, 2), - value: o.value, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - title: function () { - return self.getValue(); - } - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { - self.fireEvent(BI.EditorTrigger.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.EditorTrigger.EVENT_FOCUS, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_EMPTY, function () { - self.fireEvent(BI.EditorTrigger.EVENT_EMPTY, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_VALID, function () { - self.fireEvent(BI.EditorTrigger.EVENT_VALID, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.EditorTrigger.EVENT_ERROR, arguments); - }); - - BI.createWidget({ - element: this, - type: "bi.horizontal_fill", - height: BI.toPix(o.height, 2), - items: [ - { - el: this.editor, - width: "fill" - }, { - el: { - type: "bi.trigger_icon_button", - width: o.triggerWidth || BI.toPix(o.height, 2) - }, - width: "" - } - ] - }); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - setValue: function (value) { - this.editor.setValue(value); - }, - - setText: function (text) { - this.editor.setState(text); - } -}); -BI.EditorTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.EditorTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.EditorTrigger.EVENT_EMPTY = "EVENT_EMPTY"; -BI.EditorTrigger.EVENT_VALID = "EVENT_VALID"; -BI.EditorTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.shortcut("bi.editor_trigger", BI.EditorTrigger); diff --git a/src/case/trigger/trigger.icon.js b/src/case/trigger/trigger.icon.js deleted file mode 100644 index 2da61d480..000000000 --- a/src/case/trigger/trigger.icon.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 图标按钮trigger - * - * Created by GUY on 2015/10/8. - * @class BI.IconTrigger - * @extends BI.Trigger - */ -BI.IconTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.IconTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-icon-trigger", - extraCls: "pull-down-font", - el: {}, - height: 24 - }); - }, - _init: function () { - var o = this.options; - BI.IconTrigger.superclass._init.apply(this, arguments); - this.iconButton = BI.createWidget(o.el, { - type: "bi.trigger_icon_button", - element: this, - width: o.width, - height: o.height, - extraCls: o.extraCls - }); - } -}); -BI.shortcut("bi.icon_trigger", BI.IconTrigger); \ No newline at end of file diff --git a/src/case/trigger/trigger.icon.text.js b/src/case/trigger/trigger.icon.text.js deleted file mode 100644 index a102b5d0c..000000000 --- a/src/case/trigger/trigger.icon.text.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * 文字trigger - * - * Created by GUY on 2015/9/15. - * @class BI.IconTextTrigger - * @extends BI.Trigger - */ -BI.IconTextTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - var conf = BI.IconTextTrigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-trigger", - height: 24, - iconHeight: null, - iconWidth: null, - textCls: "" - }); - }, - - _init: function () { - BI.IconTextTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - cls: "select-text-label" + (BI.isKey(o.textCls) ? (" " + o.textCls) : ""), - textAlign: "left", - height: o.height, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - tgap: o.textTgap, - bgap: o.textBgap, - text: o.text - }); - this.trigerButton = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.triggerWidth || o.height - }); - - BI.createWidget({ - element: this, - type: "bi.horizontal_fill", - columnSize: ["", "fill", ""], - ref: function (_ref) { - self.wrapper = _ref; - }, - items: [{ - el: { - type: "bi.icon_change_button", - cls: "icon-combo-trigger-icon", - width: o.triggerWidth || o.height, - iconCls: o.iconCls, - invisible: !o.iconCls, - ref: function (_ref) { - self.icon = _ref; - }, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - disableSelected: true - } - }, { - el: this.text, - lgap: BI.isEmptyString(o.iconCls) ? 5 : 0 - }, { - el: this.trigerButton - }] - }); - }, - - setValue: function (value) { - this.text.setValue(value); - }, - - setIcon: function (iconCls) { - var o = this.options; - this.icon.setIcon(iconCls); - this.icon.setVisible(!!iconCls); - }, - - setTextCls: function (cls) { - var o = this.options; - var oldCls = o.textCls; - o.textCls = cls; - this.text.element.removeClass(oldCls).addClass(cls); - }, - - setText: function (text) { - this.text.setText(text); - } -}); -BI.shortcut("bi.icon_text_trigger", BI.IconTextTrigger); diff --git a/src/case/trigger/trigger.icon.text.select.js b/src/case/trigger/trigger.icon.text.select.js deleted file mode 100644 index b0142b91e..000000000 --- a/src/case/trigger/trigger.icon.text.select.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Created by Windy on 2017/12/12. - */ -BI.SelectIconTextTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.SelectIconTextTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-text-trigger", - height: 24, - iconHeight: null, - iconWidth: null, - iconCls: "" - }); - }, - - _init: function () { - BI.SelectIconTextTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var obj = this._digist(o.value, o.items); - this.trigger = BI.createWidget({ - type: "bi.icon_text_trigger", - element: this, - text: obj.text, - textCls: obj.textCls, - iconCls: obj.iconCls, - textHgap: o.textHgap, - textVgap: o.textVgap, - textLgap: o.textLgap, - textRgap: o.textRgap, - textTgap: o.textTgap, - textBgap: o.textBgap, - height: o.height, - iconHeight: o.iconHeight, - iconWidth: o.iconWidth, - iconWrapperWidth: o.iconWrapperWidth - }); - }, - - _digist: function (vals, items) { - var o = this.options; - vals = BI.isArray(vals) ? vals : [vals]; - var result; - var formatItems = BI.Tree.transformToArrayFormat(items); - BI.any(formatItems, function (i, item) { - if (BI.deepContains(vals, item.value)) { - result = { - text: item.text || item.value, - iconCls: item.iconCls - }; - return true; - } - }); - - if (BI.isNotNull(result)) { - return { - text: result.text, - textCls: "", - iconCls: result.iconCls - }; - } else { - return { - text: BI.isFunction(o.text) ? o.text() : o.text, - textCls: "bi-water-mark", - iconCls: o.iconCls - }; - } - }, - - setValue: function (vals) { - var obj = this._digist(vals, this.options.items); - this.trigger.setText(obj.text); - this.trigger.setIcon(obj.iconCls); - this.trigger.setTextCls(obj.textCls); - }, - - populate: function (items) { - this.options.items = items; - } -}); -BI.shortcut("bi.select_icon_text_trigger", BI.SelectIconTextTrigger); diff --git a/src/case/trigger/trigger.text.js b/src/case/trigger/trigger.text.js deleted file mode 100644 index 6e7273252..000000000 --- a/src/case/trigger/trigger.text.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * 文字trigger - * - * Created by GUY on 2015/9/15. - * @class BI.TextTrigger - * @extends BI.Trigger - */ -BI.TextTrigger = BI.inherit(BI.Trigger, { - - props: function () { - var self = this; - return { - baseCls: "bi-text-trigger", - height: 24, - textHgap: 6, - textCls: "", - allowClear: false, - title: function () { - return self.text.getText(); - }, - defaultText: "", - text: "", - }; - }, - - render: function () { - var self = this, o = this.options, c = this._const; - - var text = this.getText(); - - var defaultText = this.getDefaultText(); - - var label = { - type: "bi.label", - ref: function (_ref) { - self.text = _ref; - }, - cls: `select-text-label ${o.textCls} ${!BI.isNotEmptyString(text) && BI.isNotEmptyString(defaultText) ? "bi-tips" : ""}`, - textAlign: "left", - height: o.height, - text: text || o.defaultText, - tipType: o.tipType, - warningTitle: o.warningTitle, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - tgap: o.textTgap, - bgap: o.textBgap, - readonly: o.readonly - }; - - var triggerButton = { - type: "bi.trigger_icon_button", - ref: function (_ref) { - self.triggerButton = _ref; - }, - width: o.triggerWidth || o.height - }; - - return ({ - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [ - { - el: label, - width: "fill" - }, { - el: o.allowClear ? { - type: "bi.vertical_adapt", - width: o.triggerWidth || o.height, - height: o.height, - horizontalAlign: "left", - scrollable: false, - items: [ - { - el: { - type: "bi.icon_button", - ref: function (_ref) { - self.clearBtn = _ref; - }, - cls: "close-h-font " + (o.allowClear ? "clear-button" : ""), - stopPropagation: true, - width: o.triggerWidth || o.height, - invisible: !BI.isNotEmptyString(o.text), - handler: function () { - self.fireEvent(BI.TextTrigger.EVENT_CLEAR); - }, - }, - }, { - el: triggerButton, - } - ] - } : triggerButton, - } - ] - }); - }, - - getText: function () { - var o = this.options; - return BI.isFunction(o.text) ? o.text() : o.text; - }, - - getDefaultText: function () { - var o = this.options; - return BI.isFunction(o.defaultText) ? o.defaultText() : o.defaultText; - }, - - getTextor: function () { - return this.text; - }, - - setTextCls: function (cls) { - var o = this.options; - var oldCls = o.textCls; - o.textCls = cls; - this.text.element.removeClass(oldCls).addClass(cls); - }, - - setText: function (text) { - if (this.options.allowClear) { - this.clearBtn.setVisible(BI.isNotEmptyString(text)); - } - if (BI.isKey(text)) { - this.text.setText(text); - this.text.element.removeClass("bi-tips"); - } else if (BI.isKey(this.options.defaultText)) { - this.text.setText(this.options.defaultText); - this.text.element.addClass("bi-tips"); - } else { - this.text.setText(""); - this.text.element.removeClass("bi-tips"); - } - }, - - setTipType: function (v) { - this.text.options.tipType = v; - this.options.tipType = v; - } -}); - -BI.TextTrigger.EVENT_CLEAR = "EVENT_CLEAR"; -BI.shortcut("bi.text_trigger", BI.TextTrigger); diff --git a/src/case/trigger/trigger.text.select.js b/src/case/trigger/trigger.text.select.js deleted file mode 100644 index 005ac241b..000000000 --- a/src/case/trigger/trigger.text.select.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 选择字段trigger - * - * Created by GUY on 2015/9/15. - * @class BI.SelectTextTrigger - * @extends BI.Trigger - */ -BI.SelectTextTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.SelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-text-trigger", - height: 24, - allowClear: false, - valueFormatter: BI.emptyFn, - defaultText: "", - }); - }, - - _init: function () { - BI.SelectTextTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var text = this._digest(o.value, o.items); - this.trigger = BI.createWidget({ - type: "bi.text_trigger", - element: this, - height: o.height, - readonly: o.readonly, - text: text, - defaultText: o.defaultText, - textHgap: o.textHgap, - textVgap: o.textVgap, - textLgap: o.textLgap, - textRgap: o.textRgap, - textTgap: o.textTgap, - textBgap: o.textBgap, - tipType: o.tipType, - title: null, - allowClear: o.allowClear, - listeners: [ - { - eventName: BI.TextTrigger.EVENT_CLEAR, - action: function () { - self.setText(""); - self.fireEvent(BI.SelectTextTrigger.EVENT_CLEAR); - } - } - ] - }); - }, - - _digest: function (val, items) { - var o = this.options; - - val = BI.isArray(val) ? val.slice() : [val]; - - var result = []; - - // 提升valueFormatter的优先级 - if (o.valueFormatter !== BI.emptyFn && BI.isFunction(o.valueFormatter)) { - BI.each(val, function (index, v) { - result.push(o.valueFormatter(v)); - }); - return result.join(","); - } - - var formatItems = BI.Tree.transformToArrayFormat(items); - BI.each(formatItems, function (i, item) { - if (BI.contains(val, item.value) && !BI.contains(result, item.text || item.value)) { - result.push(item.text || item.value); - BI.remove(val, item.value); - } - }); - - if (result.length > 0 && val.length === 0) { - return result.join(","); - } else { - return BI.isFunction(o.text) ? o.text() : o.text; - } - }, - - setText: function (text) { - this.options.text = text; - this.trigger.setText(text); - }, - - setValue: function (val) { - var formatText = this._digest(val, this.options.items); - this.trigger.setText(formatText); - }, - - setTipType: function (v) { - this.options.tipType = v; - this.trigger.setTipType(v); - }, - - getTextor: function () { - return this.trigger.getTextor(); - }, - - populate: function (items) { - this.options.items = items; - } -}); - -BI.SelectTextTrigger.EVENT_CLEAR = "EVENT_CLEAR"; -BI.shortcut("bi.select_text_trigger", BI.SelectTextTrigger); diff --git a/src/case/trigger/trigger.text.select.small.js b/src/case/trigger/trigger.text.select.small.js deleted file mode 100644 index adbd5603c..000000000 --- a/src/case/trigger/trigger.text.select.small.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 选择字段trigger小一号的 - * - * @class BI.SmallSelectTextTrigger - * @extends BI.Trigger - */ -BI.SmallSelectTextTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.SmallSelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-small-select-text-trigger bi-border", - height: 20, - }); - }, - - _init: function () { - BI.SmallSelectTextTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options; - var obj = this._digest(o.value, o.items); - this.trigger = BI.createWidget({ - type: "bi.small_text_trigger", - element: this, - height: BI.toPix(o.height, 2), - text: obj.text, - cls: obj.cls, - textHgap: o.textHgap, - textVgap: o.textVgap, - textLgap: o.textLgap, - textRgap: o.textRgap, - textTgap: o.textTgap, - textBgap: o.textBgap, - }); - }, - - _digest: function(vals, items){ - var o = this.options; - vals = BI.isArray(vals) ? vals : [vals]; - var result = []; - var formatItems = BI.Tree.transformToArrayFormat(items); - BI.each(formatItems, function (i, item) { - if (BI.deepContains(vals, item.value) && !BI.contains(result, item.text || item.value)) { - result.push(item.text || item.value); - } - }); - - if (result.length > 0) { - return { - cls: "", - text: result.join(",") - } - } else { - return { - cls: "bi-water-mark", - text: o.text - } - } - }, - - setValue: function (vals) { - var formatValue = this._digest(vals, this.options.items); - this.trigger.element.removeClass("bi-water-mark").addClass(formatValue.cls); - this.trigger.setText(formatValue.text); - }, - - populate: function (items) { - this.options.items = items; - } -}); -BI.shortcut("bi.small_select_text_trigger", BI.SmallSelectTextTrigger); diff --git a/src/case/trigger/trigger.text.small.js b/src/case/trigger/trigger.text.small.js deleted file mode 100644 index 27c395a69..000000000 --- a/src/case/trigger/trigger.text.small.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 文字trigger(右边小三角小一号的) == - * - * @class BI.SmallTextTrigger - * @extends BI.Trigger - */ -BI.SmallTextTrigger = BI.inherit(BI.Trigger, { - _defaultConfig: function () { - var conf = BI.SmallTextTrigger.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-text-trigger", - height: 20, - textHgap: 6, - }); - }, - - _init: function () { - BI.SmallTextTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - height: o.height, - text: o.text, - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - tgap: o.textTgap, - bgap: o.textBgap, - }); - this.trigerButton = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.triggerWidth || o.height - }); - - BI.createWidget({ - element: this, - type: "bi.horizontal_fill", - items: [ - { - el: this.text, - width: "fill" - }, { - el: this.trigerButton, - width: "" - } - ] - }); - }, - - setValue: function (value) { - this.text.setValue(value); - }, - - setText: function (text) { - this.text.setText(text); - } -}); -BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger); diff --git a/src/case/ztree/0.treeview.js b/src/case/ztree/0.treeview.js deleted file mode 100644 index 41166220d..000000000 --- a/src/case/ztree/0.treeview.js +++ /dev/null @@ -1,575 +0,0 @@ -/** - * guy - * 异步树 - * @class BI.TreeView - * @extends BI.Pane - */ -BI.TreeView = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.TreeView.superclass._defaultConfig.apply(this, arguments), { - _baseCls: "bi-tree", - paras: { - selectedValues: {} - }, - itemsCreator: BI.emptyFn, - showLine: true - }); - }, - _init: function () { - BI.TreeView.superclass._init.apply(this, arguments); - var o = this.options; - this._stop = false; - - this._createTree(); - this.tip = BI.createWidget({ - type: "bi.loading_bar", - invisible: true, - handler: BI.bind(this._loadMore, this) - }); - BI.createWidget({ - type: "bi.vertical", - scrollable: true, - scrolly: false, - element: this, - items: [this.tip] - }); - if (BI.isNotNull(o.value)) { - this.setSelectedValue(o.value); - } - if (BI.isIE9Below && BI.isIE9Below()) { - this.element.addClass("hack"); - } - }, - - _createTree: function () { - this.id = "bi-tree" + BI.UUID(); - if (this.nodes) { - this.nodes.destroy(); - } - if (this.tree) { - this.tree.destroy(); - } - this.tree = BI.createWidget({ - type: "bi.layout", - element: "" - }); - BI.createWidget({ - type: "bi.default", - element: this, - items: [this.tree] - }); - }, - - // 选择节点触发方法 - _selectTreeNode: function (treeId, treeNode) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, treeNode, this); - this.fireEvent(BI.TreeView.EVENT_CHANGE, treeNode, this); - }, - - // 配置属性 - _configSetting: function () { - var paras = this.options.paras; - var self = this; - var o = this.options; - var setting = { - async: { - enable: true, - url: getUrl, - autoParam: ["id", "name"], // 节点展开异步请求自动提交id和name - otherParam: BI.cjkEncodeDO(paras) // 静态参数 - }, - check: { - enable: true - }, - data: { - key: { - title: "title", - name: "text" // 节点的name属性替换成text - }, - simpleData: { - enable: true // 可以穿id,pid属性的对象数组 - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true, // 节点可以用html标签代替 - dblClickExpand: false, - showLine: o.showLine, - }, - callback: { - beforeExpand: beforeExpand, - onAsyncSuccess: onAsyncSuccess, - onAsyncError: onAsyncError, - beforeCheck: beforeCheck, - onCheck: onCheck, - onExpand: onExpand, - onCollapse: onCollapse, - onClick: onClick - } - }; - var className = "dark", perTime = 100; - - function onClick(event, treeId, treeNode) { - // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 - var checked = treeNode.checked; - var status = treeNode.getCheckStatus(); - if (status.half === true && status.checked === true) { - checked = false; - } - // 更新此node的check状态, 影响父子关联,并调用beforeCheck和onCheck回调 - self.nodes.checkNode(treeNode, !checked, true, true); - } - - function getUrl(treeId, treeNode) { - var parentNode = self._getParentValues(treeNode); - treeNode.times = treeNode.times || 1; - var param = "id=" + treeNode.id - + "×=" + (treeNode.times++) - + "&parentValues= " + _global.encodeURIComponent(BI.jsonEncode(parentNode)) - + "&checkState=" + _global.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus())); - - return "&" + param; - } - - function beforeExpand(treeId, treeNode) { - if (!treeNode.isAjaxing) { - if (!treeNode.children) { - treeNode.times = 1; - ajaxGetNodes(treeNode, "refresh"); - } - return true; - } - BI.Msg.toast("Please Wait。", { - level: "warning" - }); // 不展开节点,也不触发onExpand事件 - return false; - - } - - function onAsyncSuccess(event, treeId, treeNode, msg) { - treeNode.halfCheck = false; - if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) { - return; - } - var zTree = self.nodes; - var totalCount = treeNode.count || 0; - - // 尝试去获取下一组节点,若获取值为空数组,表示获取完成 - // TODO by GUY - if (treeNode.children.length > totalCount) { - treeNode.count = treeNode.children.length; - BI.delay(function () { - ajaxGetNodes(treeNode); - }, perTime); - } else { - // treeNode.icon = ""; - zTree.updateNode(treeNode); - zTree.selectNode(treeNode.children[0]); - // className = (className === "dark" ? "":"dark"); - } - } - - function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) { - var zTree = self.nodes; - BI.Msg.toast("Error!", "warning"); - // treeNode.icon = ""; - // zTree.updateNode(treeNode); - } - - function ajaxGetNodes(treeNode, reloadType) { - var zTree = self.nodes; - if (reloadType == "refresh") { - zTree.updateNode(treeNode); // 刷新一下当前节点,如果treeNode.xxx被改了的话 - } - zTree.reAsyncChildNodes(treeNode, reloadType, true); // 强制加载子节点,reloadType === refresh为先清空再加载,否则为追加到现有子节点之后 - } - - function beforeCheck(treeId, treeNode) { - if (treeNode.disabled) { - return false; - } - // 下面主动修改了node的halfCheck属性, 节点属性的判断依赖halfCheck,改之前就获取一下 - var status = treeNode.getCheckStatus(); - treeNode.halfCheck = false; - if (treeNode.checked === true) { - // 将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy - // 所有的半选状态都需要取消halfCheck=true的情况 - function track(children) { - BI.each(children, function (i, ch) { - if (ch.halfCheck === true) { - ch.halfCheck = false; - track(ch.children); - } - }); - } - - track(treeNode.children); - var treeObj = self.nodes; - var nodes = treeObj.getSelectedNodes(); - BI.$.each(nodes, function (index, node) { - node.halfCheck = false; - }); - } - // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 - if (status.half === true && status.checked === true) { - treeNode.checked = false; - } - } - - function onCheck(event, treeId, treeNode) { - if (treeNode.disabled) { - return false; - } - self._selectTreeNode(treeId, treeNode); - } - - function onExpand(event, treeId, treeNode) { - treeNode.halfCheck = false; - } - - function onCollapse(event, treeId, treeNode) { - } - - return setting; - }, - - _getParentValues: function (treeNode) { - if (!treeNode.getParentNode()) { - return []; - } - var parentNode = treeNode.getParentNode(); - var result = this._getParentValues(parentNode); - result = result.concat([this._getNodeValue(parentNode)]); - return result; - }, - - _getNodeValue: function (node) { - // 去除标红 - return BI.isUndefined(node.value) ? BI.replaceAll(node.text.replace(/<[^>]+>/g, ""), " ", " ") : node.value; - }, - - // 获取半选框值 - _getHalfSelectedValues: function (map, node) { - var self = this; - var checkState = node.getCheckStatus(); - // 将未选的去掉 - if (checkState.checked === false && checkState.half === false) { - return; - } - // 如果节点已展开,并且是半选 - if (BI.isNotEmptyArray(node.children) && checkState.half === true) { - var children = node.children; - BI.each(children, function (i, ch) { - self._getHalfSelectedValues(map, ch); - }); - return; - } - var parent = node.parentValues || self._getParentValues(node); - var path = parent.concat(this._getNodeValue(node)); - // 当前节点是全选的,因为上面的判断已经排除了不选和半选 - if (BI.isNotEmptyArray(node.children) || checkState.half === false) { - this._buildTree(map, path); - return; - } - // 剩下的就是半选不展开的节点,因为不知道里面是什么情况,所以借助selectedValues(这个是完整的选中情况) - var storeValues = BI.deepClone(this.options.paras.selectedValues); - var treeNode = this._getTree(storeValues, path); - this._addTreeNode(map, parent, this._getNodeValue(node), treeNode); - }, - - // 获取的是以values最后一个节点为根的子树 - _getTree: function (map, values) { - var cur = map; - BI.any(values, function (i, value) { - if (cur[value] == null) { - return true; - } - cur = cur[value]; - }); - return cur; - }, - - // 以values为path一路向里补充map, 并在末尾节点添加key: value节点 - _addTreeNode: function (map, values, key, value) { - var cur = map; - BI.each(values, function (i, value) { - if (cur[value] == null) { - cur[value] = {}; - } - cur = cur[value]; - }); - cur[key] = value; - }, - - // 构造树节点 - _buildTree: function (map, values) { - var cur = map; - BI.each(values, function (i, value) { - if (cur[value] == null) { - cur[value] = {}; - } - cur = cur[value]; - }); - }, - - // 获取选中的值 - _getSelectedValues: function () { - var self = this; - var hashMap = {}; - var rootNoots = this.nodes.getNodes(); - track(rootNoots); // 可以看到这个方法没有递归调用,所以在_getHalfSelectedValues中需要关心全选的节点 - function track(nodes) { - BI.each(nodes, function (i, node) { - var checkState = node.getCheckStatus(); - if (checkState.checked === true || checkState.half === true) { - if (checkState.half === true) { - self._getHalfSelectedValues(hashMap, node); - } else { - var parentValues = node.parentValues || self._getParentValues(node); - var values = parentValues.concat([self._getNodeValue(node)]); - self._buildTree(hashMap, values); - } - } - }); - } - - return hashMap; - }, - - // 处理节点 - _dealWidthNodes: function (nodes) { - var self = this, o = this.options; - var ns = BI.Tree.arrayFormat(nodes); - return BI.map(ns, function (i, n) { - var newNode = BI.extend({}, n); - newNode.isParent = newNode.isParent || newNode.parent; - // n.value = BI.isUndefined(n.value) ? n.text : n.value; - // n.text = BI.isUndefined(n.text) ? n.value : n.text; - // if (n.text === null) { - // n.text = ""; - // } - if (BI.isNull(newNode.title)) { - newNode.title = newNode.text; - } - if (newNode.disabled) { - newNode.title = newNode.warningTitle || newNode.title; - } - var text = BI.createWidget(BI.extend({ - cls: "tree-node-text", - tagName: "span", - whiteSpace: "nowrap", - root: true, - keyword: o.paras.keyword, - }, newNode, { - type: "bi.text", - text: BI.replaceAll(newNode.text, "\n", " ") - })); - var fragment = BI.Widget._renderEngine.createElement("
    "); - fragment.append(text.element[0]); - newNode.text = fragment.html(); - // // 处理标红 - // if (BI.isNotNull(n.text)) { - // if (BI.isKey(o.paras.keyword)) { - // n.text = BI.$("
    ").__textKeywordMarked__(BI.Text.formatText(n.text + ""), o.paras.keyword, n.py).html(); - // } else { - // n.text = BI.htmlEncode(BI.Text.formatText(n.text + "")); - // } - // } - return newNode; - }); - }, - - _loadMore: function () { - var self = this, o = this.options; - this.tip.setLoading(); - var op = BI.extend({}, o.paras, { - times: ++this.times - }); - o.itemsCreator(op, function (res) { - if (self._stop === true) { - return; - } - var hasNext = !!res.hasNext, nodes = res.items || []; - - if (!hasNext) { - self.tip.setEnd(); - } else { - self.tip.setLoaded(); - } - if (nodes.length > 0) { - self.nodes.addNodes(null, self._dealWidthNodes(nodes)); - } - }); - }, - - // 生成树内部方法 - _initTree: function (setting) { - var self = this, o = this.options; - self.fireEvent(BI.Events.INIT); - this.times = 1; - var tree = this.tree; - tree.empty(); - this.loading(); - this.tip.setVisible(false); - var callback = function (nodes) { - if (self._stop === true) { - return; - } - self.nodes = BI.$.fn.zTree.init(tree.element, setting, nodes); - }; - var op = BI.extend({}, o.paras, { - times: 1 - }); - - o.itemsCreator(op, function (res) { - if (self._stop === true) { - return; - } - var hasNext = !!res.hasNext, nodes = res.items || []; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes)); - } - self.setTipVisible(nodes.length <= 0); - self.loaded(); - if (!hasNext) { - self.tip.invisible(); - } else { - self.tip.setLoaded(); - } - op.times === 1 && self.fireEvent(BI.Events.AFTERINIT); - }); - }, - - // 构造树结构, - initTree: function (nodes, setting) { - var setting = setting || { - async: { - enable: false - }, - check: { - enable: false - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true - }, - callback: {} - }; - this.nodes = BI.$.fn.zTree.init(this.tree.element, setting, nodes); - }, - - start: function () { - this._stop = false; - }, - - stop: function () { - this._stop = true; - }, - - // 生成树方法 - stroke: function (config) { - delete this.options.keyword; - BI.extend(this.options.paras, config); - var setting = this._configSetting(); - this._createTree(); - this.start(); - this._initTree(setting); - }, - - populate: function () { - this.stroke.apply(this, arguments); - }, - - hasChecked: function () { - var treeObj = this.nodes; - return treeObj.getCheckedNodes(true).length > 0; - }, - - checkAll: function (checked) { - function setNode(children) { - BI.each(children, function (i, child) { - child.halfCheck = false; - setNode(child.children); - }); - } - - if (!this.nodes) { - return; - } - - BI.each(this.nodes.getNodes(), function (i, node) { - node.halfCheck = false; - setNode(node.children); - }); - this.nodes.checkAllNodes(checked); - }, - - expandAll: function (flag) { - this.nodes && this.nodes.expandAll(flag); - }, - - // 设置树节点的状态 - setValue: function (value, param) { - this.checkAll(false); - this.updateValue(value, param); - this.refresh(); - }, - - setSelectedValue: function (value) { - this.options.paras.selectedValues = BI.deepClone(value || {}); - }, - - updateValue: function (values, param) { - if (!this.nodes) { - return; - } - param || (param = "value"); - var treeObj = this.nodes; - BI.each(values, function (v, op) { - var nodes = treeObj.getNodesByParam(param, v, null); - BI.each(nodes, function (j, node) { - BI.extend(node, { checked: true }, op); - treeObj.updateNode(node); - }); - }); - }, - - refresh: function () { - this.nodes && this.nodes.refresh(); - }, - - getValue: function () { - if (!this.nodes) { - return null; - } - return this._getSelectedValues(); - }, - - destroyed: function () { - this.stop(); - this.nodes && this.nodes.destroy(); - } -}); -BI.extend(BI.TreeView, { - REQ_TYPE_INIT_DATA: 1, - REQ_TYPE_ADJUST_DATA: 2, - REQ_TYPE_SELECT_DATA: 3, - REQ_TYPE_GET_SELECTED_DATA: 4 -}); - -BI.TreeView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.TreeView.EVENT_INIT = BI.Events.INIT; -BI.TreeView.EVENT_AFTERINIT = BI.Events.AFTERINIT; - -BI.shortcut("bi.tree_view", BI.TreeView); diff --git a/src/case/ztree/1.asynctree.js b/src/case/ztree/1.asynctree.js deleted file mode 100644 index ef44f50d3..000000000 --- a/src/case/ztree/1.asynctree.js +++ /dev/null @@ -1,264 +0,0 @@ -/** - * guy - * 异步树 - * @class BI.AsyncTree - * @extends BI.TreeView - */ -BI.AsyncTree = BI.inherit(BI.TreeView, { - _defaultConfig: function () { - return BI.extend(BI.AsyncTree.superclass._defaultConfig.apply(this, arguments), { - showIcon: false, - showLine: true, - }); - }, - _init: function () { - BI.AsyncTree.superclass._init.apply(this, arguments); - var self = this; - this.service = new BI.TreeRenderPageService({ - subNodeListGetter: function (tId) { - // 获取待检测的子节点列表, ztree并没有获取节点列表dom的API, 此处使用BI.$获取 - return BI.$("#" + self.id + " #" + tId + "_ul"); - } - }); - }, - - // 配置属性 - _configSetting: function () { - var o = this.options; - var paras = this.options.paras; - var self = this; - var setting = { - async: { - enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 - otherParam: BI.cjkEncodeDO(paras) - }, - check: { - enable: true - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: o.showIcon, - expandSpeed: "", - nameIsHTML: true, - dblClickExpand: false, - showLine: o.showLine, - nodeClasses: function (treeId, treeNode) { - return { add: [treeNode.iconCls || ""] }; - } - }, - callback: { - beforeCheck: beforeCheck, - onCheck: onCheck, - beforeExpand: beforeExpand, - onExpand: onExpand, - onCollapse: onCollapse, - onClick: onClick, - } - }; - - function onClick(event, treeId, treeNode) { - if (treeNode.disabled) { - return false; - } - var zTree = BI.$.fn.zTree.getZTreeObj(treeId); - // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 - var checked = treeNode.checked; - var status = treeNode.getCheckStatus(); - if (status.half === true && status.checked === true) { - checked = false; - } - zTree.checkNode(treeNode, !checked, true, true); - } - - function beforeCheck(treeId, treeNode) { - if (treeNode.disabled) { - return false; - } - // 下面主动修改了node的halfCheck属性, 节点属性的判断依赖halfCheck,改之前就获取一下 - var status = treeNode.getCheckStatus(); - treeNode.halfCheck = false; - if (treeNode.checked === true) { - // 将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy - // 所有的半选状态都需要取消halfCheck=true的情况 - function track(children) { - BI.each(children, function (i, ch) { - ch.halfCheck = false; - track(ch.children); - }); - } - - track(treeNode.children); - - var treeObj = BI.$.fn.zTree.getZTreeObj(treeId); - var nodes = treeObj.getSelectedNodes(); - BI.each(nodes, function (index, node) { - node.halfCheck = false; - }); - } - // 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选 - if (status.half === true && status.checked === true) { - treeNode.checked = false; - } - } - - function beforeExpand(treeId, treeNode) { - self._beforeExpandNode(treeId, treeNode); - } - - function onCheck(event, treeId, treeNode) { - if (treeNode.disabled) { - return false; - } - self._selectTreeNode(treeId, treeNode); - } - - function onExpand(event, treeId, treeNode) { - treeNode.halfCheck = false; - } - - function onCollapse(event, treeId, treeNode) { - treeNode.halfCheck = false; - } - - return setting; - }, - - // 用来更新this.options.paras.selectedValues, 和ztree内部无关 - _selectTreeNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); - var name = this._getNodeValue(treeNode); - // var values = parentValues.concat([name]); - if (treeNode.checked === true) { - this._addTreeNode(this.options.paras.selectedValues, parentValues, name, {}); - } else { - var tNode = treeNode; - var pNode = this._getTree(this.options.paras.selectedValues, parentValues); - if (BI.isNotNull(pNode[name])) { - delete pNode[name]; - } - while (tNode != null && BI.isEmpty(pNode)) { - parentValues = parentValues.slice(0, parentValues.length - 1); - tNode = tNode.getParentNode(); - if (tNode != null) { - pNode = this._getTree(this.options.paras.selectedValues, parentValues); - name = this._getNodeValue(tNode); - delete pNode[name]; - } - } - this.options.paras.selectedValues = this._getJoinValue(); - } - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); - }, - - // 展开节点 - _beforeExpandNode: function (treeId, treeNode) { - var self = this, o = this.options; - var complete = function (d) { - var nodes = d.items || []; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes), !!d.hasNext); - } - }; - - function callback(nodes, hasNext) { - self.nodes.addNodes(treeNode, nodes); - if (hasNext) { - self.service.pushNodeList(treeNode.tId, getNodes); - } else { - self.service.removeNodeList(treeNode.tId); - } - - } - - function getNodes(options) { - // console.log(times); - options = options || {}; - var parentValues = treeNode.parentValues || self._getParentValues(treeNode); - var op = BI.extend({}, o.paras, { - id: treeNode.id, - times: options.times, - parentValues: parentValues.concat(self._getNodeValue(treeNode)), - checkState: treeNode.getCheckStatus() - }, options); - o.itemsCreator(op, complete); - } - - // 展开节点会将halfCheck置为false以开启自动计算半选, 所以第一次展开节点的时候需要在置为false之前获取配置 - var checkState = treeNode.getCheckStatus(); - if (!treeNode.children && !treeNode.requested) { - treeNode.requested = true; - setTimeout(function () { - getNodes({ - times: 1, - checkState: checkState - }); - }, 17); - } - }, - - // a,b 两棵树 - // a->b b->a 做两次校验, 构造一个校验后的map - // e.g. 以a为基准,如果b没有此节点,则在map中添加。 如b有,且是全选的, 则在map中构造全选(为什么不添加a的值呢? 因为这次是取并集), 如果b中也有和a一样的存值,就递归 - _join: function (valueA, valueB) { - var self = this; - var map = {}; - track([], valueA, valueB); - track([], valueB, valueA); - - function track(parent, node, compare) { - BI.each(node, function (n, item) { - if (BI.isNull(compare[n])) { - self._addTreeNode(map, parent, n, item); - } else if (BI.isEmpty(compare[n])) { - self._addTreeNode(map, parent, n, item); - } else { - track(parent.concat([n]), node[n], compare[n]); - } - }); - } - - return map; - }, - - hasChecked: function () { - return !BI.isEmpty(this.options.paras.selectedValues) || BI.AsyncTree.superclass.hasChecked.apply(this, arguments); - }, - - _getJoinValue: function () { - if (!this.nodes) { - return this.options.paras.selectedValues || {}; - } - var checkedValues = this._getSelectedValues(); - if (BI.isEmpty(checkedValues)) { - return BI.deepClone(this.options.paras.selectedValues); - } - if (BI.isEmpty(this.options.paras.selectedValues)) { - return checkedValues; - } - return this._join(checkedValues, this.options.paras.selectedValues); - }, - - getValue: function () { - return this._getJoinValue(); - }, - - // 生成树方法 - stroke: function (config) { - delete this.options.keyword; - this.service.clear(); - BI.extend(this.options.paras, config); - var setting = this._configSetting(); - this._initTree(setting); - } -}); - -BI.shortcut("bi.async_tree", BI.AsyncTree); diff --git a/src/case/ztree/jquery.ztree.core-3.5.js b/src/case/ztree/jquery.ztree.core-3.5.js deleted file mode 100644 index 875f33e67..000000000 --- a/src/case/ztree/jquery.ztree.core-3.5.js +++ /dev/null @@ -1,2020 +0,0 @@ -/* - * JQuery zTree core - * v3.5.48 - * http://treejs.cn/ - * - * Copyright (c) 2010 Hunter.z - * - * Licensed same as jquery - MIT License - * http://www.opensource.org/licenses/mit-license.php - * - * Date: 2020-11-21 - */ - -(function ($) { - var settings = {}, roots = {}, caches = {}, - //default consts of core - _consts = { - className: { - BUTTON: "button", - ICON: "icon", - LEVEL: "level", - ICO_LOADING: "ico_loading", - SWITCH: "switch", - NAME: 'node_name' - }, - event: { - NODECREATED: "ztree_nodeCreated", - CLICK: "ztree_click", - EXPAND: "ztree_expand", - COLLAPSE: "ztree_collapse", - ASYNC_SUCCESS: "ztree_async_success", - ASYNC_ERROR: "ztree_async_error", - REMOVE: "ztree_remove", - SELECTED: "ztree_selected", - UNSELECTED: "ztree_unselected" - }, - id: { - A: "_a", - ICON: "_ico", - SPAN: "_span", - SWITCH: "_switch", - UL: "_ul" - }, - line: { - ROOT: "root", - ROOTS: "roots", - CENTER: "center", - BOTTOM: "bottom", - NOLINE: "noline", - LINE: "line" - }, - folder: { - OPEN: "open", - CLOSE: "close", - DOCU: "docu" - }, - node: { - CURSELECTED: "curSelectedNode" - } - }, - //default setting of core - _setting = { - treeId: "", - treeObj: null, - view: { - addDiyDom: null, - autoCancelSelected: true, - dblClickExpand: true, - expandSpeed: "fast", - fontCss: {}, - nodeClasses: {}, - nameIsHTML: false, - selectedMulti: true, - showIcon: true, - showLine: true, - showTitle: true, - txtSelectedEnable: false - }, - data: { - key: { - isParent: "isParent", - children: "children", - name: "name", - title: "", - url: "url", - icon: "icon" - }, - render: { - name: null, - title: null, - }, - simpleData: { - enable: false, - idKey: "id", - pIdKey: "pId", - rootPId: null - }, - keep: { - parent: false, - leaf: false - } - }, - async: { - enable: false, - contentType: "application/x-www-form-urlencoded", - type: "post", - dataType: "text", - headers: {}, - xhrFields: {}, - url: "", - autoParam: [], - otherParam: [], - dataFilter: null - }, - callback: { - beforeAsync: null, - beforeClick: null, - beforeDblClick: null, - beforeRightClick: null, - beforeMouseDown: null, - beforeMouseUp: null, - beforeExpand: null, - beforeCollapse: null, - beforeRemove: null, - - onAsyncError: null, - onAsyncSuccess: null, - onNodeCreated: null, - onClick: null, - onDblClick: null, - onRightClick: null, - onMouseDown: null, - onMouseUp: null, - onExpand: null, - onCollapse: null, - onRemove: null - } - }, - //default root of core - //zTree use root to save full data - _initRoot = function (setting) { - var r = data.getRoot(setting); - if (!r) { - r = {}; - data.setRoot(setting, r); - } - data.nodeChildren(setting, r, []); - r.expandTriggerFlag = false; - r.curSelectedList = []; - r.noSelection = true; - r.createdNodes = []; - r.zId = 0; - r._ver = (new Date()).getTime(); - }, - //default cache of core - _initCache = function (setting) { - var c = data.getCache(setting); - if (!c) { - c = {}; - data.setCache(setting, c); - } - c.nodes = []; - c.doms = []; - }, - //default bindEvent of core - _bindEvent = function (setting) { - var o = setting.treeObj, - c = consts.event; - o.bind(c.NODECREATED, function (event, treeId, node) { - tools.apply(setting.callback.onNodeCreated, [event, treeId, node]); - }); - - o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) { - tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]); - }); - - o.bind(c.EXPAND, function (event, treeId, node) { - tools.apply(setting.callback.onExpand, [event, treeId, node]); - }); - - o.bind(c.COLLAPSE, function (event, treeId, node) { - tools.apply(setting.callback.onCollapse, [event, treeId, node]); - }); - - o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) { - tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]); - }); - - o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) { - tools.apply(setting.callback.onAsyncError, [event, treeId, node, XMLHttpRequest, textStatus, errorThrown]); - }); - - o.bind(c.REMOVE, function (event, treeId, treeNode) { - tools.apply(setting.callback.onRemove, [event, treeId, treeNode]); - }); - - o.bind(c.SELECTED, function (event, treeId, node) { - tools.apply(setting.callback.onSelected, [treeId, node]); - }); - o.bind(c.UNSELECTED, function (event, treeId, node) { - tools.apply(setting.callback.onUnSelected, [treeId, node]); - }); - }, - _unbindEvent = function (setting) { - var o = setting.treeObj, - c = consts.event; - o.unbind(c.NODECREATED) - .unbind(c.CLICK) - .unbind(c.EXPAND) - .unbind(c.COLLAPSE) - .unbind(c.ASYNC_SUCCESS) - .unbind(c.ASYNC_ERROR) - .unbind(c.REMOVE) - .unbind(c.SELECTED) - .unbind(c.UNSELECTED); - }, - //default event proxy of core - _eventProxy = function (event) { - var target = event.target, - setting = data.getSetting(event.data.treeId), - tId = "", node = null, - nodeEventType = "", treeEventType = "", - nodeEventCallback = null, treeEventCallback = null, - tmp = null; - - if (tools.eqs(event.type, "mousedown")) { - treeEventType = "mousedown"; - } else if (tools.eqs(event.type, "mouseup")) { - treeEventType = "mouseup"; - } else if (tools.eqs(event.type, "contextmenu")) { - treeEventType = "contextmenu"; - } else if (tools.eqs(event.type, "click")) { - if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode" + consts.id.SWITCH) !== null) { - tId = tools.getNodeMainDom(target).id; - nodeEventType = "switchNode"; - } else { - tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); - if (tmp) { - tId = tools.getNodeMainDom(tmp).id; - nodeEventType = "clickNode"; - } - } - } else if (tools.eqs(event.type, "dblclick")) { - treeEventType = "dblclick"; - tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); - if (tmp) { - tId = tools.getNodeMainDom(tmp).id; - nodeEventType = "switchNode"; - } - } - if (treeEventType.length > 0 && tId.length == 0) { - tmp = tools.getMDom(setting, target, [{ tagName: "a", attrName: "treeNode" + consts.id.A }]); - if (tmp) { - tId = tools.getNodeMainDom(tmp).id; - } - } - // event to node - if (tId.length > 0) { - node = data.getNodeCache(setting, tId); - switch (nodeEventType) { - case "switchNode" : - var isParent = data.nodeIsParent(setting, node); - if (!isParent) { - nodeEventType = ""; - } else if (tools.eqs(event.type, "click") - || (tools.eqs(event.type, "dblclick") && tools.apply(setting.view.dblClickExpand, [setting.treeId, node], setting.view.dblClickExpand))) { - nodeEventCallback = handler.onSwitchNode; - } else { - nodeEventType = ""; - } - break; - case "clickNode" : - nodeEventCallback = handler.onClickNode; - break; - } - } - // event to zTree - switch (treeEventType) { - case "mousedown" : - treeEventCallback = handler.onZTreeMousedown; - break; - case "mouseup" : - treeEventCallback = handler.onZTreeMouseup; - break; - case "dblclick" : - treeEventCallback = handler.onZTreeDblclick; - break; - case "contextmenu" : - treeEventCallback = handler.onZTreeContextmenu; - break; - } - var proxyResult = { - stop: false, - node: node, - nodeEventType: nodeEventType, - nodeEventCallback: nodeEventCallback, - treeEventType: treeEventType, - treeEventCallback: treeEventCallback - }; - return proxyResult; - }, - //default init node of core - _initNode = function (setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { - if (!n) return; - var r = data.getRoot(setting), - children = data.nodeChildren(setting, n); - n.level = level; - n.tId = setting.treeId + "_" + (++r.zId); - n.parentTId = parentNode ? parentNode.tId : null; - n.open = (typeof n.open == "string") ? tools.eqs(n.open, "true") : !!n.open; - var isParent = data.nodeIsParent(setting, n); - if (tools.isArray(children)) { - data.nodeIsParent(setting, n, true); - n.zAsync = true; - } else { - isParent = data.nodeIsParent(setting, n, isParent); - n.open = (isParent && !setting.async.enable) ? n.open : false; - n.zAsync = !isParent; - } - n.isFirstNode = isFirstNode; - n.isLastNode = isLastNode; - n.getParentNode = function () { - return data.getNodeCache(setting, n.parentTId); - }; - n.getPreNode = function () { - return data.getPreNode(setting, n); - }; - n.getNextNode = function () { - return data.getNextNode(setting, n); - }; - n.getIndex = function () { - return data.getNodeIndex(setting, n); - }; - n.getPath = function () { - return data.getNodePath(setting, n); - }; - n.isAjaxing = false; - data.fixPIdKeyValue(setting, n); - }, - _init = { - bind: [_bindEvent], - unbind: [_unbindEvent], - caches: [_initCache], - nodes: [_initNode], - proxys: [_eventProxy], - roots: [_initRoot], - beforeA: [], - afterA: [], - innerBeforeA: [], - innerAfterA: [], - zTreeTools: [] - }, - //method of operate data - data = { - addNodeCache: function (setting, node) { - data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node; - }, - getNodeCacheId: function (tId) { - return tId.substring(tId.lastIndexOf("_") + 1); - }, - addAfterA: function (afterA) { - _init.afterA.push(afterA); - }, - addBeforeA: function (beforeA) { - _init.beforeA.push(beforeA); - }, - addInnerAfterA: function (innerAfterA) { - _init.innerAfterA.push(innerAfterA); - }, - addInnerBeforeA: function (innerBeforeA) { - _init.innerBeforeA.push(innerBeforeA); - }, - addInitBind: function (bindEvent) { - _init.bind.push(bindEvent); - }, - addInitUnBind: function (unbindEvent) { - _init.unbind.push(unbindEvent); - }, - addInitCache: function (initCache) { - _init.caches.push(initCache); - }, - addInitNode: function (initNode) { - _init.nodes.push(initNode); - }, - addInitProxy: function (initProxy, isFirst) { - if (!!isFirst) { - _init.proxys.splice(0, 0, initProxy); - } else { - _init.proxys.push(initProxy); - } - }, - addInitRoot: function (initRoot) { - _init.roots.push(initRoot); - }, - addNodesData: function (setting, parentNode, index, nodes) { - var children = data.nodeChildren(setting, parentNode), params; - if (!children) { - children = data.nodeChildren(setting, parentNode, []); - index = -1; - } else if (index >= children.length) { - index = -1; - } - - if (children.length > 0 && index === 0) { - children[0].isFirstNode = false; - view.setNodeLineIcos(setting, children[0]); - } else if (children.length > 0 && index < 0) { - children[children.length - 1].isLastNode = false; - view.setNodeLineIcos(setting, children[children.length - 1]); - } - data.nodeIsParent(setting, parentNode, true); - - if (index < 0) { - data.nodeChildren(setting, parentNode, children.concat(nodes)); - } else { - params = [index, 0].concat(nodes); - children.splice.apply(children, params); - } - }, - addSelectedNode: function (setting, node) { - var root = data.getRoot(setting); - if (!data.isSelectedNode(setting, node)) { - root.curSelectedList.push(node); - } - }, - addCreatedNode: function (setting, node) { - if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { - var root = data.getRoot(setting); - root.createdNodes.push(node); - } - }, - addZTreeTools: function (zTreeTools) { - _init.zTreeTools.push(zTreeTools); - }, - exSetting: function (s) { - $.extend(true, _setting, s); - }, - fixPIdKeyValue: function (setting, node) { - if (setting.data.simpleData.enable) { - node[setting.data.simpleData.pIdKey] = node.parentTId ? node.getParentNode()[setting.data.simpleData.idKey] : setting.data.simpleData.rootPId; - } - }, - getAfterA: function (setting, node, array) { - for (var i = 0, j = _init.afterA.length; i < j; i++) { - _init.afterA[i].apply(this, arguments); - } - }, - getBeforeA: function (setting, node, array) { - for (var i = 0, j = _init.beforeA.length; i < j; i++) { - _init.beforeA[i].apply(this, arguments); - } - }, - getInnerAfterA: function (setting, node, array) { - for (var i = 0, j = _init.innerAfterA.length; i < j; i++) { - _init.innerAfterA[i].apply(this, arguments); - } - }, - getInnerBeforeA: function (setting, node, array) { - for (var i = 0, j = _init.innerBeforeA.length; i < j; i++) { - _init.innerBeforeA[i].apply(this, arguments); - } - }, - getCache: function (setting) { - return caches[setting.treeId]; - }, - getNodeIndex: function (setting, node) { - if (!node) return null; - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - children = data.nodeChildren(setting, p); - for (var i = 0, l = children.length - 1; i <= l; i++) { - if (children[i] === node) { - return i; - } - } - return -1; - }, - getNextNode: function (setting, node) { - if (!node) return null; - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - children = data.nodeChildren(setting, p); - for (var i = 0, l = children.length - 1; i <= l; i++) { - if (children[i] === node) { - return (i == l ? null : children[i + 1]); - } - } - return null; - }, - getNodeByParam: function (setting, nodes, key, value) { - if (!nodes || !key) return null; - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (node[key] == value) { - return nodes[i]; - } - var children = data.nodeChildren(setting, node); - var tmp = data.getNodeByParam(setting, children, key, value); - if (tmp) return tmp; - } - return null; - }, - getNodeCache: function (setting, tId) { - if (!tId) return null; - var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)]; - return n ? n : null; - }, - getNodePath: function (setting, node) { - if (!node) return null; - - var path; - if (node.parentTId) { - path = node.getParentNode().getPath(); - } else { - path = []; - } - - if (path) { - path.push(node); - } - - return path; - }, - getNodes: function (setting) { - return data.nodeChildren(setting, data.getRoot(setting)); - }, - getNodesByParam: function (setting, nodes, key, value) { - if (!nodes || !key) return []; - var result = []; - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (node[key] == value) { - result.push(node); - } - var children = data.nodeChildren(setting, node); - result = result.concat(data.getNodesByParam(setting, children, key, value)); - } - return result; - }, - getNodesByParamFuzzy: function (setting, nodes, key, value) { - if (!nodes || !key) return []; - var result = []; - value = value.toLowerCase(); - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (typeof node[key] == "string" && nodes[i][key].toLowerCase().indexOf(value) > -1) { - result.push(node); - } - var children = data.nodeChildren(setting, node); - result = result.concat(data.getNodesByParamFuzzy(setting, children, key, value)); - } - return result; - }, - getNodesByFilter: function (setting, nodes, filter, isSingle, invokeParam) { - if (!nodes) return (isSingle ? null : []); - var result = isSingle ? null : []; - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (tools.apply(filter, [node, invokeParam], false)) { - if (isSingle) { - return node; - } - result.push(node); - } - var children = data.nodeChildren(setting, node); - var tmpResult = data.getNodesByFilter(setting, children, filter, isSingle, invokeParam); - if (isSingle && !!tmpResult) { - return tmpResult; - } - result = isSingle ? tmpResult : result.concat(tmpResult); - } - return result; - }, - getPreNode: function (setting, node) { - if (!node) return null; - var p = node.parentTId ? node.getParentNode() : data.getRoot(setting), - children = data.nodeChildren(setting, p); - for (var i = 0, l = children.length; i < l; i++) { - if (children[i] === node) { - return (i == 0 ? null : children[i - 1]); - } - } - return null; - }, - getRoot: function (setting) { - return setting ? roots[setting.treeId] : null; - }, - getRoots: function () { - return roots; - }, - getSetting: function (treeId) { - return settings[treeId]; - }, - getSettings: function () { - return settings; - }, - getZTreeTools: function (treeId) { - var r = this.getRoot(this.getSetting(treeId)); - return r ? r.treeTools : null; - }, - initCache: function (setting) { - for (var i = 0, j = _init.caches.length; i < j; i++) { - _init.caches[i].apply(this, arguments); - } - }, - initNode: function (setting, level, node, parentNode, preNode, nextNode) { - for (var i = 0, j = _init.nodes.length; i < j; i++) { - _init.nodes[i].apply(this, arguments); - } - }, - initRoot: function (setting) { - for (var i = 0, j = _init.roots.length; i < j; i++) { - _init.roots[i].apply(this, arguments); - } - }, - isSelectedNode: function (setting, node) { - var root = data.getRoot(setting); - for (var i = 0, j = root.curSelectedList.length; i < j; i++) { - if (node === root.curSelectedList[i]) return true; - } - return false; - }, - nodeChildren: function (setting, node, newChildren) { - if (!node) { - return null; - } - var key = setting.data.key.children; - if (typeof newChildren !== 'undefined') { - node[key] = newChildren; - } - return node[key]; - }, - nodeIsParent: function (setting, node, newIsParent) { - if (!node) { - return false; - } - var key = setting.data.key.isParent; - if (typeof newIsParent !== 'undefined') { - if (typeof newIsParent === "string") { - newIsParent = tools.eqs(newIsParent, "true"); - } - newIsParent = !!newIsParent; - node[key] = newIsParent; - } else if (typeof node[key] == "string") { - node[key] = tools.eqs(node[key], "true"); - } else { - node[key] = !!node[key]; - } - return node[key]; - }, - nodeName: function (setting, node, newName) { - var key = setting.data.key.name; - if (typeof newName !== 'undefined') { - node[key] = newName; - } - var rawName = "" + node[key]; - if (typeof setting.data.render.name === 'function') { - return setting.data.render.name.call(this, rawName, node); - } - return rawName; - }, - nodeTitle: function (setting, node) { - var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title; - var rawTitle = "" + node[t]; - if (typeof setting.data.render.title === 'function') { - return setting.data.render.title.call(this, rawTitle, node); - } - return rawTitle; - }, - removeNodeCache: function (setting, node) { - var children = data.nodeChildren(setting, node); - if (children) { - for (var i = 0, l = children.length; i < l; i++) { - data.removeNodeCache(setting, children[i]); - } - } - data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null; - }, - removeSelectedNode: function (setting, node) { - var root = data.getRoot(setting); - for (var i = 0, j = root.curSelectedList.length; i < j; i++) { - if (node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) { - root.curSelectedList.splice(i, 1); - setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, node]); - i--; - j--; - } - } - }, - setCache: function (setting, cache) { - caches[setting.treeId] = cache; - }, - setRoot: function (setting, root) { - roots[setting.treeId] = root; - }, - setZTreeTools: function (setting, zTreeTools) { - for (var i = 0, j = _init.zTreeTools.length; i < j; i++) { - _init.zTreeTools[i].apply(this, arguments); - } - }, - transformToArrayFormat: function (setting, nodes) { - if (!nodes) return []; - var r = []; - if (tools.isArray(nodes)) { - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - _do(node); - } - } else { - _do(nodes); - } - return r; - - function _do(_node) { - r.push(_node); - var children = data.nodeChildren(setting, _node); - if (children) { - r = r.concat(data.transformToArrayFormat(setting, children)); - } - } - }, - transformTozTreeFormat: function (setting, sNodes) { - var i, l, - key = setting.data.simpleData.idKey, - parentKey = setting.data.simpleData.pIdKey; - if (!key || key == "" || !sNodes) return []; - - if (tools.isArray(sNodes)) { - var r = []; - var tmpMap = {}; - for (i = 0, l = sNodes.length; i < l; i++) { - tmpMap[sNodes[i][key]] = sNodes[i]; - } - for (i = 0, l = sNodes.length; i < l; i++) { - var p = tmpMap[sNodes[i][parentKey]]; - if (p && sNodes[i][key] != sNodes[i][parentKey]) { - var children = data.nodeChildren(setting, p); - if (!children) { - children = data.nodeChildren(setting, p, []); - } - children.push(sNodes[i]); - } else { - r.push(sNodes[i]); - } - } - return r; - } else { - return [sNodes]; - } - } - }, - //method of event proxy - event = { - bindEvent: function (setting) { - for (var i = 0, j = _init.bind.length; i < j; i++) { - _init.bind[i].apply(this, arguments); - } - }, - unbindEvent: function (setting) { - for (var i = 0, j = _init.unbind.length; i < j; i++) { - _init.unbind[i].apply(this, arguments); - } - }, - bindTree: function (setting) { - var eventParam = { - treeId: setting.treeId - }, - o = setting.treeObj; - if (!setting.view.txtSelectedEnable) { - // for can't select text - o.bind('selectstart', handler.onSelectStart).css({ - "-moz-user-select": "-moz-none" - }); - } - o.bind('click', eventParam, event.proxy); - o.bind('dblclick', eventParam, event.proxy); - o.bind('mouseover', eventParam, event.proxy); - o.bind('mouseout', eventParam, event.proxy); - o.bind('mousedown', eventParam, event.proxy); - o.bind('mouseup', eventParam, event.proxy); - o.bind('contextmenu', eventParam, event.proxy); - }, - unbindTree: function (setting) { - var o = setting.treeObj; - o.unbind('selectstart', handler.onSelectStart) - .unbind('click', event.proxy) - .unbind('dblclick', event.proxy) - .unbind('mouseover', event.proxy) - .unbind('mouseout', event.proxy) - .unbind('mousedown', event.proxy) - .unbind('mouseup', event.proxy) - .unbind('contextmenu', event.proxy); - }, - doProxy: function (e) { - var results = []; - for (var i = 0, j = _init.proxys.length; i < j; i++) { - var proxyResult = _init.proxys[i].apply(this, arguments); - results.push(proxyResult); - if (proxyResult.stop) { - break; - } - } - return results; - }, - proxy: function (e) { - var setting = data.getSetting(e.data.treeId); - if (!tools.uCanDo(setting, e)) return true; - var results = event.doProxy(e), - r = true, x = false; - for (var i = 0, l = results.length; i < l; i++) { - var proxyResult = results[i]; - if (proxyResult.nodeEventCallback) { - x = true; - r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; - } - if (proxyResult.treeEventCallback) { - x = true; - r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; - } - } - return r; - } - }, - //method of event handler - handler = { - onSwitchNode: function (event, node) { - var setting = data.getSetting(event.data.treeId); - if (node.open) { - if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) return true; - data.getRoot(setting).expandTriggerFlag = true; - view.switchNode(setting, node); - } else { - if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true; - data.getRoot(setting).expandTriggerFlag = true; - view.switchNode(setting, node); - } - return true; - }, - onClickNode: function (event, node) { - var setting = data.getSetting(event.data.treeId), - clickFlag = ((setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey)) && data.isSelectedNode(setting, node)) ? 0 : (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey) && setting.view.selectedMulti) ? 2 : 1; - if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) return true; - if (clickFlag === 0) { - view.cancelPreSelectedNode(setting, node); - } else { - view.selectNode(setting, node, clickFlag === 2); - } - setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]); - return true; - }, - onZTreeMousedown: function (event, node) { - var setting = data.getSetting(event.data.treeId); - if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) { - tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]); - } - return true; - }, - onZTreeMouseup: function (event, node) { - var setting = data.getSetting(event.data.treeId); - if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) { - tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]); - } - return true; - }, - onZTreeDblclick: function (event, node) { - var setting = data.getSetting(event.data.treeId); - if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) { - tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]); - } - return true; - }, - onZTreeContextmenu: function (event, node) { - var setting = data.getSetting(event.data.treeId); - if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) { - tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]); - } - return (typeof setting.callback.onRightClick) != "function"; - }, - onSelectStart: function (e) { - var n = e.originalEvent.srcElement.nodeName.toLowerCase(); - return (n === "input" || n === "textarea"); - } - }, - //method of tools for zTree - tools = { - apply: function (fun, param, defaultValue) { - if ((typeof fun) == "function") { - return fun.apply(zt, param ? param : []); - } - return defaultValue; - }, - canAsync: function (setting, node) { - var children = data.nodeChildren(setting, node); - var isParent = data.nodeIsParent(setting, node); - return (setting.async.enable && node && isParent && !(node.zAsync || (children && children.length > 0))); - }, - clone: function (obj) { - if (obj === null) return null; - var o = tools.isArray(obj) ? [] : {}; - for (var i in obj) { - o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? tools.clone(obj[i]) : obj[i]); - } - return o; - }, - eqs: function (str1, str2) { - return str1.toLowerCase() === str2.toLowerCase(); - }, - isArray: function (arr) { - return Object.prototype.toString.apply(arr) === "[object Array]"; - }, - isElement: function (o) { - return ( - typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2 - o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string" - ); - }, - $: function (node, exp, setting) { - if (!!exp && typeof exp != "string") { - setting = exp; - exp = ""; - } - if (typeof node == "string") { - return $(node, setting ? setting.treeObj.get(0).ownerDocument : null); - } else { - return $("#" + node.tId + exp, setting ? setting.treeObj : null); - } - }, - getMDom: function (setting, curDom, targetExpr) { - if (!curDom) return null; - while (curDom && curDom.id !== setting.treeId) { - for (var i = 0, l = targetExpr.length; curDom.tagName && i < l; i++) { - if (tools.eqs(curDom.tagName, targetExpr[i].tagName) && curDom.getAttribute(targetExpr[i].attrName) !== null) { - return curDom; - } - } - curDom = curDom.parentNode; - } - return null; - }, - getNodeMainDom: function (target) { - return ($(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0)); - }, - isChildOrSelf: function (dom, parentId) { - return ($(dom).closest("#" + parentId).length > 0); - }, - uCanDo: function (setting, e) { - return true; - } - }, - //method of operate ztree dom - view = { - addNodes: function (setting, parentNode, index, newNodes, isSilent) { - var isParent = data.nodeIsParent(setting, parentNode); - if (setting.data.keep.leaf && parentNode && !isParent) { - return; - } - if (!tools.isArray(newNodes)) { - newNodes = [newNodes]; - } - if (setting.data.simpleData.enable) { - newNodes = data.transformTozTreeFormat(setting, newNodes); - } - if (parentNode) { - var target_switchObj = $$(parentNode, consts.id.SWITCH, setting), - target_icoObj = $$(parentNode, consts.id.ICON, setting), - target_ulObj = $$(parentNode, consts.id.UL, setting); - - if (!parentNode.open) { - view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE); - view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE); - parentNode.open = false; - target_ulObj.css({ - "display": "none" - }); - } - - data.addNodesData(setting, parentNode, index, newNodes); - view.createNodes(setting, parentNode.level + 1, newNodes, parentNode, index); - if (!isSilent) { - view.expandCollapseParentNode(setting, parentNode, true); - } - } else { - data.addNodesData(setting, data.getRoot(setting), index, newNodes); - view.createNodes(setting, 0, newNodes, null, index); - } - }, - appendNodes: function (setting, level, nodes, parentNode, index, initFlag, openFlag) { - if (!nodes) return []; - var html = []; - - var tmpPNode = (parentNode) ? parentNode : data.getRoot(setting), - tmpPChild = data.nodeChildren(setting, tmpPNode), - isFirstNode, isLastNode; - - if (!tmpPChild || index >= tmpPChild.length - nodes.length) { - index = -1; - } - - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - if (initFlag) { - isFirstNode = ((index === 0 || tmpPChild.length == nodes.length) && (i == 0)); - isLastNode = (index < 0 && i == (nodes.length - 1)); - data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); - data.addNodeCache(setting, node); - } - var isParent = data.nodeIsParent(setting, node); - - var childHtml = []; - var children = data.nodeChildren(setting, node); - if (children && children.length > 0) { - //make child html first, because checkType - childHtml = view.appendNodes(setting, level + 1, children, node, -1, initFlag, openFlag && node.open); - } - if (openFlag) { - view.makeDOMNodeMainBefore(html, setting, node); - view.makeDOMNodeLine(html, setting, node); - data.getBeforeA(setting, node, html); - view.makeDOMNodeNameBefore(html, setting, node); - data.getInnerBeforeA(setting, node, html); - view.makeDOMNodeIcon(html, setting, node); - data.getInnerAfterA(setting, node, html); - view.makeDOMNodeNameAfter(html, setting, node); - data.getAfterA(setting, node, html); - if (isParent && node.open) { - view.makeUlHtml(setting, node, html, childHtml.join('')); - } - view.makeDOMNodeMainAfter(html, setting, node); - data.addCreatedNode(setting, node); - } - } - return html; - }, - appendParentULDom: function (setting, node) { - var html = [], - nObj = $$(node, setting); - if (!nObj.get(0) && !!node.parentTId) { - view.appendParentULDom(setting, node.getParentNode()); - nObj = $$(node, setting); - } - var ulObj = $$(node, consts.id.UL, setting); - if (ulObj.get(0)) { - ulObj.remove(); - } - var children = data.nodeChildren(setting, node), - childHtml = view.appendNodes(setting, node.level + 1, children, node, -1, false, true); - view.makeUlHtml(setting, node, html, childHtml.join('')); - nObj.append(html.join('')); - }, - asyncNode: function (setting, node, isSilent, callback) { - var i, l; - var isParent = data.nodeIsParent(setting, node); - if (node && !isParent) { - tools.apply(callback); - return false; - } else if (node && node.isAjaxing) { - return false; - } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) { - tools.apply(callback); - return false; - } - if (node) { - node.isAjaxing = true; - var icoObj = $$(node, consts.id.ICON, setting); - icoObj.attr({ "style": "", "class": consts.className.BUTTON + " " + consts.className.ICO_LOADING }); - } - - var tmpParam = {}; - var autoParam = tools.apply(setting.async.autoParam, [setting.treeId, node], setting.async.autoParam); - for (i = 0, l = autoParam.length; node && i < l; i++) { - var pKey = autoParam[i].split("="), spKey = pKey; - if (pKey.length > 1) { - spKey = pKey[1]; - pKey = pKey[0]; - } - tmpParam[spKey] = node[pKey]; - } - var otherParam = tools.apply(setting.async.otherParam, [setting.treeId, node], setting.async.otherParam); - if (tools.isArray(otherParam)) { - for (i = 0, l = otherParam.length; i < l; i += 2) { - tmpParam[otherParam[i]] = otherParam[i + 1]; - } - } else { - for (var p in otherParam) { - tmpParam[p] = otherParam[p]; - } - } - - var _tmpV = data.getRoot(setting)._ver; - $.ajax({ - contentType: setting.async.contentType, - cache: false, - type: setting.async.type, - url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url), - data: setting.async.contentType.indexOf('application/json') > -1 ? JSON.stringify(tmpParam) : tmpParam, - dataType: setting.async.dataType, - headers: setting.async.headers, - xhrFields: setting.async.xhrFields, - success: function (msg) { - if (_tmpV != data.getRoot(setting)._ver) { - return; - } - var newNodes = []; - try { - if (!msg || msg.length == 0) { - newNodes = []; - } else if (typeof msg == "string") { - newNodes = eval("(" + msg + ")"); - } else { - newNodes = msg; - } - } catch (err) { - newNodes = msg; - } - - if (node) { - node.isAjaxing = null; - node.zAsync = true; - } - view.setNodeLineIcos(setting, node); - if (newNodes && newNodes !== "") { - newNodes = tools.apply(setting.async.dataFilter, [setting.treeId, node, newNodes], newNodes); - view.addNodes(setting, node, -1, !!newNodes ? tools.clone(newNodes) : [], !!isSilent); - } else { - view.addNodes(setting, node, -1, [], !!isSilent); - } - setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]); - tools.apply(callback); - }, - error: function (XMLHttpRequest, textStatus, errorThrown) { - if (_tmpV != data.getRoot(setting)._ver) { - return; - } - if (node) node.isAjaxing = null; - view.setNodeLineIcos(setting, node); - setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]); - } - }); - return true; - }, - cancelPreSelectedNode: function (setting, node, excludeNode) { - var list = data.getRoot(setting).curSelectedList, - i, n; - for (i = list.length - 1; i >= 0; i--) { - n = list[i]; - if (node === n || (!node && (!excludeNode || excludeNode !== n))) { - $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED); - if (node) { - data.removeSelectedNode(setting, node); - break; - } else { - list.splice(i, 1); - setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, n]); - } - } - } - }, - createNodeCallback: function (setting) { - if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { - var root = data.getRoot(setting); - while (root.createdNodes.length > 0) { - var node = root.createdNodes.shift(); - tools.apply(setting.view.addDiyDom, [setting.treeId, node]); - if (!!setting.callback.onNodeCreated) { - setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]); - } - } - } - }, - createNodes: function (setting, level, nodes, parentNode, index) { - if (!nodes || nodes.length == 0) return; - var root = data.getRoot(setting), - openFlag = !parentNode || parentNode.open || !!$$(data.nodeChildren(setting, parentNode)[0], setting).get(0); - root.createdNodes = []; - var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, index, true, openFlag), - parentObj, nextObj; - - if (!parentNode) { - parentObj = setting.treeObj; - //setting.treeObj.append(zTreeHtml.join('')); - } else { - var ulObj = $$(parentNode, consts.id.UL, setting); - if (ulObj.get(0)) { - parentObj = ulObj; - //ulObj.append(zTreeHtml.join('')); - } - } - if (parentObj) { - if (index >= 0) { - nextObj = parentObj.children()[index]; - } - if (index >= 0 && nextObj) { - $(nextObj).before(zTreeHtml.join('')); - } else { - parentObj.append(zTreeHtml.join('')); - } - } - - view.createNodeCallback(setting); - }, - destroy: function (setting) { - if (!setting) return; - data.initCache(setting); - data.initRoot(setting); - event.unbindTree(setting); - event.unbindEvent(setting); - setting.treeObj.empty(); - delete settings[setting.treeId]; - }, - expandCollapseNode: function (setting, node, expandFlag, animateFlag, callback) { - var root = data.getRoot(setting); - var tmpCb, _callback; - if (!node) { - tools.apply(callback, []); - return; - } - var children = data.nodeChildren(setting, node); - var isParent = data.nodeIsParent(setting, node); - if (root.expandTriggerFlag) { - _callback = callback; - tmpCb = function () { - if (_callback) _callback(); - if (node.open) { - setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]); - } else { - setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]); - } - }; - callback = tmpCb; - root.expandTriggerFlag = false; - } - if (!node.open && isParent && ((!$$(node, consts.id.UL, setting).get(0)) || (children && children.length > 0 && !$$(children[0], setting).get(0)))) { - view.appendParentULDom(setting, node); - view.createNodeCallback(setting); - } - if (node.open == expandFlag) { - tools.apply(callback, []); - return; - } - var ulObj = $$(node, consts.id.UL, setting), - switchObj = $$(node, consts.id.SWITCH, setting), - icoObj = $$(node, consts.id.ICON, setting); - - if (isParent) { - node.open = !node.open; - if (node.iconOpen && node.iconClose) { - icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); - } - - if (node.open) { - view.replaceSwitchClass(node, switchObj, consts.folder.OPEN); - view.replaceIcoClass(node, icoObj, consts.folder.OPEN); - if (animateFlag == false || setting.view.expandSpeed == "") { - ulObj.show(); - tools.apply(callback, []); - } else { - if (children && children.length > 0) { - ulObj.slideDown(setting.view.expandSpeed, callback); - } else { - ulObj.show(); - tools.apply(callback, []); - } - } - } else { - view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE); - view.replaceIcoClass(node, icoObj, consts.folder.CLOSE); - if (animateFlag == false || setting.view.expandSpeed == "" || !(children && children.length > 0)) { - ulObj.hide(); - tools.apply(callback, []); - } else { - ulObj.slideUp(setting.view.expandSpeed, callback); - } - } - } else { - tools.apply(callback, []); - } - }, - expandCollapseParentNode: function (setting, node, expandFlag, animateFlag, callback) { - if (!node) return; - if (!node.parentTId) { - view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); - return; - } else { - view.expandCollapseNode(setting, node, expandFlag, animateFlag); - } - if (node.parentTId) { - view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback); - } - }, - expandCollapseSonNode: function (setting, node, expandFlag, animateFlag, callback) { - var root = data.getRoot(setting), - treeNodes = (node) ? data.nodeChildren(setting, node) : data.nodeChildren(setting, root), - selfAnimateSign = (node) ? false : animateFlag, - expandTriggerFlag = data.getRoot(setting).expandTriggerFlag; - data.getRoot(setting).expandTriggerFlag = false; - if (treeNodes) { - for (var i = 0, l = treeNodes.length; i < l; i++) { - if (treeNodes[i]) view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign); - } - } - data.getRoot(setting).expandTriggerFlag = expandTriggerFlag; - view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); - }, - isSelectedNode: function (setting, node) { - if (!node) { - return false; - } - var list = data.getRoot(setting).curSelectedList, - i; - for (i = list.length - 1; i >= 0; i--) { - if (node === list[i]) { - return true; - } - } - return false; - }, - makeDOMNodeIcon: function (html, setting, node) { - var nameStr = data.nodeName(setting, node), - name = setting.view.nameIsHTML ? nameStr : nameStr.replace(/&/g, '&').replace(//g, '>'); - html.push("", name, ""); - }, - makeDOMNodeLine: function (html, setting, node) { - html.push(""); - }, - makeDOMNodeMainAfter: function (html, setting, node) { - html.push(""); - }, - makeDOMNodeMainBefore: function (html, setting, node) { - html.push("
  • "); - }, - makeDOMNodeNameAfter: function (html, setting, node) { - html.push(""); - }, - makeDOMNodeNameBefore: function (html, setting, node) { - var title = data.nodeTitle(setting, node), - url = view.makeNodeUrl(setting, node), - fontcss = view.makeNodeFontCss(setting, node), - nodeClasses = view.makeNodeClasses(setting, node), - fontStyle = []; - for (var f in fontcss) { - fontStyle.push(f, ":", fontcss[f], ";"); - } - html.push(" 0) ? " href='" + url + "'" : ""), " target='", view.makeNodeTarget(node), "' style='", fontStyle.join(''), - "'"); - if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) { - html.push("title='", title.replace(/'/g, "'").replace(//g, '>'), "'"); - } - html.push(">"); - }, - makeNodeFontCss: function (setting, node) { - var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss); - return (fontCss && ((typeof fontCss) != "function")) ? fontCss : {}; - }, - makeNodeClasses: function (setting, node) { - var classes = tools.apply(setting.view.nodeClasses, [setting.treeId, node], setting.view.nodeClasses); - return (classes && (typeof classes !== "function")) ? classes : { add: [], remove: [] }; - }, - makeNodeIcoClass: function (setting, node) { - var icoCss = ["ico"]; - if (!node.isAjaxing) { - var isParent = data.nodeIsParent(setting, node); - icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0]; - if (isParent) { - icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); - } else { - icoCss.push(consts.folder.DOCU); - } - } - return "x-icon b-font " + consts.className.ICON + " " + icoCss.join('_'); - }, - makeNodeIcoStyle: function (setting, node) { - var icoStyle = []; - if (!node.isAjaxing) { - var isParent = data.nodeIsParent(setting, node); - var icon = (isParent && node.iconOpen && node.iconClose) ? (node.open ? node.iconOpen : node.iconClose) : node[setting.data.key.icon]; - if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;"); - if (setting.view.showIcon == false || !tools.apply(setting.view.showIcon, [setting.treeId, node], true)) { - icoStyle.push("display:none;"); - } - } - return icoStyle.join(''); - }, - makeNodeLineClass: function (setting, node) { - var lineClass = []; - if (setting.view.showLine) { - if (node.level == 0 && node.isFirstNode && node.isLastNode) { - lineClass.push(consts.line.ROOT); - } else if (node.level == 0 && node.isFirstNode) { - lineClass.push(consts.line.ROOTS); - } else if (node.isLastNode) { - lineClass.push(consts.line.BOTTOM); - } else { - lineClass.push(consts.line.CENTER); - } - } else { - lineClass.push(consts.line.NOLINE); - } - if (data.nodeIsParent(setting, node)) { - lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); - } else { - lineClass.push(consts.folder.DOCU); - } - return view.makeNodeLineClassEx(node) + lineClass.join('_'); - }, - makeNodeLineClassEx: function (node) { - return consts.className.BUTTON + " " + consts.className.LEVEL + node.level + " " + consts.className.SWITCH + " "; - }, - makeNodeTarget: function (node) { - return (node.target || "_blank"); - }, - makeNodeUrl: function (setting, node) { - var urlKey = setting.data.key.url; - return node[urlKey] ? node[urlKey] : null; - }, - makeUlHtml: function (setting, node, html, content) { - html.push("
      "); - html.push(content); - html.push("
    "); - }, - makeUlLineClass: function (setting, node) { - return ((setting.view.showLine && !node.isLastNode) ? consts.line.LINE : ""); - }, - removeChildNodes: function (setting, node) { - if (!node) return; - var nodes = data.nodeChildren(setting, node); - if (!nodes) return; - - for (var i = 0, l = nodes.length; i < l; i++) { - data.removeNodeCache(setting, nodes[i]); - } - data.removeSelectedNode(setting); - delete node[setting.data.key.children]; - - if (!setting.data.keep.parent) { - data.nodeIsParent(setting, node, false); - node.open = false; - var tmp_switchObj = $$(node, consts.id.SWITCH, setting), - tmp_icoObj = $$(node, consts.id.ICON, setting); - view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU); - view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU); - $$(node, consts.id.UL, setting).remove(); - } else { - $$(node, consts.id.UL, setting).empty(); - } - }, - scrollIntoView: function (setting, dom) { - if (!dom) { - return; - } - // support IE 7 / 8 - if (typeof Element === 'undefined' || typeof HTMLElement === 'undefined') { - var contRect = setting.treeObj.get(0).getBoundingClientRect(), - findMeRect = dom.getBoundingClientRect(); - if (findMeRect.top < contRect.top || findMeRect.bottom > contRect.bottom - || findMeRect.right > contRect.right || findMeRect.left < contRect.left) { - dom.scrollIntoView(); - } - return; - } - // CC-BY jocki84@googlemail.com, https://gist.github.com/jocki84/6ffafd003387179a988e - if (!Element.prototype.scrollIntoViewIfNeeded) { - Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) { - "use strict"; - - function makeRange(start, length) { - return { "start": start, "length": length, "end": start + length }; - } - - function coverRange(inner, outer) { - if ( - false === centerIfNeeded || - (outer.start < inner.end && inner.start < outer.end) - ) { - return Math.max( - inner.end - outer.length, - Math.min(outer.start, inner.start) - ); - } - return (inner.start + inner.end - outer.length) / 2; - } - - function makePoint(x, y) { - return { - "x": x, - "y": y, - "translate": function translate(dX, dY) { - return makePoint(x + dX, y + dY); - } - }; - } - - function absolute(elem, pt) { - while (elem) { - pt = pt.translate(elem.offsetLeft, elem.offsetTop); - elem = elem.offsetParent; - } - return pt; - } - - var target = absolute(this, makePoint(0, 0)), - extent = makePoint(this.offsetWidth, this.offsetHeight), - elem = this.parentNode, - origin; - - while (elem instanceof HTMLElement) { - // Apply desired scroll amount. - origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop)); - elem.scrollLeft = coverRange( - makeRange(target.x - origin.x, extent.x), - makeRange(elem.scrollLeft, elem.clientWidth) - ); - elem.scrollTop = coverRange( - makeRange(target.y - origin.y, extent.y), - makeRange(elem.scrollTop, elem.clientHeight) - ); - - // Determine actual scroll amount by reading back scroll properties. - target = target.translate(-elem.scrollLeft, -elem.scrollTop); - elem = elem.parentNode; - } - }; - } - dom.scrollIntoViewIfNeeded(); - }, - setFirstNode: function (setting, parentNode) { - var children = data.nodeChildren(setting, parentNode); - if (children.length > 0) { - children[0].isFirstNode = true; - } - }, - setLastNode: function (setting, parentNode) { - var children = data.nodeChildren(setting, parentNode); - if (children.length > 0) { - children[children.length - 1].isLastNode = true; - } - }, - removeNode: function (setting, node) { - var root = data.getRoot(setting), - parentNode = (node.parentTId) ? node.getParentNode() : root; - - node.isFirstNode = false; - node.isLastNode = false; - node.getPreNode = function () { - return null; - }; - node.getNextNode = function () { - return null; - }; - - if (!data.getNodeCache(setting, node.tId)) { - return; - } - - $$(node, setting).remove(); - data.removeNodeCache(setting, node); - data.removeSelectedNode(setting, node); - - var children = data.nodeChildren(setting, parentNode); - for (var i = 0, l = children.length; i < l; i++) { - if (children[i].tId == node.tId) { - children.splice(i, 1); - break; - } - } - view.setFirstNode(setting, parentNode); - view.setLastNode(setting, parentNode); - - var tmp_ulObj, tmp_switchObj, tmp_icoObj, - childLength = children.length; - - //repair nodes old parent - if (!setting.data.keep.parent && childLength == 0) { - //old parentNode has no child nodes - data.nodeIsParent(setting, parentNode, false); - parentNode.open = false; - delete parentNode[setting.data.key.children]; - tmp_ulObj = $$(parentNode, consts.id.UL, setting); - tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting); - tmp_icoObj = $$(parentNode, consts.id.ICON, setting); - view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU); - view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU); - tmp_ulObj.css("display", "none"); - - } else if (setting.view.showLine && childLength > 0) { - //old parentNode has child nodes - var newLast = children[childLength - 1]; - tmp_ulObj = $$(newLast, consts.id.UL, setting); - tmp_switchObj = $$(newLast, consts.id.SWITCH, setting); - tmp_icoObj = $$(newLast, consts.id.ICON, setting); - if (parentNode == root) { - if (children.length == 1) { - //node was root, and ztree has only one root after move node - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT); - } else { - var tmp_first_switchObj = $$(children[0], consts.id.SWITCH, setting); - view.replaceSwitchClass(children[0], tmp_first_switchObj, consts.line.ROOTS); - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); - } - } else { - view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); - } - tmp_ulObj.removeClass(consts.line.LINE); - } - }, - replaceIcoClass: function (node, obj, newName) { - if (!obj || node.isAjaxing) return; - var tmpName = obj.attr("class"); - if (tmpName == undefined) return; - var tmpList = tmpName.split("_"); - switch (newName) { - case consts.folder.OPEN: - case consts.folder.CLOSE: - case consts.folder.DOCU: - tmpList[tmpList.length - 1] = newName; - break; - } - obj.attr("class", tmpList.join("_")); - }, - replaceSwitchClass: function (node, obj, newName) { - if (!obj) return; - var tmpName = obj.attr("class"); - if (tmpName == undefined) return; - var tmpList = tmpName.split("_"); - switch (newName) { - case consts.line.ROOT: - case consts.line.ROOTS: - case consts.line.CENTER: - case consts.line.BOTTOM: - case consts.line.NOLINE: - tmpList[0] = view.makeNodeLineClassEx(node) + newName; - break; - case consts.folder.OPEN: - case consts.folder.CLOSE: - case consts.folder.DOCU: - tmpList[1] = newName; - break; - } - obj.attr("class", tmpList.join("_")); - if (newName !== consts.folder.DOCU) { - obj.removeAttr("disabled"); - } else { - obj.attr("disabled", "disabled"); - } - }, - selectNode: function (setting, node, addFlag) { - if (!addFlag) { - view.cancelPreSelectedNode(setting, null, node); - } - $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED); - data.addSelectedNode(setting, node); - setting.treeObj.trigger(consts.event.SELECTED, [setting.treeId, node]); - }, - setNodeFontCss: function (setting, treeNode) { - var aObj = $$(treeNode, consts.id.A, setting), - fontCss = view.makeNodeFontCss(setting, treeNode); - if (fontCss) { - aObj.css(fontCss); - } - }, - setNodeClasses: function (setting, treeNode) { - var aObj = $$(treeNode, consts.id.A, setting), - classes = view.makeNodeClasses(setting, treeNode); - if ('add' in classes && classes.add.length) { - aObj.addClass(classes.add.join(' ')); - } - if ('remove' in classes && classes.remove.length) { - aObj.removeClass(classes.remove.join(' ')); - } - }, - setNodeLineIcos: function (setting, node) { - if (!node) return; - var switchObj = $$(node, consts.id.SWITCH, setting), - ulObj = $$(node, consts.id.UL, setting), - icoObj = $$(node, consts.id.ICON, setting), - ulLine = view.makeUlLineClass(setting, node); - if (ulLine.length == 0) { - ulObj.removeClass(consts.line.LINE); - } else { - ulObj.addClass(ulLine); - } - switchObj.attr("class", view.makeNodeLineClass(setting, node)); - if (data.nodeIsParent(setting, node)) { - switchObj.removeAttr("disabled"); - } else { - switchObj.attr("disabled", "disabled"); - } - icoObj.removeAttr("style"); - icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); - icoObj.attr("class", view.makeNodeIcoClass(setting, node)); - }, - setNodeName: function (setting, node) { - var title = data.nodeTitle(setting, node), - nObj = $$(node, consts.id.SPAN, setting); - nObj.empty(); - if (setting.view.nameIsHTML) { - nObj.html(data.nodeName(setting, node)); - } else { - nObj.text(data.nodeName(setting, node)); - } - if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) { - var aObj = $$(node, consts.id.A, setting); - aObj.attr("title", !title ? "" : title); - } - }, - setNodeTarget: function (setting, node) { - var aObj = $$(node, consts.id.A, setting); - aObj.attr("target", view.makeNodeTarget(node)); - }, - setNodeUrl: function (setting, node) { - var aObj = $$(node, consts.id.A, setting), - url = view.makeNodeUrl(setting, node); - if (url == null || url.length == 0) { - aObj.removeAttr("href"); - } else { - aObj.attr("href", url); - } - }, - switchNode: function (setting, node) { - if (node.open || !tools.canAsync(setting, node)) { - view.expandCollapseNode(setting, node, !node.open); - } else if (setting.async.enable) { - if (!view.asyncNode(setting, node)) { - view.expandCollapseNode(setting, node, !node.open); - return; - } - } else if (node) { - view.expandCollapseNode(setting, node, !node.open); - } - } - }; - // zTree defind - $.fn.zTree = { - consts: _consts, - _z: { - tools: tools, - view: view, - event: event, - data: data - }, - getZTreeObj: function (treeId) { - var o = data.getZTreeTools(treeId); - return o ? o : null; - }, - destroy: function (treeId) { - if (!!treeId && treeId.length > 0) { - view.destroy(data.getSetting(treeId)); - } else { - for (var s in settings) { - view.destroy(settings[s]); - } - } - }, - init: function (obj, zSetting, zNodes) { - var setting = tools.clone(_setting); - $.extend(true, setting, zSetting); - setting.treeId = obj.attr("id"); - setting.treeObj = obj; - setting.treeObj.empty(); - settings[setting.treeId] = setting; - //For some older browser,(e.g., ie6) - if (typeof document.body.style.maxHeight === "undefined") { - setting.view.expandSpeed = ""; - } - data.initRoot(setting); - var root = data.getRoot(setting); - zNodes = zNodes ? tools.clone(tools.isArray(zNodes) ? zNodes : [zNodes]) : []; - if (setting.data.simpleData.enable) { - data.nodeChildren(setting, root, data.transformTozTreeFormat(setting, zNodes)); - } else { - data.nodeChildren(setting, root, zNodes); - } - - data.initCache(setting); - event.unbindTree(setting); - event.bindTree(setting); - event.unbindEvent(setting); - event.bindEvent(setting); - - var zTreeTools = { - setting: setting, - addNodes: function (parentNode, index, newNodes, isSilent) { - if (!parentNode) parentNode = null; - var isParent = data.nodeIsParent(setting, parentNode); - if (parentNode && !isParent && setting.data.keep.leaf) return null; - - var i = parseInt(index, 10); - if (isNaN(i)) { - isSilent = !!newNodes; - newNodes = index; - index = -1; - } else { - index = i; - } - if (!newNodes) return null; - - - var xNewNodes = tools.clone(tools.isArray(newNodes) ? newNodes : [newNodes]); - - function addCallback() { - view.addNodes(setting, parentNode, index, xNewNodes, (isSilent == true)); - } - - if (tools.canAsync(setting, parentNode)) { - view.asyncNode(setting, parentNode, isSilent, addCallback); - } else { - addCallback(); - } - return xNewNodes; - }, - cancelSelectedNode: function (node) { - view.cancelPreSelectedNode(setting, node); - }, - destroy: function () { - view.destroy(setting); - }, - expandAll: function (expandFlag) { - expandFlag = !!expandFlag; - view.expandCollapseSonNode(setting, null, expandFlag, true); - return expandFlag; - }, - expandNode: function (node, expandFlag, sonSign, focus, callbackFlag) { - if (!node || !data.nodeIsParent(setting, node)) return null; - if (expandFlag !== true && expandFlag !== false) { - expandFlag = !node.open; - } - callbackFlag = !!callbackFlag; - - if (callbackFlag && expandFlag && (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false)) { - return null; - } else if (callbackFlag && !expandFlag && (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false)) { - return null; - } - if (expandFlag && node.parentTId) { - view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false); - } - if (expandFlag === node.open && !sonSign) { - return null; - } - - data.getRoot(setting).expandTriggerFlag = callbackFlag; - if (!tools.canAsync(setting, node) && sonSign) { - view.expandCollapseSonNode(setting, node, expandFlag, true, showNodeFocus); - } else { - node.open = !expandFlag; - view.switchNode(this.setting, node); - showNodeFocus(); - } - return expandFlag; - - function showNodeFocus() { - var a = $$(node, consts.id.A, setting).get(0); - if (a && focus !== false) { - view.scrollIntoView(setting, a); - } - } - }, - getNodes: function () { - return data.getNodes(setting); - }, - getNodeByParam: function (key, value, parentNode) { - if (!key) return null; - return data.getNodeByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodeByTId: function (tId) { - return data.getNodeCache(setting, tId); - }, - getNodesByParam: function (key, value, parentNode) { - if (!key) return null; - return data.getNodesByParam(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodesByParamFuzzy: function (key, value, parentNode) { - if (!key) return null; - return data.getNodesByParamFuzzy(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), key, value); - }, - getNodesByFilter: function (filter, isSingle, parentNode, invokeParam) { - isSingle = !!isSingle; - if (!filter || (typeof filter != "function")) return (isSingle ? null : []); - return data.getNodesByFilter(setting, parentNode ? data.nodeChildren(setting, parentNode) : data.getNodes(setting), filter, isSingle, invokeParam); - }, - getNodeIndex: function (node) { - if (!node) return null; - var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); - var children = data.nodeChildren(setting, parentNode); - for (var i = 0, l = children.length; i < l; i++) { - if (children[i] == node) return i; - } - return -1; - }, - getSelectedNodes: function () { - var r = [], list = data.getRoot(setting).curSelectedList; - for (var i = 0, l = list.length; i < l; i++) { - r.push(list[i]); - } - return r; - }, - isSelectedNode: function (node) { - return data.isSelectedNode(setting, node); - }, - reAsyncChildNodesPromise: function (parentNode, reloadType, isSilent) { - var promise = new Promise(function (resolve, reject) { - try { - zTreeTools.reAsyncChildNodes(parentNode, reloadType, isSilent, function () { - resolve(parentNode); - }); - } catch (e) { - reject(e); - } - }); - return promise; - }, - reAsyncChildNodes: function (parentNode, reloadType, isSilent, callback) { - if (!this.setting.async.enable) return; - var isRoot = !parentNode; - if (isRoot) { - parentNode = data.getRoot(setting); - } - if (reloadType == "refresh") { - var children = data.nodeChildren(setting, parentNode); - for (var i = 0, l = children ? children.length : 0; i < l; i++) { - data.removeNodeCache(setting, children[i]); - } - data.removeSelectedNode(setting); - data.nodeChildren(setting, parentNode, []); - if (isRoot) { - this.setting.treeObj.empty(); - } else { - var ulObj = $$(parentNode, consts.id.UL, setting); - ulObj.empty(); - } - } - view.asyncNode(this.setting, isRoot ? null : parentNode, !!isSilent, callback); - }, - refresh: function () { - this.setting.treeObj.empty(); - var root = data.getRoot(setting), - nodes = data.nodeChildren(setting, root); - data.initRoot(setting); - data.nodeChildren(setting, root, nodes); - data.initCache(setting); - view.createNodes(setting, 0, data.nodeChildren(setting, root), null, -1); - }, - removeChildNodes: function (node) { - if (!node) return null; - var nodes = data.nodeChildren(setting, node); - view.removeChildNodes(setting, node); - return nodes ? nodes : null; - }, - removeNode: function (node, callbackFlag) { - if (!node) return; - callbackFlag = !!callbackFlag; - if (callbackFlag && tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return; - view.removeNode(setting, node); - if (callbackFlag) { - this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); - } - }, - selectNode: function (node, addFlag, isSilent) { - if (!node) return; - if (tools.uCanDo(setting)) { - addFlag = setting.view.selectedMulti && addFlag; - if (node.parentTId) { - view.expandCollapseParentNode(setting, node.getParentNode(), true, false, showNodeFocus); - } else if (!isSilent) { - try { - $$(node, setting).focus().blur(); - } catch (e) { - } - } - view.selectNode(setting, node, addFlag); - } - - function showNodeFocus() { - if (isSilent) { - return; - } - var a = $$(node, setting).get(0); - view.scrollIntoView(setting, a); - } - }, - transformTozTreeNodes: function (simpleNodes) { - return data.transformTozTreeFormat(setting, simpleNodes); - }, - transformToArray: function (nodes) { - return data.transformToArrayFormat(setting, nodes); - }, - updateNode: function (node, checkTypeFlag) { - if (!node) return; - var nObj = $$(node, setting); - if (nObj.get(0) && tools.uCanDo(setting)) { - view.setNodeName(setting, node); - view.setNodeTarget(setting, node); - view.setNodeUrl(setting, node); - view.setNodeLineIcos(setting, node); - view.setNodeFontCss(setting, node); - view.setNodeClasses(setting, node); - } - } - }; - root.treeTools = zTreeTools; - data.setZTreeTools(setting, zTreeTools); - var children = data.nodeChildren(setting, root); - if (children && children.length > 0) { - view.createNodes(setting, 0, children, null, -1); - } else if (setting.async.enable && setting.async.url && setting.async.url !== '') { - view.asyncNode(setting); - } - return zTreeTools; - } - }; - - var zt = $.fn.zTree, - $$ = tools.$, - consts = zt.consts; -})(BI.jQuery); diff --git a/src/case/ztree/jquery.ztree.excheck-3.5.js b/src/case/ztree/jquery.ztree.excheck-3.5.js deleted file mode 100644 index e28915a6f..000000000 --- a/src/case/ztree/jquery.ztree.excheck-3.5.js +++ /dev/null @@ -1,646 +0,0 @@ -/* - * JQuery zTree excheck v3.5.18 - * http://zTree.me/ - * - * Copyright (c) 2010 Hunter.z - * - * Licensed same as jquery - MIT License - * http://www.opensource.org/licenses/mit-license.php - * - * email: hunter.z@263.net - * Date: 2015-06-18 - */ -(function($){ - //default consts of excheck - var _consts = { - event: { - CHECK: "ztree_check" - }, - id: { - CHECK: "_check" - }, - checkbox: { - STYLE: "checkbox", - DEFAULT: "chk", - DISABLED: "disable", - FALSE: "false", - TRUE: "true", - FULL: "full", - PART: "part", - FOCUS: "focus" - }, - radio: { - STYLE: "radio", - TYPE_ALL: "all", - TYPE_LEVEL: "level" - } - }, - //default setting of excheck - _setting = { - check: { - enable: false, - autoCheckTrigger: false, - chkStyle: _consts.checkbox.STYLE, - nocheckInherit: false, - chkDisabledInherit: false, - radioType: _consts.radio.TYPE_LEVEL, - chkboxType: { - "Y": "ps", - "N": "ps" - } - }, - data: { - key: { - checked: "checked" - } - }, - callback: { - beforeCheck:null, - onCheck:null - } - }, - //default root of excheck - _initRoot = function (setting) { - var r = data.getRoot(setting); - r.radioCheckedList = []; - }, - //default cache of excheck - _initCache = function(treeId) {}, - //default bind event of excheck - _bindEvent = function(setting) { - var o = setting.treeObj, - c = consts.event; - o.bind(c.CHECK, function (event, srcEvent, treeId, node) { - event.srcEvent = srcEvent; - tools.apply(setting.callback.onCheck, [event, treeId, node]); - }); - }, - _unbindEvent = function(setting) { - var o = setting.treeObj, - c = consts.event; - o.unbind(c.CHECK); - }, - //default event proxy of excheck - _eventProxy = function(e) { - var target = e.target, - setting = data.getSetting(e.data.treeId), - tId = "", node = null, - nodeEventType = "", treeEventType = "", - nodeEventCallback = null, treeEventCallback = null; - - if (tools.eqs(e.type, "mouseover")) { - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { - tId = tools.getNodeMainDom(target).id; - nodeEventType = "mouseoverCheck"; - } - } else if (tools.eqs(e.type, "mouseout")) { - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { - tId = tools.getNodeMainDom(target).id; - nodeEventType = "mouseoutCheck"; - } - } else if (tools.eqs(e.type, "click")) { - if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { - tId = tools.getNodeMainDom(target).id; - nodeEventType = "checkNode"; - } - } - if (tId.length>0) { - node = data.getNodeCache(setting, tId); - switch (nodeEventType) { - case "checkNode" : - nodeEventCallback = _handler.onCheckNode; - break; - case "mouseoverCheck" : - nodeEventCallback = _handler.onMouseoverCheck; - break; - case "mouseoutCheck" : - nodeEventCallback = _handler.onMouseoutCheck; - break; - } - } - var proxyResult = { - stop: nodeEventType === "checkNode", - node: node, - nodeEventType: nodeEventType, - nodeEventCallback: nodeEventCallback, - treeEventType: treeEventType, - treeEventCallback: treeEventCallback - }; - return proxyResult - }, - //default init node of excheck - _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { - if (!n) return; - var checkedKey = setting.data.key.checked; - if (typeof n[checkedKey] == "string") n[checkedKey] = tools.eqs(n[checkedKey], "true"); - n[checkedKey] = !!n[checkedKey]; - n.checkedOld = n[checkedKey]; - if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true"); - n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck); - if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true"); - n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled); - if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true"); - n.halfCheck = !!n.halfCheck; - n.check_Child_State = -1; - n.check_Focus = false; - n.getCheckStatus = function() {return data.getCheckStatus(setting, n);}; - - if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && n[checkedKey] ) { - var r = data.getRoot(setting); - r.radioCheckedList.push(n); - } - }, - //add dom for check - _beforeA = function(setting, node, html) { - var checkedKey = setting.data.key.checked; - if (setting.check.enable) { - data.makeChkFlag(setting, node); - html.push(""); - } - }, - //update zTreeObj, add method of check - _zTreeTools = function(setting, zTreeTools) { - zTreeTools.checkNode = function(node, checked, checkTypeFlag, callbackFlag) { - var checkedKey = this.setting.data.key.checked; - if (node.chkDisabled === true) return; - if (checked !== true && checked !== false) { - checked = !node[checkedKey]; - } - callbackFlag = !!callbackFlag; - - if (node[checkedKey] === checked && !checkTypeFlag) { - return; - } else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) { - return; - } - if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) { - node[checkedKey] = checked; - var checkObj = $$(node, consts.id.CHECK, this.setting); - if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); - view.setChkClass(this.setting, checkObj, node); - view.repairParentChkClassWithSelf(this.setting, node); - if (callbackFlag) { - this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]); - } - } - } - - zTreeTools.checkAllNodes = function(checked) { - view.repairAllChk(this.setting, !!checked); - } - - zTreeTools.getCheckedNodes = function(checked) { - var childKey = this.setting.data.key.children; - checked = (checked !== false); - return data.getTreeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey], checked); - } - - zTreeTools.getChangeCheckedNodes = function() { - var childKey = this.setting.data.key.children; - return data.getTreeChangeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey]); - } - - zTreeTools.setChkDisabled = function(node, disabled, inheritParent, inheritChildren) { - disabled = !!disabled; - inheritParent = !!inheritParent; - inheritChildren = !!inheritChildren; - view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren); - view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent); - } - - var _updateNode = zTreeTools.updateNode; - zTreeTools.updateNode = function(node, checkTypeFlag) { - if (_updateNode) _updateNode.apply(zTreeTools, arguments); - if (!node || !this.setting.check.enable) return; - var nObj = $$(node, this.setting); - if (nObj.get(0) && tools.uCanDo(this.setting)) { - var checkObj = $$(node, consts.id.CHECK, this.setting); - if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); - view.setChkClass(this.setting, checkObj, node); - view.repairParentChkClassWithSelf(this.setting, node); - } - } - }, - //method of operate data - _data = { - getRadioCheckedList: function(setting) { - var checkedList = data.getRoot(setting).radioCheckedList; - for (var i=0, j=checkedList.length; i -1 && node.check_Child_State < 2) : (node.check_Child_State > 0))) - }; - return r; - }, - getTreeCheckedNodes: function(setting, nodes, checked, results) { - if (!nodes) return []; - var childKey = setting.data.key.children, - checkedKey = setting.data.key.checked, - onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL); - results = !results ? [] : results; - for (var i = 0, l = nodes.length; i < l; i++) { - if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] == checked) { - results.push(nodes[i]); - if(onlyOne) { - break; - } - } - data.getTreeCheckedNodes(setting, nodes[i][childKey], checked, results); - if(onlyOne && results.length > 0) { - break; - } - } - return results; - }, - getTreeChangeCheckedNodes: function(setting, nodes, results) { - if (!nodes) return []; - var childKey = setting.data.key.children, - checkedKey = setting.data.key.checked; - results = !results ? [] : results; - for (var i = 0, l = nodes.length; i < l; i++) { - if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] != nodes[i].checkedOld) { - results.push(nodes[i]); - } - data.getTreeChangeCheckedNodes(setting, nodes[i][childKey], results); - } - return results; - }, - makeChkFlag: function(setting, node) { - if (!node) return; - var childKey = setting.data.key.children, - checkedKey = setting.data.key.checked, - chkFlag = -1; - if (node[childKey]) { - for (var i = 0, l = node[childKey].length; i < l; i++) { - var cNode = node[childKey][i]; - var tmp = -1; - if (setting.check.chkStyle == consts.radio.STYLE) { - if (cNode.nocheck === true || cNode.chkDisabled === true) { - tmp = cNode.check_Child_State; - } else if (cNode.halfCheck === true) { - tmp = 2; - } else if (cNode[checkedKey]) { - tmp = 2; - } else { - tmp = cNode.check_Child_State > 0 ? 2:0; - } - if (tmp == 2) { - chkFlag = 2; break; - } else if (tmp == 0){ - chkFlag = 0; - } - } else if (setting.check.chkStyle == consts.checkbox.STYLE) { - if (cNode.nocheck === true || cNode.chkDisabled === true) { - tmp = cNode.check_Child_State; - } else if (cNode.halfCheck === true) { - tmp = 1; - } else if (cNode[checkedKey] ) { - tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1; - } else { - tmp = (cNode.check_Child_State > 0) ? 1 : 0; - } - if (tmp === 1) { - chkFlag = 1; break; - } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) { - chkFlag = 1; break; - } else if (chkFlag === 2 && tmp > -1 && tmp < 2) { - chkFlag = 1; break; - } else if (tmp > -1) { - chkFlag = tmp; - } - } - } - } - node.check_Child_State = chkFlag; - } - }, - //method of event proxy - _event = { - - }, - //method of event handler - _handler = { - onCheckNode: function (event, node) { - if (node.chkDisabled === true) return false; - var setting = data.getSetting(event.data.treeId), - checkedKey = setting.data.key.checked; - if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true; - node[checkedKey] = !node[checkedKey]; - view.checkNodeRelation(setting, node); - var checkObj = $$(node, consts.id.CHECK, setting); - view.setChkClass(setting, checkObj, node); - view.repairParentChkClassWithSelf(setting, node); - setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]); - return true; - }, - onMouseoverCheck: function(event, node) { - if (node.chkDisabled === true) return false; - var setting = data.getSetting(event.data.treeId), - checkObj = $$(node, consts.id.CHECK, setting); - node.check_Focus = true; - view.setChkClass(setting, checkObj, node); - return true; - }, - onMouseoutCheck: function(event, node) { - if (node.chkDisabled === true) return false; - var setting = data.getSetting(event.data.treeId), - checkObj = $$(node, consts.id.CHECK, setting); - node.check_Focus = false; - view.setChkClass(setting, checkObj, node); - return true; - } - }, - //method of tools for zTree - _tools = { - - }, - //method of operate ztree dom - _view = { - checkNodeRelation: function(setting, node) { - var pNode, i, l, - childKey = setting.data.key.children, - checkedKey = setting.data.key.checked, - r = consts.radio; - if (setting.check.chkStyle == r.STYLE) { - var checkedList = data.getRadioCheckedList(setting); - if (node[checkedKey]) { - if (setting.check.radioType == r.TYPE_ALL) { - for (i = checkedList.length-1; i >= 0; i--) { - pNode = checkedList[i]; - if (pNode[checkedKey] && pNode != node) { - pNode[checkedKey] = false; - checkedList.splice(i, 1); - - view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); - if (pNode.parentTId != node.parentTId) { - view.repairParentChkClassWithSelf(setting, pNode); - } - } - } - checkedList.push(node); - } else { - var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); - for (i = 0, l = parentNode[childKey].length; i < l; i++) { - pNode = parentNode[childKey][i]; - if (pNode[checkedKey] && pNode != node) { - pNode[checkedKey] = false; - view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); - } - } - } - } else if (setting.check.radioType == r.TYPE_ALL) { - for (i = 0, l = checkedList.length; i < l; i++) { - if (node == checkedList[i]) { - checkedList.splice(i, 1); - break; - } - } - } - - } else { - if (node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.Y.indexOf("s") > -1)) { - view.setSonNodeCheckBox(setting, node, true); - } - if (!node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.N.indexOf("s") > -1)) { - view.setSonNodeCheckBox(setting, node, false); - } - if (node[checkedKey] && setting.check.chkboxType.Y.indexOf("p") > -1) { - view.setParentNodeCheckBox(setting, node, true); - } - if (!node[checkedKey] && setting.check.chkboxType.N.indexOf("p") > -1) { - view.setParentNodeCheckBox(setting, node, false); - } - } - }, - makeChkClass: function(setting, node) { - var checkedKey = setting.data.key.checked, - c = consts.checkbox, r = consts.radio, - checkboxType = setting.check.chkboxType; - var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); - fullStyle = ""; - if (node.chkDisabled === true) { - fullStyle = c.DISABLED; - } else if (node.halfCheck) { - fullStyle = c.PART; - } else if (setting.check.chkStyle == r.STYLE) { - fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; - } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); - } - var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; - chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; - var chClass = consts.className.BUTTON + " " + c.DEFAULT + " " + chkName; - switch (chkName) { - case 'checkbox_true_part': - case 'checkbox_true_part_focus': - chClass += ' bi-half-button bi-high-light-border'; - break; - case 'checkbox_true_full': - case 'checkbox_true_full_focus': - chClass += ' bi-checkbox checkbox-content bi-high-light-background active'; - break; - case 'checkbox_false_full': - case 'checkbox_false_full_focus': - default: - chClass += ' bi-checkbox checkbox-content'; - break; - } - return chClass + (node.disabled ? " disabled" : ""); - }, - repairAllChk: function(setting, checked) { - if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) { - var checkedKey = setting.data.key.checked, - childKey = setting.data.key.children, - root = data.getRoot(setting); - for (var i = 0, l = root[childKey].length; i 0) { - view.repairParentChkClass(setting, node[childKey][0]); - } else { - view.repairParentChkClass(setting, node); - } - }, - repairSonChkDisabled: function(setting, node, chkDisabled, inherit) { - if (!node) return; - var childKey = setting.data.key.children; - if (node.chkDisabled != chkDisabled) { - node.chkDisabled = chkDisabled; - } - view.repairChkClass(setting, node); - if (node[childKey] && inherit) { - for (var i = 0, l = node[childKey].length; i < l; i++) { - var sNode = node[childKey][i]; - view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit); - } - } - }, - repairParentChkDisabled: function(setting, node, chkDisabled, inherit) { - if (!node) return; - if (node.chkDisabled != chkDisabled && inherit) { - node.chkDisabled = chkDisabled; - } - view.repairChkClass(setting, node); - view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit); - }, - setChkClass: function(setting, obj, node) { - if (!obj) return; - if (node.nocheck === true) { - obj.hide(); - } else { - obj.show(); - } - obj.attr('class', view.makeChkClass(setting, node)); - }, - setParentNodeCheckBox: function(setting, node, value, srcNode) { - var childKey = setting.data.key.children, - checkedKey = setting.data.key.checked, - checkObj = $$(node, consts.id.CHECK, setting); - if (!srcNode) srcNode = node; - data.makeChkFlag(setting, node); - if (node.nocheck !== true && node.chkDisabled !== true) { - node[checkedKey] = value; - view.setChkClass(setting, checkObj, node); - if (setting.check.autoCheckTrigger && node != srcNode) { - setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); - } - } - if (node.parentTId) { - var pSign = true; - if (!value) { - var pNodes = node.getParentNode()[childKey]; - for (var i = 0, l = pNodes.length; i < l; i++) { - if ((pNodes[i].nocheck !== true && pNodes[i].chkDisabled !== true && pNodes[i][checkedKey]) - || ((pNodes[i].nocheck === true || pNodes[i].chkDisabled === true) && pNodes[i].check_Child_State > 0)) { - pSign = false; - break; - } - } - } - if (pSign) { - view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode); - } - } - }, - setSonNodeCheckBox: function(setting, node, value, srcNode) { - if (!node) return; - var childKey = setting.data.key.children, - checkedKey = setting.data.key.checked, - checkObj = $$(node, consts.id.CHECK, setting); - if (!srcNode) srcNode = node; - - var hasDisable = false; - if (node[childKey]) { - for (var i = 0, l = node[childKey].length; i < l && node.chkDisabled !== true; i++) { - var sNode = node[childKey][i]; - view.setSonNodeCheckBox(setting, sNode, value, srcNode); - if (sNode.chkDisabled === true) hasDisable = true; - } - } - - if (node != data.getRoot(setting) && node.chkDisabled !== true) { - if (hasDisable && node.nocheck !== true) { - data.makeChkFlag(setting, node); - } - if (node.nocheck !== true && node.chkDisabled !== true) { - node[checkedKey] = value; - if (!hasDisable) node.check_Child_State = (node[childKey] && node[childKey].length > 0) ? (value ? 2 : 0) : -1; - } else { - node.check_Child_State = -1; - } - view.setChkClass(setting, checkObj, node); - if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) { - setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); - } - } - - } - }, - - _z = { - tools: _tools, - view: _view, - event: _event, - data: _data - }; - $.extend(true, $.fn.zTree.consts, _consts); - $.extend(true, $.fn.zTree._z, _z); - - var zt = $.fn.zTree, - tools = zt._z.tools, - consts = zt.consts, - view = zt._z.view, - data = zt._z.data, - event = zt._z.event, - $$ = tools.$; - - data.exSetting(_setting); - data.addInitBind(_bindEvent); - data.addInitUnBind(_unbindEvent); - data.addInitCache(_initCache); - data.addInitNode(_initNode); - data.addInitProxy(_eventProxy, true); - data.addInitRoot(_initRoot); - data.addBeforeA(_beforeA); - data.addZTreeTools(_zTreeTools); - - var _createNodes = view.createNodes; - view.createNodes = function(setting, level, nodes, parentNode) { - if (_createNodes) _createNodes.apply(view, arguments); - if (!nodes) return; - view.repairParentChkClassWithSelf(setting, parentNode); - } - var _removeNode = view.removeNode; - view.removeNode = function(setting, node) { - var parentNode = node.getParentNode(); - if (_removeNode) _removeNode.apply(view, arguments); - if (!node || !parentNode) return; - view.repairChkClass(setting, parentNode); - view.repairParentChkClass(setting, parentNode); - } - - var _appendNodes = view.appendNodes; - view.appendNodes = function(setting, level, nodes, parentNode, initFlag, openFlag) { - var html = ""; - if (_appendNodes) { - html = _appendNodes.apply(view, arguments); - } - if (parentNode) { - data.makeChkFlag(setting, parentNode); - } - return html; - } -})(BI.jQuery); \ No newline at end of file diff --git a/src/case/ztree/list/0.listtreeview.js b/src/case/ztree/list/0.listtreeview.js deleted file mode 100644 index dd9a1f8c8..000000000 --- a/src/case/ztree/list/0.listtreeview.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * author: windy - * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 - * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a - * @class BI.ListTreeView - * @extends BI.TreeView - */ -BI.ListTreeView = BI.inherit(BI.TreeView, { - - _constants: { - SPLIT: "<|>" - }, - - _defaultConfig: function () { - return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), { - value: {} - }); - }, - _init: function () { - BI.ListTreeView.superclass._init.apply(this, arguments); - var o = this.options; - if(BI.isNotNull(o.value)) { - this.setSelectedValue(o.value); - } - }, - - // 配置属性 - _configSetting: function () { - var paras = this.options.paras; - var self = this; - var setting = { - async: { - enable: false - }, - check: { - enable: true, - chkboxType: {Y: "", N: ""} - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true, - dblClickExpand: false - }, - callback: { - onCheck: onCheck, - onClick: onClick - } - }; - - function onClick (event, treeId, treeNode) { - var zTree = BI.$.fn.zTree.getZTreeObj(treeId); - var checked = treeNode.checked; - self._checkValue(treeNode, !checked); - zTree.checkNode(treeNode, !checked, true, true); - } - - function onCheck (event, treeId, treeNode) { - self._selectTreeNode(treeId, treeNode); - } - - return setting; - }, - - _selectTreeNode: function (treeId, treeNode) { - this._checkValue(treeNode, treeNode.checked); - BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); - }, - - _transArrayToMap: function (treeArrays) { - var self = this; - var map = {}; - BI.each(treeArrays, function (idx, array) { - var key = array.join(self._constants.SPLIT); - map[key] = true; - }); - return map; - }, - - _transMapToArray: function (treeMap) { - var self = this; - var array = []; - BI.each(treeMap, function (key) { - var item = key.split(self._constants.SPLIT); - array.push(item); - }); - return array; - }, - - _checkValue: function (treeNode, checked) { - var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); - if(checked) { - this.storeValue[key] = true; - } else { - delete this.storeValue[key]; - } - }, - - setSelectedValue: function (value) { - this.options.paras.selectedValues = value || []; - this.storeValue = this._transArrayToMap(value); - }, - - getValue: function () { - return this._transMapToArray(this.storeValue); - } -}); - -BI.shortcut("bi.list_tree_view", BI.ListTreeView); \ No newline at end of file diff --git a/src/case/ztree/list/1.listasynctree.js b/src/case/ztree/list/1.listasynctree.js deleted file mode 100644 index 7e1f25b10..000000000 --- a/src/case/ztree/list/1.listasynctree.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * author: windy - * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 - * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a - * @class BI.ListListAsyncTree - * @extends BI.TreeView - */ -BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { - _defaultConfig: function () { - return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); - }, - _init: function () { - BI.ListAsyncTree.superclass._init.apply(this, arguments); - }, - - // 配置属性 - _configSetting: function () { - var paras = this.options.paras; - var self = this; - var setting = { - async: { - enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 - otherParam: BI.cjkEncodeDO(paras) - }, - check: { - enable: true, - chkboxType: {Y: "", N: ""} - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - view: { - showIcon: false, - expandSpeed: "", - nameIsHTML: true, - dblClickExpand: false - }, - callback: { - onCheck: onCheck, - beforeExpand: beforeExpand, - beforeCheck: beforeCheck, - onClick: onClick - } - }; - - function beforeCheck (treeId, treeNode) { - treeNode.half = false; - } - - function onClick (event, treeId, treeNode) { - var zTree = BI.$.fn.zTree.getZTreeObj(treeId); - var checked = treeNode.checked; - self._checkValue(treeNode, !checked); - zTree.checkNode(treeNode, !checked, true, true); - } - - function beforeExpand (treeId, treeNode) { - self._beforeExpandNode(treeId, treeNode); - } - - function onCheck (event, treeId, treeNode) { - self._selectTreeNode(treeId, treeNode); - } - - return setting; - }, - - // 展开节点 - _beforeExpandNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parentValues = treeNode.parentValues || self._getParentValues(treeNode); - var op = BI.extend({}, o.paras, { - id: treeNode.id, - times: 1, - parentValues: parentValues.concat(this._getNodeValue(treeNode)) - }); - var complete = function (d) { - var nodes = d.items || []; - if (nodes.length > 0) { - callback(self._dealWidthNodes(nodes), !!d.hasNext); - } - }; - var times = 1; - - function callback (nodes, hasNext) { - self.nodes.addNodes(treeNode, nodes); - // 展开节点是没有分页的 - if (hasNext === true) { - BI.delay(function () { - times++; - op.times = times; - o.itemsCreator(op, complete); - }, 100); - } - } - - if (!treeNode.children) { - setTimeout(function () { - o.itemsCreator(op, complete); - }, 17); - } - }, - - hasChecked: function () { - return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); - }, - - // 生成树方法 - stroke: function (config) { - delete this.options.keyword; - BI.extend(this.options.paras, config); - var setting = this._configSetting(); - this._initTree(setting); - } -}); - -BI.shortcut("bi.list_async_tree", BI.ListAsyncTree); \ No newline at end of file diff --git a/src/case/ztree/list/listparttree.js b/src/case/ztree/list/listparttree.js deleted file mode 100644 index cc4462166..000000000 --- a/src/case/ztree/list/listparttree.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * guy - * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 - * @class BI.ListPartTree - * @extends BI.AsyncTree - */ -BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { - _defaultConfig: function () { - return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); - }, - - _init: function () { - BI.ListPartTree.superclass._init.apply(this, arguments); - }, - - _loadMore: function () { - var self = this, o = this.options; - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: ++this.times - }); - this.tip.setLoading(); - o.itemsCreator(op, function (d) { - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.lastSearchValue = d.lastSearchValue; - if (self._stop === true) { - return; - } - if (!hasNext) { - self.tip.setEnd(); - } else { - self.tip.setLoaded(); - } - if (nodes.length > 0) { - self.nodes.addNodes(null, self._dealWidthNodes(nodes)); - } - }); - }, - - _initTree: function (setting, keyword) { - var self = this, o = this.options; - this.times = 1; - var tree = this.tree; - tree.empty(); - self.tip.setVisible(false); - this.loading(); - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: this.times - }); - var complete = function (d) { - if (self._stop === true || keyword != o.paras.keyword) { - return; - } - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.lastSearchValue = d.lastSearchValue; - // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 - callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); - self.setTipVisible(nodes.length <= 0); - self.loaded(); - if (!hasNext) { - self.tip.invisible(); - } else { - self.tip.setLoaded(); - } - self.fireEvent(BI.Events.AFTERINIT); - }; - - function callback (nodes) { - if (self._stop === true) { - return; - } - self.nodes = BI.$.fn.zTree.init(tree.element, setting, nodes); - } - - BI.delay(function () { - o.itemsCreator(op, complete); - }, 100); - }, - - // 生成树方法 - stroke: function (config) { - var o = this.options; - delete o.paras.keyword; - BI.extend(o.paras, config); - delete o.paras.lastSearchValue; - var setting = this._configSetting(); - this._initTree(setting, o.paras.keyword); - } -}); - -BI.shortcut("bi.list_part_tree", BI.ListPartTree); \ No newline at end of file diff --git a/src/case/ztree/parttree.js b/src/case/ztree/parttree.js deleted file mode 100644 index 8a347548a..000000000 --- a/src/case/ztree/parttree.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * guy - * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 - * @class BI.PartTree - * @extends BI.AsyncTree - */ -BI.PartTree = BI.inherit(BI.AsyncTree, { - _defaultConfig: function () { - return BI.extend(BI.PartTree.superclass._defaultConfig.apply(this, arguments), {}); - }, - - _loadMore: function () { - var self = this, o = this.options; - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: ++this.times - }); - this.tip.setLoading(); - o.itemsCreator(op, function (d) { - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.lastSearchValue = d.lastSearchValue; - if (self._stop === true) { - return; - } - if (!hasNext) { - self.tip.setEnd(); - } else { - self.tip.setLoaded(); - } - if (nodes.length > 0) { - self.nodes.addNodes(null, self._dealWidthNodes(nodes)); - } - }); - }, - - _selectTreeNode: function (treeId, treeNode) { - var self = this, o = this.options; - var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); - var name = this._getNodeValue(treeNode); - this.fireEvent(BI.PartTree.EVENT_CLICK_TREE_NODE); - if (treeNode.checked === true) { - this.options.paras.selectedValues = this._getUnionValue(); - // this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); - o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - curSelectedValue: name, - parentValues: parentValues - }), function (res) { - self.options.paras.selectedValues = res; - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); - }); - } else { - // 如果选中的值中不存在该值不处理 - // 因为反正是不选中,没必要管 - var t = this.options.paras.selectedValues; - var p = parentValues.concat(name); - for (var i = 0, len = p.length; i < len; i++) { - t = t[p[i]]; - if (t == null) { - return; - } - // 选中中国-江苏, 搜索南京,取消勾选 - if (BI.isEmpty(t)) { - break; - } - } - o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_SELECT_DATA, - notSelectedValue: name, - parentValues: parentValues - }), function (new_values) { - self.options.paras.selectedValues = new_values; - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); - }); - } - }, - - _getSelectedValues: function () { - var self = this; - var hashMap = {}; - var rootNoots = this.nodes.getNodes(); - track(rootNoots); - - function track(nodes) { - BI.each(nodes, function (i, node) { - var checkState = node.getCheckStatus(); - if (checkState.checked === false) { - return true; - } - var parentValues = node.parentValues || self._getParentValues(node); - // 把文字中的html去掉,其实就是把文字颜色去掉 - var values = parentValues.concat([self._getNodeValue(node)]); - self._buildTree(hashMap, values); - // if(checkState.checked === true && checkState.half === false && nodes[i].flag === true){ - // continue; - // } - if (BI.isNotEmptyArray(node.children)) { - track(node.children); - return true; - } - if (checkState.half === true) { - self._getHalfSelectedValues(hashMap, node); - } - }); - } - - return hashMap; - }, - - _initTree: function (setting, keyword) { - var self = this, o = this.options; - this.times = 1; - var tree = this.tree; - tree.empty(); - self.tip.setVisible(false); - this.loading(); - var op = BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_INIT_DATA, - times: this.times - }); - var complete = function (d) { - if (self._stop === true || keyword != o.paras.keyword) { - return; - } - var hasNext = !!d.hasNext, nodes = d.items || []; - o.paras.lastSearchValue = d.lastSearchValue; - // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 - callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); - self.setTipVisible(nodes.length <= 0); - self.loaded(); - if (!hasNext) { - self.tip.invisible(); - } else { - self.tip.setLoaded(); - } - self.fireEvent(BI.Events.AFTERINIT); - }; - - function callback(nodes) { - if (self._stop === true) { - return; - } - self.nodes = BI.$.fn.zTree.init(tree.element, setting, nodes); - } - - BI.delay(function () { - o.itemsCreator(op, complete); - }, 100); - }, - - getValue: function () { - return BI.deepClone(this.options.paras.selectedValues || {}); - }, - - _getUnionValue: function () { - if (!this.nodes) { - return {}; - } - var checkedValues = this._getSelectedValues(); - if (BI.isEmpty(checkedValues)) { - return BI.deepClone(this.options.paras.selectedValues); - } - if (BI.isEmpty(this.options.paras.selectedValues)) { - return checkedValues; - } - return this._union(checkedValues, this.options.paras.selectedValues); - }, - - _union: function (valueA, valueB) { - var self = this; - var map = {}; - track([], valueA, valueB); - track([], valueB, valueA); - - function track(parent, node, compare) { - BI.each(node, function (n, item) { - if (BI.isNull(compare[n])) { - self._addTreeNode(map, parent, n, item); - } else if (BI.isEmpty(compare[n])) { - self._addTreeNode(map, parent, n, {}); - } else { - track(parent.concat([n]), node[n], compare[n]); - } - }); - } - - return map; - }, - - // 生成树方法 - stroke: function (config) { - var o = this.options; - delete o.paras.keyword; - BI.extend(o.paras, config); - delete o.paras.lastSearchValue; - var setting = this._configSetting(); - this._initTree(setting, o.paras.keyword); - } -}); - -BI.PartTree.EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; -BI.shortcut("bi.part_tree", BI.PartTree); diff --git a/src/case/ztree/tree.display.js b/src/case/ztree/tree.display.js deleted file mode 100644 index 4c0135675..000000000 --- a/src/case/ztree/tree.display.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * guy - * 异步树 - * @class BI.DisplayTree - * @extends BI.TreeView - */ -BI.DisplayTree = BI.inherit(BI.TreeView, { - _defaultConfig: function () { - return BI.extend(BI.DisplayTree.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-display-tree" - }); - }, - - // 配置属性 - _configSetting: function () { - var setting = { - view: { - selectedMulti: false, - dblClickExpand: false, - showIcon: false, - nameIsHTML: true, - showTitle: false - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - callback: { - beforeCollapse: beforeCollapse - } - }; - - function beforeCollapse(treeId, treeNode) { - return false; - } - - return setting; - }, - - _dealWidthNodes: function (nodes) { - nodes = BI.DisplayTree.superclass._dealWidthNodes.apply(this, arguments); - var self = this, o = this.options; - BI.each(nodes, function (i, node) { - node.isParent = node.isParent || node.parent; - if (node.text == null) { - if (node.count > 0) { - node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; - } - } - }); - return nodes; - }, - - initTree: function (nodes, setting) { - var setting = setting || this._configSetting(); - this.nodes = BI.$.fn.zTree.init(this.tree.element, setting, nodes); - } -}); -BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.display_tree", BI.DisplayTree); diff --git a/src/case/ztree/tree.list.display.js b/src/case/ztree/tree.list.display.js deleted file mode 100644 index 60ce5574d..000000000 --- a/src/case/ztree/tree.list.display.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * guy - * 异步树 - * @class BI.ListListDisplayTree - * @extends BI.TreeView - */ -BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { - _defaultConfig: function () { - return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-list-display-tree" - }); - }, - _init: function () { - BI.ListDisplayTree.superclass._init.apply(this, arguments); - }, - - // 配置属性 - _configSetting: function () { - var setting = { - view: { - selectedMulti: false, - dblClickExpand: false, - showIcon: false, - nameIsHTML: true, - showTitle: false, - fontCss: getFont - }, - data: { - key: { - title: "title", - name: "text" - }, - simpleData: { - enable: true - } - }, - callback: { - beforeCollapse: beforeCollapse - } - }; - - function beforeCollapse(treeId, treeNode) { - return false; - } - - function getFont(treeId, node) { - return node.isLeaf ? {} : {color: "#999999"}; - } - - return setting; - }, - - _dealWidthNodes: function (nodes) { - nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); - var self = this, o = this.options; - BI.each(nodes, function (i, node) { - node.isParent = node.isParent || node.parent; - if (node.text == null) { - if (node.count > 0) { - node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; - } - } - }); - return nodes; - }, - - initTree: function (nodes, setting) { - var setting = setting || this._configSetting(); - this.nodes = BI.$.fn.zTree.init(this.tree.element, setting, nodes); - }, - - destroy: function () { - BI.ListDisplayTree.superclass.destroy.apply(this, arguments); - } -}); -BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.list_display_tree", BI.ListDisplayTree); \ No newline at end of file diff --git a/src/case/ztree/tree.simple.js b/src/case/ztree/tree.simple.js deleted file mode 100644 index 690a445a7..000000000 --- a/src/case/ztree/tree.simple.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * 简单的多选树 - * - * Created by GUY on 2016/2/16. - * @class BI.SimpleTreeView - * @extends BI.Widget - */ -BI.SimpleTreeView = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.SimpleTreeView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-simple-tree", - itemsCreator: BI.emptyFn, - items: null - }); - }, - _init: function () { - BI.SimpleTreeView.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.structure = new BI.Tree(); - this.tree = BI.createWidget({ - type: "bi.tree_view", - element: this, - itemsCreator: function (op, callback) { - var fn = function (items) { - callback({ - items: items - }); - self.structure.initTree(BI.Tree.transformToTreeFormat(items)); - }; - if (BI.isNotNull(o.items)) { - fn(o.items); - } else { - o.itemsCreator(op, fn); - } - } - }); - this.tree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.SimpleTreeView.EVENT_CHANGE, arguments); - }); - if (BI.isNotEmptyArray(o.items)) { - this.populate(); - } - if (BI.isNotNull(o.value)) { - this.setValue(o.value); - } - }, - - populate: function (items, keyword) { - if (items) { - this.options.items = items; - } - this.tree.stroke({ - keyword: keyword - }); - }, - - _digest: function (v) { - v || (v = []); - var self = this, map = {}; - var selected = []; - BI.each(v, function (i, val) { - var node = self.structure.search(val, "value"); - if (node) { - var p = node; - p = p.getParent(); - if (p) { - if (!map[p.value]) { - map[p.value] = 0; - } - map[p.value]++; - } - - while (p && p.getChildrenLength() <= map[p.value]) { - selected.push(p.value); - p = p.getParent(); - if (p) { - if (!map[p.value]) { - map[p.value] = 0; - } - map[p.value]++; - } - } - } - }); - return BI.makeObject(v.concat(selected)); - }, - - setValue: function (v) { - this.tree.setValue(this._digest(v)); - }, - - _getValue: function () { - var self = this, result = [], val = this.tree.getValue(); - var track = function (nodes) { - BI.each(nodes, function (key, node) { - if (BI.isEmpty(node)) { - result.push(key); - } else { - track(node); - } - }); - }; - track(val); - return result; - }, - - empty: function () { - this.tree.empty(); - }, - - getValue: function () { - var self = this, result = [], val = this._getValue(); - BI.each(val, function (i, key) { - var target = self.structure.search(key, "value"); - if (target) { - self.structure._traverse(target, function (node) { - if (node.isLeaf()) { - result.push(node.value); - } - }); - } - }); - return result; - } -}); -BI.SimpleTreeView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.simple_tree", BI.SimpleTreeView); diff --git a/src/case/ztree/treerender.scroll.service.js b/src/case/ztree/treerender.scroll.service.js deleted file mode 100644 index a2d019c46..000000000 --- a/src/case/ztree/treerender.scroll.service.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/1/8 - * 提供节点滚动加载方式 - */ - -!(function () { - BI.TreeRenderScrollService = BI.inherit(BI.OB, { - _init: function () { - this.nodeLists = {}; - - this.id = this.options.id; - // renderService是否已经注册了滚动 - this.hasBinded = false; - - this.container = this.options.container; - }, - - _getNodeListBounds: function (tId) { - var nodeList = this.options.subNodeListGetter(tId)[0]; - return { - top: nodeList.offsetTop, - left: nodeList.offsetLeft, - width: nodeList.offsetWidth, - height: nodeList.offsetHeight - } - }, - - _getTreeContainerBounds: function () { - var nodeList = this.container[0]; - if (BI.isNotNull(nodeList)) { - return { - top: nodeList.offsetTop + nodeList.scrollTop, - left: nodeList.offsetLeft + nodeList.scrollLeft, - width: nodeList.offsetWidth, - height: nodeList.offsetHeight - }; - } - return {}; - }, - - _canNodePopulate: function (tId) { - if (this.nodeLists[tId].locked) { - return false; - } - // 获取ul, 即子节点列表的bounds - // 是否需要继续加载,只需要看子节点列表的下边界与container是否无交集 - var bounds = this._getNodeListBounds(tId); - var containerBounds = this._getTreeContainerBounds(tId); - // ul底部是不是漏出来了 - if (bounds.top + bounds.height < containerBounds.top + containerBounds.height) { - return true; - } - return false; - }, - - _isNodeInVisible: function (tId) { - var nodeList = this.options.subNodeListGetter(tId); - return nodeList.length === 0 || nodeList.css("display") === "none"; - }, - - pushNodeList: function (tId, populate) { - var self = this; - if (!BI.has(this.nodeLists, tId)) { - this.nodeLists[tId] = { - populate: BI.debounce(populate, 0), - options: { - times: 1 - }, - // 在上一次请求返回前, 通过滚动再次触发加载的时候, 不应该认为是下一次分页, 需要等待上次请求返回 - // 以保证顺序和请求次数的完整 - locked: false - }; - } else { - this.nodeLists[tId].locked = false; - } - if(!this.hasBinded) { - // console.log("绑定事件"); - this.hasBinded = true; - this.container && this.container.on("scroll", BI.debounce(function () { - self.refreshAllNodes(); - }, 30)); - } - }, - - refreshAllNodes: function () { - var self = this; - BI.each(this.nodeLists, function (tId) { - // 不展开的节点就不看了 - !self._isNodeInVisible(tId) && self.refreshNodes(tId); - }); - }, - - refreshNodes: function (tId) { - if (this._canNodePopulate(tId)) { - var nodeList = this.nodeLists[tId]; - nodeList.options.times++; - nodeList.locked = true; - nodeList.populate({ - times: nodeList.options.times - }); - } - }, - - removeNodeList: function (tId) { - delete this.nodeLists[tId]; - if (BI.size(this.nodeLists) === 0) { - this.clear(); - } - }, - - clear: function () { - var self = this; - BI.each(this.nodeLists, function (tId) { - self.removeNodeList(tId); - }); - this.nodeLists = {}; - // console.log("解绑事件"); - this.container.off("scroll"); - this.hasBinded = false; - } - }); -})(); \ No newline at end of file diff --git a/src/case/ztree/treetrender.page.service.js b/src/case/ztree/treetrender.page.service.js deleted file mode 100644 index e1d7edb81..000000000 --- a/src/case/ztree/treetrender.page.service.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/1/8 - * 提供节点分页加载方式 - */ - -!(function () { - BI.TreeRenderPageService = BI.inherit(BI.OB, { - _init: function () { - this.nodeLists = {}; - }, - - _getLoadingBar: function(tId) { - var self = this; - var tip = BI.createWidget({ - type: "bi.loading_bar", - height: 25, - handler: function () { - self.refreshNodes(tId); - } - }); - tip.setLoaded(); - return tip; - }, - - pushNodeList: function (tId, populate) { - var self = this, o = this.options; - var tip = this._getLoadingBar(tId); - if (!BI.has(this.nodeLists, tId)) { - this.nodeLists[tId] = { - populate: BI.debounce(populate, 0), - options: { - times: 1 - }, - loadWidget: tip - }; - } else { - this.nodeLists[tId].loadWidget.destroy(); - this.nodeLists[tId].loadWidget = tip; - } - BI.createWidget({ - type: "bi.vertical", - element: o.subNodeListGetter(tId), - items: [tip] - }); - }, - - refreshNodes: function (tId) { - var nodeList = this.nodeLists[tId]; - nodeList.options.times++; - nodeList.loadWidget.setLoading(); - nodeList.populate({ - times: nodeList.options.times - }); - }, - - removeNodeList: function (tId) { - this.nodeLists[tId] && this.nodeLists[tId].loadWidget.destroy(); - this.nodeLists[tId] && (this.nodeLists[tId].loadWidget = null); - delete this.nodeLists[tId]; - if (BI.size(this.nodeLists) === 0) { - this.clear(); - } - }, - - clear: function () { - var self = this; - BI.each(this.nodeLists, function (tId) { - self.removeNodeList(tId); - }); - this.nodeLists = {}; - } - }); - -})(); \ No newline at end of file diff --git a/src/component/allvaluechooser/abstract.allvaluechooser.js b/src/component/allvaluechooser/abstract.allvaluechooser.js deleted file mode 100644 index c13d8a30f..000000000 --- a/src/component/allvaluechooser/abstract.allvaluechooser.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.AbstractAllValueChooser - * @extends BI.Widget - */ -BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { - - _const: { - perPage: 100 - }, - - _defaultConfig: function () { - return BI.extend(BI.AbstractAllValueChooser.superclass._defaultConfig.apply(this, arguments), { - width: 200, - height: 30, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _valueFormatter: function (v) { - var text = v; - if (this.options.valueFormatter) { - return this.options.valueFormatter(v); - } - if (BI.isNotNull(this.items)) { - BI.some(this.items, function (i, item) { - // 把value都换成字符串 - // 需要考虑到value也可能是数字 - if (item.value === v || item.value + "" === v) { - text = item.text; - return true; - } - }); - } - return text; - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * this._const.perPage < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!o.cache || !this.items) { - o.itemsCreator({}, function (items) { - self.items = items; - call(items); - }); - } else { - call(this.items); - } - - function call(items) { - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - var resultItems = items; - if (BI.isNotEmptyArray(keywords)) { - resultItems = []; - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - resultItems = resultItems.concat(search.match).concat(search.find); - }); - resultItems = BI.uniq(resultItems); - } - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - resultItems = BI.filter(resultItems, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: resultItems - }); - return; - } - if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({ count: resultItems.length }); - return; - } - callback({ - items: self._getItemsByTimes(resultItems, options.times), - hasNext: self._hasNextByTimes(resultItems, options.times) - }); - } - }, - - _assertValue: function (v) { - v = v || {}; - var value = v; - if (BI.isNotNull(this.items)) { - var isAllSelect = BI.difference(BI.map(this.items, "value"), v.value).length === 0; - if (isAllSelect) { - value = { - type: BI.Selection.All, - value: [], - }; - } - } - return value; - }, -}); diff --git a/src/component/allvaluechooser/combo.allvaluechooser.js b/src/component/allvaluechooser/combo.allvaluechooser.js deleted file mode 100644 index 17dc244b7..000000000 --- a/src/component/allvaluechooser/combo.allvaluechooser.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.AllValueChooserCombo - * @extends BI.AbstractAllValueChooser - */ -BI.AllValueChooserCombo = BI.inherit(BI.AbstractAllValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-all-value-chooser-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _init: function () { - BI.AllValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: "bi.multi_select_combo", - simple: o.simple, - text: o.text, - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - defaultText: o.defaultText, - value: this._assertValue({ - type: BI.Selection.Multi, - value: o.value || [] - }) - }); - - this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); - }); - }, - - setValue: function (v) { - this.combo.setValue(this._assertValue({ - type: BI.Selection.Multi, - value: v || [] - })); - }, - - getValue: function () { - return this.getAllValue(); - }, - - getAllValue: function () { - var val = this.combo.getValue() || {}; - if (val.type === BI.Selection.Multi) { - return val.value || []; - } - - return BI.difference(BI.map(this.items, "value"), val.value || []); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.combo.populate(); - } -}); -BI.AllValueChooserCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.all_value_chooser_combo", BI.AllValueChooserCombo); diff --git a/src/component/allvaluechooser/pane.allvaluechooser.js b/src/component/allvaluechooser/pane.allvaluechooser.js deleted file mode 100644 index 6188f14ee..000000000 --- a/src/component/allvaluechooser/pane.allvaluechooser.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 简单的复选面板, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.AllValueChooserPane - * @extends BI.AbstractAllValueChooser - */ -BI.AllValueChooserPane = BI.inherit(BI.AbstractAllValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.AllValueChooserPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-all-value-chooser-pane", - width: 200, - height: 30, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _init: function () { - BI.AllValueChooserPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.list = BI.createWidget({ - type: "bi.multi_select_list", - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height - }); - - this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.AllValueChooserPane.EVENT_CHANGE); - }); - - if (BI.isNotNull(o.items)) { - this.items = o.items; - this.list.populate(); - } - }, - - setValue: function (v) { - this.list.setValue({ - type: BI.Selection.Multi, - value: v || [] - }); - }, - - getValue: function () { - var val = this.list.getValue() || {}; - if (val.type === BI.Selection.Multi) { - return val.value || []; - } - - return BI.difference(BI.map(this.items, "value"), val.value || []); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.list.populate(); - } -}); -BI.AllValueChooserPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.all_value_chooser_pane", BI.AllValueChooserPane); diff --git a/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js b/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js deleted file mode 100644 index 2ac30295b..000000000 --- a/src/component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo.js +++ /dev/null @@ -1,66 +0,0 @@ -BI.AllValueMultiTextValueCombo = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-all-value-multi-text-value-combo", - width: 200, - height: 24, - items: [] - }, - - render: function () { - var self = this, o = this.options; - var value = this._digestValue(o.value); - return { - type: "bi.search_multi_text_value_combo", - simple: o.simple, - text: o.text, - height: o.height, - items: o.items, - value: value, - numOfPage: 100, - valueFormatter: o.valueFormatter, - warningTitle: o.warningTitle, - listeners: [{ - eventName: BI.SearchMultiTextValueCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.AllValueMultiTextValueCombo.EVENT_CONFIRM); - } - }], - ref: function () { - self.combo = this; - } - }; - }, - - setValue: function (v) { - var value = this._digestValue(v); - this.combo.setValue(value); - }, - - getValue: function () { - var obj = this.combo.getValue() || {}; - obj.value = obj.value || []; - if(obj.type === BI.Selection.All) { - var values = []; - BI.each(this.options.items, function (idx, item) { - !BI.contains(obj.value, item.value) && values.push(item.value); - }); - return values; - } - return obj.value || []; - }, - - populate: function (items) { - this.options.items = items; - this.combo.populate.apply(this.combo, arguments); - }, - - _digestValue: function (v) { - return { - type: BI.Selection.Multi, - value: v || [] - }; - } -}); -BI.AllValueMultiTextValueCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.all_value_multi_text_value_combo", BI.AllValueMultiTextValueCombo); diff --git a/src/component/form/form.field.js b/src/component/form/form.field.js deleted file mode 100644 index 0b67041b8..000000000 --- a/src/component/form/form.field.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2022/1/11 - */ - BI.FormField = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-form-field", - label: "", - el: {}, - headerCls: "", - labelAlign: "right", // 文字默认右对齐 - validate: function () { - return true; - } // 默认返回true - }, - - render: function () { - var self = this, o = this.options; - - var field = { - type: "bi.absolute", - items: [{ - el: BI.extend({}, o.el, { - ref: function (_ref) { - self.field = _ref; - o.el.ref && o.el.ref.call(this, _ref); - }, - height: o.el.height || 28, - listeners: BI.concat(o.el.listeners, [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_CONFIRM", - action: function () { - self.fireEvent("EVENT_CONFIRM"); - } - }]) - }), - left: 0, - bottom: 0, - right: 0, - top: 0 - }, { - el: { - type: "bi.label", - cls: "error-tip bi-error", - ref: function (_ref) { - self.error = _ref; - }, - invisible: true - }, - bottom: -20, - left: 0, - right: 0, - height: 20 - }] - }; - - return { - type: "bi.vertical_adapt", - columnSize: ["auto", "fill"], - verticalAlign: BI.VerticalAlign.Stretch, - items: BI.isKey(o.label) ? [{ - el: { - type: "bi.label", - textAlign: o.labelAlign, - text: o.label, - width: o.labelWidth, - cls: o.headerCls, - rgap: 20 // 表单文字与右侧输入间距均为20px - } - }, field] : [field] - }; - }, - - getValue: function () { - return this.field.getValue(); - }, - - validate: function () { - var isValid = this.validateWithNoTip(); - !isValid && this.error.setText(this.options.tip(this.field.getValue(), this.field)); - this.error.setVisible(!isValid); - this.field.element[isValid ? "removeClass" : "addClass"]("bi-error"); - - return isValid; - }, - - validateWithNoTip: function () { - return this.options.validate(this.field.getValue(), this.field); - } -}); - -BI.shortcut("bi.form_field", BI.FormField); diff --git a/src/component/form/form.js b/src/component/form/form.js deleted file mode 100644 index de8caeaea..000000000 --- a/src/component/form/form.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2022/1/11 - */ - BI.Form = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-form", - labelAlign: "right", - layout: { - type: "bi.vertical", - vgap: 20 - }, - items: [{ - validate: BI.emptyFn, - tip: BI.emptyFn, - label: "", - el: {} - }], - labelWidth: "", - headerCls: "", // 左侧文字样式 - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.button_group", - items: this._createItems(), - layouts: [o.layout], - ref: function (ref) { - self.group = ref; - } - }; - }, - - _createItems: function () { - var self = this; - var o = this.options; - - return BI.map(o.items, function (idx, item) { - return { - type: "bi.form_field", - height: item.el.height || 28, - labelAlign: o.labelAlign, - labelWidth: o.labelWidth, - headerCls: o.headerCls, - el: item.el, - label: item.label, - tip: item.tip, - validate: item.validate, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent(BI.Form.EVENT_CHANGE, this.validate()); - } - }] - }; - }); - }, - - isAllValid: function () { - return !BI.some(this.validateWithNoTip(), function (idx, v) { - return !v; - }); - }, - - validateWithNoTip: function () { - var validInfo = []; - BI.each(this.group.getAllButtons(), function (idx, button) { - validInfo.push(button.validateWithNoTip()); - }); - - return validInfo; - }, - - validate: function () { - var validInfo = []; - BI.each(this.group.getAllButtons(), function (idx, button) { - validInfo.push(button.validate()); - }); - - return validInfo; - }, - - getValue: function () { - return !this.isAllValid() ? null : BI.map(this.group.getAllButtons(), function (idx, button) { - return button.getValue(); - }); - } -}); - -BI.Form.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.custom_form", BI.Form); diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.js b/src/component/treevaluechooser/abstract.treevaluechooser.js deleted file mode 100644 index f1a7665d5..000000000 --- a/src/component/treevaluechooser/abstract.treevaluechooser.js +++ /dev/null @@ -1,917 +0,0 @@ -BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { - - _const: { - perPage: 100 - }, - - _defaultConfig: function () { - return BI.extend(BI.AbstractTreeValueChooser.superclass._defaultConfig.apply(this, arguments), { - items: null, - itemsCreator: BI.emptyFn, - open: false - }); - }, - - _valueFormatter: function (v) { - var text = v; - if (this.options.valueFormatter) { - return this.options.valueFormatter(v); - } - if (BI.isNotNull(this.items)) { - BI.some(this.items, function (i, item) { - if (item.value === v || item.value + "" === v) { - text = item.text; - return true; - } - }); - } - return text; - }, - - _initData: function (items) { - this.items = items; - var nodes = BI.Tree.treeFormat(items); - this.tree = new BI.Tree(); - this.tree.initTree(nodes); - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!this.items) { - o.itemsCreator({}, function (items) { - self._initData(items); - call(); - }); - } else { - call(); - } - - function call() { - switch (options.type) { - case BI.TreeView.REQ_TYPE_INIT_DATA: - self._reqInitTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_ADJUST_DATA: - self._reqAdjustTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_SELECT_DATA: - self._reqSelectedTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: - self._reqDisplayTreeNode(options, callback); - break; - default : - self._reqTreeNode(options, callback); - break; - } - } - }, - - _reqDisplayTreeNode: function (op, callback) { - var self = this; - var result = []; - var selectedValues = op.selectedValues; - - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - - doCheck([], this.tree.getRoot(), selectedValues); - - callback({ - items: result - }); - - function doCheck(parentValues, node, selected) { - if (selected == null || BI.isEmpty(selected)) { - BI.each(node.getChildren(), function (i, child) { - var newParents = BI.clone(parentValues); - newParents.push(child.value); - var llen = self._getChildCount(newParents); - createOneJson(child, node.id, llen); - doCheck(newParents, child, {}); - }); - return; - } - BI.each(selected, function (k) { - var node = self._getTreeNode(parentValues, k); - // 找不到就是新增值 - if(BI.isNull(node)) { - createOneJson({ - id: BI.UUID(), - text: k, - value: k - }, BI.UUID(), 0); - } else { - var newParents = BI.clone(parentValues); - newParents.push(node.value); - createOneJson(node, node.parent && node.parent.id, getCount(selected[k], newParents)); - doCheck(newParents, node, selected[k]); - } - }); - } - - function getCount(jo, parentValues) { - if (jo == null) { - return 0; - } - if (BI.isEmpty(jo)) { - return self._getChildCount(parentValues); - } - - return BI.size(jo); - } - - function createOneJson(node, pId, llen) { - result.push({ - id: node.id, - pId: pId, - text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), - value: node.value, - open: true, - disabled: node.disabled - }); - } - }, - - _reqSelectedTreeNode: function (op, callback) { - var self = this; - var selectedValues = BI.deepClone(op.selectedValues); - var notSelectedValue = op.notSelectedValue || {}; - var keyword = op.keyword || ""; - var parentValues = op.parentValues || []; - - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - - dealWithSelectedValues(selectedValues); - callback(selectedValues); - - - function dealWithSelectedValues(selectedValues) { - var p = parentValues.concat(notSelectedValue); - // 存储的值中存在这个值就把它删掉 - // 例如选中了中国-江苏-南京, 取消中国或江苏或南京 - // p长度不大于selectedValues的情况才可能找到,这样可以直接删除selectedValues的节点 - if (canFindKey(selectedValues, p)) { - // 如果搜索的值在父亲链中 - if (isSearchValueInParent(p)) { - // 例如选中了 中国-江苏, 搜索江苏, 取消江苏(干掉了江苏) - self._deleteNode(selectedValues, p); - } else { - var searched = []; - // 要找到所有以notSelectedValue为叶子节点的链路 - var find = search(parentValues, notSelectedValue, [], searched); - if (find && BI.isNotEmptyArray(searched)) { - BI.each(searched, function (i, arr) { - var node = self._getNode(selectedValues, arr); - if (node) { - // 例如选中了 中国-江苏, 搜索江苏, 取消中国(实际上只想删除中国-江苏,因为搜的是江苏) - // 例如选中了 中国-江苏-南京,搜索南京,取消中国(实际上只想删除中国-江苏-南京,因为搜的是南京) - self._deleteNode(selectedValues, arr); - } else { - // 例如选中了 中国-江苏,搜索南京,取消中国(实际上只想删除中国-江苏-南京,因为搜的是南京) - expandSelectedValue(selectedValues, arr, BI.last(arr)); - } - }); - } - } - } - - // 存储的值中不存在这个值,但父亲节点是全选的情况 - // 例如选中了中国-江苏,取消南京 - // important 选中了中国-江苏,取消了江苏,但是搜索的是南京 - if (isChild(selectedValues, p)) { - var result = [], find = false; - // 如果parentValues中有匹配的值,说明搜索结果不在当前值下 - if (isSearchValueInParent(p)) { - find = true; - } else { - // 从当前值开始搜 - find = search(parentValues, notSelectedValue, result); - p = parentValues; - } - - if (find === true) { - // 去掉点击的节点之后的结果集 - expandSelectedValue(selectedValues, p, notSelectedValue); - // 添加去掉搜索的结果集 - if (result.length > 0) { - BI.each(result, function (i, strs) { - self._buildTree(selectedValues, strs); - }); - } - } - } - - } - - function expandSelectedValue(selectedValues, parents, notSelectedValue) { - var next = selectedValues; - var childrenCount = []; - var path = []; - // 去掉点击的节点之后的结果集 - BI.some(parents, function (i, v) { - var t = next[v]; - if (t == null) { - if (i === 0) { - return true; - } - if (BI.isEmpty(next)) { - var split = parents.slice(0, i); - var expanded = self._getChildren(split); - path.push(split); - childrenCount.push(expanded.length); - // 如果只有一个值且取消的就是这个值 - if (i === parents.length - 1 && expanded.length === 1 && expanded[0].value === notSelectedValue) { - for (var j = childrenCount.length - 1; j >= 0; j--) { - if (childrenCount[j] === 1) { - self._deleteNode(selectedValues, path[j]); - } else { - break; - } - } - } else { - BI.each(expanded, function (m, child) { - if (i === parents.length - 1 && child.value === notSelectedValue) { - return true; - } - next[child.value] = {}; - }); - } - next = next[v]; - } else { - return true; - // next = {}; - // next[v] = {}; - } - } else { - next = t; - } - }); - } - - function search(parents, current, result, searched) { - var newParents = BI.clone(parents); - newParents.push(current); - if (self._isMatch(parents, current, keyword)) { - searched && searched.push(newParents); - return true; - } - - var children = self._getChildren(newParents); - - var notSearch = []; - var can = false; - - BI.each(children, function (i, child) { - if (search(newParents, child.value, result, searched)) { - can = true; - } else { - notSearch.push(child.value); - } - }); - if (can === true) { - BI.each(notSearch, function (i, v) { - var next = BI.clone(newParents); - next.push(v); - result.push(next); - }); - } - return can; - } - - function isSearchValueInParent(parentValues) { - for (var i = 0, len = parentValues.length; i < len; i++) { - if (self._isMatch(parentValues.slice(0, i), parentValues[i], keyword)) { - return true; - } - } - return false; - } - - function canFindKey(selectedValues, parents) { - var t = selectedValues; - for (var i = 0; i < parents.length; i++) { - var v = parents[i]; - t = t[v]; - if (t == null) { - return false; - } - } - return true; - } - - function isChild(selectedValues, parents) { - var t = selectedValues; - for (var i = 0; i < parents.length; i++) { - var v = parents[i]; - if (!BI.has(t, v)) { - return false; - } - t = t[v]; - if (BI.isEmpty(t)) { - return true; - } - } - return false; - } - }, - - _reqAdjustTreeNode: function (op, callback) { - var self = this; - var result = []; - var selectedValues = op.selectedValues; - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - BI.each(selectedValues, function (k, v) { - result.push([k]); - }); - - dealWithSelectedValues(selectedValues, []); - - var jo = {}; - BI.each(result, function (i, strs) { - self._buildTree(jo, strs); - }); - callback(jo); - - function dealWithSelectedValues(selected, parents) { - if (selected == null || BI.isEmpty(selected)) { - return true; - } - var can = true; - BI.each(selected, function (k, v) { - var p = BI.clone(parents); - p.push(k); - if (!dealWithSelectedValues(selected[k], p)) { - BI.each(selected[k], function (nk, nv) { - var t = BI.clone(p); - t.push(nk); - result.push(t); - }); - can = false; - } - }); - return can && isAllSelected(selected, parents); - } - - function isAllSelected(selected, parents) { - return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); - } - }, - - _reqInitTreeNode: function (op, callback) { - var self = this; - var result = []; - var keyword = op.keyword || ""; - var selectedValues = op.selectedValues; - var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 - var output = search(); - BI.nextTick(function () { - callback({ - hasNext: output.length > self._const.perPage, - items: result, - lastSearchValue: BI.last(output) - }); - }); - - function search() { - var children = self._getChildren([]); - var start = children.length; - if (lastSearchValue !== "") { - for (var j = 0, len = start; j < len; j++) { - if (children[j].value === lastSearchValue) { - start = j + 1; - break; - } - } - } else { - start = 0; - } - var output = []; - for (var i = start, len = children.length; i < len; i++) { - if (output.length < self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, result); - } else if (output.length === self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, []); - } - if (find[0] === true) { - output.push(children[i].value); - } - if (output.length > self._const.perPage) { - break; - } - } - - // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 - if (op.times === 1) { - var nodes = self._getAddedValueNode([], selectedValues); - result = BI.concat(BI.filter(nodes, function (idx, node) { - var find = BI.Func.getSearchResult([node.text || node.value], keyword); - return find.find.length > 0 || find.match.length > 0; - }), result); - } - return output; - } - - function nodeSearch(deep, parentValues, current, isAllSelect, result) { - if (self._isMatch(parentValues, current, keyword)) { - var checked = isAllSelect || isSelected(parentValues, current); - createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); - return [true, checked]; - } - var newParents = BI.clone(parentValues); - newParents.push(current); - var children = self._getChildren(newParents); - - var can = false, checked = false; - - var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); - BI.each(children, function (i, child) { - var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); - // 当前节点的子节点是否选中,并不确定全选还是半选 - if (state[1] === true) { - checked = true; - } - // 当前节点的子节点要不要加入到结果集中 - if (state[0] === true) { - can = true; - } - }); - // 子节点匹配, 补充父节点 - if (can === true) { - checked = isCurAllSelected || (isSelected(parentValues, current) && checked); - createOneJson(parentValues, current, true, checked, false, false, result); - } - return [can, checked]; - } - - function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { - var node = self._getTreeNode(parentValues, value); - result.push({ - id: node.id, - pId: node.pId, - text: node.text, - value: node.value, - title: node.title, - isParent: node.getChildrenLength() > 0, - open: isOpen, - checked: checked, - halfCheck: half, - flag: flag, - disabled: node.disabled - }); - } - - function isHalf(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return null; - } - return BI.any(find, function (v, ob) { - if (v === value) { - if (ob != null && !BI.isEmpty(ob)) { - return true; - } - } - }); - } - - function isAllSelected(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return null; - } - return BI.any(find, function (v, ob) { - if (v === value) { - if (ob != null && BI.isEmpty(ob)) { - return true; - } - } - }); - } - - function isSelected(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return false; - } - return BI.any(find, function (v) { - if (v === value) { - return true; - } - }); - } - - function findSelectedObj(parentValues) { - var find = selectedValues; - if (find == null) { - return null; - } - BI.every(parentValues, function (i, v) { - find = find[v]; - if (find == null) { - return false; - } - return true; - }); - return find; - } - }, - - _reqTreeNode: function (op, callback) { - var self = this, o = this.options; - var result = []; - var times = op.times; - var checkState = op.checkState || {}; - var parentValues = op.parentValues || []; - var selectedValues = op.selectedValues || {}; - function getResult(parentValues, checkState) { - var valueMap = {}; - // if (judgeState(parentValues, selectedValues, checkState)) { - valueMap = dealWithSelectedValue(parentValues, selectedValues); - // } - var nodes = self._getChildren(parentValues); - for (var i = (times - 1) * self._const.perPage; nodes[i] && i < times * self._const.perPage; i++) { - var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); - var openState = o.open || nodes[i].open; - result.push({ - id: nodes[i].id, - pId: nodes[i].pId, - value: nodes[i].value, - text: nodes[i].text, - times: 1, - isParent: nodes[i].isParent || nodes[i].getChildrenLength() > 0, - checked: state[0], - half: state[1], - halfCheck: openState ? false : state[1], - open: openState, - disabled: nodes[i].disabled, - title: nodes[i].title || nodes[i].text, - warningTitle: nodes[i].warningTitle, - }); - if (openState) { - getResult(parentValues.concat([nodes[i].value]), {checked: state[0], half: state[1]}); - } - } - } - - getResult(parentValues, checkState); - - // 如果指定节点全部打开 - // if (o.open) { - // var allNodes = []; - // // 获取所有节点 - // BI.each(nodes, function (idx, node) { - // allNodes = BI.concat(allNodes, self._getAllChildren(parentValues.concat([node.value]))); - // }); - // var lastFind; - // BI.each(allNodes, function (idx, node) { - // var valueMap = dealWithSelectedValue(node.parentValues, selectedValues); - // // REPORT-24409 fix: 设置节点全部展开,添加的节点没有给状态 - // var parentCheckState = {}; - // var find = BI.find(result, function (idx, pNode) { - // return pNode.id === node.pId; - // }); - // if (find) { - // parentCheckState.checked = find.halfCheck ? false : find.checked; - // parentCheckState.half = find.halfCheck; - // // 默认展开也需要重置父节点的halfCheck - // if (BI.isNotNull(lastFind) && (lastFind !== find || allNodes.length - 1 === idx)) { - // lastFind.half = lastFind.halfCheck; - // lastFind.halfCheck = false; - // } - // } - // lastFind = find; - // var state = getCheckState(node.value, node.parentValues, valueMap, parentCheckState); - // result.push({ - // id: node.id, - // pId: node.pId, - // value: node.value, - // text: node.text, - // times: 1, - // isParent: node.getChildrenLength() > 0, - // checked: state[0], - // halfCheck: state[1], - // open: true, - // disabled: node.disabled, - // title: node.title || node.text, - // warningTitle: node.warningTitle, - // }); - // }); - // } - - // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 - if (parentValues.length === 0 && times === 1) { - result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); - } - BI.nextTick(function () { - callback({ - items: result, - hasNext: self._getChildren(parentValues).length > times * self._const.perPage - }); - }); - - // function judgeState(parentValues, selected_value, checkState) { - // var checked = checkState.checked, half = checkState.half; - // if (parentValues.length > 0 && !checked) { - // return false; - // } - // return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); - // } - - function dealWithSelectedValue(parentValues, selectedValues) { - var valueMap = {}, parents = (parentValues || []).slice(0); - BI.each(parentValues, function (i, v) { - parents.push(v); - - selectedValues = selectedValues[v] || {}; - }); - BI.each(selectedValues, function (value, obj) { - var currentParents = BI.concat(parents, value); - - if (BI.isNull(obj)) { - valueMap[value] = [0, 0]; - return; - } - if (BI.isEmpty(obj)) { - valueMap[value] = [2, 0]; - return; - } - var nextNames = {}; - BI.each(obj, function (t, o) { - if (BI.isNull(o) || BI.isEmpty(o)) { - nextNames[t] = true; - } else { - isAllSelected(o, BI.concat(currentParents, [t])) && (nextNames[t] = true); - } - }); - // valueMap的数组第一个参数为不选: 0, 半选: 1, 全选:2, 第二个参数为改节点下选中的子节点个数(子节点全选或者不存在) - valueMap[value] = [1, BI.size(nextNames)]; - }); - return valueMap; - } - - function isAllSelected(selected, parents) { - if (BI.isEmpty(selected)) { - return true; - } - - if (self._getChildCount(parents) !== BI.size(selected)) { - return false; - } - - return BI.every(selected, function (value) { - return isAllSelected(selected[value], BI.concat(parents, value)); - }); - } - - function getCheckState(current, parentValues, valueMap, checkState) { - // 节点本身的checked和half优先级最高 - var checked = checkState.checked, half = checkState.half; - var tempCheck = false, halfCheck = false; - if (BI.has(valueMap, current)) { - // 可能是半选 - if (valueMap[current][0] === 1) { - var values = BI.clone(parentValues); - values.push(current); - var childCount = self._getChildCount(values); - if (childCount > 0 && childCount !== valueMap[current][1]) { - halfCheck = true; - } - } else if (valueMap[current][0] === 2) { - tempCheck = true; - } - } - var check; - // 展开的节点checked为false 且没有明确得出当前子节点是半选或者全选, 则check状态取决于valueMap - if (!checked && !halfCheck && !tempCheck) { - check = BI.has(valueMap, current); - } else { - // 不是上面那种情况就先看在节点没有带有明确半选的时候,通过节点自身的checked和valueMap的状态能都得到选中信息 - check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); - } - return [check, halfCheck]; - } - }, - - _getAddedValueNode: function (parentValues, selectedValues) { - var nodes = this._getChildren(parentValues); - return BI.map(BI.difference(BI.keys(selectedValues), BI.map(nodes, "value")), function (idx, v) { - return { - id: BI.UUID(), - pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), - value: v, - text: v, - times: 1, - isParent: false, - checked: true, - halfCheck: false, - }; - }); - }, - - _getNode: function (selectedValues, parentValues) { - var pNode = selectedValues; - for (var i = 0, len = parentValues.length; i < len; i++) { - if (pNode == null) { - return null; - } - pNode = pNode[parentValues[i]]; - } - return pNode; - }, - - _deleteNode: function (selectedValues, values) { - var name = values[values.length - 1]; - var p = values.slice(0, values.length - 1); - var pNode = this._getNode(selectedValues, p); - if (pNode != null && pNode[name]) { - delete pNode[name]; - // 递归删掉空父节点 - while (p.length > 0 && BI.isEmpty(pNode)) { - name = p[p.length - 1]; - p = p.slice(0, p.length - 1); - pNode = this._getNode(selectedValues, p); - if (pNode != null) { - delete pNode[name]; - } - } - } - }, - - _buildTree: function (jo, values) { - var t = jo; - BI.each(values, function (i, v) { - if (!BI.has(t, v)) { - t[v] = {}; - } - t = t[v]; - }); - }, - - _isMatch: function (parentValues, value, keyword) { - var o = this.options; - var node = this._getTreeNode(parentValues, value); - if (!node) { - return false; - } - var find = BI.Func.getSearchResult([node.text || node.value], keyword); - if(o.allowSearchValue && node.value) { - var valueFind = BI.Func.getSearchResult([node.value], keyword); - return valueFind.find.length > 0 || valueFind.match.length > 0 || - find.find.length > 0 || find.match.length > 0; - } - return find.find.length > 0 || find.match.length > 0; - }, - - _getTreeNode: function (parentValues, v) { - var self = this; - var findParentNode; - var index = 0; - var currentParent = this.tree.getRoot(); - this.tree.traverse(function (node) { - if (self.tree.isRoot(node)) { - return; - } - if (index > parentValues.length) { - return false; - } - - /** - * 一个树结构。要找root_1_3的子节点 - * {root: { 1: {1: {}, 2: {}, 3: {}}, 3: {1: {}, 2: {}} } } - * 当遍历到root_1节点时,index++,而下一个节点root_3时,符合下面的if逻辑,这样找到的节点就是root_3节点了,需要加步判断是否是root_1的子节点 - */ - if (index === parentValues.length && node.value === v) { - if (node.getParent() !== currentParent) { - return; - } - - findParentNode = node; - - return false; - } - if (node.value === parentValues[index] && node.getParent() === currentParent) { - index++; - currentParent = node; - - return; - } - - return true; - }); - - return findParentNode; - }, - - _getChildren: function (parentValues) { - if (parentValues.length > 0) { - var value = BI.last(parentValues); - var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); - } else { - var parent = this.tree.getRoot(); - } - - return parent ? parent.getChildren() : []; - }, - - _getAllChildren: function(parentValues) { - var children = this._getChildren(parentValues); - var nodes = [].concat(children); - BI.each(nodes, function (idx, node) { - node.parentValues = parentValues; - }); - var queue = BI.map(children, function (idx, node) { - return { - parentValues: parentValues, - value: node.value - }; - }); - while (BI.isNotEmptyArray(queue)) { - var node = queue.shift(); - var pValues = (node.parentValues).concat(node.value); - var childNodes = this._getChildren(pValues); - BI.each(childNodes, function (idx, node) { - node.parentValues = pValues; - }); - queue = queue.concat(childNodes); - nodes = nodes.concat(childNodes); - } - return nodes; - }, - - _getChildCount: function (parentValues) { - return this._getChildren(parentValues).length; - }, - - assertSelectedValue: function (selectedValues, items = []) { - if (BI.isPlainObject(selectedValues)) { - return selectedValues; - } - - var tree = BI.Tree.transformToTreeFormat(items); - var value2ParentMap = {}; - BI.Tree.traversal(tree, function (index, node, pNode) { - value2ParentMap[node.value] = pNode; - }); - - var result = {}; - BI.each(selectedValues, function (index, value) { - var curr = value; - var parentPath = []; - while (curr) { - parentPath.unshift(curr); - curr = value2ParentMap[curr]?.value; - } - BI.each(parentPath, function (index) { - if (BI.isNull(BI.get(result, parentPath.slice(0, index + 1)))) { - BI.set(result, parentPath.slice(0, index + 1), {}); - } - }); - // 执行完一条路径,check一下 - var lengths = BI.size(BI.get(result, parentPath.slice(0, -1))); - if (lengths === value2ParentMap[value]?.children?.length) { - BI.set(result, parentPath.slice(0, -1), {}); - } - }); - - return result; - }, - - buildCompleteTree: function (selectedValues) { - var self = this; - var result = {}; - - if (selectedValues !== null && !BI.isEmpty(selectedValues)) { - fill([], this.tree.getRoot(), selectedValues, result); - } - - return result; - - function fill(parentValues, node, selected, r) { - if (selected === null || BI.isEmpty(selected)) { - BI.each(node.getChildren(), function (i, child) { - var newParents = BI.clone(parentValues); - newParents.push(child.value); - r[child.value] = {}; - fill(newParents, child, null, r[child.value]); - }); - return; - } - BI.each(selected, function (k) { - var node = self._getTreeNode(parentValues, k); - var newParents = BI.clone(parentValues); - newParents.push(node.value); - r[k] = {}; - fill(newParents, node, selected[k], r[k]); - }); - } - }, -}); diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.list.js b/src/component/treevaluechooser/abstract.treevaluechooser.list.js deleted file mode 100644 index 0a44af0f1..000000000 --- a/src/component/treevaluechooser/abstract.treevaluechooser.list.js +++ /dev/null @@ -1,290 +0,0 @@ -BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { - - _reqDisplayTreeNode: function (op, callback) { - var self = this; - var result = {}; - var selectedValues = op.selectedValues; - - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - - doCheck([], this.tree.getRoot(), selectedValues); - - callback({ - items: BI.values(result) - }); - - function doCheck(parentValues, node, selected) { - BI.each(selected, function (idx, path) { - BI.each(path, function (id, value) { - var nodeValue = value; - var node = self._getTreeNode(path.slice(0, id), nodeValue); - // 找不到就是新增值 - if (BI.isNull(node)) { - createOneJson({ - id: BI.UUID(), - text: nodeValue, - value: nodeValue, - isLeaf: true - }, BI.UUID()); - } else { - if(!BI.has(result, node.id)) { - createOneJson(node, node.parent && node.parent.id); - } - result[node.id].isLeaf !== true && (result[node.id].isLeaf = id === path.length - 1); - } - }); - }); - } - - function createOneJson(node, pId) { - result[node.id] = { - id: node.id, - pId: pId, - text: node.text, - value: node.value, - open: true, - isLeaf: node.isLeaf - }; - } - }, - - _reqInitTreeNode: function (op, callback) { - var self = this; - var result = []; - var keyword = op.keyword || ""; - var selectedValues = op.selectedValues; - var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 - var output = search(); - BI.nextTick(function () { - callback({ - hasNext: output.length > self._const.perPage, - items: result, - lastSearchValue: BI.last(output) - }); - }); - - function search() { - var children = self._getChildren([]); - var start = children.length; - if (lastSearchValue !== "") { - for (var j = 0, len = start; j < len; j++) { - if (children[j].value === lastSearchValue) { - start = j + 1; - break; - } - } - } else { - start = 0; - } - var output = []; - for (var i = start, len = children.length; i < len; i++) { - if (output.length < self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, result); - } else if (output.length === self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, []); - } - if (find[0] === true) { - output.push(children[i].value); - } - if (output.length > self._const.perPage) { - break; - } - } - - // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 - if (op.times === 1) { - var nodes = self._getAddedValueNode([], selectedValues); - result = BI.concat(BI.filter(nodes, function (idx, node) { - var find = BI.Func.getSearchResult([node.text || node.value], keyword); - return find.find.length > 0 || find.match.length > 0; - }), result); - } - return output; - } - - function nodeSearch(deep, parentValues, current, result) { - if (self._isMatch(parentValues, current, keyword)) { - var checked = isSelected(parentValues, current); - createOneJson(parentValues, current, false, checked, true, result); - return [true, checked]; - } - var newParents = BI.clone(parentValues); - newParents.push(current); - var children = self._getChildren(newParents); - - var can = false, checked = false; - - BI.each(children, function (i, child) { - var state = nodeSearch(deep + 1, newParents, child.value, result); - if (state[1] === true) { - checked = true; - } - if (state[0] === true) { - can = true; - } - }); - if (can === true) { - checked = isSelected(parentValues, current); - createOneJson(parentValues, current, true, checked, false, result); - } - return [can, checked]; - } - - function createOneJson(parentValues, value, isOpen, checked, flag, result) { - var node = self._getTreeNode(parentValues, value); - result.push({ - id: node.id, - pId: node.pId, - text: node.text, - value: node.value, - title: node.title, - isParent: node.getChildrenLength() > 0, - open: isOpen, - checked: checked, - halfCheck: false, - flag: flag, - disabled: node.disabled - }); - } - - function isHalf(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return null; - } - return BI.any(find, function (v, ob) { - if (v === value) { - if (ob != null && !BI.isEmpty(ob)) { - return true; - } - } - }); - } - - function isAllSelected(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return null; - } - return BI.any(find, function (v, ob) { - if (v === value) { - if (ob != null && BI.isEmpty(ob)) { - return true; - } - } - }); - } - - function isSelected(parentValues, value) { - return BI.any(selectedValues, function (idx, array) { - return BI.isEqual(parentValues, array.slice(0, parentValues.length)) && BI.last(array) === value; - }); - } - - function findSelectedObj(parentValues) { - var find = selectedValues; - if (find == null) { - return null; - } - BI.every(parentValues, function (i, v) { - find = find[v]; - if (find == null) { - return false; - } - return true; - }); - return find; - } - }, - - _reqTreeNode: function (op, callback) { - var self = this, o = this.options; - var result = []; - var times = op.times; - var parentValues = op.parentValues || []; - var selectedValues = op.selectedValues || []; - var valueMap = dealWithSelectedValue(parentValues, selectedValues); - var nodes = this._getChildren(parentValues); - for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { - var checked = BI.has(valueMap, nodes[i].value); - result.push({ - id: nodes[i].id, - pId: nodes[i].pId, - value: nodes[i].value, - text: nodes[i].text, - times: 1, - isParent: nodes[i].getChildrenLength() > 0, - checked: checked, - halfCheck: false, - open: o.open, - disabled: nodes[i].disabled - }); - } - // 如果指定节点全部打开 - if (o.open) { - var allNodes = []; - // 获取所有节点 - BI.each(nodes, function (idx, node) { - allNodes = BI.concat(allNodes, self._getAllChildren(parentValues.concat([node.value]))); - }); - BI.each(allNodes, function (idx, node) { - var valueMap = dealWithSelectedValue(node.parentValues, selectedValues); - var checked = BI.has(valueMap, node.value); - result.push({ - id: node.id, - pId: node.pId, - value: node.value, - text: node.text, - times: 1, - isParent: node.getChildrenLength() > 0, - checked: checked, - halfCheck: false, - open: o.open, - disabled: node.disabled - }); - }); - } - // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 - if (parentValues.length === 0 && times === 1) { - result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); - } - BI.nextTick(function () { - callback({ - items: result, - hasNext: nodes.length > times * self._const.perPage - }); - }); - - function dealWithSelectedValue(parentValues, selectedValues) { - var valueMap = {}; - BI.each(selectedValues, function (idx, v) { - if (BI.isEqual(parentValues, v.slice(0, parentValues.length))) { - valueMap[BI.last(v)] = [2, 0]; - } - }); - return valueMap; - } - }, - - _getAddedValueNode: function (parentValues, selectedValues) { - var nodes = this._getChildren(parentValues); - var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { - return array.length === 1; - })); - return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { - return { - id: BI.UUID(), - pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), - value: v, - text: v, - times: 1, - isParent: false, - checked: true, - halfCheck: false - }; - }); - } -}); \ No newline at end of file diff --git a/src/component/treevaluechooser/combo.listtreevaluechooser.js b/src/component/treevaluechooser/combo.listtreevaluechooser.js deleted file mode 100644 index 0366a4bbc..000000000 --- a/src/component/treevaluechooser/combo.listtreevaluechooser.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 - * - * Created by GUY on 2015/10/29. - * @class BI.ListTreeValueChooserInsertCombo - * @extends BI.Widget - */ -BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-tree-value-chooser-insert-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - isNeedAdjustWidth: true, - }); - }, - - _init: function () { - BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this._initData(o.items); - } - this.combo = BI.createWidget({ - type: "bi.multi_tree_list_combo", - simple: o.simple, - isNeedAdjustWidth: o.isNeedAdjustWidth, - element: this, - text: o.text, - defaultText: o.defaultText, - value: o.value, - watermark: o.watermark, - allowInsertValue: o.allowInsertValue, - allowEdit: o.allowEdit, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - listeners: [{ - eventName: BI.MultiTreeListCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiTreeListCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiTreeListCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiTreeListCombo.EVENT_CLICK_ITEM, - action: function (v) { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CLICK_ITEM, v); - } - }, { - eventName: BI.MultiTreeListCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiTreeListCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getSearcher: function () { - return this.combo.getSearcher(); - }, - - setValue: function (v) { - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - this._initData(items); - } - this.combo.populate(); - }, - - focus: function () { - this.combo.focus(); - }, - - blur: function () { - this.combo.blur(); - }, - - setWaterMark: function (v) { - this.combo.setWaterMark(v); - } -}); - -BI.ListTreeValueChooserInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ListTreeValueChooserInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.ListTreeValueChooserInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.ListTreeValueChooserInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.ListTreeValueChooserInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.ListTreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo); diff --git a/src/component/treevaluechooser/combo.treevaluechooser.insert.js b/src/component/treevaluechooser/combo.treevaluechooser.insert.js deleted file mode 100644 index f9c6ebf4b..000000000 --- a/src/component/treevaluechooser/combo.treevaluechooser.insert.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 - * - * Created by GUY on 2015/10/29. - * @class BI.TreeValueChooserInsertCombo - * @extends BI.Widget - */ -BI.TreeValueChooserInsertCombo = BI.inherit(BI.AbstractTreeValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.TreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-value-chooser-insert-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - isNeedAdjustWidth: true - }); - }, - - _init: function () { - BI.TreeValueChooserInsertCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this._initData(o.items); - } - this.combo = BI.createWidget({ - type: "bi.multi_tree_insert_combo", - simple: o.simple, - isNeedAdjustWidth: o.isNeedAdjustWidth, - allowEdit: o.allowEdit, - text: o.text, - defaultText: o.defaultText, - value: o.value, - watermark: o.watermark, - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - listeners: [{ - eventName: BI.MultiTreeInsertCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiTreeInsertCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiTreeInsertCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiTreeInsertCombo.EVENT_CLICK_ITEM, - action: function (v) { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_CLICK_ITEM, v); - } - }, { - eventName: BI.MultiTreeInsertCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiTreeInsertCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.TreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getSearcher: function () { - return this.combo.getSearcher(); - }, - - setValue: function (v) { - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - this._initData(items); - } - this.combo.populate(); - }, - - focus: function () { - this.combo.focus(); - }, - - blur: function () { - this.combo.blur(); - }, - - setWaterMark: function (v) { - this.combo.setWaterMark(v); - } -}); - -BI.TreeValueChooserInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.TreeValueChooserInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.TreeValueChooserInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.TreeValueChooserInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.TreeValueChooserInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.TreeValueChooserInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.TreeValueChooserInsertCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.tree_value_chooser_insert_combo", BI.TreeValueChooserInsertCombo); diff --git a/src/component/treevaluechooser/combo.treevaluechooser.js b/src/component/treevaluechooser/combo.treevaluechooser.js deleted file mode 100644 index 2c0709d67..000000000 --- a/src/component/treevaluechooser/combo.treevaluechooser.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * 简单的复选下拉树控件, 适用于数据量少的情况 - * - * Created by GUY on 2015/10/29. - * @class BI.TreeValueChooserCombo - * @extends BI.Widget - */ -BI.TreeValueChooserCombo = BI.inherit(BI.AbstractTreeValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-value-chooser-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - isNeedAdjustWidth: true - }); - }, - - _init: function () { - BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this._initData(o.items); - } - this.combo = BI.createWidget({ - type: "bi.multi_tree_combo", - simple: o.simple, - text: o.text, - defaultText: o.defaultText, - allowEdit: o.allowEdit, - value: this.assertSelectedValue(o.value, o.items), - watermark: o.watermark, - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - isNeedAdjustWidth: o.isNeedAdjustWidth, - listeners: [{ - eventName: BI.MultiTreeCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_CLICK_ITEM, - action: function (v) { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_CLICK_ITEM, v); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_BEFORE_POPUPVIEW); - } - }, { - eventName: BI.MultiTreeCombo.EVENT_AFTER_HIDEVIEW, - action: function () { - self.fireEvent(BI.TreeValueChooserCombo.EVENT_AFTER_HIDEVIEW); - } - }] - }); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getSearcher: function () { - return this.combo.getSearcher(); - }, - - setValue: function (v) { - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - getAllValue: function () { - return this.buildCompleteTree(this.combo.getValue()); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - this._initData(items); - } - this.combo.populate(); - }, - - focus: function () { - this.combo.focus(); - }, - - blur: function () { - this.combo.blur(); - }, - - setWaterMark: function (v) { - this.combo.setWaterMark(v); - } -}); - -BI.TreeValueChooserCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.TreeValueChooserCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.TreeValueChooserCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.TreeValueChooserCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.TreeValueChooserCombo.EVENT_STOP = "EVENT_STOP"; -BI.TreeValueChooserCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.TreeValueChooserCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.TreeValueChooserCombo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; -BI.shortcut("bi.tree_value_chooser_combo", BI.TreeValueChooserCombo); diff --git a/src/component/treevaluechooser/pane.treevaluechooser.js b/src/component/treevaluechooser/pane.treevaluechooser.js deleted file mode 100644 index 8171c04d8..000000000 --- a/src/component/treevaluechooser/pane.treevaluechooser.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 简单的树面板, 适用于数据量少的情况 - * - * Created by GUY on 2015/10/29. - * @class BI.TreeValueChooserPane - * @extends BI.AbstractTreeValueChooser - */ -BI.TreeValueChooserPane = BI.inherit(BI.AbstractTreeValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.TreeValueChooserPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-value-chooser-pane", - items: null, - itemsCreator: BI.emptyFn, - showLine: true - }); - }, - - _init: function () { - BI.TreeValueChooserPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.pane = BI.createWidget({ - type: o.hideSearch ? "bi.multi_select_tree_popup" : "bi.multi_select_tree", - element: this, - showLine: o.showLine, - itemsCreator: BI.bind(this._itemsCreator, this) - }); - - this.pane.on(BI.MultiSelectTree.EVENT_CHANGE, function () { - self.fireEvent(BI.TreeValueChooserPane.EVENT_CHANGE); - }); - if (BI.isNotNull(o.value)) { - var selectedValues = this.assertSelectedValue(o.value, o.items); - this.pane.setSelectedValue(selectedValues); - } - if (BI.isNotNull(o.items)) { - this._initData(o.items); - this.pane.populate(); - } - }, - - setSelectedValue: function (v) { - this.pane.setSelectedValue(v); - }, - - setValue: function (v) { - this.pane.setValue(v); - }, - - getValue: function () { - return this.pane.getValue(); - }, - - getAllValue: function() { - return this.buildCompleteTree(this.pane.getValue()); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - this._initData(items); - } - this.pane.populate(); - } -}); -BI.TreeValueChooserPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.tree_value_chooser_pane", BI.TreeValueChooserPane); diff --git a/src/component/valuechooser/abstract.valuechooser.js b/src/component/valuechooser/abstract.valuechooser.js deleted file mode 100644 index a97434a84..000000000 --- a/src/component/valuechooser/abstract.valuechooser.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 简单的复选下拉框控件, 适用于数据量少的情况 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.AbstractValueChooser - * @extends BI.Widget - */ -BI.AbstractValueChooser = BI.inherit(BI.Widget, { - - _const: { - perPage: 100 - }, - - _defaultConfig: function () { - return BI.extend(BI.AbstractValueChooser.superclass._defaultConfig.apply(this, arguments), { - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _valueFormatter: function (v) { - var text = v; - if (this.options.valueFormatter) { - return this.options.valueFormatter(v); - } - if (BI.isNotNull(this.items)) { - BI.some(this.items, function (i, item) { - // 把value都换成字符串 - if (item.value === v || item.value + "" === v) { - text = item.text; - return true; - } - }); - } - return text; - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * this._const.perPage < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!o.cache || !this.items) { - o.itemsCreator({}, function (items) { - self.items = items; - call(items); - }); - } else { - call(this.items); - } - function call (items) { - var keywords = (options.keywords || []).slice(); - var resultItems = items; - if(BI.isNotEmptyArray(keywords)) { - resultItems = []; - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - resultItems = resultItems.concat(search.match).concat(search.find); - }); - resultItems = BI.uniq(resultItems); - } - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - resultItems = BI.filter(resultItems, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: resultItems - }); - return; - } - if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: resultItems.length}); - return; - } - callback({ - items: self._getItemsByTimes(resultItems, options.times), - hasNext: self._hasNextByTimes(resultItems, options.times) - }); - } - }, - - _assertValue: function (v) { - v = v || {}; - var value = v; - if (v.type === BI.Selection.Multi && BI.isNotNull(this.items)) { - var isAllSelect = BI.difference(BI.map(this.items, "value"), v.value).length === 0; - if (isAllSelect) { - value = { - type: BI.Selection.All, - value: [], - }; - } - } - return value; - }, -}); \ No newline at end of file diff --git a/src/component/valuechooser/combo.valuechooser.insert.js b/src/component/valuechooser/combo.valuechooser.insert.js deleted file mode 100644 index a2cdce0d9..000000000 --- a/src/component/valuechooser/combo.valuechooser.insert.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 简单的复选下拉框控件, 适用于数据量少的情况 - * 封装了字段处理逻辑 - */ -BI.ValueChooserInsertCombo = BI.inherit(BI.AbstractValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.ValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-value-chooser-insert-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _init: function () { - BI.ValueChooserInsertCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: "bi.multi_select_insert_combo", - simple: o.simple, - element: this, - allowEdit: o.allowEdit, - text: o.text, - value: this._assertValue(o.value), - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - listeners: [{ - eventName: BI.MultiSelectCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CLICK_ITEM, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_CLICK_ITEM); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.ValueChooserInsertCombo.EVENT_CONFIRM); - } - }] - }); - }, - - setValue: function (v) { - this.combo.setValue(this._assertValue(v)); - }, - - getValue: function () { - var val = this.combo.getValue() || {}; - return { - type: val.type, - value: val.value - }; - }, - - getAllValue: function() { - var val = this.combo.getValue() || {}; - if (val.type === BI.Selection.Multi) { - return val.value || []; - } - - return BI.difference(BI.map(this.items, "value"), val.value || []); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.combo.populate(); - } -}); - -BI.ValueChooserInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.ValueChooserInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ValueChooserInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.ValueChooserInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.ValueChooserInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.ValueChooserInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.value_chooser_insert_combo", BI.ValueChooserInsertCombo); diff --git a/src/component/valuechooser/combo.valuechooser.js b/src/component/valuechooser/combo.valuechooser.js deleted file mode 100644 index 786dc1abd..000000000 --- a/src/component/valuechooser/combo.valuechooser.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 简单的复选下拉框控件, 适用于数据量少的情况 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.ValueChooserCombo - * @extends BI.Widget - */ -BI.ValueChooserCombo = BI.inherit(BI.AbstractValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-value-chooser-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _init: function () { - BI.ValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: "bi.multi_select_combo", - simple: o.simple, - element: this, - allowEdit: o.allowEdit, - text: o.text, - defaultText: o.defaultText, - value: this._assertValue(o.value), - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - listeners: [{ - eventName: BI.MultiSelectCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CLICK_ITEM, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_CLICK_ITEM); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); - } - }] - }); - }, - - setValue: function (v) { - this.combo.setValue(this._assertValue(v)); - }, - - getValue: function () { - var val = this.combo.getValue() || {}; - return { - type: val.type, - value: val.value - }; - }, - - getAllValue: function () { - var val = this.combo.getValue() || {}; - if (val.type === BI.Selection.Multi) { - return val.value || []; - } - - return BI.difference(BI.map(this.items, "value"), val.value || []); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.combo.populate(); - } -}); - -BI.ValueChooserCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.ValueChooserCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ValueChooserCombo.EVENT_STOP = "EVENT_STOP"; -BI.ValueChooserCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.ValueChooserCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.ValueChooserCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.value_chooser_combo", BI.ValueChooserCombo); diff --git a/src/component/valuechooser/combo.valuechooser.nobar.js b/src/component/valuechooser/combo.valuechooser.nobar.js deleted file mode 100644 index 2910ea4fa..000000000 --- a/src/component/valuechooser/combo.valuechooser.nobar.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2020/12/31 - */ -BI.ValueChooserNoBarCombo = BI.inherit(BI.AbstractValueChooser, { - - props: { - baseCls: "bi-value-chooser-combo", - width: 200, - height: 24, - items: null, - itemsCreator: BI.emptyFn, - cache: true - }, - - render: function () { - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - - return { - type: "bi.multi_select_no_bar_combo", - simple: o.simple, - allowEdit: o.allowEdit, - text: o.text, - defaultText: o.defaultText, - value: this._assertValue(o.value), - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this), - width: o.width, - height: o.height, - ref: function (_ref) { - self.combo = _ref; - }, - listeners: [{ - eventName: BI.MultiSelectCombo.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_BLUR, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_STOP, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CLICK_ITEM, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_CLICK_ITEM); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiSelectCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.ValueChooserNoBarCombo.EVENT_CONFIRM); - } - }] - }; - }, - - setValue: function (v) { - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - getAllValue: function () { - return this.getValue(); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.combo.populate(); - } -}); - -BI.ValueChooserNoBarCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.ValueChooserNoBarCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.ValueChooserNoBarCombo.EVENT_STOP = "EVENT_STOP"; -BI.ValueChooserNoBarCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.ValueChooserNoBarCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.ValueChooserNoBarCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.value_chooser_no_bar_combo", BI.ValueChooserNoBarCombo); diff --git a/src/component/valuechooser/pane.valuechooser.js b/src/component/valuechooser/pane.valuechooser.js deleted file mode 100644 index d483f26fb..000000000 --- a/src/component/valuechooser/pane.valuechooser.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 简单的复选面板, 适用于数据量少的情况 - * 封装了字段处理逻辑 - * - * Created by GUY on 2015/10/29. - * @class BI.ValueChooserPane - * @extends BI.Widget - */ -BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { - - _defaultConfig: function () { - return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-value-chooser-pane", - items: null, - itemsCreator: BI.emptyFn, - cache: true - }); - }, - - _init: function () { - BI.ValueChooserPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.list = BI.createWidget({ - type: "bi.multi_select_list", - element: this, - value: o.value, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: BI.bind(this._valueFormatter, this) - }); - - this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.ValueChooserPane.EVENT_CHANGE); - }); - if (BI.isNotNull(o.items)) { - this.items = o.items; - this.list.populate(); - } - }, - - setValue: function (v) { - this.list.setValue(v); - }, - - getValue: function () { - var val = this.list.getValue() || {}; - return { - type: val.type, - value: val.value - }; - }, - - getAllValue: function() { - var val = this.combo.getValue() || {}; - if (val.type === BI.Selection.Multi) { - return val.value || []; - } - - return BI.difference(BI.map(this.items, "value"), val.value || []); - }, - - populate: function (items) { - // 直接用combo的populate不会作用到AbstractValueChooser上 - if (BI.isNotNull(items)) { - this.items = items; - } - this.list.populate(); - } -}); -BI.ValueChooserPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.value_chooser_pane", BI.ValueChooserPane); diff --git a/src/core/0.foundation.js b/src/core/0.foundation.js deleted file mode 100644 index ea69e97a9..000000000 --- a/src/core/0.foundation.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Created by richie on 15/7/8. - */ -/** - * 初始化BI对象 - */ -var _global = undefined; -if (typeof window !== "undefined") { - _global = window; -} else if (typeof global !== "undefined") { - _global = global; -} else if (typeof self !== "undefined") { - _global = self; -} else { - _global = this; -} - -if (_global) { - _global._global = _global; -} - -if (_global.BI == null) { - _global.BI = {prepares: []}; -} -if(_global.BI.prepares == null) { - _global.BI.prepares = []; -} \ No newline at end of file diff --git a/src/core/1.lodash.js b/src/core/1.lodash.js deleted file mode 100644 index 1fdf1bbc4..000000000 --- a/src/core/1.lodash.js +++ /dev/null @@ -1,10318 +0,0 @@ -/** - * @license - * Lodash (Custom Build) - * Build: `lodash core plus="debounce,throttle,get,set,findIndex,findLastIndex,findKey,findLastKey,isArrayLike,invert,invertBy,uniq,uniqBy,omit,omitBy,zip,unzip,rest,range,random,reject,intersection,drop,countBy,union,zipObject,initial,cloneDeep,clamp,isPlainObject,take,takeRight,without,difference,defaultsDeep,trim,merge,groupBy,uniqBy,before,after,unescape,chunk,pick,pickBy,identity"` - * Copyright JS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '4.17.5'; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Error message constants. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used as the maximum memoize cache size. */ - var MAX_MEMOIZE_SIZE = 500; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** Used to compose bitmasks for cloning. */ - var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG = 4; - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - - /** Used to compose bitmasks for function metadata. */ - var WRAP_BIND_FLAG = 1, - WRAP_BIND_KEY_FLAG = 2, - WRAP_CURRY_BOUND_FLAG = 4, - WRAP_CURRY_FLAG = 8, - WRAP_CURRY_RIGHT_FLAG = 16, - WRAP_PARTIAL_FLAG = 32, - WRAP_PARTIAL_RIGHT_FLAG = 64, - WRAP_ARY_FLAG = 128, - WRAP_REARG_FLAG = 256, - WRAP_FLIP_FLAG = 512; - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 800, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2, - LAZY_WHILE_FLAG = 3; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991, - MAX_INTEGER = 1.7976931348623157e+308, - NAN = 0 / 0; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295; - - /** Used to associate wrap methods with their bit flags. */ - var wrapFlags = [ - ['ary', WRAP_ARY_FLAG], - ['bind', WRAP_BIND_FLAG], - ['bindKey', WRAP_BIND_KEY_FLAG], - ['curry', WRAP_CURRY_FLAG], - ['curryRight', WRAP_CURRY_RIGHT_FLAG], - ['flip', WRAP_FLIP_FLAG], - ['partial', WRAP_PARTIAL_FLAG], - ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], - ['rearg', WRAP_REARG_FLAG] - ]; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - asyncTag = '[object AsyncFunction]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - nullTag = '[object Null]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - proxyTag = '[object Proxy]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - undefinedTag = '[object Undefined]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, - reUnescapedHtml = /[&<>"']/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g; - - /** Used to match wrap detail comments. */ - var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, - reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, - reSplitDetails = /,? & /; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect bad signed hexadecimal string values. */ - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - - /** Used to detect binary string values. */ - var reIsBinary = /^0b[01]+$/i; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect octal string values. */ - var reIsOctal = /^0o[0-7]+$/i; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsAstral = '[' + rsAstralRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ = '\\u200d'; - - /** Used to compose unicode regexes. */ - var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = - cloneableTags[boolTag] = cloneableTags[dateTag] = - cloneableTags[float32Tag] = cloneableTags[float64Tag] = - cloneableTags[int8Tag] = cloneableTags[int16Tag] = - cloneableTags[int32Tag] = cloneableTags[mapTag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[setTag] = - cloneableTags[stringTag] = cloneableTags[symbolTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'" - }; - - /** Built-in method references without a dependency on `root`. */ - var freeParseFloat = parseFloat, - freeParseInt = parseInt; - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsDate = nodeUtil && nodeUtil.isDate, - nodeIsMap = nodeUtil && nodeUtil.isMap, - nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, - nodeIsSet = nodeUtil && nodeUtil.isSet, - nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /*--------------------------------------------------------------------------*/ - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; - } - - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && baseIndexOf(array, value, 0) > -1; - } - - /** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array == null ? 0 : array.length; - - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * Gets the size of an ASCII `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - var asciiSize = baseProperty('length'); - - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.propertyOf` without support for deep paths. - * - * @private - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyOf(object) { - return function(key) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); - } - - /** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Gets the number of `placeholder` occurrences in `array`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} placeholder The placeholder to search for. - * @returns {number} Returns the placeholder count. - */ - function countHolders(array, placeholder) { - var length = array.length, - result = 0; - - while (length--) { - if (array[length] === placeholder) { - ++result; - } - } - return result; - } - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - var escapeHtmlChar = basePropertyOf(htmlEscapes); - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } - - /** - * Converts `iterator` to an array. - * - * @private - * @param {Object} iterator The iterator to convert. - * @returns {Array} Returns the converted array. - */ - function iteratorToArray(iterator) { - var data, - result = []; - - while (!(data = iterator.next()).done) { - result.push(data.value); - } - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value === placeholder || value === PLACEHOLDER) { - array[index] = PLACEHOLDER; - result[resIndex++] = index; - } - } - return result; - } - - /** - * Gets the value at `key`, unless `key` is "__proto__". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function safeGet(object, key) { - return key == '__proto__' - ? undefined - : object[key]; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ - function stringSize(string) { - return hasUnicode(string) - ? unicodeSize(string) - : asciiSize(string); - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - var unescapeHtmlChar = basePropertyOf(htmlUnescapes); - - /** - * Gets the size of a Unicode `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - function unicodeSize(string) { - var result = reUnicode.lastIndex = 0; - while (reUnicode.test(string)) { - ++result; - } - return result; - } - - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } - - /*--------------------------------------------------------------------------*/ - - /** Used for built-in method references. */ - var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - - /** Used to detect overreaching core-js shims. */ - var coreJsData = root['__core-js_shared__']; - - /** Used to resolve the decompiled source of functions. */ - var funcToString = funcProto.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString.call(Object); - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Built-in value references. */ - var Buffer = moduleExports ? root.Buffer : undefined, - Symbol = root.Symbol, - Uint8Array = root.Uint8Array, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, - getPrototype = overArg(Object.getPrototypeOf, Object), - objectCreate = Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, - symIterator = Symbol ? Symbol.iterator : undefined, - symToStringTag = Symbol ? Symbol.toStringTag : undefined; - - var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} - }()); - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeFloor = Math.floor, - nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeIsFinite = root.isFinite, - nativeKeys = overArg(Object.keys, Object), - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = Date.now, - nativeRandom = Math.random, - nativeReverse = arrayProto.reverse; - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(root, 'DataView'), - Map = getNative(root, 'Map'), - Promise = getNative(root, 'Promise'), - Set = getNative(root, 'Set'), - WeakMap = getNative(root, 'WeakMap'), - nativeCreate = getNative(Object, 'create'); - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array and iteratees accept only - * one argument. The heuristic for whether a section qualifies for shortcut - * fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; - }()); - - /** - * The function whose prototype chain sequence wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. - */ - function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; - } - - // Ensure wrappers are instances of `baseLodash`. - lodash.prototype = baseLodash.prototype; - lodash.prototype.constructor = lodash; - - LodashWrapper.prototype = baseCreate(baseLodash.prototype); - LodashWrapper.prototype.constructor = LodashWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = copyArray(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = copyArray(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = copyArray(this.__views__); - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || (!isRight && arrLength == length && takeCount == length)) { - return baseWrapperValue(array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; - } - - // Ensure `LazyWrapper` is an instance of `baseLodash`. - LazyWrapper.prototype = baseCreate(baseLodash.prototype); - LazyWrapper.prototype.constructor = LazyWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; - } - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); - } - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - this.size = 0; - } - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - this.size = 0; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); - } - - /** - * The base implementation of `_.assignIn` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssignIn(object, source) { - return object && copyObject(source, keysIn(source), object); - } - - /** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } - } - - /** - * The base implementation of `_.at` without support for individual paths. - * - * @private - * @param {Object} object The object to iterate over. - * @param {string[]} paths The property paths to pick. - * @returns {Array} Returns the picked elements. - */ - function baseAt(object, paths) { - var index = -1, - length = paths.length, - result = Array(length), - skip = object == null; - - while (++index < length) { - result[index] = skip ? undefined : get(object, paths[index]); - } - return result; - } - - /** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ - function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } - } - return number; - } - - /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} bitmask The bitmask flags. - * 1 - Deep clone - * 2 - Flatten inherited properties - * 4 - Clone symbols - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, bitmask, customizer, key, object, stack) { - var result, - isDeep = bitmask & CLONE_DEEP_FLAG, - isFlat = bitmask & CLONE_FLAT_FLAG, - isFull = bitmask & CLONE_SYMBOLS_FLAG; - - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = (isFlat || isFunc) ? {} : initCloneObject(value); - if (!isDeep) { - return isFlat - ? copySymbolsIn(value, baseAssignIn(result, value)) - : copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (isSet(value)) { - value.forEach(function(subValue) { - result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); - }); - - return result; - } - - if (isMap(value)) { - value.forEach(function(subValue, key) { - result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - - return result; - } - - var keysFunc = isFull - ? (isFlat ? getAllKeysIn : getAllKeys) - : (isFlat ? keysIn : keys); - - var props = isArr ? undefined : keysFunc(value); - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - return result; - } - - /** - * The base implementation of `_.delay` and `_.defer` which accepts `args` - * to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Array} args The arguments to provide to `func`. - * @returns {number|Object} Returns the timer id or timeout object. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee == null ? value : iteratee(value); - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.every` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * The base implementation of methods like `_.max` and `_.min` which accepts a - * `comparator` to determine the extremum value. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The iteratee invoked per iteration. - * @param {Function} comparator The comparator used to compare values. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(array, iteratee, comparator) { - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index], - current = iteratee(value); - - if (current != null && (computed === undefined - ? (current === current && !isSymbol(current)) - : comparator(current, computed) - )) { - var computed = current, - result = value; - } - } - return result; - } - - /** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return object && baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from `props`. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the function names. - */ - function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); - }); - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); - } - - /** - * The base implementation of `_.gt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - */ - function baseGt(value, other) { - return value > other; - } - - /** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHas(object, key) { - return object != null && hasOwnProperty.call(object, key); - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. - */ - function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; - - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; - } - array = arrays[0]; - - var index = -1, - seen = caches[0]; - - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.invert` and `_.invertBy` which inverts - * `object` with values transformed by `iteratee` and set by `setter`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform values. - * @param {Object} accumulator The initial inverted object. - * @returns {Function} Returns `accumulator`. - */ - function baseInverter(object, setter, iteratee, accumulator) { - baseForOwn(object, function(value, key, object) { - setter(accumulator, iteratee(value), key, object); - }); - return accumulator; - } - - /** - * The base implementation of `_.invoke` without support for individual - * method arguments. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function baseInvoke(object, path, args) { - path = castPath(path, object); - object = parent(object, path); - var func = object == null ? object : object[toKey(last(path))]; - return func == null ? undefined : apply(func, object, args); - } - - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } - - /** - * The base implementation of `_.isDate` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - */ - function baseIsDate(value) { - return isObjectLike(value) && baseGetTag(value) == dateTag; - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); - - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); - } - - /** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ - function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; - } - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * The base implementation of `_.isRegExp` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - */ - function baseIsRegExp(value) { - return isObjectLike(value) && baseGetTag(value) == regexpTag; - } - - /** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ - function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; - } - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } - - /** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * The base implementation of `_.lt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - */ - function baseLt(value, other) { - return value < other; - } - - /** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseOrderBy(collection, iteratees, orders) { - var index = -1; - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(baseIteratee)); - - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } - - /** - * The base implementation of `_.pick` without support for individual - * property identifiers. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @returns {Object} Returns the new object. - */ - function basePick(object, paths) { - return basePickBy(object, paths, function(value, path) { - return hasIn(object, path); - }); - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; - - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); - - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } - } - return result; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * The base implementation of `_.random` without support for returning - * floating-point numbers. - * - * @private - * @param {number} lower The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the random number. - */ - function baseRandom(lower, upper) { - return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); - } - - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `setData` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); - }; - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The property path to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ - function baseUnset(object, path) { - path = castPath(path, object); - object = parent(object, path); - return object == null || delete object[toKey(last(path))]; - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to perform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - return arrayReduce(actions, function(result, action) { - return action.func.apply(action.thisArg, arrayPush([result], action.args)); - }, result); - } - - /** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ - function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); - } - return result; - } - - /** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ - function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); - } - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; - } - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ - function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); - } - - /** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ - function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; - } - - /** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ - function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); - - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); - - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } - } - return 0; - } - - /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersLength = holders.length, - leftIndex = -1, - leftLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(leftLength + rangeLength), - isUncurried = !isCurried; - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - } - while (rangeLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersIndex = -1, - holdersLength = holders.length, - rightIndex = -1, - rightLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(rangeLength + rightLength), - isUncurried = !isCurried; - - while (++argsIndex < rangeLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - } - return result; - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; - } - - /** - * Copies own symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); - } - - /** - * Copies own and inherited symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbolsIn(source, object) { - return copyObject(source, getSymbolsIn(source), object); - } - - /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; - - return func(collection, setter, baseIteratee(iteratee, 2), accumulator); - }; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` to invoke it with the optional `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createBind(func, bitmask, thisArg) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, arguments); - } - return wrapper; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtor(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. See - // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a function that wraps `func` to enable currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {number} arity The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createCurry(func, bitmask, arity) { - var Ctor = createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length, - placeholder = getHolder(wrapper); - - while (index--) { - args[index] = arguments[index]; - } - var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) - ? [] - : replaceHolders(args, placeholder); - - length -= holders.length; - if (length < arity) { - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, undefined, - args, holders, undefined, undefined, arity - length); - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return apply(fn, this, args); - } - return wrapper; - } - - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ - function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = baseIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; - } - - /** - * Creates a function that wraps `func` to invoke it with optional `this` - * binding of `thisArg`, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided - * to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & WRAP_ARY_FLAG, - isBind = bitmask & WRAP_BIND_FLAG, - isBindKey = bitmask & WRAP_BIND_KEY_FLAG, - isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), - isFlip = bitmask & WRAP_FLIP_FLAG, - Ctor = isBindKey ? undefined : createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length; - - while (index--) { - args[index] = arguments[index]; - } - if (isCurried) { - var placeholder = getHolder(wrapper), - holdersCount = countHolders(args, placeholder); - } - if (partials) { - args = composeArgs(args, partials, holders, isCurried); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight, isCurried); - } - length -= holdersCount; - if (isCurried && length < arity) { - var newHolders = replaceHolders(args, placeholder); - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, thisArg, - args, newHolders, argPos, ary, arity - length - ); - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - length = args.length; - if (argPos) { - args = reorder(args, argPos); - } else if (isFlip && length > 1) { - args.reverse(); - } - if (isAry && ary < length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtor(fn); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates a function like `_.invertBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} toIteratee The function to resolve iteratees. - * @returns {Function} Returns the new inverter function. - */ - function createInverter(setter, toIteratee) { - return function(object, iteratee) { - return baseInverter(object, setter, toIteratee(iteratee), {}); - }; - } - - /** - * Creates a function that wraps `func` to invoke it with the `this` binding - * of `thisArg` and `partials` prepended to the arguments it receives. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to - * the new function. - * @returns {Function} Returns the new wrapped function. - */ - function createPartial(func, bitmask, thisArg, partials) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength), - fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return apply(fn, isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - function createRange(fromRight) { - return function(start, end, step) { - if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { - end = step = undefined; - } - // Ensure the sign of `-0` is preserved. - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); - return baseRange(start, end, step, fromRight); - }; - } - - /** - * Creates a function that wraps `func` to continue currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {Function} wrapFunc The function to create the `func` wrapper. - * @param {*} placeholder The placeholder value. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { - var isCurry = bitmask & WRAP_CURRY_FLAG, - newHolders = isCurry ? holders : undefined, - newHoldersRight = isCurry ? undefined : holders, - newPartials = isCurry ? partials : undefined, - newPartialsRight = isCurry ? undefined : partials; - - bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); - - if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { - bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); - } - var newData = [ - func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, - newHoldersRight, argPos, ary, arity - ]; - - var result = wrapFunc.apply(undefined, newData); - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return setWrapToString(result, func, bitmask); - } - - /** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ - var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); - }; - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * 512 - `_.flip` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); - arity = arity === undefined ? arity : toInteger(arity); - length -= holders ? holders.length : 0; - - if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func); - - var newData = [ - func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, - argPos, ary, arity - ]; - - if (data) { - mergeData(newData, data); - } - func = newData[0]; - bitmask = newData[1]; - thisArg = newData[2]; - partials = newData[3]; - holders = newData[4]; - arity = newData[9] = newData[9] === undefined - ? (isBindKey ? 0 : func.length) - : nativeMax(newData[9] - length, 0); - - if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { - bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); - } - if (!bitmask || bitmask == WRAP_BIND_FLAG) { - var result = createBind(func, bitmask, thisArg); - } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { - result = createCurry(func, bitmask, arity); - } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { - result = createPartial(func, bitmask, thisArg, partials); - } else { - result = createHybrid.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setWrapToString(setter(result, newData), func, bitmask); - } - - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source - * objects into destination objects that are passed thru. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ - function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); - stack['delete'](srcValue); - } - return objValue; - } - - /** - * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain - * objects. - * - * @private - * @param {*} value The value to inspect. - * @param {string} key The key of the property to inspect. - * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. - */ - function customOmitClone(value) { - return isPlainObject(value) ? undefined : value; - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseRest` which flattens the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ - function flatRest(func) { - return setToString(overRest(func, undefined, flatten), func + ''); - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } - - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getHolder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; - } - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; - } - - /** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); - }; - - /** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Extracts wrapper details from the `source` body comment. - * - * @private - * @param {string} source The source to inspect. - * @returns {Array} Returns the wrapper details. - */ - function getWrapDetails(source) { - var match = source.match(reWrapDetails); - return match ? match[1].split(reSplitDetails) : []; - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case dataViewTag: - return cloneDataView(object, isDeep); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); - - case mapTag: - return new Ctor; - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - return cloneRegExp(object); - - case setTag: - return new Ctor; - - case symbolTag: - return cloneSymbol(object); - } - } - - /** - * Inserts wrapper `details` in a comment at the top of the `source` body. - * - * @private - * @param {string} source The source to modify. - * @returns {Array} details The details to insert. - * @returns {string} Returns the modified source. - */ - function insertWrapDetails(source, details) { - var length = details.length; - if (!length) { - return source; - } - var lastIndex = length - 1; - details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; - details = details.join(length > 2 ? ', ' : ' '); - return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); - } - - /** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ - function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; - } - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ - function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers used to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and - * `_.rearg` modify function arguments, making the order in which they are - * executed important, preventing the merging of metadata. However, we make - * an exception for a safe combined case where curried functions have `_.ary` - * and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); - - var isCombo = - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || - ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & WRAP_BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : value; - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = value; - } - // Use source `ary` if it's smaller. - if (srcBitmask & WRAP_ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString.call(value); - } - - /** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ - function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; - } - - /** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ - function parent(object, path) { - return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = copyArray(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity - * function to avoid garbage collection pauses in V8. See - * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = shortOut(baseSetData); - - /** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var setToString = shortOut(baseSetToString); - - /** - * Sets the `toString` method of `wrapper` to mimic the source of `reference` - * with wrapper details in a comment at the top of the source body. - * - * @private - * @param {Function} wrapper The function to modify. - * @param {Function} reference The reference function. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Function} Returns `wrapper`. - */ - function setWrapToString(wrapper, reference, bitmask) { - var source = (reference + ''); - return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); - } - - /** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ - function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; - } - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Updates wrapper `details` based on `bitmask` flags. - * - * @private - * @returns {Array} details The details to modify. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Array} Returns `details`. - */ - function updateWrapDetails(details, bitmask) { - arrayEach(wrapFlags, function(pair) { - var value = '_.' + pair[0]; - if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { - details.push(value); - } - }); - return details.sort(); - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `array` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array of chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array == null ? 0 : array.length; - if (!length || size < 1) { - return []; - } - var index = 0, - resIndex = 0, - result = Array(nativeCeil(length / size)); - - while (index < length) { - result[resIndex++] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - function concat() { - var length = arguments.length; - if (!length) { - return []; - } - var args = Array(length - 1), - array = arguments[0], - index = length; - - while (index--) { - args[index - 1] = arguments[index]; - } - return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); - } - - /** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ - var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; - }); - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ - function findIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, baseIteratee(predicate, 3), index); - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); - * // => 2 - * - * // The `_.matches` iteratee shorthand. - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastIndex(users, ['active', false]); - * // => 2 - * - * // The `_.property` iteratee shorthand. - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = length - 1; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = fromIndex < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1); - } - return baseFindIndex(array, baseIteratee(predicate, 3), index, true); - } - - /** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ - function flatten(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, 1) : []; - } - - /** - * Recursively flattens `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, [3, [4]], 5]]); - * // => [1, 2, 3, 4, 5] - */ - function flattenDeep(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, INFINITY) : []; - } - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ - function head(array) { - return (array && array.length) ? array[0] : undefined; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it's used as the - * offset from the end of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // Search from the `fromIndex`. - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - */ - function indexOf(array, value, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseIndexOf(array, value, index); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - var length = array == null ? 0 : array.length; - return length ? baseSlice(array, 0, -1) : []; - } - - /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersection([2, 1], [2, 3]); - * // => [2] - */ - var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; - }); - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array == null ? 0 : array.length; - return length ? array[length - 1] : undefined; - } - - /** - * Reverses `array` so that the first element becomes the last, the second - * element becomes the second to last, and so on. - * - * **Note:** This method mutates `array` and is based on - * [`Array#reverse`](https://mdn.io/Array/reverse). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.reverse(array); - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function reverse(array) { - return array == null ? array : nativeReverse.call(array); - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of - * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are - * returned. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - else { - start = start == null ? 0 : toInteger(start); - end = end === undefined ? length : toInteger(end); - } - return baseSlice(array, start, end); - } - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - if (!(array && array.length)) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ - var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each element - * is kept. The order of result values is determined by the order they occur - * in the array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ - function uniq(array) { - return (array && array.length) ? baseUniq(array) : []; - } - - /** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The order of result values is determined by the - * order they occur in the array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniqBy(array, iteratee) { - return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : []; - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); - } - - /** - * Creates an array excluding all given values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.pull`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.xor - * @example - * - * _.without([2, 1, 2, 3], 1, 2); - * // => [3] - */ - var without = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, values) - : []; - }); - - /** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ - var zip = baseRest(unzip); - - /** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - function zipObject(props, values) { - return baseZipObject(props || [], values || [], assignValue); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` wrapper instance that wraps `value` with explicit method - * chain sequences enabled. The result of such sequences must be unwrapped - * with `_#value`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Seq - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _ - * .chain(users) - * .sortBy('age') - * .map(function(o) { - * return o.user + ' is ' + o.age; - * }) - * .head() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor - * is invoked with one argument; (value). The purpose of this method is to - * "tap into" a method chain sequence in order to modify intermediate results. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * // Mutate input array. - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor) { - interceptor(value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * The purpose of this method is to "pass thru" values replacing intermediate - * results in a method chain sequence. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor) { - return interceptor(value); - } - - /** - * This method is the wrapper version of `_.at`. - * - * @name at - * @memberOf _ - * @since 1.0.0 - * @category Seq - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _(object).at(['a[0].b.c', 'a[1]']).value(); - * // => [3, 4] - */ - var wrapperAt = flatRest(function(paths) { - var length = paths.length, - start = length ? paths[0] : 0, - value = this.__wrapped__, - interceptor = function(object) { return baseAt(object, paths); }; - - if (length > 1 || this.__actions__.length || - !(value instanceof LazyWrapper) || !isIndex(start)) { - return this.thru(interceptor); - } - value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ - 'func': thru, - 'args': [interceptor], - 'thisArg': undefined - }); - return new LodashWrapper(value, this.__chain__).thru(function(array) { - if (length && !array.length) { - array.push(undefined); - } - return array; - }); - }); - - /** - * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. - * - * @name chain - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // A sequence without explicit chaining. - * _(users).head(); - * // => { 'user': 'barney', 'age': 36 } - * - * // A sequence with explicit chaining. - * _(users) - * .chain() - * .head() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chain sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Gets the next value on a wrapped object following the - * [iterator protocol](https://mdn.io/iteration_protocols#iterator). - * - * @name next - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the next iterator value. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped.next(); - * // => { 'done': false, 'value': 1 } - * - * wrapped.next(); - * // => { 'done': false, 'value': 2 } - * - * wrapped.next(); - * // => { 'done': true, 'value': undefined } - */ - function wrapperNext() { - if (this.__values__ === undefined) { - this.__values__ = toArray(this.value()); - } - var done = this.__index__ >= this.__values__.length, - value = done ? undefined : this.__values__[this.__index__++]; - - return { 'done': done, 'value': value }; - } - - /** - * Enables the wrapper to be iterable. - * - * @name Symbol.iterator - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the wrapper object. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped[Symbol.iterator]() === wrapped; - * // => true - * - * Array.from(wrapped); - * // => [1, 2] - */ - function wrapperToIterator() { - return this; - } - - /** - * Creates a clone of the chain sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @param {*} value The value to plant. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2]).map(square); - * var other = wrapped.plant([3, 4]); - * - * other.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - clone.__index__ = 0; - clone.__values__ = undefined; - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * This method is the wrapper version of `_.reverse`. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ - 'func': thru, - 'args': [reverse], - 'thisArg': undefined - }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(reverse); - } - - /** - * Executes the chain sequence to resolve the unwrapped value. - * - * @name value - * @memberOf _ - * @since 0.1.0 - * @alias toJSON, valueOf - * @category Seq - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the number of times the key was returned by `iteratee`. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': 1, '6': 2 } - * - * // The `_.property` iteratee shorthand. - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - ++result[key]; - } else { - baseAssignValue(result, key, 1); - } - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * Iteration is stopped once `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * **Note:** This method returns `true` for - * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because - * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of - * elements of empty collections. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.every(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, guard) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, baseIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - */ - function filter(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, baseIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ - var find = createFind(findIndex); - - /** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _.forEach([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, baseIteratee(iteratee, 3)); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - baseAssignValue(result, key, [value]); - } - }); - - /** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee) { - var func = isArray(collection) ? arrayMap : baseMap; - return func(collection, baseIteratee(iteratee, 3)); - } - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduce : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach); - } - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.filter - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * _.reject(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.reject(users, { 'age': 40, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.reject(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.reject(users, 'active'); - * // => objects for ['barney'] - */ - function reject(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, negate(baseIteratee(predicate, 3))); - } - - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - return isString(collection) ? stringSize(collection) : collection.length; - } - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - return baseKeys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * Iteration is stopped once `predicate` returns truthy. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.some(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, guard) { - var func = isArray(collection) ? arraySome : baseSome; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, baseIteratee(predicate, 3)); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection thru each iteratee. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The iteratees are invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to sort by. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.sortBy(users, [function(o) { return o.user; }]); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - * - * _.sortBy(users, ['user', 'age']); - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] - */ - var sortBy = baseRest(function(collection, iteratees) { - if (collection == null) { - return []; - } - var length = iteratees.length; - if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { - iteratees = []; - } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { - iteratees = [iteratees[0]]; - } - return baseOrderBy(collection, baseFlatten(iteratees, 1), []); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Gets the timestamp of the number of milliseconds that have elapsed since - * the Unix epoch (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Date - * @returns {number} Returns the timestamp. - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred invocation. - */ - var now = function() { - return root.Date.now(); - }; - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it's called `n` or more times. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => Logs 'done saving!' after the two async saves have completed. - */ - function after(n, func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it's called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery(element).on('click', _.before(5, addContactToList)); - * // => Allows adding up to 4 contacts to the list. - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and `partials` prepended to the arguments it receives. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * function greet(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // Bound with placeholders. - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = baseRest(function(func, thisArg, partials) { - var bitmask = WRAP_BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bind)); - bitmask |= WRAP_PARTIAL_FLAG; - } - return createWrap(func, bitmask, thisArg, partials, holders); - }); - - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed `func` invocations and a `flush` method to immediately invoke them. - * Provide `options` to indicate whether `func` should be invoked on the - * leading and/or trailing edge of the `wait` timeout. The `func` is invoked - * with the last arguments provided to the debounced function. Subsequent - * calls to the debounced function return the result of the last `func` - * invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the debounced function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=false] - * Specify invoking on the leading edge of the timeout. - * @param {number} [options.maxWait] - * The maximum time `func` is allowed to be delayed before it's invoked. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // Avoid costly calculations while the window size is in flux. - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // Invoke `sendMail` when clicked, debouncing subsequent calls. - * jQuery(element).on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // Ensure `batchLog` is invoked once after 1 second of debounced calls. - * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); - * var source = new EventSource('/stream'); - * jQuery(source).on('message', debounced); - * - * // Cancel the trailing debounced invocation. - * jQuery(window).on('popstate', debounced.cancel); - */ - function debounce(func, wait, options) { - var lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime, - lastInvokeTime = 0, - leading = false, - maxing = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject(options)) { - leading = !!options.leading; - maxing = 'maxWait' in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - - function invokeFunc(time) { - var args = lastArgs, - thisArg = lastThis; - - lastArgs = lastThis = undefined; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } - - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time; - // Start the timer for the trailing edge. - timerId = setTimeout(timerExpired, wait); - // Invoke the leading edge. - return leading ? invokeFunc(time) : result; - } - - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime, - timeWaiting = wait - timeSinceLastCall; - - return maxing - ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) - : timeWaiting; - } - - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime; - - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); - } - - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - // Restart the timer. - timerId = setTimeout(timerExpired, remainingWait(time)); - } - - function trailingEdge(time) { - timerId = undefined; - - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = undefined; - return result; - } - - function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = undefined; - } - - function flush() { - return timerId === undefined ? result : trailingEdge(now()); - } - - function debounced() { - var time = now(), - isInvoking = shouldInvoke(time); - - lastArgs = arguments; - lastThis = this; - lastCallTime = time; - - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime); - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === undefined) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // => Logs 'deferred' after one millisecond. - */ - var defer = baseRest(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => Logs 'later' after one second. - */ - var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber(wait) || 0, args); - }); - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Expose `MapCache`. - memoize.Cache = MapCache; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first invocation. The `func` is - * invoked with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // => `createApplication` is invoked once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as - * an array. - * - * **Note:** This method is based on the - * [rest parameter](https://mdn.io/rest_parameters). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.rest(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function rest(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? start : toInteger(start); - return baseRest(func, start); - } - - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed `func` invocations and a `flush` method to - * immediately invoke them. Provide `options` to indicate whether `func` - * should be invoked on the leading and/or trailing edge of the `wait` - * timeout. The `func` is invoked with the last arguments provided to the - * throttled function. Subsequent calls to the throttled function return the - * result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the throttled function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=true] - * Specify invoking on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // Avoid excessively updating the position while scrolling. - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); - * jQuery(element).on('click', throttled); - * - * // Cancel the trailing throttled invocation. - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { - 'leading': leading, - 'maxWait': wait, - 'trailing': trailing - }); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ - function clone(value) { - return baseClone(value, CLONE_SYMBOLS_FLAG); - } - - /** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ - function cloneDeep(value) { - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && baseGetTag(value) == boolTag); - } - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; - - /** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike(value) && - (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || - isBuffer(value) || isTypedArray(value) || isArguments(value))) { - return !value.length; - } - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { - return !value.size; - } - if (isPrototype(value)) { - return !baseKeys(value).length; - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return true; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on - * [`Number.isFinite`](https://mdn.io/Number/isFinite). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(3); - * // => true - * - * _.isFinite(Number.MIN_VALUE); - * // => true - * - * _.isFinite(Infinity); - * // => false - * - * _.isFinite('3'); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } - - /** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && baseGetTag(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; - } - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; - - /** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); - } - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Converts `value` to an array. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [1, 2] - * - * _.toArray('abc'); - * // => ['a', 'b', 'c'] - * - * _.toArray(1); - * // => [] - * - * _.toArray(null); - * // => [] - */ - function toArray(value) { - if (!value) { - return []; - } - if (isArrayLike(value)) { - return isString(value) ? stringToArray(value) : copyArray(value); - } - if (symIterator && value[symIterator]) { - return iteratorToArray(value[symIterator]()); - } - var tag = getTag(value), - func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); - - return func(value); - } - - /** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - - /** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ - function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; - } - - /** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ - function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /*------------------------------------------------------------------------*/ - - /** - * This method is like `_.assign` except that it iterates over own and - * inherited source properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assign - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assignIn({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } - */ - var assignIn = createAssigner(function(object, source) { - copyObject(source, keysIn(source), object); - }); - - /** - * Creates an object that inherits from the `prototype` object. If a - * `properties` object is given, its own enumerable string keyed properties - * are assigned to the created object. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties == null ? result : baseAssign(result, properties); - } - - /** - * Assigns own and inherited enumerable string keyed properties of source - * objects to the destination object for all destination properties that - * resolve to `undefined`. Source objects are applied from left to right. - * Once a property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaultsDeep - * @example - * - * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var defaults = baseRest(function(object, sources) { - object = Object(object); - - var index = -1; - var length = sources.length; - var guard = length > 2 ? sources[2] : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - length = 1; - } - - while (++index < length) { - var source = sources[index]; - var props = keysIn(source); - var propsIndex = -1; - var propsLength = props.length; - - while (++propsIndex < propsLength) { - var key = props[propsIndex]; - var value = object[key]; - - if (value === undefined || - (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { - object[key] = source[key]; - } - } - } - - return object; - }); - - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ - var defaultsDeep = baseRest(function(args) { - args.push(undefined, customDefaultsMerge); - return apply(mergeWith, undefined, args); - }); - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(o) { return o.age < 40; }); - * // => returns 'pebbles' assuming `_.findKey` returns 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate) { - return baseFindKey(object, baseIteratee(predicate, 3), baseForOwnRight); - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ - function has(object, path) { - return object != null && hasPath(object, path, baseHas); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite - * property assignments of previous values. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Object - * @param {Object} object The object to invert. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - */ - var invert = createInverter(function(result, value, key) { - if (value != null && - typeof value.toString != 'function') { - value = nativeObjectToString.call(value); - } - - result[value] = key; - }, constant(identity)); - - /** - * This method is like `_.invert` except that the inverted object is generated - * from the results of running each element of `object` thru `iteratee`. The - * corresponding inverted value of each inverted key is an array of keys - * responsible for generating the inverted value. The iteratee is invoked - * with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Object - * @param {Object} object The object to invert. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invertBy(object); - * // => { '1': ['a', 'c'], '2': ['b'] } - * - * _.invertBy(object, function(value) { - * return 'group' + value; - * }); - * // => { 'group1': ['a', 'c'], 'group2': ['b'] } - */ - var invertBy = createInverter(function(result, value, key) { - if (value != null && - typeof value.toString != 'function') { - value = nativeObjectToString.call(value); - } - - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - }, baseIteratee); - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with six arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ - var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); - }); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable property paths of `object` that are not omitted. - * - * **Note:** This method is considerably slower than `_.pick`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ - var omit = flatRest(function(object, paths) { - var result = {}; - if (object == null) { - return result; - } - var isDeep = false; - paths = arrayMap(paths, function(path) { - path = castPath(path, object); - isDeep || (isDeep = path.length > 1); - return path; - }); - copyObject(object, getAllKeysIn(object), result); - if (isDeep) { - result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); - } - var length = paths.length; - while (length--) { - baseUnset(result, paths[length]); - } - return result; - }); - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(baseIteratee(predicate))); - } - - /** - * Creates an object composed of the picked `object` properties. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pick(object, ['a', 'c']); - * // => { 'a': 1, 'c': 3 } - */ - var pick = flatRest(function(object, paths) { - return object == null ? {} : basePick(object, paths); - }); - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = baseIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); - } - - /** - * This method is like `_.get` except that if the resolved value is a - * function it's invoked with the `this` binding of its parent object and - * its result is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a[0].b.c3', 'default'); - * // => 'default' - * - * _.result(object, 'a[0].b.c3', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - path = castPath(path, object); - - var index = -1, - length = path.length; - - // Ensure the loop is entered when path is empty. - if (!length) { - length = 1; - object = undefined; - } - while (++index < length) { - var value = object == null ? undefined : object[toKey(path[index])]; - if (value === undefined) { - index = length; - value = defaultValue; - } - object = isFunction(value) ? value.call(object) : value; - } - return object; - } - - /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); - } - - /** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return object == null ? [] : baseValues(object, keys(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Clamps `number` within the inclusive `lower` and `upper` bounds. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Number - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - * @example - * - * _.clamp(-10, -5, 5); - * // => -5 - * - * _.clamp(10, -5, 5); - * // => 5 - */ - function clamp(number, lower, upper) { - if (upper === undefined) { - upper = lower; - lower = undefined; - } - if (upper !== undefined) { - upper = toNumber(upper); - upper = upper === upper ? upper : 0; - } - if (lower !== undefined) { - lower = toNumber(lower); - lower = lower === lower ? lower : 0; - } - return baseClamp(toNumber(number), lower, upper); - } - - /** - * Produces a random number between the inclusive `lower` and `upper` bounds. - * If only one argument is provided a number between `0` and the given number - * is returned. If `floating` is `true`, or either `lower` or `upper` are - * floats, a floating-point number is returned instead of an integer. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Number - * @param {number} [lower=0] The lower bound. - * @param {number} [upper=1] The upper bound. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(lower, upper, floating) { - if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { - upper = floating = undefined; - } - if (floating === undefined) { - if (typeof upper == 'boolean') { - floating = upper; - upper = undefined; - } - else if (typeof lower == 'boolean') { - floating = lower; - lower = undefined; - } - } - if (lower === undefined && upper === undefined) { - lower = 0; - upper = 1; - } - else { - lower = toFinite(lower); - if (upper === undefined) { - upper = lower; - lower = 0; - } else { - upper = toFinite(upper); - } - } - if (lower > upper) { - var temp = lower; - lower = upper; - upper = temp; - } - if (floating || lower % 1 || upper % 1) { - var rand = nativeRandom(); - return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); - } - return baseRandom(lower, upper); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts the characters "&", "<", ">", '"', and "'" in `string` to their - * corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional - * characters use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. See - * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * When working with HTML you should always - * [quote attribute values](http://wonko.com/post/html-escaping) to reduce - * XSS vectors. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - string = toString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Removes leading and trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trim(' abc '); - * // => 'abc' - * - * _.trim('-_-abc-_-', '_-'); - * // => 'abc' - * - * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar'] - */ - function trim(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrim, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - chrSymbols = stringToArray(chars), - start = charsStartIndex(strSymbols, chrSymbols), - end = charsEndIndex(strSymbols, chrSymbols) + 1; - - return castSlice(strSymbols, start, end).join(''); - } - - /** - * The inverse of `_.escape`; this method converts the HTML entities - * `&`, `<`, `>`, `"`, and `'` in `string` to - * their corresponding characters. - * - * **Note:** No other HTML entities are unescaped. To unescape additional - * HTML entities use a third-party library like [_he_](https://mths.be/he). - * - * @static - * @memberOf _ - * @since 0.6.0 - * @category String - * @param {string} [string=''] The string to unescape. - * @returns {string} Returns the unescaped string. - * @example - * - * _.unescape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function unescape(string) { - string = toString(string); - return (string && reHasEscapedHtml.test(string)) - ? string.replace(reEscapedHtml, unescapeHtmlChar) - : string; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ - function identity(value) { - return value; - } - - /** - * Creates a function that invokes `func` with the arguments of the created - * function. If `func` is a property name, the created function returns the - * property value for a given element. If `func` is an array or object, the - * created function returns `true` for elements that contain the equivalent - * source properties, otherwise it returns `false`. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Util - * @param {*} [func=_.identity] The value to convert to a callback. - * @returns {Function} Returns the callback. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); - * // => [{ 'user': 'barney', 'age': 36, 'active': true }] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, _.iteratee(['user', 'fred'])); - * // => [{ 'user': 'fred', 'age': 40 }] - * - * // The `_.property` iteratee shorthand. - * _.map(users, _.iteratee('user')); - * // => ['barney', 'fred'] - * - * // Create custom iteratee shorthands. - * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { - * return !_.isRegExp(func) ? iteratee(func) : function(string) { - * return func.test(string); - * }; - * }); - * - * _.filter(['abc', 'def'], /ef/); - * // => ['def'] - */ - function iteratee(func) { - return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG)); - } - - /** - * Creates a function that performs a partial deep comparison between a given - * object and `source`, returning `true` if the given object has equivalent - * property values, else `false`. - * - * **Note:** The created function is equivalent to `_.isMatch` with `source` - * partially applied. - * - * Partial comparisons will match empty array and empty object `source` - * values against any array or object value, respectively. See `_.isEqual` - * for a list of supported value comparisons. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - * @example - * - * var objects = [ - * { 'a': 1, 'b': 2, 'c': 3 }, - * { 'a': 4, 'b': 5, 'c': 6 } - * ]; - * - * _.filter(objects, _.matches({ 'a': 4, 'c': 6 })); - * // => [{ 'a': 4, 'b': 5, 'c': 6 }] - */ - function matches(source) { - return baseMatches(baseClone(source, CLONE_DEEP_FLAG)); - } - - /** - * Adds all own enumerable string keyed function properties of a source - * object to the destination object. If `object` is a function, then methods - * are added to its prototype as well. - * - * **Note:** Use `_.runInContext` to create a pristine `lodash` function to - * avoid conflicts caused by modifying the original. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {Function|Object} [object=lodash] The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.chain=true] Specify whether mixins are chainable. - * @returns {Function|Object} Returns `object`. - * @example - * - * function vowels(string) { - * return _.filter(string, function(v) { - * return /[aeiou]/i.test(v); - * }); - * } - * - * _.mixin({ 'vowels': vowels }); - * _.vowels('fred'); - * // => ['e'] - * - * _('fred').vowels().value(); - * // => ['e'] - * - * _.mixin({ 'vowels': vowels }, { 'chain': false }); - * _('fred').vowels(); - * // => ['e'] - */ - function mixin(object, source, options) { - var props = keys(source), - methodNames = baseFunctions(source, props); - - if (options == null && - !(isObject(source) && (methodNames.length || !props.length))) { - options = source; - source = object; - object = this; - methodNames = baseFunctions(source, keys(source)); - } - var chain = !(isObject(options) && 'chain' in options) || !!options.chain, - isFunc = isFunction(object); - - arrayEach(methodNames, function(methodName) { - var func = source[methodName]; - object[methodName] = func; - if (isFunc) { - object.prototype[methodName] = function() { - var chainAll = this.__chain__; - if (chain || chainAll) { - var result = object(this.__wrapped__), - actions = result.__actions__ = copyArray(this.__actions__); - - actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); - result.__chain__ = chainAll; - return result; - } - return func.apply(object, arrayPush([this.value()], arguments)); - }; - } - }); - - return object; - } - - /** - * Reverts the `_` variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - if (root._ === this) { - root._ = oldDash; - } - return this; - } - - /** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ - function noop() { - // No operation performed. - } - - /** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ - function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to, but not including, `end`. A step of `-1` is used if a negative - * `start` is specified without an `end` or `step`. If `end` is not specified, - * it's set to `start` with `start` then set to `0`. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the range of numbers. - * @see _.inRange, _.rangeRight - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(-4); - * // => [0, -1, -2, -3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - var range = createRange(); - - /** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ - function stubArray() { - return []; - } - - /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ - function stubFalse() { - return false; - } - - /** - * Generates a unique ID. If `prefix` is given, the ID is appended to it. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {string} [prefix=''] The value to prefix the ID with. - * @returns {string} Returns the unique ID. - * @example - * - * _.uniqueId('contact_'); - * // => 'contact_104' - * - * _.uniqueId(); - * // => '105' - */ - function uniqueId(prefix) { - var id = ++idCounter; - return toString(prefix) + id; - } - - /*------------------------------------------------------------------------*/ - - /** - * Computes the maximum value of `array`. If `array` is empty or falsey, - * `undefined` is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Math - * @param {Array} array The array to iterate over. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * _.max([]); - * // => undefined - */ - function max(array) { - return (array && array.length) - ? baseExtremum(array, identity, baseGt) - : undefined; - } - - /** - * Computes the minimum value of `array`. If `array` is empty or falsey, - * `undefined` is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Math - * @param {Array} array The array to iterate over. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * _.min([]); - * // => undefined - */ - function min(array) { - return (array && array.length) - ? baseExtremum(array, identity, baseLt) - : undefined; - } - - /*------------------------------------------------------------------------*/ - - // Add methods that return wrapped values in chain sequences. - lodash.after = after; - lodash.assignIn = assignIn; - lodash.before = before; - lodash.bind = bind; - lodash.chain = chain; - lodash.chunk = chunk; - lodash.compact = compact; - lodash.concat = concat; - lodash.countBy = countBy; - lodash.create = create; - lodash.debounce = debounce; - lodash.defaults = defaults; - lodash.defaultsDeep = defaultsDeep; - lodash.defer = defer; - lodash.delay = delay; - lodash.difference = difference; - lodash.drop = drop; - lodash.filter = filter; - lodash.flatten = flatten; - lodash.flattenDeep = flattenDeep; - lodash.groupBy = groupBy; - lodash.initial = initial; - lodash.intersection = intersection; - lodash.invert = invert; - lodash.invertBy = invertBy; - lodash.iteratee = iteratee; - lodash.keys = keys; - lodash.map = map; - lodash.matches = matches; - lodash.merge = merge; - lodash.mixin = mixin; - lodash.negate = negate; - lodash.omit = omit; - lodash.omitBy = omitBy; - lodash.once = once; - lodash.pick = pick; - lodash.pickBy = pickBy; - lodash.range = range; - lodash.reject = reject; - lodash.rest = rest; - lodash.set = set; - lodash.slice = slice; - lodash.sortBy = sortBy; - lodash.take = take; - lodash.takeRight = takeRight; - lodash.tap = tap; - lodash.throttle = throttle; - lodash.thru = thru; - lodash.toArray = toArray; - lodash.union = union; - lodash.uniq = uniq; - lodash.uniqBy = uniqBy; - lodash.unzip = unzip; - lodash.values = values; - lodash.without = without; - lodash.zip = zip; - lodash.zipObject = zipObject; - - // Add aliases. - lodash.extend = assignIn; - - // Add methods to `lodash.prototype`. - mixin(lodash, lodash); - - /*------------------------------------------------------------------------*/ - - // Add methods that return unwrapped values in chain sequences. - lodash.clamp = clamp; - lodash.clone = clone; - lodash.cloneDeep = cloneDeep; - lodash.escape = escape; - lodash.every = every; - lodash.find = find; - lodash.findIndex = findIndex; - lodash.findKey = findKey; - lodash.findLastIndex = findLastIndex; - lodash.findLastKey = findLastKey; - lodash.forEach = forEach; - lodash.get = get; - lodash.has = has; - lodash.head = head; - lodash.identity = identity; - lodash.indexOf = indexOf; - lodash.isArguments = isArguments; - lodash.isArray = isArray; - lodash.isArrayLike = isArrayLike; - lodash.isBoolean = isBoolean; - lodash.isDate = isDate; - lodash.isEmpty = isEmpty; - lodash.isEqual = isEqual; - lodash.isFinite = isFinite; - lodash.isFunction = isFunction; - lodash.isNaN = isNaN; - lodash.isNull = isNull; - lodash.isNumber = isNumber; - lodash.isObject = isObject; - lodash.isPlainObject = isPlainObject; - lodash.isRegExp = isRegExp; - lodash.isString = isString; - lodash.isUndefined = isUndefined; - lodash.last = last; - lodash.max = max; - lodash.min = min; - lodash.noConflict = noConflict; - lodash.noop = noop; - lodash.random = random; - lodash.reduce = reduce; - lodash.result = result; - lodash.size = size; - lodash.some = some; - lodash.trim = trim; - lodash.unescape = unescape; - lodash.uniqueId = uniqueId; - - // Add aliases. - lodash.each = forEach; - lodash.first = head; - - mixin(lodash, (function() { - var source = {}; - baseForOwn(lodash, function(func, methodName) { - if (!hasOwnProperty.call(lodash.prototype, methodName)) { - source[methodName] = func; - } - }); - return source; - }()), { 'chain': false }); - - /*------------------------------------------------------------------------*/ - - /** - * The semantic version number. - * - * @static - * @memberOf _ - * @type {string} - */ - lodash.VERSION = VERSION; - - // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. - arrayEach(['drop', 'take'], function(methodName, index) { - LazyWrapper.prototype[methodName] = function(n) { - n = n === undefined ? 1 : nativeMax(toInteger(n), 0); - - var result = (this.__filtered__ && !index) - ? new LazyWrapper(this) - : this.clone(); - - if (result.__filtered__) { - result.__takeCount__ = nativeMin(n, result.__takeCount__); - } else { - result.__views__.push({ - 'size': nativeMin(n, MAX_ARRAY_LENGTH), - 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') - }); - } - return result; - }; - - LazyWrapper.prototype[methodName + 'Right'] = function(n) { - return this.reverse()[methodName](n).reverse(); - }; - }); - - // Add `LazyWrapper` methods that accept an `iteratee` value. - arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { - var type = index + 1, - isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG; - - LazyWrapper.prototype[methodName] = function(iteratee) { - var result = this.clone(); - result.__iteratees__.push({ - 'iteratee': getIteratee(iteratee, 3), - 'type': type - }); - result.__filtered__ = result.__filtered__ || isFilter; - return result; - }; - }); - - // Add `LazyWrapper` methods for `_.head` and `_.last`. - arrayEach(['head', 'last'], function(methodName, index) { - var takeName = 'take' + (index ? 'Right' : ''); - - LazyWrapper.prototype[methodName] = function() { - return this[takeName](1).value()[0]; - }; - }); - - // Add `LazyWrapper` methods for `_.initial` and `_.tail`. - arrayEach(['initial', 'tail'], function(methodName, index) { - var dropName = 'drop' + (index ? '' : 'Right'); - - LazyWrapper.prototype[methodName] = function() { - return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); - }; - }); - - LazyWrapper.prototype.compact = function() { - return this.filter(identity); - }; - - LazyWrapper.prototype.find = function(predicate) { - return this.filter(predicate).head(); - }; - - LazyWrapper.prototype.findLast = function(predicate) { - return this.reverse().find(predicate); - }; - - LazyWrapper.prototype.invokeMap = baseRest(function(path, args) { - if (typeof path == 'function') { - return new LazyWrapper(this); - } - return this.map(function(value) { - return baseInvoke(value, path, args); - }); - }); - - LazyWrapper.prototype.reject = function(predicate) { - return this.filter(negate(getIteratee(predicate))); - }; - - LazyWrapper.prototype.slice = function(start, end) { - start = toInteger(start); - - var result = this; - if (result.__filtered__ && (start > 0 || end < 0)) { - return new LazyWrapper(result); - } - if (start < 0) { - result = result.takeRight(-start); - } else if (start) { - result = result.drop(start); - } - if (end !== undefined) { - end = toInteger(end); - result = end < 0 ? result.dropRight(-end) : result.take(end - start); - } - return result; - }; - - LazyWrapper.prototype.takeRightWhile = function(predicate) { - return this.reverse().takeWhile(predicate).reverse(); - }; - - LazyWrapper.prototype.toArray = function() { - return this.take(MAX_ARRAY_LENGTH); - }; - - // Add `LazyWrapper` methods to `lodash.prototype`. - baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), - isTaker = /^(?:head|last)$/.test(methodName), - lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName], - retUnwrapped = isTaker || /^find/.test(methodName); - - if (!lodashFunc) { - return; - } - lodash.prototype[methodName] = function() { - var value = this.__wrapped__, - args = isTaker ? [1] : arguments, - isLazy = value instanceof LazyWrapper, - iteratee = args[0], - useLazy = isLazy || isArray(value); - - var interceptor = function(value) { - var result = lodashFunc.apply(lodash, arrayPush([value], args)); - return (isTaker && chainAll) ? result[0] : result; - }; - - if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { - // Avoid lazy use if the iteratee has a "length" value other than `1`. - isLazy = useLazy = false; - } - var chainAll = this.__chain__, - isHybrid = !!this.__actions__.length, - isUnwrapped = retUnwrapped && !chainAll, - onlyLazy = isLazy && !isHybrid; - - if (!retUnwrapped && useLazy) { - value = onlyLazy ? value : new LazyWrapper(this); - var result = func.apply(value, args); - result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); - return new LodashWrapper(result, chainAll); - } - if (isUnwrapped && onlyLazy) { - return func.apply(this, args); - } - result = this.thru(interceptor); - return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result; - }; - }); - - // Add `Array` methods to `lodash.prototype`. - arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { - var func = arrayProto[methodName], - chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', - retUnwrapped = /^(?:pop|shift)$/.test(methodName); - - lodash.prototype[methodName] = function() { - var args = arguments; - if (retUnwrapped && !this.__chain__) { - var value = this.value(); - return func.apply(isArray(value) ? value : [], args); - } - return this[chainName](function(value) { - return func.apply(isArray(value) ? value : [], args); - }); - }; - }); - - // Map minified method names to their real names. - baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var lodashFunc = lodash[methodName]; - if (lodashFunc) { - var key = (lodashFunc.name + ''), - names = realNames[key] || (realNames[key] = []); - - names.push({ 'name': methodName, 'func': lodashFunc }); - } - }); - - realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{ - 'name': 'wrapper', - 'func': undefined - }]; - - // Add methods to `LazyWrapper`. - LazyWrapper.prototype.clone = lazyClone; - LazyWrapper.prototype.reverse = lazyReverse; - LazyWrapper.prototype.value = lazyValue; - - // Add lazy aliases. - lodash.prototype.first = lodash.prototype.head; - - if (symIterator) { - lodash.prototype[symIterator] = wrapperToIterator; - } - - /*--------------------------------------------------------------------------*/ - - // Some AMD build optimizers, like r.js, check for condition patterns like: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose Lodash on the global object to prevent errors when Lodash is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - // Use `_.noConflict` to remove Lodash from the global object. - root._ = lodash; - - // Define as an anonymous module so, through path mapping, it can be - // referenced as the "underscore" module. - define(function() { - return lodash; - }); - } - // Check for `exports` after `define` in case a build optimizer adds it. - else if (freeModule) { - // Export for Node.js. - (freeModule.exports = lodash)._ = lodash; - // Export for CommonJS support. - freeExports._ = lodash; - } - else { - // Export to the global object. - BI._ = lodash; - } -}.call(this)); diff --git a/src/core/2.base.js b/src/core/2.base.js deleted file mode 100644 index ba7bc06b2..000000000 --- a/src/core/2.base.js +++ /dev/null @@ -1,1293 +0,0 @@ -/** - * 基本函数 - * Create By GUY 2014\11\17 - * - */ -!(function (undefined) { - var traverse = function (func, context) { - return function (value, key, obj) { - return func.call(context, key, value, obj); - }; - }; - var _apply = function (name) { - return function () { - return BI._[name].apply(BI._, arguments); - }; - }; - var _applyFunc = function (name) { - return function () { - var args = Array.prototype.slice.call(arguments, 0); - args[1] = BI._.isFunction(args[1]) ? traverse(args[1], args[2]) : args[1]; - return BI._[name].apply(BI._, args); - }; - }; - - // Utility - BI._.extend(BI, { - assert: function (v, is) { - if (this.isFunction(is)) { - if (!is(v)) { - throw new Error(v + " error"); - } else { - return true; - } - } - if (!this.isArray(is)) { - is = [is]; - } - if (!this.deepContains(is, v)) { - throw new Error(v + " error"); - } - return true; - }, - - warn: function (message) { - console.warn(message); - }, - - UUID: function () { - var f = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; - var str = ""; - for (var i = 0; i < 16; i++) { - var r = parseInt(f.length * Math.random(), 10); - str += f[r]; - } - return str; - }, - - isWidget: function (widget) { - return widget instanceof BI.Widget; - }, - - createWidgets: function (items, options, context) { - if (!BI.isArray(items)) { - throw new Error("items must be array", items); - } - if (BI.isWidget(options)) { - context = options; - options = {}; - } else { - options || (options = {}); - } - return BI.map(BI.flatten(items), function (i, item) { - return BI.createWidget(item, BI.deepClone(options), context); - }); - }, - - createItems: function (data, innerAttr, outerAttr) { - innerAttr = BI.isArray(innerAttr) ? innerAttr : BI.makeArray(BI.flatten(data).length, innerAttr || {}); - outerAttr = BI.isArray(outerAttr) ? outerAttr : BI.makeArray(BI.flatten(data).length, outerAttr || {}); - return BI.map(data, function (i, item) { - if (BI.isArray(item)) { - return BI.createItems(item, innerAttr, outerAttr); - } - if (item instanceof BI.Widget) { - return BI.extend({}, innerAttr.shift(), outerAttr.shift(), { - type: null, - el: item - }); - } - if (innerAttr[0] instanceof BI.Widget) { - outerAttr.shift(); - return BI.extend({}, item, { - el: innerAttr.shift() - }); - } - if (item.el instanceof BI.Widget) { - innerAttr.shift(); - return BI.extend({}, outerAttr.shift(), { type: null }, item); - } - if (item.el) { - return BI.extend({}, outerAttr.shift(), item, { - el: BI.extend({}, innerAttr.shift(), item.el) - }); - } - return BI.extend({}, outerAttr.shift(), { - el: BI.extend({}, innerAttr.shift(), item) - }); - }); - }, - - // 用容器包装items - packageItems: function (items, layouts) { - for (var i = layouts.length - 1; i >= 0; i--) { - items = BI.map(items, function (k, it) { - return BI.extend({}, layouts[i], { - items: [ - BI.extend({}, layouts[i].el, { - el: it - }) - ] - }); - }); - } - return items; - }, - - formatEL: function (obj) { - if (obj && !obj.type && obj.el) { - return obj; - } - return { - el: obj - }; - }, - - // 剥开EL - stripEL: function (obj) { - return obj.type && obj || obj.el || obj; - }, - - trans2Element: function (widgets) { - return BI.map(widgets, function (i, wi) { - return wi.element; - }); - } - }); - - // 集合相关方法 - BI._.each(["where", "findWhere", "invoke", "pluck", "shuffle", "sample", "toArray", "size"], function (name) { - BI[name] = _apply(name); - }); - BI._.each([ - "get", "set", "each", "map", "reduce", "reduceRight", "find", "filter", "reject", "every", "all", "some", "any", "max", "min", - "sortBy", "groupBy", "indexBy", "countBy", "partition", "clamp" - ], function (name) { - if (name === "any") { - BI[name] = _applyFunc("some"); - } else { - BI[name] = _applyFunc(name); - } - }); - BI._.extend(BI, { - // 数数 - count: function (from, to, predicate) { - var t; - if (predicate) { - for (t = from; t < to; t++) { - predicate(t); - } - } - return to - from; - }, - - // 倒数 - inverse: function (from, to, predicate) { - return BI.count(to, from, predicate); - }, - - firstKey: function (obj) { - var res = undefined; - BI.any(obj, function (key, value) { - res = key; - return true; - }); - return res; - }, - - lastKey: function (obj) { - var res = undefined; - BI.each(obj, function (key, value) { - res = key; - return true; - }); - return res; - }, - - firstObject: function (obj) { - var res = undefined; - BI.any(obj, function (key, value) { - res = value; - return true; - }); - return res; - }, - - lastObject: function (obj) { - var res = undefined; - BI.each(obj, function (key, value) { - res = value; - return true; - }); - return res; - }, - - concat: function (obj1, obj2) { - if (BI.isKey(obj1)) { - return BI.map([].slice.apply(arguments), function (idx, v) { - return v; - }).join(""); - } - if (BI.isArray(obj1)) { - return BI._.concat.apply([], arguments); - } - if (BI.isObject(obj1)) { - return BI._.extend.apply({}, arguments); - } - }, - - backEach: function (obj, predicate, context) { - predicate = BI.iteratee(predicate, context); - for (var index = obj.length - 1; index >= 0; index--) { - predicate(index, obj[index], obj); - } - return false; - }, - - backAny: function (obj, predicate, context) { - predicate = BI.iteratee(predicate, context); - for (var index = obj.length - 1; index >= 0; index--) { - if (predicate(index, obj[index], obj)) { - return true; - } - } - return false; - }, - - backEvery: function (obj, predicate, context) { - predicate = BI.iteratee(predicate, context); - for (var index = obj.length - 1; index >= 0; index--) { - if (!predicate(index, obj[index], obj)) { - return false; - } - } - return true; - }, - - backFindKey: function (obj, predicate, context) { - predicate = BI.iteratee(predicate, context); - var keys = BI._.keys(obj), key; - for (var i = keys.length - 1; i >= 0; i--) { - key = keys[i]; - if (predicate(obj[key], key, obj)) { - return key; - } - } - }, - - backFind: function (obj, predicate, context) { - var key; - if (BI.isArray(obj)) { - key = BI.findLastIndex(obj, predicate, context); - } else { - key = BI.backFindKey(obj, predicate, context); - } - if (key !== void 0 && key !== -1) { - return obj[key]; - } - }, - - remove: function (obj, target, context) { - var isFunction = BI.isFunction(target); - target = isFunction || BI.isArray(target) ? target : [target]; - var i; - if (BI.isArray(obj)) { - for (i = 0; i < obj.length; i++) { - if ((isFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || (!isFunction && BI.contains(target, obj[i]))) { - obj.splice(i--, 1); - } - } - } else { - BI.each(obj, function (i, v) { - if ((isFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || (!isFunction && BI.contains(target, obj[i]))) { - delete obj[i]; - } - }); - } - }, - - removeAt: function (obj, index) { - index = BI.isArray(index) ? index : [index]; - var isArray = BI.isArray(obj), i; - for (i = 0; i < index.length; i++) { - if (isArray) { - obj[index[i]] = "$deleteIndex"; - } else { - delete obj[index[i]]; - } - } - if (isArray) { - BI.remove(obj, "$deleteIndex"); - } - }, - - string2Array: function (str) { - return str.split("&-&"); - }, - - array2String: function (array) { - return array.join("&-&"); - }, - - abc2Int: function (str) { - var idx = 0, start = "A", str = str.toUpperCase(); - for (var i = 0, len = str.length; i < len; ++i) { - idx = str.charAt(i).charCodeAt(0) - start.charCodeAt(0) + 26 * idx + 1; - if (idx > (2147483646 - str.charAt(i).charCodeAt(0) + start.charCodeAt(0)) / 26) { - return 0; - } - } - return idx; - }, - - int2Abc: function (num) { - var DIGITS = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; - var idx = num, str = ""; - if (num === 0) { - return ""; - } - while (idx !== 0) { - var t = idx % 26; - if (t === 0) { - t = 26; - } - str = DIGITS[t - 1] + str; - idx = (idx - t) / 26; - } - return str; - } - }); - - // 数组相关的方法 - BI._.each([ - "first", "initial", "last", "rest", "compact", "flatten", "without", "union", "intersection", - "difference", "zip", "unzip", "object", "indexOf", "lastIndexOf", "sortedIndex", "range", "take", "takeRight", "uniqBy" - ], function (name) { - BI[name] = _apply(name); - }); - BI._.each(["findIndex", "findLastIndex"], function (name) { - BI[name] = _applyFunc(name); - }); - BI._.extend(BI, { - // 构建一个长度为length的数组 - makeArray: function (length, value) { - var res = []; - for (var i = 0; i < length; i++) { - if (BI.isNull(value)) { - res.push(i); - } else { - res.push(BI.deepClone(value)); - } - } - return res; - }, - - makeObject: function (array, value) { - var map = {}; - for (var i = 0; i < array.length; i++) { - if (BI.isNull(value)) { - map[array[i]] = array[i]; - } else if (BI.isFunction(value)) { - map[array[i]] = value(i, array[i]); - } else { - map[array[i]] = BI.deepClone(value); - } - } - return map; - }, - - makeArrayByArray: function (array, value) { - var res = []; - if (!array) { - return res; - } - for (var i = 0, len = array.length; i < len; i++) { - if (BI.isArray(array[i])) { - res.push(BI.makeArrayByArray(array[i], value)); - } else { - res.push(BI.deepClone(value)); - } - } - return res; - }, - - uniq: function (array, isSorted, iteratee, context) { - if (array == null) { - return []; - } - if (!BI._.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - iteratee && (iteratee = traverse(iteratee, context)); - return BI._.uniq.call(BI._, array, isSorted, iteratee, context); - } - }); - - // 对象相关方法 - BI._.each([ - "keys", "allKeys", "values", "pairs", "invert", "create", "functions", "extend", "extendOwn", - "defaults", "clone", "property", "propertyOf", "matcher", "isEqual", "isMatch", "isEmpty", - "isElement", "isNumber", "isString", "isArray", "isObject", "isPlainObject", "isArguments", "isFunction", "isFinite", - "isBoolean", "isDate", "isRegExp", "isError", "isNaN", "isUndefined", "zipObject", "cloneDeep" - ], function (name) { - BI[name] = _apply(name); - }); - BI._.each(["mapObject", "findKey", "pick", "omit", "tap"], function (name) { - BI[name] = _applyFunc(name); - }); - BI._.extend(BI, { - - inherit: function (sp, overrides) { - var sb = function () { - return sp.apply(this, arguments); - }; - var F = function () { - }, spp = sp.prototype; - F.prototype = spp; - sb.prototype = new F(); - sb.superclass = spp; - BI._.extend(sb.prototype, overrides, { - superclass: sp - }); - return sb; - }, - - init: function () { - // 先把准备环境准备好 - while (BI.prepares && BI.prepares.length > 0) { - BI.prepares.shift()(); - } - while (_global.___fineuiExposedFunction && _global.___fineuiExposedFunction.length > 0) { - _global.___fineuiExposedFunction.shift()(); - } - BI.initialized = true; - }, - - has: function (obj, keys) { - if (BI.isArray(keys)) { - if (keys.length === 0) { - return false; - } - return BI.every(keys, function (i, key) { - return BI._.has(obj, key); - }); - } - return BI._.has.apply(BI._, arguments); - }, - - freeze: function (value) { - // 在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 TypeError - // 在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回 - if (Object.freeze && BI.isObject(value)) { - return Object.freeze(value); - } - return value; - }, - - // 数字和字符串可以作为key - isKey: function (key) { - return BI.isNumber(key) || (BI.isString(key) && key.length > 0); - }, - - // 忽略大小写的等于 - isCapitalEqual: function (a, b) { - a = BI.isNull(a) ? a : ("" + a).toLowerCase(); - b = BI.isNull(b) ? b : ("" + b).toLowerCase(); - return BI.isEqual(a, b); - }, - - isWidthOrHeight: function (w) { - if (typeof w === "number") { - return w >= 0; - } else if (typeof w === "string") { - return /^\d{1,3}(\.\d)?%$/.test(w) || w === "auto" || /^\d+(\.\d+)?px$/.test(w) || /^calc/.test(w); - } - }, - - isNotNull: function (obj) { - return !BI.isNull(obj); - }, - - isNull: function (obj) { - return typeof obj === "undefined" || obj === null; - }, - - isEmptyArray: function (arr) { - return BI.isArray(arr) && BI.isEmpty(arr); - }, - - isNotEmptyArray: function (arr) { - return BI.isArray(arr) && !BI.isEmpty(arr); - }, - - isEmptyObject: function (obj) { - return BI.isEqual(obj, {}); - }, - - isNotEmptyObject: function (obj) { - return BI.isPlainObject(obj) && !BI.isEmptyObject(obj); - }, - - isEmptyString: function (obj) { - return BI.isString(obj) && obj.length === 0; - }, - - isNotEmptyString: function (obj) { - return BI.isString(obj) && !BI.isEmptyString(obj); - }, - - isWindow: function (obj) { - return obj != null && obj == obj.window; - }, - - isPromise: function (obj) { - return !!obj && (BI.isObject(obj) || BI.isFunction(obj)) && BI.isFunction(obj.then); - } - }); - - // deep方法 - BI._.extend(BI, { - deepClone: BI._.cloneDeep, - deepExtend: BI._.merge, - - isDeepMatch: function (object, attrs) { - var keys = BI.keys(attrs), length = keys.length; - if (object == null) { - return !length; - } - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = keys[i]; - if (!BI.isEqual(attrs[key], obj[key]) || !(key in obj)) { - return false; - } - } - return true; - }, - - contains: function (obj, target, fromIndex) { - if (!BI._.isArrayLike(obj)) obj = BI._.values(obj); - return BI._.indexOf(obj, target, typeof fromIndex === "number" && fromIndex) >= 0; - }, - - deepContains: function (obj, copy) { - if (BI.isObject(copy)) { - return BI.any(obj, function (i, v) { - if (BI.isEqual(v, copy)) { - return true; - } - }); - } - return BI.contains(obj, copy); - }, - - deepIndexOf: function (obj, target) { - for (var i = 0; i < obj.length; i++) { - if (BI.isEqual(target, obj[i])) { - return i; - } - } - return -1; - }, - - deepRemove: function (obj, target) { - var done = false; - var i; - if (BI.isArray(obj)) { - for (i = 0; i < obj.length; i++) { - if (BI.isEqual(target, obj[i])) { - obj.splice(i--, 1); - done = true; - } - } - } else { - BI.each(obj, function (i, v) { - if (BI.isEqual(target, obj[i])) { - delete obj[i]; - done = true; - } - }); - } - return done; - }, - - deepWithout: function (obj, target) { - if (BI.isArray(obj)) { - var result = []; - for (var i = 0; i < obj.length; i++) { - if (!BI.isEqual(target, obj[i])) { - result.push(obj[i]); - } - } - return result; - } - var result = {}; - BI.each(obj, function (i, v) { - if (!BI.isEqual(target, obj[i])) { - result[i] = v; - } - }); - return result; - - }, - - deepUnique: function (array) { - var result = []; - BI.each(array, function (i, item) { - if (!BI.deepContains(result, item)) { - result.push(item); - } - }); - return result; - }, - - // 比较两个对象得出不一样的key值 - deepDiff: function (object, other) { - object || (object = {}); - other || (other = {}); - var result = []; - var used = []; - for (var b in object) { - if (BI.has(object, b)) { - if (!BI.isEqual(object[b], other[b])) { - result.push(b); - } - used.push(b); - } - } - for (var b in other) { - if (BI.has(other, b) && !BI.contains(used, b)) { - result.push(b); - } - } - return result; - } - }); - - // 通用方法 - BI._.each(["uniqueId", "result", "chain", "iteratee", "escape", "unescape", "before", "after", "chunk"], function (name) { - BI[name] = function () { - return BI._[name].apply(BI._, arguments); - }; - }); - - // 事件相关方法 - BI._.each(["bind", "once", "partial", "debounce", "throttle", "delay", "defer", "wrap"], function (name) { - BI[name] = function () { - return BI._[name].apply(BI._, arguments); - }; - }); - - BI._.extend(BI, { - nextTick: (function () { - var callbacks = []; - var pending = false; - var timerFunc = void 0; - - function nextTickHandler() { - pending = false; - var copies = callbacks.slice(0); - callbacks.length = 0; - for (var i = 0; i < copies.length; i++) { - copies[i](); - } - } - - if (typeof Promise !== "undefined") { - var p = Promise.resolve(); - timerFunc = function timerFunc() { - p.then(nextTickHandler); - }; - } else if (typeof MutationObserver !== "undefined") { - var counter = 1; - var observer = new MutationObserver(nextTickHandler); - var textNode = document.createTextNode(String(counter)); - observer.observe(textNode, { - characterData: true - }); - timerFunc = function timerFunc() { - counter = (counter + 1) % 2; - textNode.data = String(counter); - }; - } else if (typeof setImmediate !== "undefined") { - timerFunc = function timerFunc() { - setImmediate(nextTickHandler); - }; - } else { - // Fallback to setTimeout. - timerFunc = function timerFunc() { - setTimeout(nextTickHandler, 0); - }; - } - - return function queueNextTick(cb) { - var _resolve = void 0; - var args = [].slice.call(arguments, 1); - callbacks.push(function () { - if (cb) { - try { - cb.apply(null, args); - } catch (e) { - console.error(e); - } - } else if (_resolve) { - _resolve.apply(null, args); - } - }); - if (!pending) { - pending = true; - timerFunc(); - } - // $flow-disable-line - if (!cb && typeof Promise !== 'undefined') { - return new Promise(function (resolve, reject) { - _resolve = resolve; - }); - } - }; - })() - }); - - // 数字相关方法 - BI._.each(["random"], function (name) { - BI[name] = _apply(name); - }); - BI._.extend(BI, { - - parseInt: function (number) { - var radix = 10; - if (/^0x/g.test(number)) { - radix = 16; - } - try { - return parseInt(number, radix); - } catch (e) { - throw new Error(number + "parse int error"); - return NaN; - } - }, - - parseSafeInt: function (value) { - var MAX_SAFE_INTEGER = 9007199254740991; - return value - ? this.clamp(this.parseInt(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) - : (value === 0 ? value : 0); - }, - - parseFloat: function (number) { - try { - return parseFloat(number); - } catch (e) { - throw new Error(number + "parse float error"); - return NaN; - } - }, - - isNaturalNumber: function (number) { - if (/^\d+$/.test(number)) { - return true; - } - return false; - }, - - isPositiveInteger: function (number) { - if (/^\+?[1-9][0-9]*$/.test(number)) { - return true; - } - return false; - }, - - isNegativeInteger: function (number) { - if (/^\-[1-9][0-9]*$/.test(number)) { - return true; - } - return false; - }, - - isInteger: function (number) { - if (/^\-?\d+$/.test(number)) { - return true; - } - return false; - }, - - isNumeric: function (number) { - return !isNaN(parseFloat(number)) && isFinite(number); - }, - - isFloat: function (number) { - if (/^([+-]?)\d*\.\d+$/.test(number)) { - return true; - } - return false; - }, - - isOdd: function (number) { - if (!BI.isInteger(number)) { - return false; - } - return (number & 1) === 1; - }, - - isEven: function (number) { - if (!BI.isInteger(number)) { - return false; - } - return (number & 1) === 0; - }, - - sum: function (array, iteratee, context) { - var sum = 0; - BI.each(array, function (i, item) { - if (iteratee) { - sum += Number(iteratee.apply(context, [i, item])); - } else { - sum += Number(item); - } - }); - return sum; - }, - - average: function (array, iteratee, context) { - var sum = BI.sum(array, iteratee, context); - return sum / array.length; - } - }); - - // 字符串相关方法 - BI._.extend(BI, { - trim: function () { - return BI._.trim.apply(BI._, arguments); - }, - - toUpperCase: function (string) { - return (string + "").toLocaleUpperCase(); - }, - - toLowerCase: function (string) { - return (string + "").toLocaleLowerCase(); - }, - - isEndWithBlank: function (string) { - return /(\s|\u00A0)$/.test(string); - }, - - isLiteral: function (exp) { - var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/; - return literalValueRE.test(exp); - }, - - stripQuotes: function (str) { - var a = str.charCodeAt(0); - var b = str.charCodeAt(str.length - 1); - return a === b && (a === 0x22 || a === 0x27) - ? str.slice(1, -1) - : str; - }, - - // background-color => backgroundColor - camelize: function (str) { - return str.replace(/-(.)/g, function (_, character) { - return character.toUpperCase(); - }); - }, - - // backgroundColor => background-color - hyphenate: function (str) { - return str.replace(/([A-Z])/g, "-$1").toLowerCase(); - }, - - isNotEmptyString: function (str) { - return BI.isString(str) && !BI.isEmpty(str); - }, - - isEmptyString: function (str) { - return BI.isString(str) && BI.isEmpty(str); - }, - - /** - * 通用加密方法 - */ - encrypt: function (type, text, key) { - switch (type) { - case BI.CRYPT_TYPE.AES: - default: - return BI.aesEncrypt(text, key); - } - }, - - /** - * 通用解密方法 - * @param type 解密方式 - * @param text 文本 - * @param key 种子 - * @return {*} - */ - decrypt: function (type, text, key) { - switch (type) { - case BI.CRYPT_TYPE.AES: - default: - return BI.aesDecrypt(text, key); - } - }, - - /** - * 对字符串中的'和\做编码处理 - * @static - * @param {String} string 要做编码处理的字符串 - * @return {String} 编码后的字符串 - */ - escape: function (string) { - return string.replace(/('|\\)/g, "\\$1"); - }, - - /** - * 让字符串通过指定字符做补齐的函数 - * - * var s = BI.leftPad('123', 5, '0');//s的值为:'00123' - * - * @static - * @param {String} val 原始值 - * @param {Number} size 总共需要的位数 - * @param {String} ch 用于补齐的字符 - * @return {String} 补齐后的字符串 - */ - leftPad: function (val, size, ch) { - var result = String(val); - if (!ch) { - ch = " "; - } - while (result.length < size) { - result = ch + result; - } - return result.toString(); - }, - - /** - * 对字符串做替换的函数 - * - * var cls = 'my-class', text = 'Some text'; - * var res = BI.format('
    {1}
    ', cls, text); - * //res的值为:'
    Some text
    '; - * - * @static - * @param {String} format 要做替换的字符串,替换字符串1,替换字符串2... - * @return {String} 做了替换后的字符串 - */ - format: function (format) { - var args = Array.prototype.slice.call(arguments, 1); - return format.replace(/\{(\d+)\}/g, function (m, i) { - return args[i]; - }); - } - }); - - // 日期相关方法 - BI._.extend(BI, { - /** - * 是否是闰年 - * @param year - * @returns {boolean} - */ - isLeapYear: function (year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - }, - - /** - * 检测是否在有效期 - * - * @param YY 年 - * @param MM 月 - * @param DD 日 - * @param minDate '1900-01-01' - * @param maxDate '2099-12-31' - * @returns {Array} 若无效返回无效状态,数组第一位为无效属性,第二位缺省为超下限,1为超上限 - */ - checkDateVoid: function (YY, MM, DD, minDate, maxDate) { - var back = []; - YY = YY | 0; - MM = MM | 0; - DD = DD | 0; - minDate = BI.isString(minDate) ? minDate.match(/\d+/g) : minDate; - maxDate = BI.isString(maxDate) ? maxDate.match(/\d+/g) : maxDate; - if (YY < minDate[0]) { - back = ["y"]; - } else if (YY > maxDate[0]) { - back = ["y", 1]; - } else if (YY >= minDate[0] && YY <= maxDate[0]) { - if (YY == minDate[0]) { - if (MM < minDate[1]) { - back = ["m"]; - } else if (MM == minDate[1]) { - if (DD < minDate[2]) { - back = ["d"]; - } - } - } - if (YY == maxDate[0]) { - if (MM > maxDate[1]) { - back = ["m", 1]; - } else if (MM == maxDate[1]) { - if (DD > maxDate[2]) { - back = ["d", 1]; - } - } - } - } - return back; - }, - - checkDateLegal: function (str) { - var ar = str.match(/\d+/g); - var YY = ar[0] | 0, MM = ar[1] | 0, DD = ar[2] | 0; - if (ar.length <= 1) { - return true; - } - if (ar.length <= 2) { - return MM >= 1 && MM <= 12; - } - var MD = BI.Date._MD.slice(0); - MD[1] = BI.isLeapYear(YY) ? 29 : 28; - return MM >= 1 && MM <= 12 && DD <= MD[MM - 1]; - }, - - /** 解析日期时间字符串 - * - * @param str - * @param fmt - * @returns {Date|Date} - * 年月日缺省值为当前日期, 时分秒缺省值为0 - */ - parseDateTime: function (str, fmt) { - var today = BI.getDate(); - var y; - var m; - var d; - // wei : 对于fmt为‘YYYYMM’或者‘YYYYMMdd’的格式,str的值为类似'201111'的形式,因为年月之间没有分隔符,所以正则表达式分割无效,导致bug7376。 - var a = str.split(/\W+/); - if (fmt.toLowerCase() == "%y%x" || fmt.toLowerCase() == "%y%x%d") { - var yearlength = 4; - var otherlength = 2; - a[0] = str.substring(0, yearlength); - a[1] = str.substring(yearlength, yearlength + otherlength); - a[2] = str.substring(yearlength + otherlength, yearlength + otherlength * 2); - } - var b = fmt.match(/%./g); - var i = 0, j = 0; - var hr = 0; - var min = 0; - var sec = 0; - for (i = 0; i < a.length; ++i) { - switch (b[i]) { - case "%d": - case "%e": - d = parseInt(a[i], 10); - break; - - case "%X": - m = parseInt(a[i], 10) - 1; - break; - case "%x": - m = parseInt(a[i], 10) - 1; - break; - - case "%Y": - case "%y": - y = parseInt(a[i], 10); - (y < 100) && (y += (y > 29) ? 1900 : 2000); - break; - - case "%b": - case "%B": - for (j = 0; j < 12; ++j) { - if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { - m = j; - break; - } - } - break; - - case "%H": - case "%I": - case "%k": - case "%l": - hr = parseInt(a[i], 10); - break; - - case "%P": - case "%p": - if (/pm/i.test(a[i]) && hr < 12) { - hr += 12; - } else if (/am/i.test(a[i]) && hr >= 12) { - hr -= 12; - } - break; - case "%Q": - case "%q": - m = (parseInt(a[i], 10) - 1) * 3; - break; - case "%M": - min = parseInt(a[i], 10); - break; - case "%S": - sec = parseInt(a[i], 10); - break; - } - } - // if (!a[i]) { - // continue; - // } - if (isNaN(y)) { - y = today.getFullYear(); - } - if (isNaN(m)) { - m = today.getMonth(); - } - if (isNaN(d)) { - d = Math.min(BI.getMonthDays(BI.getDate(y, m)), today.getDate()); - } - if (isNaN(hr)) { - hr = today.getHours(); - } - if (isNaN(min)) { - min = today.getMinutes(); - } - if (isNaN(sec)) { - sec = today.getSeconds(); - } - if (y != 0) { - return BI.getDate(y, m, d, hr, min, sec); - } - y = 0; - m = -1; - d = 0; - for (i = 0; i < a.length; ++i) { - if (a[i].search(/[a-zA-Z]+/) != -1) { - var t = -1; - for (j = 0; j < 12; ++j) { - if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { - t = j; - break; - } - } - if (t != -1) { - if (m != -1) { - d = m + 1; - } - m = t; - } - } else if (parseInt(a[i], 10) <= 12 && m == -1) { - m = a[i] - 1; - } else if (parseInt(a[i], 10) > 31 && y == 0) { - y = parseInt(a[i], 10); - (y < 100) && (y += (y > 29) ? 1900 : 2000); - } else if (d == 0) { - d = a[i]; - } - } - if (y == 0) { - y = today.getFullYear(); - } - if (m === -1) { - m = today.getMonth(); - } - if (m != -1 && d != 0) { - return BI.getDate(y, m, d, hr, min, sec); - } - return today; - }, - - getDate: function () { - var length = arguments.length; - var args = arguments; - var dt; - switch (length) { - // new Date() - case 0: - dt = new Date(); - break; - // new Date(long) - case 1: - dt = new Date(args[0]); - break; - // new Date(year, month) - case 2: - dt = new Date(args[0], args[1]); - break; - // new Date(year, month, day) - case 3: - dt = new Date(args[0], args[1], args[2]); - break; - // new Date(year, month, day, hour) - case 4: - dt = new Date(args[0], args[1], args[2], args[3]); - break; - // new Date(year, month, day, hour, minute) - case 5: - dt = new Date(args[0], args[1], args[2], args[3], args[4]); - break; - // new Date(year, month, day, hour, minute, second) - case 6: - dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); - break; - // new Date(year, month, day, hour, minute, second, millisecond) - case 7: - dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - break; - default: - dt = new Date(); - break; - } - if (BI.isNotNull(BI.timeZone) && (arguments.length === 0 || (arguments.length === 1 && BI.isNumber(arguments[0])))) { - var localTime = dt.getTime(); - // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 - var localOffset = dt.getTimezoneOffset() * 60000; // 获得当地时间偏移的毫秒数 - var utc = localTime + localOffset; // utc即GMT时间标准时区 - return new Date(utc + BI.timeZone);// + Pool.timeZone.offset); - } - return dt; - - }, - - getTime: function () { - var length = arguments.length; - var args = arguments; - var dt; - switch (length) { - // new Date() - case 0: - dt = new Date(); - break; - // new Date(long) - case 1: - dt = new Date(args[0]); - break; - // new Date(year, month) - case 2: - dt = new Date(args[0], args[1]); - break; - // new Date(year, month, day) - case 3: - dt = new Date(args[0], args[1], args[2]); - break; - // new Date(year, month, day, hour) - case 4: - dt = new Date(args[0], args[1], args[2], args[3]); - break; - // new Date(year, month, day, hour, minute) - case 5: - dt = new Date(args[0], args[1], args[2], args[3], args[4]); - break; - // new Date(year, month, day, hour, minute, second) - case 6: - dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); - break; - // new Date(year, month, day, hour, minute, second, millisecond) - case 7: - dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - break; - default: - dt = new Date(); - break; - } - if (BI.isNotNull(BI.timeZone)) { - // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 - return dt.getTime() - BI.timeZone - new Date().getTimezoneOffset() * 60000; - } - return dt.getTime(); - - } - }); -})(); diff --git a/src/core/3.ob.js b/src/core/3.ob.js deleted file mode 100644 index 100fcac17..000000000 --- a/src/core/3.ob.js +++ /dev/null @@ -1,220 +0,0 @@ -!(function () { - function extend() { - var target = arguments[0] || {}, length = arguments.length, i = 1, options, name, src, copy; - for (; i < length; i++) { - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) { - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - if (copy !== undefined) { - target[name] = copy; - } - } - } - } - return target; - } - - /** - * 客户端观察者,主要处理事件的添加、删除、执行等 - * @class BI.OB - * @abstract - */ - var OB = function (config) { - this._constructor(config); - }; - BI._.extend(OB.prototype, { - props: {}, - - init: null, - - destroyed: null, - - _constructor: function (config) { - this._initProps(config); - this._init(); - this._initRef(); - }, - - _defaultConfig: function (config) { - return {}; - }, - - _initProps: function (config) { - var props = this.props; - if (BI.isFunction(this.props)) { - props = this.props(config); - } - var defaultProps = extend(this._defaultConfig(config), props); - var modifiedDefaultProps = (config && config.type && BI.OB.configFunctions[config.type + ".props"]) ? BI.reduce(BI.OB.configFunctions[config.type + ".props"], function (value, conf, index) { - return extend(conf, value.fn(defaultProps, config, value.opt)); - }, {}) : null; - this.options = extend(defaultProps, modifiedDefaultProps, config); - }, - - _init: function () { - this._initListeners(); - this.init && this.init(); - }, - - _initListeners: function () { - var self = this; - if (this.options.listeners != null) { - BI._.each(this.options.listeners, function (lis, eventName) { - if (BI._.isFunction(lis)) { - self.on(eventName, lis); - return; - } - if (BI._.isArray(lis)) { - BI._.each(lis, function (l) { - self.on(eventName, l); - }); - return; - } - (lis.target ? lis.target : self)[lis.once ? "once" : "on"](lis.eventName, BI._.bind(lis.action, self)); - }); - delete this.options.listeners; - } - }, - - // 获得一个当前对象的引用 - _initRef: function () { - var o = this.options; - if (o.__ref) { - BI.isFunction(o.__ref) ? o.__ref.call(this, this) : o.__ref.current = this; - } - if (o.ref) { - BI.isFunction(o.ref) ? o.ref.call(this, this) : o.ref.current = this; - } - }, - - //释放当前对象 - _purgeRef: function () { - var o = this.options; - if (o.__ref) { - BI.isFunction(o.__ref) ? o.__ref.call(null, null) : o.__ref.current = null; - o.__ref = null; - } - if (o.ref) { - BI.isFunction(o.ref) ? o.ref.call(null, null) : o.ref.current = null; - o.ref = null; - } - }, - - _getEvents: function () { - if (!BI._.isObject(this.events)) { - this.events = {}; - } - return this.events; - }, - - /** - * 给观察者绑定一个事件 - * @param {String} eventName 事件的名字 - * @param {Function} fn 事件对应的执行函数 - */ - on: function (eventName, fn) { - var self = this; - eventName = eventName.toLowerCase(); - var fns = this._getEvents()[eventName]; - if (!BI._.isArray(fns)) { - fns = []; - this._getEvents()[eventName] = fns; - } - fns.push(fn); - - return function () { - self.un(eventName, fn); - }; - }, - - /** - * 给观察者绑定一个只执行一次的事件 - * @param {String} eventName 事件的名字 - * @param {Function} fn 事件对应的执行函数 - */ - once: function (eventName, fn) { - var proxy = function () { - fn.apply(this, arguments); - this.un(eventName, proxy); - }; - this.on(eventName, proxy); - }, - - /** - * 解除观察者绑定的指定事件 - * @param {String} eventName 要解除绑定事件的名字 - * @param {Function} fn 事件对应的执行函数,该参数是可选的,没有该参数时,将解除绑定所有同名字的事件 - */ - un: function (eventName, fn) { - eventName = eventName.toLowerCase(); - - /* alex:如果fn是null,就是把eventName上面所有方法都un掉*/ - if (fn == null) { - delete this._getEvents()[eventName]; - } else { - var fns = this._getEvents()[eventName]; - if (BI._.isArray(fns)) { - var newFns = []; - BI._.each(fns, function (ifn) { - if (ifn != fn) { - newFns.push(ifn); - } - }); - this._getEvents()[eventName] = newFns; - } - } - }, - - /** - * 清除观察者的所有事件绑定 - */ - purgeListeners: function () { - /* alex:清空events*/ - this.events = {}; - }, - - /** - * 触发绑定过的事件 - * - * @param {String} eventName 要触发的事件的名字 - * @returns {Boolean} 如果事件函数返回false,则返回false并中断其他同名事件的执行,否则执行所有的同名事件并返回true - */ - fireEvent: function () { - var eventName = arguments[0].toLowerCase(); - var fns = this._getEvents()[eventName]; - if (BI.isArray(fns)) { - if (BI.isArguments(arguments[1])) { - for (var i = 0; i < fns.length; i++) { - if (fns[i].apply(this, arguments[1]) === false) { - return false; - } - } - } else { - var args = Array.prototype.slice.call(arguments, 1); - for (var i = 0; i < fns.length; i++) { - if (fns[i].apply(this, args) === false) { - return false; - } - } - } - } - return true; - }, - - destroy: function () { - this.destroyed && this.destroyed(); - this._purgeRef(); - this.purgeListeners(); - } - }); - BI.OB = BI.OB || OB; -})(); diff --git a/src/core/4.widget.js b/src/core/4.widget.js deleted file mode 100644 index 73ef472fe..000000000 --- a/src/core/4.widget.js +++ /dev/null @@ -1,1083 +0,0 @@ -/** - * Widget超类 - * @class BI.Widget - * @extends BI.OB - * - * @cfg {JSON} options 配置属性 - */ - -!(function () { - var cancelAnimationFrame = - _global.cancelAnimationFrame || - _global.webkitCancelAnimationFrame || - _global.mozCancelAnimationFrame || - _global.oCancelAnimationFrame || - _global.msCancelAnimationFrame || - _global.clearTimeout; - - var requestAnimationFrame = _global.requestAnimationFrame || _global.webkitRequestAnimationFrame || _global.mozRequestAnimationFrame || _global.oRequestAnimationFrame || _global.msRequestAnimationFrame || _global.setTimeout; - - function callLifeHook(self, life) { - var hooks = [], hook; - hook = self[life]; - if (hook) { - hooks = hooks.concat(BI.isArray(hook) ? hook : [hook]); - } - hook = self.options[life]; - if (hook) { - hooks = hooks.concat(BI.isArray(hook) ? hook : [hook]); - } - BI.each(hooks, function (i, hook) { - hook.call(self); - }); - } - - BI.Widget = BI.Widget || BI.inherit(BI.OB, { - _defaultConfig: function () { - return BI.extend(BI.Widget.superclass._defaultConfig.apply(this), { - root: false, - tagName: "div", - attributes: null, - data: null, - key: null, - - tag: null, - disabled: false, - invisible: false, - animation: "", - animationDuring: 0, - invalid: false, - baseCls: "", - extraCls: "", - cls: "", - css: null - - // vdom: false - }); - }, - - _constructor: function () { - - }, - - // 覆盖父类的_constructor方法,widget不走ob的生命周期 - _constructed: function () { - if (this.setup) { - pushTarget(this); - var delegate = this.setup(this.options); - if (BI.isPlainObject(delegate)) { - // 如果setup返回一个json,即对外暴露的方法 - BI.extend(this, delegate); - } else { - this.render = delegate; - } - popTarget(); - } - }, - - _lazyConstructor: function () { - if (!this.__constructed) { - this.__constructed = true; - this._init(); - this._initRef(); - } - }, - - // 生命周期函数 - beforeInit: null, - - beforeRender: null, - - beforeCreate: null, - - created: null, - - render: null, - - beforeMount: null, - - mounted: null, - // 不想重写mounted时用 - _mounted: null, - - shouldUpdate: null, - - update: null, - - beforeUpdate: null, - - updated: null, - - beforeDestroy: null, - - destroyed: null, - // 不想重写destroyed时用 - _destroyed: null, - - _init: function () { - BI.Widget.superclass._init.apply(this, arguments); - this._initVisual(); - this._initState(); - this._initRender(); - }, - - _initRender: function () { - var self = this; - var initCallbackCalled = false; - var renderCallbackCalled = false; - - function init() { - // 加个保险 - if (initCallbackCalled === true) { - _global.console && console.error("widget:please check the beforeInit method. The callback can only be executed once"); - return; - } - initCallbackCalled = true; - - function render() { - // 加个保险 - if (renderCallbackCalled === true) { - _global.console && console.error("widget:please check the beforeRender method. The callback can only be executed once"); - return; - } - renderCallbackCalled = true; - self._render(); - self.__afterRender(); - } - - if (self.options.beforeRender || self.beforeRender) { - self.__async = true; - var beforeRenderResult = (self.options.beforeRender || self.beforeRender).call(self, render); - if (beforeRenderResult instanceof Promise) { - beforeRenderResult.then(render).catch(function (e) { - _global.console && console.error(e); - render(); - }); - } - } else { - self._render(); - self.__afterRender(); - } - } - - if (this.options.beforeInit || this.beforeInit) { - this.__asking = true; - var beforeInitResult = (this.options.beforeInit || this.beforeInit).call(this, init); - if (beforeInitResult instanceof Promise) { - beforeInitResult.then(init).catch(function (e) { - _global.console && console.error(e); - init(); - }); - } - } else { - init(); - } - }, - - __afterRender: function () { - pushTarget(this); - var async = this.__async; - this.__async = false; - if (async && this._isMounted) { - callLifeHook(this, "beforeMount"); - this._mount(); - callLifeHook(this, "mounted"); - this.fireEvent(BI.Events.MOUNT); - } else { - this._mount(); - } - popTarget(); - }, - - _render: function () { - this.__asking = false; - pushTarget(this); - callLifeHook(this, "beforeCreate"); - this._initElement(); - this._initEffects(); - callLifeHook(this, "created"); - popTarget(); - }, - - _initCurrent: function () { - var self = this, o = this.options; - this._initElementWidth(); - this._initElementHeight(); - if (o._baseCls || o.baseCls || o.extraCls) { - this.element.addClass((o._baseCls || "") + " " + (o.baseCls || "") + " " + (o.extraCls || "")); - } - if (o.cls) { - if (BI.isFunction(o.cls)) { - var cls = this.__watch(o.cls, function (context, newValue) { - self.element.removeClass(cls).addClass(cls = newValue); - }); - this.element.addClass(cls); - } else { - this.element.addClass(o.cls); - } - } - // if (o.key != null) { - // this.element.attr("key", o.key); - // } - if (o.attributes) { - this.element.attr(o.attributes); - } - if (o.data) { - this.element.data(o.data); - } - if (o.css) { - if (BI.isFunction(o.css)) { - var css = this.__watch(o.css, function (context, newValue) { - for (var k in css) { - if (BI.isNull(newValue[k])) { - newValue[k] = ""; - } - } - self.element.css(css = newValue); - }); - this.element.css(css); - } else { - this.element.css(o.css); - } - } - }, - - __watch: function (getter, handler, options) { - var self = this; - if (_global.Fix) { - this._watchers = this._watchers || []; - var watcher = new Fix.Watcher(null, function () { - return getter.call(self, self); - }, (handler && function (v) { - handler.call(self, self, v); - }) || BI.emptyFn, BI.extend({ deep: true }, options)); - this._watchers.push(function unwatchFn() { - watcher.teardown(); - }); - return watcher.value; - } else { - return getter(); - } - }, - - /** - * 初始化根节点 - * @private - */ - _initRoot: function () { - var o = this.options; - this.widgetName = o.widgetName || BI.uniqueId("widget"); - this._isRoot = o.root; - this._children = {}; - if (BI.isWidget(o.element)) { - this.element = this.options.element.element; - this._parent = o.element; - this._parent.addWidget(this.widgetName, this); - } else if (o.element) { - this.element = BI.Widget._renderEngine.createElement(this); - this._isRoot = true; - } else { - this.element = BI.Widget._renderEngine.createElement(this); - } - this.element._isWidget = true; - // var widgets = this.element.data("__widgets") || []; - // widgets.push(this); - // this.element.data("__widgets", widgets); - this._initCurrent(); - }, - - _initElementWidth: function () { - var o = this.options; - if (BI.isWidthOrHeight(o.width)) { - this.element.css("width", BI.pixFormat(o.width)); - } - }, - - _initElementHeight: function () { - var o = this.options; - if (BI.isWidthOrHeight(o.height)) { - this.element.css("height", BI.pixFormat(o.height)); - } - }, - - _initVisual: function () { - var self = this, o = this.options; - if (o.invisible) { - var invisible = o.invisible = BI.isFunction(o.invisible) ? this.__watch(o.invisible, function (context, newValue) { - self.setVisible(!newValue); - }) : o.invisible; - if (invisible) { - // 用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性 - this.__setElementVisible(false); - } - } - }, - - _initEffects: function () { - var self = this, o = this.options; - if (o.disabled || o.invalid) { - if (this.options.disabled) { - var disabled = o.disabled = BI.isFunction(o.disabled) ? this.__watch(o.disabled, function (context, newValue) { - self.setEnable(!newValue); - }) : o.disabled; - if (disabled) { - this.setEnable(false); - } - } - if (this.options.invalid) { - var invalid = o.invalid = BI.isFunction(o.invalid) ? this.__watch(o.invalid, function (context, newValue) { - self.setValid(!newValue); - }) : o.invalid; - if (invalid) { - this.setValid(false); - } - } - } - if (o.effect) { - if (BI.isArray(o.effect)) { - if (BI.isArray(o.effect[0])) { - BI.each(o.effect, function (i, effect) { - self.__watch(effect[0], effect[1]); - }); - } else { - self.__watch(o.effect[0], o.effect[1]); - } - } else { - this.__watch(o.effect); - } - } - }, - - _initState: function () { - this._isMounted = false; - this._isDestroyed = false; - }, - - __initWatch: function () { - // initWatch拦截的方法 - }, - - _initElement: function () { - var self = this; - this.__isMounting = true; - // 当开启worker模式时,可以通过$render来实现另一种效果 - var workerMode = BI.Providers.getProvider("bi.provider.system").getWorkerMode(); - var render = BI.isFunction(this.options.render) ? this.options.render : (workerMode ? (this.$render || this.render) : this.render); - var els = render && render.call(this); - els = this.options.configRender ? this.options.configRender.call(this, els) : els; - els = BI.Plugin.getRender(this.options.type, els); - if (BI.isPlainObject(els)) { - els = [els]; - } - this.__initWatch(); - if (BI.isArray(els)) { - BI.each(els, function (i, el) { - if (el) { - BI._lazyCreateWidget(el, { - element: self - }); - } - }); - } - }, - - _setParent: function (parent) { - this._parent = parent; - }, - - /** - * - * @param force 是否强制挂载子节点 - * @param deep 子节点是否也是按照当前force处理 - * @param lifeHook 生命周期钩子触不触发,默认触发 - * @param predicate 递归每个widget的回调 - * @param layer 组件层级 - * @returns {boolean} - * @private - */ - _mount: function (force, deep, lifeHook, predicate, layer) { - var self = this; - if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) { - return false; - } - layer = layer || 0; - lifeHook !== false && !this.__async && callLifeHook(this, "beforeMount"); - this._isMounted = true; - this.__isMounting = false; - for (var key in this._children) { - var child = this._children[key]; - child._mount && child._mount(deep ? force : false, deep, lifeHook, predicate, layer + 1); - } - if (this._parent) { - if (!this._parent.isEnabled()) { - this._setEnable(false); - } - if (!this._parent.isValid()) { - this._setValid(false); - } - } - this._mountChildren && this._mountChildren(); - if (layer === 0) { - // mounted里面会执行scrollTo之类的方法,如果放宏任务里会闪 - // setTimeout(function () { - self.__afterMount(lifeHook, predicate); - // }, 0); - } - return true; - }, - - __afterMount: function (lifeHook, predicate) { - if (this._isMounted) { - for (var key in this._children) { - var child = this._children[key]; - child.__afterMount && child.__afterMount(lifeHook, predicate); - } - if (lifeHook !== false && !this.__async) { - callLifeHook(this, "_mounted"); - callLifeHook(this, "mounted"); - this.fireEvent(BI.Events.MOUNT); - } - predicate && predicate(this); - } - }, - - _mountChildren: null, - - _update: function (nextProps, shouldUpdate) { - callLifeHook(this, "beforeUpdate"); - if (shouldUpdate) { - var res = this.update && this.update(nextProps, shouldUpdate); - } - callLifeHook(this, "updated"); - return res; - }, - - isMounted: function () { - return this._isMounted; - }, - - isDestroyed: function () { - return this._isDestroyed; - }, - - setWidth: function (w) { - this.options.width = w; - this._initElementWidth(); - }, - - setHeight: function (h) { - this.options.height = h; - this._initElementHeight(); - }, - - _setEnable: function (enable) { - if (enable === true) { - this.options._disabled = false; - } else if (enable === false) { - this.options._disabled = true; - } - // 递归将所有子组件使能 - BI.each(this._children, function (i, child) { - !child._manualSetEnable && child._setEnable && child._setEnable(enable); - }); - }, - - _setValid: function (valid) { - if (valid === true) { - this.options._invalid = false; - } else if (valid === false) { - this.options._invalid = true; - } - // 递归将所有子组件使有效 - BI.each(this._children, function (i, child) { - !child._manualSetValid && child._setValid && child._setValid(valid); - }); - }, - - _setVisible: function (visible) { - if (visible === true) { - this.options.invisible = false; - } else if (visible === false) { - this.options.invisible = true; - } - }, - - setEnable: function (enable) { - this._manualSetEnable = true; - this.options.disabled = !enable; - this._setEnable(enable); - if (enable === true) { - this.element.removeClass("base-disabled disabled"); - } else if (enable === false) { - this.element.addClass("base-disabled disabled"); - } - }, - - __setElementVisible: function (visible) { - this.element.css("display", visible ? "" : "none"); - }, - - _innerSetVisible: function (visible) { - var self = this, o = this.options; - var lastVisible = !o.invisible; - this._setVisible(visible); - if (visible === true) { - // 用this.element.show()会把display属性改成block - this.__setElementVisible(true); - this._mount(); - if (o.animation && !lastVisible) { - this.element.removeClass(o.animation + "-leave").removeClass(o.animation + "-leave-active").addClass(o.animation + "-enter"); - if (this._requestAnimationFrame) { - cancelAnimationFrame(this._requestAnimationFrame); - } - this._requestAnimationFrame = function () { - self.element.addClass(o.animation + "-enter-active"); - }; - requestAnimationFrame(this._requestAnimationFrame); - if (this._animationDuring) { - clearTimeout(this._animationDuring); - } - this._animationDuring = setTimeout(function () { - self.element.removeClass(o.animation + "-enter").removeClass(o.animation + "-enter-active"); - }, o.animationDuring); - } - } else if (visible === false) { - if (o.animation && lastVisible) { - this.element.removeClass(o.animation + "-enter").removeClass(o.animation + "-enter-active").addClass(o.animation + "-leave"); - if (this._requestAnimationFrame) { - cancelAnimationFrame(this._requestAnimationFrame); - } - this._requestAnimationFrame = function () { - self.element.addClass(o.animation + "-leave-active"); - }; - requestAnimationFrame(this._requestAnimationFrame); - if (this._animationDuring) { - clearTimeout(this._animationDuring); - } - this._animationDuring = setTimeout(function () { - self.element.removeClass(o.animation + "-leave").removeClass(o.animation + "-leave-active"); - self.__setElementVisible(false); - }, o.animationDuring); - } else { - this.__setElementVisible(false); - } - } - }, - - setVisible: function (visible) { - this._innerSetVisible(visible); - this.fireEvent(BI.Events.VIEW, visible); - }, - - setValid: function (valid) { - this._manualSetValid = true; - this.options.invalid = !valid; - this._setValid(valid); - if (valid === true) { - this.element.removeClass("base-invalid invalid"); - } else if (valid === false) { - this.element.addClass("base-invalid invalid"); - } - }, - - doBehavior: function () { - var args = arguments; - // 递归将所有子组件使有效 - BI.each(this._children, function (i, child) { - child.doBehavior && child.doBehavior.apply(child, args); - }); - }, - - getWidth: function () { - return this.options.width; - }, - - getHeight: function () { - return this.options.height; - }, - - addWidget: function (name, widget) { - var self = this; - if (name instanceof BI.Widget) { - widget = name; - name = widget.getName(); - } - if (BI.isKey(name)) { - name = name + ""; - } - name = name || widget.getName() || BI.uniqueId("widget"); - if (this._children[name]) { - throw new Error("widget:widget name already exists, cannot be added "); - } - widget._setParent && widget._setParent(this); - widget.on(BI.Events.DESTROY, function () { - BI.remove(self._children, this); - }); - return (this._children[name] = widget); - }, - - getWidgetByName: function (name) { - if (!BI.isKey(name) || name === this.getName()) { - return this; - } - name = name + ""; - var widget = void 0, other = {}; - BI.any(this._children, function (i, wi) { - if (i === name) { - widget = wi; - return true; - } - other[i] = wi; - }); - if (!widget) { - BI.any(other, function (i, wi) { - return (widget = wi.getWidgetByName(i)); - }); - } - return widget; - }, - - removeWidget: function (nameOrWidget) { - if (BI.isWidget(nameOrWidget)) { - BI.remove(this._children, nameOrWidget); - } else { - delete this._children[nameOrWidget]; - } - }, - - hasWidget: function (name) { - return this._children[name] != null; - }, - - getName: function () { - return this.widgetName; - }, - - setTag: function (tag) { - this.options.tag = tag; - }, - - getTag: function () { - return this.options.tag; - }, - - attr: function (key, value) { - var self = this; - if (BI.isPlainObject(key)) { - BI.each(key, function (k, v) { - self.attr(k, v); - }); - return; - } - if (BI.isNotNull(value)) { - return this.options[key] = value; - } - return this.options[key]; - }, - - css: function (name, value) { - return this.element.css(name, value); - }, - - getText: function () { - - }, - - setText: function (text) { - - }, - - getValue: function () { - - }, - - setValue: function (value) { - - }, - - isEnabled: function () { - return this.options.disabled === true ? false : !this.options._disabled; - }, - - isValid: function () { - return this.options.invalid === true ? false : !this.options._invalid; - }, - - isVisible: function () { - return !this.options.invisible; - }, - - disable: function () { - this.setEnable(false); - }, - - enable: function () { - this.setEnable(true); - }, - - valid: function () { - this.setValid(true); - }, - - invalid: function () { - this.setValid(false); - }, - - invisible: function () { - this.setVisible(false); - }, - - visible: function () { - this.setVisible(true); - }, - - __d: function () { - BI.each(this._children, function (i, widget) { - widget && widget._unMount && widget._unMount(); - }); - this._children = {}; - }, - - // 主要是因为_destroy已经提供了protected方法 - __destroy: function () { - callLifeHook(this, "beforeDestroy"); - this.beforeDestroy = null; - this.__d(); - this._parent = null; - this._isMounted = false; - callLifeHook(this, "_destroyed"); - callLifeHook(this, "destroyed"); - this.destroyed = null; - this._isDestroyed = true; - // this._purgeRef(); // 清除ref的时机还是要仔细考虑一下 - - }, - - _unMount: function () { - this._assetMounted(); - this.__destroy(); - this.fireEvent(BI.Events.UNMOUNT); - this.purgeListeners(); - }, - - _assetMounted: function () { - if (!this.isVisible()) { - this._setVisible(true); - this._mount(false, false, false); - this._setVisible(false); - } - }, - - _empty: function () { - this._assetMounted(); - BI.each(this._children, function (i, widget) { - widget && widget._unMount && widget._unMount(); - }); - this._children = {}; - this.element.empty(); - }, - - isolate: function () { - if (this._parent) { - this._parent.removeWidget(this); - } - BI.DOM.hang([this]); - }, - - empty: function () { - this._empty(); - }, - - // 默认的reset方法就是干掉重来 - reset: function () { - // 还在异步状态的不需要执行reset - if (this.__async === true || this.__asking === true) { - return; - } - // if (this.options.vdom) { - // var vnode = this._renderVNode(); - // BI.patchVNode(this.vnode, vnode); - // this.vnode = vnode; - // return; - // } - // this._isMounted = false; - // this.purgeListeners(); - - // 去掉组件绑定的watcher - BI.each(this._watchers, function (i, unwatches) { - unwatches = BI.isArray(unwatches) ? unwatches : [unwatches]; - BI.each(unwatches, function (j, unwatch) { - unwatch(); - }); - }); - this._watchers && (this._watchers = []); - this._assetMounted(); - this.__d(); - this.element.empty(); - this.element.unbind(); - this._initCurrent(); - this._init(); - // this._initRef(); - }, - - _destroy: function () { - this._assetMounted(); - this.__destroy(); - this.element.destroy(); - this.purgeListeners(); - }, - - destroy: function () { - var self = this, o = this.options; - this._assetMounted(); - this.__destroy(); - if (o.animation) { - this._innerSetVisible(false); - setTimeout(function () { - self.element.destroy(); - }, o.animationDuring); - } else { - this.element.destroy(); - } - this.fireEvent(BI.Events.UNMOUNT); - this.fireEvent(BI.Events.DESTROY); - this._purgeRef(); - this.purgeListeners(); - } - }); - var context = null, current = null; - var contextStack = [], currentStack = []; - - BI.Widget.pushContext = function (_context) { - if (context) contextStack.push(context); - BI.Widget.context = context = _context; - }; - - BI.Widget.popContext = function () { - BI.Widget.context = context = contextStack.pop(); - }; - - BI.Widget.execWithContext = function (context, execFunc) { - BI.Widget.pushContext(context); - try { - execFunc(); - } catch (e) { - throw e; - } finally { - BI.Widget.popContext(); - } - }; - - function pushTarget(_current) { - if (current) currentStack.push(current); - BI.Widget.current = current = _current; - } - - function popTarget() { - BI.Widget.current = current = currentStack.pop(); - } - - BI.useStore = function (_store) { - if (current && current.store) { - return current.store; - } - if (current && current.$storeDelegate) { - return current.$storeDelegate; - } - if (current) { - var currentStore = current._store; - var delegate = {}, origin; - if (_global.Proxy) { - var proxy = new Proxy(delegate, { - get: function (target, key) { - return Reflect.get(origin, key); - }, - set: function (target, key, value) { - return Reflect.set(origin, key, value); - } - }); - current._store = function () { - origin = (_store || currentStore).apply(this, arguments); - delegate.$delegate = origin; - return origin; - }; - return current.$storeDelegate = proxy; - } - current._store = function () { - var st = (_store || currentStore).apply(this, arguments); - BI.extend(delegate, st); - return st; - }; - return current.$storeDelegate = delegate; - } - }; - - BI.useContext = function (inject) { - // 通过组件找最近的store - var vm = BI.Widget.findStore(BI.Widget.current || BI.Widget.context); - if (vm) { - if (inject) { - if (vm.$$computed && inject in vm.$$computed) { - return vm; - } - if (vm.$$state && inject in vm.$$state) { - return vm; - } - if (vm.$$model && inject in vm.$$model) { - return vm; - } - while (vm) { - if (vm.$$context && inject in vm.$$context) { - return vm; - } - vm = vm._parent; - } - return null; - } - } - return vm; - }; - - BI.watch = function (vm, watch, handler) { - // 必须要保证组件当前环境存在 - if (BI.Widget.current) { - if (vm instanceof BI.Model) { - var watchers = []; - if (BI.isKey(watch)) { - var k = watch; - watch = {}; - watch[k] = handler; - } - for (var key in watch) { - var innerHandler = watch[key]; - if (BI.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - watchers.push(Fix.watch(vm.model, key, innerHandler, { - store: vm - })); - } - } else { - watchers.push(Fix.watch(vm.model, key, innerHandler, { - store: vm - })); - } - } - // vm中一定有_widget - BI.Widget.current._watchers || (BI.Widget.current._watchers = []); - BI.Widget.current._watchers = BI.Widget.current._watchers.concat(watchers); - return; - } - handler = watch; - watch = vm; - BI.Widget.current.$watchDelayCallbacks || (BI.Widget.current.$watchDelayCallbacks = []); - BI.Widget.current.$watchDelayCallbacks.push([watch, handler]); - } - }; - - BI.onBeforeMount = function (beforeMount) { - if (current) { - if (current.__isMounting) { - beforeMount(); - return; - } - if (!current.beforeMount) { - current.beforeMount = []; - } else if (!BI.isArray(current.beforeMount)) { - current.beforeMount = [current.beforeMount]; - } - current.beforeMount.push(beforeMount); - } - }; - BI.onMounted = function (mounted) { - if (current) { - if (current._isMounted && !this.__async) { - mounted(); - return; - } - if (!current.mounted) { - current.mounted = []; - } else if (!BI.isArray(current.mounted)) { - current.mounted = [current.mounted]; - } - current.mounted.push(mounted); - } - }; - BI.onBeforeUnmount = function (beforeDestroy) { - if (current) { - if (!current.beforeDestroy) { - current.beforeDestroy = []; - } else if (!BI.isArray(current.beforeDestroy)) { - current.beforeDestroy = [current.beforeDestroy]; - } - current.beforeDestroy.push(beforeDestroy); - } - }; - BI.onUnmounted = function (destroyed) { - if (current) { - if (!current.destroyed) { - current.destroyed = []; - } else if (!BI.isArray(current.destroyed)) { - current.destroyed = [current.destroyed]; - } - current.destroyed.push(destroyed); - } - }; - - BI.Widget.registerRenderEngine = function (engine) { - BI.Widget._renderEngine = engine; - }; - BI.Widget.registerRenderEngine({ - createElement: function (widget) { - if (BI.isWidget(widget)) { - var o = widget.options; - if (o.element) { - return BI.$(o.element); - } - if (o.tagName) { - return BI.$(document.createElement(o.tagName)); - } - return BI.$(document.createDocumentFragment()); - } - return BI.$(widget); - }, - createFragment: function () { - return document.createDocumentFragment(); - } - }); - - BI.mount = function (widget, container, predicate, hydrate) { - if (hydrate === true) { - // 将widget的element元素都挂载好,并建立相互关系 - widget.element.data("__widgets", [widget]); - var res = widget._mount(true, false, false, function (w) { - BI.each(w._children, function (i, child) { - var ws = child.element.data("__widgets"); - if (!ws) { - ws = []; - } - ws.push(child); - child.element.data("__widgets", ws); - }); - predicate && predicate.apply(this, arguments); - }); - // 将新的dom树属性(事件等)patch到已存在的dom上 - var c = BI.Widget._renderEngine.createElement; - BI.DOM.patchProps(widget.element, c(c(container).children()[0])); - - var triggerLifeHook = function (w) { - w.beforeMount && w.beforeMount(); - w.mounted && w.mounted(); - BI.each(w._children, function (i, child) { - triggerLifeHook(child); - }); - }; - // 最后触发组件树生命周期函数 - triggerLifeHook(widget); - return res; - } - if (container) { - BI.Widget._renderEngine.createElement(container).append(widget.element); - } - return widget._mount(true, false, false, predicate); - }; -})(); diff --git a/src/core/5.inject.js b/src/core/5.inject.js deleted file mode 100644 index b7c539f4d..000000000 --- a/src/core/5.inject.js +++ /dev/null @@ -1,528 +0,0 @@ -(function () { - var moduleInjection = {}, moduleInjectionMap = { - components: {}, - constants: {}, - stores: {}, - services: {}, - models: {}, - providers: {} - }; - BI.module = BI.module || function (xtype, cls) { - if (moduleInjection[xtype] != null) { - _global.console && console.error("module: [" + xtype + "] already registered"); - } else { - if (BI.isFunction(cls)) { - cls = cls(); - } - for (var k in moduleInjectionMap) { - if (cls[k]) { - for (var key in cls[k]) { - if (!moduleInjectionMap[k]) { - continue; - } - if (!moduleInjectionMap[k][key]) { - moduleInjectionMap[k][key] = []; - } - moduleInjectionMap[k][key].push({ - version: cls[k][key], - moduleId: xtype - }); - } - } - } - moduleInjection[xtype] = cls; - } - - return function () { - return BI.Modules.getModule(xtype); - }; - }; - - var constantInjection = {}; - BI.constant = BI.constant || function (xtype, cls) { - if (constantInjection[xtype] != null) { - _global.console && console.error("constant: [" + xtype + "]already registered"); - } else { - constantInjection[xtype] = cls; - } - - return function () { - return BI.Constants.getConstant(xtype); - }; - }; - - var modelInjection = {}; - BI.model = BI.model || function (xtype, cls) { - if (modelInjection[xtype] != null) { - _global.console && console.error("model: [" + xtype + "] already registered"); - } else { - modelInjection[xtype] = cls; - } - - return function (config) { - return BI.Models.getModel(xtype, config); - }; - }; - - var storeInjection = {}; - BI.store = BI.store || function (xtype, cls) { - if (storeInjection[xtype] != null) { - _global.console && console.error("store: [" + xtype + "] already registered"); - } else { - storeInjection[xtype] = cls; - } - - return function (config) { - return BI.Stores.getStore(xtype, config); - }; - }; - - var serviceInjection = {}; - BI.service = BI.service || function (xtype, cls) { - if (serviceInjection[xtype] != null) { - _global.console && console.error("service: [" + xtype + "] already registered"); - } - - serviceInjection[xtype] = cls; - - return function (config) { - return BI.Services.getService(xtype, config); - }; - }; - - var providerInjection = {}; - BI.provider = BI.provider || function (xtype, cls) { - if (providerInjection[xtype] != null) { - _global.console && console.error("provider: [" + xtype + "] already registered"); - } else { - providerInjection[xtype] = cls; - } - - return function (config) { - return BI.Providers.getProvider(xtype, config); - }; - }; - - var configFunctions = BI.OB.configFunctions = {}; - var runConfigFunction = function (type, configFn) { - if (!type || !configFunctions[type]) { - return false; - } - - var queue = []; - if (configFn) { - queue = configFunctions[type].filter(function (conf) { - return conf.fn === configFn; - }); - configFunctions[type] = configFunctions[type].filter(function (conf) { - return conf.fn !== configFn; - }); - } else { - queue = configFunctions[type]; - delete configFunctions[type]; - } - - var dependencies = BI.Providers.getProvider("bi.provider.system").getDependencies(); - var modules = moduleInjectionMap.components[type] - || moduleInjectionMap.constants[type] - || moduleInjectionMap.services[type] - || moduleInjectionMap.stores[type] - || moduleInjectionMap.models[type] - || moduleInjectionMap.providers[type]; - for (var i = 0; i < queue.length; i++) { - var conf = queue[i]; - var version = conf.opt.version; - var fn = conf.fn; - if (modules && version) { - var findVersion = false; - for (var j = 0; j < modules.length; j++) { - var module = modules[j]; - if (module && dependencies[module.moduleId] && module.version === version) { - var minVersion = dependencies[module.moduleId].minVersion, - maxVersion = dependencies[module.moduleId].maxVersion; - if (minVersion && (moduleInjection[module.moduleId].version || version) < minVersion) { - findVersion = true; - break; - } - if (maxVersion && (moduleInjection[module.moduleId].version || version) > maxVersion) { - findVersion = true; - break; - } - } - } - if (findVersion === true) { - _global.console && console.error("moduleId: [" + module.moduleId + "] interface : [" + type + "] version: [" + version + "] has expired,The version requirement is:", dependencies[module.moduleId], "=>", moduleInjection[module.moduleId]); - continue; - } - } - if (constantInjection[type]) { - constantInjection[type] = fn(constantInjection[type]); - continue; - } - if (providerInjection[type]) { - if (!providers[type]) { - providers[type] = new providerInjection[type](); - } - if (providerInstance[type]) { - delete providerInstance[type]; - } - fn(providers[type]); - continue; - } - BI.Plugin.configWidget(type, fn, conf.opt); - } - }; - BI.config = BI.config || function (type, configFn, opt) { - if (BI.isFunction(type)) { - opt = configFn; - configFn = type; - type = "bi.provider.system"; - } - opt = opt || {}; - - // 系统配置直接执行 - if ("bi.provider.system" === type) { - if (!providers[type]) { - providers[type] = new providerInjection[type](); - } - // 如果config被重新配置的话,需要删除掉之前的实例 - if (providerInstance[type]) { - delete providerInstance[type]; - } - return configFn(providers[type]); - } - - if (!configFunctions[type]) { - configFunctions[type] = []; - } - configFunctions[type].push({ - fn: configFn, - opt: opt - }); - - if (opt.immediately) { - return runConfigFunction(type, configFn); - } - }; - - BI.getReference = BI.getReference || function (type, fn) { - return BI.Plugin.registerObject(type, fn); - }; - - var actions = {}; - var globalAction = []; - BI.action = BI.action || function (type, actionFn) { - if (BI.isFunction(type)) { - globalAction.push(type); - return function () { - BI.remove(globalAction, function (idx) { - return globalAction.indexOf(actionFn) === idx; - }); - }; - } - if (!actions[type]) { - actions[type] = []; - } - actions[type].push(actionFn); - return function () { - BI.remove(actions[type], function (idx) { - return actions[type].indexOf(actionFn) === idx; - }); - if (actions[type].length === 0) { - delete actions[type]; - } - }; - }; - - var points = {}; - BI.point = BI.point || function (type, action, pointFn, after) { - if (!points[type]) { - points[type] = {}; - } - if (!points[type][action]) { - points[type][action] = {}; - } - if (!points[type][action][after ? "after" : "before"]) { - points[type][action][after ? "after" : "before"] = []; - } - points[type][action][after ? "after" : "before"].push(pointFn); - }; - - BI.Modules = BI.Modules || { - getModule: function (type) { - if (!moduleInjection[type]) { - _global.console && console.error("module: [" + type + "] undefined"); - } - return moduleInjection[type]; - }, - getAllModules: function () { - return moduleInjection; - } - }; - - BI.Constants = BI.Constants || { - getConstant: function (type) { - if (BI.isNull(constantInjection[type])) { - _global.console && console.error("constant: [" + type + "] undefined"); - } - runConfigFunction(type); - return BI.isFunction(constantInjection[type]) ? constantInjection[type]() : constantInjection[type]; - } - }; - - var callPoint = function (inst, types) { - types = BI.isArray(types) ? types : [types]; - BI.each(types, function (idx, type) { - if (points[type]) { - for (var action in points[type]) { - var bfns = points[type][action].before; - if (bfns) { - BI.aspect.before(inst, action, function (bfns) { - return function () { - for (var i = 0, len = bfns.length; i < len; i++) { - try { - bfns[i].apply(inst, arguments); - } catch (e) { - _global.console && console.error(e); - } - } - }; - }(bfns)); - } - var afns = points[type][action].after; - if (afns) { - BI.aspect.after(inst, action, function (afns) { - return function () { - for (var i = 0, len = afns.length; i < len; i++) { - try { - afns[i].apply(inst, arguments); - } catch (e) { - _global.console && console.error(e); - } - } - }; - }(afns)); - } - } - } - }); - }; - - BI.Models = BI.Models || { - getModel: function (type, config) { - if (!modelInjection[type]) { - _global.console && console.error("model: [" + type + "] undefined"); - } - runConfigFunction(type); - var inst = new modelInjection[type](config); - inst._constructor && inst._constructor(config); - inst.mixins && callPoint(inst, inst.mixins); - callPoint(inst, type); - return inst; - } - }; - - var stores = {}; - - BI.Stores = BI.Stores || { - getStore: function (type, config) { - if (!storeInjection[type]) { - _global.console && console.error("store: [" + type + "] undefined"); - } - if (stores[type]) { - return stores[type]; - } - var inst = stores[type] = new storeInjection[type](config); - inst._constructor && inst._constructor(config, function () { - delete stores[type]; - }); - callPoint(inst, type); - return inst; - } - }; - - var services = {}; - - BI.Services = BI.Services || { - getService: function (type, config) { - if (!serviceInjection[type]) { - _global.console && console.error("service: [" + type + "] undefined"); - } - if (services[type]) { - return services[type]; - } - services[type] = new serviceInjection[type](config); - callPoint(services[type], type); - return services[type]; - } - }; - - var providers = {}, - providerInstance = {}; - - BI.Providers = BI.Providers || { - getProvider: function (type, config) { - if (!providerInjection[type]) { - _global.console && console.error("provider: [" + type + "] undefined"); - } - runConfigFunction(type); - if (!providers[type]) { - providers[type] = new providerInjection[type](); - } - if (!providerInstance[type] && providers[type].$get) { - providerInstance[type] = new (providers[type].$get())(config); - } - return providerInstance[type]; - } - }; - - BI.Actions = BI.Actions || { - runAction: function (type, event, config) { - BI.each(actions[type], function (i, act) { - try { - act(event, config); - } catch (e) { - _global.console && console.error(e); - } - }); - }, - runGlobalAction: function () { - var args = [].slice.call(arguments); - BI.each(globalAction, function (i, act) { - try { - act.apply(null, args); - } catch (e) { - _global.console && console.error(e); - } - }); - } - }; - - var kv = {}; - BI.shortcut = BI.component = BI.shortcut || function (xtype, cls) { - if (kv[xtype] != null) { - _global.console && console.error("widget: [" + xtype + "] already registered"); - } - if (cls) { - cls["xtype"] = xtype; - } - kv[xtype] = cls; - }; - - // 根据配置属性生成widget - var createWidget = function (config, context, lazy) { - var cls = BI.isFunction(config.type) ? config.type : kv[config.type]; - - if (!cls) { - throw new Error("widget: [" + config.type + "] undefined"); - } - var pushed = false; - var widget = new cls(); - widget._context = BI.Widget.context || context; - if (!BI.Widget.context && context) { - pushed = true; - BI.Widget.pushContext(context); - } - callPoint(widget, config.type); - widget._initProps(config); - widget._initRoot(); - widget._constructed(); - // if (!lazy || config.element || config.root) { - widget._lazyConstructor(); - // } - pushed && BI.Widget.popContext(); - return widget; - }; - - BI.createWidget = BI.createWidget || function (item, options, context, lazy) { - item || (item = {}); - if (BI.isWidget(options)) { - context = options; - options = {}; - } else { - options || (options = {}); - } - - var el, w; - if (item.type || options.type) { - el = BI.extend({}, options, item); - } else if (item.el && (item.el.type || options.type)) { - el = BI.extend({}, options, item.el); - } - - if (el) { - var elType = (el.type && el.type.xtype) || el.type; - runConfigFunction(elType); - } - - // 先把准备环境准备好 - BI.init(); - - if (BI.isEmpty(item) && BI.isEmpty(options)) { - return BI.createWidget({ - type: "bi.layout" - }); - } - if (BI.isWidget(item)) { - return item; - } - if (el) { - w = BI.Plugin.getWidget(elType, el); - var wType = (w.type && w.type.xtype) || w.type; - if (wType === elType) { - if (BI.Plugin.hasObject(elType)) { - if (!w.listeners || BI.isArray(w.listeners)) { - w.listeners = (w.listeners || []).concat([ - { - eventName: BI.Events.MOUNT, - action: function () { - BI.Plugin.getObject(elType, this); - } - } - ]); - } else { - w.listeners[BI.Events.MOUNT] = [ - function () { - BI.Plugin.getObject(elType, this); - } - ].concat(w.listeners[BI.Events.MOUNT] || []); - } - } - return createWidget(w, context, lazy); - } - return BI.createWidget(w, options, context, lazy); - } - if (BI.isWidget(item.el)) { - return item.el; - } - throw new Error("widget: Unable to create widget from item ", item); - }; - - BI._lazyCreateWidget = BI._lazyCreateWidget || function (item, options, context) { - return BI.createWidget(item, options, context, true); - }; - - BI.createElement = BI.createElement || function () { - var widget = BI.createWidget.apply(this, arguments); - return widget.element; - }; - - BI.getResource = BI.getResource || function (type, config) { - if (BI.isNotNull(constantInjection[type])) { - return BI.Constants.getConstant(type); - } - if (modelInjection[type]) { - return BI.Models.getModel(type, config); - } - if (storeInjection[type]) { - return BI.Stores.getStore(type, config); - } - if (serviceInjection[type]) { - return BI.Services.getService(type, config); - } - if (providerInjection[type]) { - return BI.Providers.getProvider(type, config); - } - throw new Error("unknown type: [" + type + "] undefined"); - }; -})(); diff --git a/src/core/6.plugin.js b/src/core/6.plugin.js deleted file mode 100644 index 8880380fc..000000000 --- a/src/core/6.plugin.js +++ /dev/null @@ -1,123 +0,0 @@ -BI.Plugin = BI.Plugin || {}; -!(function () { - var _WidgetsPlugin = {}; - var _ObjectPlugin = {}; - var _ConfigPlugin = {}; - var _ConfigRenderPlugin = {}; - var _GlobalWidgetConfigFns = []; - var __GlobalObjectConfigFns = []; - BI.defaults(BI.Plugin, { - - getWidget: function (type, options) { - if (_GlobalWidgetConfigFns.length > 0) { - var fns = _GlobalWidgetConfigFns.slice(0); - for (var i = fns.length - 1; i >= 0; i--) { - fns[i](type, options); - } - } - - var res; - if (_ConfigPlugin[type]) { - for (var i = _ConfigPlugin[type].length - 1; i >= 0; i--) { - if (res = _ConfigPlugin[type][i](options)) { - options = res; - } - } - } - // Deprecated - if (_WidgetsPlugin[type]) { - for (var i = _WidgetsPlugin[type].length - 1; i >= 0; i--) { - if (res = _WidgetsPlugin[type][i](options)) { - return res; - } - } - } - return options; - }, - - config: function (widgetConfigFn, objectConfigFn) { - _GlobalWidgetConfigFns = _GlobalWidgetConfigFns.concat(BI._.isArray(widgetConfigFn) ? widgetConfigFn : [widgetConfigFn]); - __GlobalObjectConfigFns = __GlobalObjectConfigFns.concat(BI._.isArray(objectConfigFn) ? objectConfigFn : [objectConfigFn]); - }, - - configWidget: function (type, fn, opt) { - // opt.single: true 最后一次注册有效 - if (!_ConfigPlugin[type] || (opt && opt.single)) { - _ConfigPlugin[type] = []; - } - _ConfigPlugin[type].push(fn); - }, - - getRender: function (type, rendered) { - var res; - if (_ConfigRenderPlugin[type]) { - for (var i = _ConfigRenderPlugin[type].length - 1; i >= 0; i--) { - if (res = _ConfigRenderPlugin[type][i](rendered)) { - rendered = res; - } - } - } - return rendered; - }, - - configRender: function (type, fn) { - if (!_ConfigRenderPlugin[type]) { - _ConfigRenderPlugin[type] = []; - } - _ConfigRenderPlugin[type].push(fn); - }, - - // Deprecated - registerWidget: function (type, fn) { - if (!_WidgetsPlugin[type]) { - _WidgetsPlugin[type] = []; - } - if (_WidgetsPlugin[type].length > 0) { - console.log("widget already registered!"); - } - _WidgetsPlugin[type].push(fn); - }, - - // Deprecated - relieveWidget: function (type) { - delete _WidgetsPlugin[type]; - }, - - getObject: function (type, object) { - if (__GlobalObjectConfigFns.length > 0) { - var fns = __GlobalObjectConfigFns.slice(0); - for (var i = fns.length - 1; i >= 0; i--) { - fns[i](type, object); - } - } - - if (_ObjectPlugin[type]) { - var res; - for (var i = 0, len = _ObjectPlugin[type].length; i < len; i++) { - if (res = _ObjectPlugin[type][i](object)) { - object = res; - } - } - } - return res || object; - }, - - hasObject: function (type) { - return __GlobalObjectConfigFns.length > 0 || !!_ObjectPlugin[type]; - }, - - registerObject: function (type, fn) { - if (!_ObjectPlugin[type]) { - _ObjectPlugin[type] = []; - } - if (_ObjectPlugin[type].length > 0) { - console.log("object already registered!"); - } - _ObjectPlugin[type].push(fn); - }, - - relieveObject: function (type) { - delete _ObjectPlugin[type]; - } - }); -})(); diff --git a/src/core/action/action.js b/src/core/action/action.js deleted file mode 100644 index 3639c00e5..000000000 --- a/src/core/action/action.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * guy - * 由一个元素切换到另一个元素的行为 - * @class BI.Action - * @extends BI.OB - * @abstract - */ -BI.Action = BI.inherit(BI.OB, { - props: function () { - return { - src: null, - tar: null - }; - }, - - actionPerformed: function (src, tar, callback) { - - }, - - actionBack: function (tar, src, callback) { - - } -}); - -BI.ActionFactory = { - createAction: function (key, options) { - var action; - switch (key) { - case "show": - action = BI.ShowAction; - break; - } - return new action(options); - } -}; diff --git a/src/core/action/action.show.js b/src/core/action/action.show.js deleted file mode 100644 index 68296ae19..000000000 --- a/src/core/action/action.show.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * guy - * 由一个元素切换到另一个元素的行为 - * @class BI.ShowAction - * @extends BI.Action - */ -BI.ShowAction = BI.inherit(BI.Action, { - actionPerformed: function (src, tar, callback) { - tar = tar || this.options.tar; - tar.setVisible(true); - callback && callback(); - }, - - actionBack: function (tar, src, callback) { - tar = tar || this.options.tar; - tar.setVisible(false); - callback && callback(); - } -}); diff --git a/src/core/behavior/0.behavior.js b/src/core/behavior/0.behavior.js deleted file mode 100644 index 3645f87b7..000000000 --- a/src/core/behavior/0.behavior.js +++ /dev/null @@ -1,32 +0,0 @@ -BI.BehaviorFactory = { - createBehavior: function (key, options) { - var behavior; - switch (key) { - case "highlight": - behavior = BI.HighlightBehavior; - break; - case "redmark": - behavior = BI.RedMarkBehavior; - break; - } - return new behavior(options); - } -}; - -/** - * guy - * 行为控件 - * @class BI.Behavior - * @extends BI.OB - */ -BI.Behavior = BI.inherit(BI.OB, { - _defaultConfig: function () { - return BI.extend(BI.Behavior.superclass._defaultConfig.apply(this, arguments), { - rule: function () {return true;} - }); - }, - - doBehavior: function () { - - } -}); diff --git a/src/core/behavior/behavior.highlight.js b/src/core/behavior/behavior.highlight.js deleted file mode 100644 index 683bc061e..000000000 --- a/src/core/behavior/behavior.highlight.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * guy - * - * @class BI.HighlightBehavior - * @extends BI.Behavior - */ -BI.HighlightBehavior = BI.inherit(BI.Behavior, { - doBehavior: function (items) { - var args = Array.prototype.slice.call(arguments, 1), - o = this.options; - BI.each(items, function (i, item) { - if (item instanceof BI.Single) { - var rule = o.rule(item.getValue(), item); - - function doBe (run) { - if (run === true) { - item.doHighLight && item.doHighLight.apply(item, args); - } else { - item.unHighLight && item.unHighLight.apply(item, args); - } - } - - if (BI.isFunction(rule)) { - rule(doBe); - } else { - doBe(rule); - } - } else { - item.doBehavior && item.doBehavior.apply(item, args); - } - }); - } -}); diff --git a/src/core/behavior/behavior.redmark.js b/src/core/behavior/behavior.redmark.js deleted file mode 100644 index b9c6572e9..000000000 --- a/src/core/behavior/behavior.redmark.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * guy - * 标红行为 - * @class BI.RedMarkBehavior - * @extends BI.Behavior - */ -BI.RedMarkBehavior = BI.inherit(BI.Behavior, { - doBehavior: function (items) { - var args = Array.prototype.slice.call(arguments, 1), - o = this.options; - BI.each(items, function (i, item) { - if(item instanceof BI.Single) { - if (o.rule(item.getValue(), item)) { - item.doRedMark && item.doRedMark.apply(item, args); - } else { - item.doRedMark && item.unRedMark.apply(item, args); - } - } else { - item.doBehavior && item.doBehavior.apply(item, args); - } - }); - } -}); diff --git a/src/core/conflict.js b/src/core/conflict.js deleted file mode 100644 index dba9b8b6f..000000000 --- a/src/core/conflict.js +++ /dev/null @@ -1,7 +0,0 @@ - -if (!_global.$ && !_global.jQuery) { - _global.jQuery = _global.$ = BI.jQuery; -} -if (!_global._) { - _global._ = BI._; -} diff --git a/src/core/constant/events.js b/src/core/constant/events.js deleted file mode 100644 index 76eb97021..000000000 --- a/src/core/constant/events.js +++ /dev/null @@ -1,444 +0,0 @@ -/** - * 事件集合 - * @class BI.Events - */ -BI._.extend(BI, { - Events: { - - /** - * @static - * @property keydown事件 - */ - KEYDOWN: "_KEYDOWN", - - /** - * @static - * @property 回撤事件 - */ - BACKSPACE: "_BACKSPACE", - - /** - * @static - * @property 空格事件 - */ - SPACE: "_SPACE", - - /** - * @static - * @property 回车事件 - */ - ENTER: "_ENTER", - - /** - * @static - * @property 确定事件 - */ - CONFIRM: "_CONFIRM", - - /** - * @static - * @property 错误事件 - */ - ERROR: "_ERROR", - - /** - * @static - * @property 暂停事件 - */ - PAUSE: "_PAUSE", - - /** - * @static - * @property destroy事件 - */ - DESTROY: "_DESTROY", - - /** - * @static - * @property 挂载事件 - */ - MOUNT: "_MOUNT", - - /** - * @static - * @property 取消挂载事件 - */ - UNMOUNT: "_UNMOUNT", - - /** - * @static - * @property 清除选择 - */ - CLEAR: "_CLEAR", - - /** - * @static - * @property 添加数据 - */ - ADD: "_ADD", - - /** - * @static - * @property 正在编辑状态事件 - */ - EDITING: "_EDITING", - - /** - * @static - * @property 空状态事件 - */ - EMPTY: "_EMPTY", - - /** - * @static - * @property 显示隐藏事件 - */ - VIEW: "_VIEW", - - /** - * @static - * @property 窗体改变大小 - */ - RESIZE: "_RESIZE", - - /** - * @static - * @property 编辑前事件 - */ - BEFOREEDIT: "_BEFOREEDIT", - - /** - * @static - * @property 编辑后事件 - */ - AFTEREDIT: "_AFTEREDIT", - - /** - * @static - * @property 开始编辑事件 - */ - STARTEDIT: "_STARTEDIT", - - /** - * @static - * @property 停止编辑事件 - */ - STOPEDIT: "_STOPEDIT", - - /** - * @static - * @property 值改变事件 - */ - CHANGE: "_CHANGE", - - /** - * @static - * @property 下拉弹出菜单事件 - */ - EXPAND: "_EXPAND", - - /** - * @static - * @property 关闭下拉菜单事件 - */ - COLLAPSE: "_COLLAPSE", - - /** - * @static - * @property 下拉菜单切换展开收起事件 - */ - TOGGLE: "_TOGGLE", - - /** - * @static - * @property 回调事件 - */ - CALLBACK: "_CALLBACK", - - /** - * @static - * @property 点击事件 - */ - CLICK: "_CLICK", - - /** - * @static - * @property 状态改变事件,一般是用在复选按钮和单选按钮 - */ - STATECHANGE: "_STATECHANGE", - - /** - * @static - * @property 状态改变前事件 - */ - BEFORESTATECHANGE: "_BEFORESTATECHANGE", - - - /** - * @static - * @property 初始化事件 - */ - INIT: "_INIT", - - /** - * @static - * @property 初始化后事件 - */ - AFTERINIT: "_AFTERINIT", - - /** - * @static - * @property 滚动条滚动事件 - */ - SCROLL: "_SCROLL", - - - /** - * @static - * @property 开始加载事件 - */ - STARTLOAD: "_STARTLOAD", - - /** - * @static - * @property 加载后事件 - */ - AFTERLOAD: "_AFTERLOAD", - - - /** - * @static - * @property 提交前事件 - */ - BS: "beforesubmit", - - /** - * @static - * @property 提交后事件 - */ - AS: "aftersubmit", - - /** - * @static - * @property 提交完成事件 - */ - SC: "submitcomplete", - - /** - * @static - * @property 提交失败事件 - */ - SF: "submitfailure", - - /** - * @static - * @property 提交成功事件 - */ - SS: "submitsuccess", - - /** - * @static - * @property 校验提交前事件 - */ - BVW: "beforeverifywrite", - - /** - * @static - * @property 校验提交后事件 - */ - AVW: "afterverifywrite", - - /** - * @static - * @property 校验后事件 - */ - AV: "afterverify", - - /** - * @static - * @property 填报前事件 - */ - BW: "beforewrite", - - /** - * @static - * @property 填报后事件 - */ - AW: "afterwrite", - - /** - * @static - * @property 填报成功事件 - */ - WS: "writesuccess", - - /** - * @static - * @property 填报失败事件 - */ - WF: "writefailure", - - /** - * @static - * @property 添加行前事件 - */ - BA: "beforeappend", - - /** - * @static - * @property 添加行后事件 - */ - AA: "afterappend", - - /** - * @static - * @property 删除行前事件 - */ - BD: "beforedelete", - - /** - * @static - * @property 删除行后事件 - */ - AD: "beforedelete", - - /** - * @static - * @property 未提交离开事件 - */ - UC: "unloadcheck", - - - /** - * @static - * @property PDF导出前事件 - */ - BTOPDF: "beforetopdf", - - /** - * @static - * @property PDF导出后事件 - */ - ATOPDF: "aftertopdf", - - /** - * @static - * @property Excel导出前事件 - */ - BTOEXCEL: "beforetoexcel", - - /** - * @static - * @property Excel导出后事件 - */ - ATOEXCEL: "aftertoexcel", - - /** - * @static - * @property Word导出前事件 - */ - BTOWORD: "beforetoword", - - /** - * @static - * @property Word导出后事件 - */ - ATOWORD: "aftertoword", - - /** - * @static - * @property 图片导出前事件 - */ - BTOIMAGE: "beforetoimage", - - /** - * @static - * @property 图片导出后事件 - */ - ATOIMAGE: "aftertoimage", - - /** - * @static - * @property HTML导出前事件 - */ - BTOHTML: "beforetohtml", - - /** - * @static - * @property HTML导出后事件 - */ - ATOHTML: "aftertohtml", - - /** - * @static - * @property Excel导入前事件 - */ - BIMEXCEL: "beforeimportexcel", - - /** - * @static - * @property Excel导出后事件 - */ - AIMEXCEL: "afterimportexcel", - - /** - * @static - * @property PDF打印前事件 - */ - BPDFPRINT: "beforepdfprint", - - /** - * @static - * @property PDF打印后事件 - */ - APDFPRINT: "afterpdfprint", - - /** - * @static - * @property Flash打印前事件 - */ - BFLASHPRINT: "beforeflashprint", - - /** - * @static - * @property Flash打印后事件 - */ - AFLASHPRINT: "afterflashprint", - - /** - * @static - * @property Applet打印前事件 - */ - BAPPLETPRINT: "beforeappletprint", - - /** - * @static - * @property Applet打印后事件 - */ - AAPPLETPRINT: "afterappletprint", - - /** - * @static - * @property 服务器打印前事件 - */ - BSEVERPRINT: "beforeserverprint", - - /** - * @static - * @property 服务器打印后事件 - */ - ASERVERPRINT: "afterserverprint", - - /** - * @static - * @property 邮件发送前事件 - */ - BEMAIL: "beforeemail", - - /** - * @static - * @property 邮件发送后事件 - */ - AEMAIL: "afteremail" - } -}); diff --git a/src/core/constant/var.js b/src/core/constant/var.js deleted file mode 100644 index f9acb8b30..000000000 --- a/src/core/constant/var.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * 常量 - */ - -BI._.extend(BI, { - MAX: 0xfffffffffffffff, - MIN: -0xfffffffffffffff, - EVENT_RESPONSE_TIME: 200, - EVENT_BLUR: true, - zIndex_layer: 1e5, - zIndex_popover: 1e6, - zIndex_popup: 1e7, - zIndex_masker: 1e8, - zIndex_tip: 1e9, - emptyStr: "", - pixUnit: "px", - pixRatio: 1, - // 一定返回最终的单位 - pixFormat: function (pix, border) { - if (!BI.isNumber(pix)) { - return pix; - } - if (BI.pixUnit === "px") { - return (pix / BI.pixRatio - (border || 0)) + BI.pixUnit; - } - var length = pix / BI.pixRatio + BI.pixUnit; - if (border > 0) { - return `calc(${length} - ${border + "px"})`; - } - return length; - }, - toPix: function (pix, border) { - if (!BI.isNumber(pix)) { - return pix; - } - if (BI.pixUnit === "px") { - return pix - (border || 0) * BI.pixRatio; - } - if (border > 0) { - return `calc(${pix / BI.pixRatio + BI.pixUnit} - ${border + "px"})`; - } - return pix; - }, - emptyFn: function () { - }, - empty: null, - Key: { - 48: "0", - 49: "1", - 50: "2", - 51: "3", - 52: "4", - 53: "5", - 54: "6", - 55: "7", - 56: "8", - 57: "9", - 65: "a", - 66: "b", - 67: "c", - 68: "d", - 69: "e", - 70: "f", - 71: "g", - 72: "h", - 73: "i", - 74: "j", - 75: "k", - 76: "l", - 77: "m", - 78: "n", - 79: "o", - 80: "p", - 81: "q", - 82: "r", - 83: "s", - 84: "t", - 85: "u", - 86: "v", - 87: "w", - 88: "x", - 89: "y", - 90: "z", - 96: "0", - 97: "1", - 98: "2", - 99: "3", - 100: "4", - 101: "5", - 102: "6", - 103: "7", - 104: "8", - 105: "9", - 106: "*", - 107: "+", - 109: "-", - 110: ".", - 111: "/" - }, - KeyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - }, - Status: { - SUCCESS: 1, - WRONG: 2, - START: 3, - END: 4, - WAITING: 5, - READY: 6, - RUNNING: 7, - OUTOFBOUNDS: 8, - NULL: -1 - }, - Direction: { - Top: "top", - Bottom: "bottom", - Left: "left", - Right: "right", - Custom: "custom" - }, - Axis: { - Vertical: "vertical", - Horizontal: "horizontal" - }, - Selection: { - Default: -2, - None: -1, - Single: 0, - Multi: 1, - All: 2 - }, - HorizontalAlign: { - Left: "left", - Right: "right", - Center: "center", - Stretch: "stretch" - }, - VerticalAlign: { - Middle: "middle", - Top: "top", - Bottom: "bottom", - Stretch: "stretch" - }, - StartOfWeek: 1, - BlankSplitChar: "\u200b \u200b", -}); diff --git a/src/core/controller/0.controller.js b/src/core/controller/0.controller.js deleted file mode 100644 index 4eba2c0ad..000000000 --- a/src/core/controller/0.controller.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * guy - * 控制器 - * Controller层超类 - * @class BI.Controller - * @extends BI.OB - * @abstract - */ -BI.Controller = BI.inherit(BI.OB, { -}); -BI.Controller.EVENT_CHANGE = "__EVENT_CHANGE__"; diff --git a/src/core/controller/controller.broadcast.js b/src/core/controller/controller.broadcast.js deleted file mode 100644 index 71d7330c7..000000000 --- a/src/core/controller/controller.broadcast.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 广播 - * - * Created by GUY on 2015/12/23. - * @class - */ -BI.BroadcastController = BI.inherit(BI.Controller, { - init: function () { - this._broadcasts = {}; - }, - - on: function (name, fn) { - var self = this; - if (!this._broadcasts[name]) { - this._broadcasts[name] = []; - } - this._broadcasts[name].push(fn); - return function () { - self.remove(name, fn); - }; - }, - - send: function (name) { - var args = [].slice.call(arguments, 1); - BI.each(this._broadcasts[name], function (i, fn) { - fn.apply(null, args); - }); - }, - - remove: function (name, fn) { - var self = this; - if (fn) { - BI.remove(this._broadcasts[name], function (index, cb) { - return fn === cb; - }); - if (this._broadcasts[name].length === 0) { - delete this._broadcasts[name]; - } - } else { - delete this._broadcasts[name]; - } - return this; - } -}); diff --git a/src/core/controller/controller.bubbles.js b/src/core/controller/controller.bubbles.js deleted file mode 100644 index fc736a094..000000000 --- a/src/core/controller/controller.bubbles.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 气泡图控制器 - * 控制气泡图的显示方向 - * - * Created by GUY on 2015/8/21. - * @class - */ -BI.BubblesController = BI.inherit(BI.Controller, { - init: function () { - this.storeBubbles = {}; - this.storePoppers = {}; - }, - - /** - * - * @param name - * @param text - * @param context - * @param offsetStyle center, left, right三种类型, 默认left - * @returns {BI.BubblesController} - */ - show: function (name, text, context, opt) { - opt || (opt = {}); - var container = opt.container || context; - var offsetStyle = opt.offsetStyle || "left"; - var level = opt.level || "error"; - var adjustYOffset = opt.adjustYOffset || 0; - var adjustXOffset = opt.adjustXOffset || 0; - // var fixed = opt.fixed !== false; - - if (!this.storeBubbles[name]) { - this.storeBubbles[name] = BI.createWidget({ - type: "bi.text", - cls: "bi-bubble" + " bubble-" + level, - text: text, - hgap: 5, - height: 18 - }); - } - var bubble = this.storeBubbles[name]; - if (bubble.getText() !== text) { - bubble.setText(text); - } - - BI.createWidget({ - type: "bi.default", - element: container, - items: [ - { - el: bubble - } - ] - }); - if (this.storePoppers[name]) { - this.storePoppers[name].destroy(); - } - this.storePoppers[name] = BI.Popper.createPopper(context.element[0], bubble.element[0], { - placement: ({ - left: "top-start", - center: "top", - right: "top-end" - })[offsetStyle], - strategy: "fixed", - modifiers: [ - { - name: "offset", - options: { - offset: [adjustXOffset, adjustYOffset] - } - }, - { - name: "preventOverflow", - enabled: false - } - ] - }); - return this; - }, - - hide: function (name) { - this.remove(name); - return this; - }, - - has: function (name) { - return this.storeBubbles[name] != null; - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - this.storeBubbles[name].destroy(); - this.storePoppers[name] && this.storePoppers[name].destroy(); - delete this.storeBubbles[name]; - return this; - }, - - removeAll: function () { - BI.each(this.storeBubbles, function (name, bubble) { - bubble.destroy(); - }); - BI.each(this.storePoppers, function (name, popper) { - popper.destroy(); - }); - this.storeBubbles = {}; - this.storePoppers = {}; - return this; - } -}); diff --git a/src/core/controller/controller.drawer.js b/src/core/controller/controller.drawer.js deleted file mode 100644 index 68fdadbc8..000000000 --- a/src/core/controller/controller.drawer.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * guy - * popover弹出层控制器, z-index在100w层级 - * @class BI.popoverController - * @extends BI.Controller - */ -BI.DrawerController = BI.inherit(BI.Controller, { - props: function () { - return { - modal: true, // 模态窗口 - render: "body" - }; - }, - - init: function () { - this.modal = this.options.modal; - this.floatManager = {}; - this.floatLayer = {}; - this.floatContainer = {}; - this.floatOpened = {}; - this.zindexMap = {}; - }, - - create: function (name, options, context) { - if (this.has(name)) { - return this; - } - var popover = BI.createWidget(options || {}, { - type: "bi.drawer" - }, context); - this.add(name, popover, options, context); - return this; - }, - - open: function (name) { - var self = this, o = this.options; - if (!this.has(name)) { - return this; - } - if (!this.floatOpened[name]) { - this.floatOpened[name] = true; - var container = this.floatContainer[name]; - var zIndex = BI.Popovers._getZIndex(); - container.element.css("zIndex", zIndex); - this.modal && container.element.__hasZIndexMask__(this.zindexMap[name]) && container.element.__releaseZIndexMask__(this.zindexMap[name]); - this.zindexMap[name] = zIndex; - if (this.modal) { - var mask = container.element.__buildZIndexMask__(BI.Popovers._getZIndex()); - mask.click(function () { - mask.destroy(); - self.get(name).close(); - }); - } - this.get(name).setZindex(BI.Popovers._getZIndex()); - this.floatContainer[name].visible(); - var popover = this.get(name); - popover.show && popover.show(); - } - return this; - }, - - close: function (name) { - if (!this.has(name)) { - return this; - } - if (this.floatOpened[name]) { - delete this.floatOpened[name]; - this.floatContainer[name].invisible(); - this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); - } - return this; - }, - - show: function (name) { - return this.open(name); - }, - - hide: function (name) { - return this.close(name); - }, - - isVisible: function (name) { - return this.has(name) && this.floatOpened[name] === true; - }, - - add: function (name, popover, options, context) { - var self = this; - options || (options = {}); - if (this.has(name)) { - return this; - } - this.floatContainer[name] = BI.createWidget({ - type: "bi.absolute", - cls: "bi-popup-view", - items: [{ - el: (this.floatLayer[name] = BI.createWidget({ - type: "bi.absolute", - items: [popover] - }, context)), - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - this.floatManager[name] = popover; - (function (key) { - popover.on(BI.Drawer.EVENT_CLOSE, function () { - self.close(key); - }); - })(name); - BI.createWidget({ - type: "bi.absolute", - element: options.container || this.options.render, - items: [{ - el: this.floatContainer[name], - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - return this; - }, - - get: function (name) { - return this.floatManager[name]; - }, - - has: function (name) { - return BI.isNotNull(this.floatManager[name]); - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - this.floatContainer[name].destroy(); - this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); - delete this.floatManager[name]; - delete this.floatLayer[name]; - delete this.zindexMap[name]; - delete this.floatContainer[name]; - delete this.floatOpened[name]; - return this; - }, - - removeAll: function () { - var self = this; - BI.each(this.floatContainer, function (name, container) { - container.destroy(); - self.modal && self.floatContainer[name].element.__releaseZIndexMask__(self.zindexMap[name]); - }); - this.floatManager = {}; - this.floatLayer = {}; - this.floatContainer = {}; - this.floatOpened = {}; - this.zindexMap = {}; - return this; - } -}); diff --git a/src/core/controller/controller.layer.js b/src/core/controller/controller.layer.js deleted file mode 100644 index f0edac403..000000000 --- a/src/core/controller/controller.layer.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * 弹出层面板控制器, z-index在10w层级 - * - * Created by GUY on 2015/6/24. - * @class - */ -BI.LayerController = BI.inherit(BI.Controller, { - props: function () { - return { - render: "body" - }; - }, - - init: function () { - this.layerManager = {}; - this.layouts = {}; - this.zindex = BI.zIndex_layer; - }, - - _initResizer: function () { - this.resizer = BI.Resizers.add("layerController" + BI.uniqueId(), BI.bind(this._resize, this)); - }, - - _resize: function () { - BI.each(this.layouts, function (i, layer) { - if (layer.element.is(":visible")) { - layer.element.trigger("__resize__"); - } - }); - }, - - make: function (name, container, op, context) { - if (BI.isWidget(container)) { - op = op || {}; - op.container = container; - } else { - context = op; - op = container; - } - return this.create(name, null, op, context); - }, - - create: function (name, from, op, context) { - BI.isNull(this.resizer) && this._initResizer(); - if (this.has(name)) { - return this.get(name); - } - op || (op = {}); - var offset = op.offset || {}; - var w = from; - if (BI.isWidget(from)) { - w = from.element; - } - if (BI.isNotEmptyString(w)) { - w = BI.Widget._renderEngine.createElement(w); - } - if (this.has(name)) { - return this.get(name); - } - var widget = BI.createWidget((op.render || {}), BI.extend({ - type: "bi.layout" - }, op), context); - var layout = BI.createWidget({ - type: "bi.absolute", - invisible: true, - items: [ - { - el: widget, - left: 0, - right: 0, - top: 0, - bottom: 0 - } - ] - }, context); - BI.createWidget({ - type: "bi.absolute", - element: op.container || this.options.render, - items: [ - { - el: layout, - left: offset.left || 0, - right: offset.right || 0, - top: offset.top || 0, - bottom: offset.bottom || 0 - } - ] - }); - if (w) { - layout.element.addClass("bi-popup-view"); - - function getComputedPosition() { - - var css = { - left: w.offset().left + (offset.left || 0), - top: w.offset().top + (offset.top || 0), - width: offset.width || (w.outerWidth() - (offset.left || 0) - (offset.right || 0)) || "", - height: offset.height || (w.outerHeight() - (offset.top || 0) - (offset.bottom || 0)) || "" - }; - - const { top, left, scaleY, scaleX } = BI.DOM.getPositionRelativeContainingBlockRect(layout.element[0]); - - css.top = (css.top - top) / scaleY; - css.left = (css.left - left) / scaleX; - - return css; - } - - - layout.element.css(getComputedPosition()); - layout.element.on("__resize__", function () { - w.is(":visible") && - layout.element.css(getComputedPosition()); - }); - } - this.add(name, widget, layout); - return widget; - }, - - show: function (name, callback) { - if (!this.has(name)) { - return this; - } - this._getLayout(name).visible(); - this._getLayout(name).element.css("z-index", this.zindex++).show(0, callback).trigger("__resize__"); - return this; - }, - - hide: function (name, callback) { - if (!this.has(name)) { - return this; - } - this._getLayout(name).invisible(); - this._getLayout(name).element.hide(0, callback); - return this; - }, - - isVisible: function (name) { - return this.has(name) && this._getLayout(name).isVisible(); - }, - - add: function (name, layer, layout) { - if (this.has(name)) { - throw new Error("can not create Layers with the same name"); - } - layout.setVisible(false); - this.layerManager[name] = layer; - this.layouts[name] = layout; - layout.element.css("z-index", this.zindex++); - return this; - }, - - _getLayout: function (name) { - return this.layouts[name]; - }, - - get: function (name) { - return this.layerManager[name]; - }, - - has: function (name) { - return this.layerManager[name] != null; - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - this.layerManager[name].destroy(); - this.layouts[name].destroy(); - delete this.layerManager[name]; - delete this.layouts[name]; - return this; - }, - - removeAll: function () { - var self = this; - BI.each(BI.keys(this.layerManager), function (index, name) { - self.layerManager[name].destroy(); - self.layouts[name].destroy(); - }); - this.layerManager = {}; - this.layouts = {}; - return this; - } -}); diff --git a/src/core/controller/controller.masker.js b/src/core/controller/controller.masker.js deleted file mode 100644 index 0b55b0781..000000000 --- a/src/core/controller/controller.masker.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * 遮罩面板, z-index在1亿层级 - * - * Created by GUY on 2015/6/24. - * @class - */ -BI.MaskersController = BI.inherit(BI.LayerController, { - init: function () { - BI.MaskersController.superclass.init.apply(this, arguments); - this.zindex = BI.zIndex_masker; - } -}); diff --git a/src/core/controller/controller.popover.js b/src/core/controller/controller.popover.js deleted file mode 100644 index 9e36e5849..000000000 --- a/src/core/controller/controller.popover.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * guy - * popover弹出层控制器, z-index在100w层级 - * @class BI.popoverController - * @extends BI.Controller - */ -BI.PopoverController = BI.inherit(BI.Controller, { - props: function () { - return { - modal: true, // 模态窗口 - render: "body" - }; - }, - - init: function () { - this.modal = this.options.modal; - this.floatManager = {}; - this.floatLayer = {}; - this.floatContainer = {}; - this.floatOpened = {}; - this.zindex = BI.zIndex_popover; - this.zindexMap = {}; - }, - - create: function (name, options, context) { - if (this.has(name)) { - return this; - } - var popover = BI.createWidget(options || {}, { - type: "bi.popover" - }, context); - this.add(name, popover, options, context); - return this; - }, - - open: function (name) { - if (!this.has(name)) { - return this; - } - if (!this.floatOpened[name]) { - this.floatOpened[name] = true; - var container = this.floatContainer[name]; - container.element.css("zIndex", this.zindex++); - this.modal && container.element.__hasZIndexMask__(this.zindexMap[name]) && container.element.__releaseZIndexMask__(this.zindexMap[name]); - this.zindexMap[name] = this.zindex; - this.modal && container.element.__buildZIndexMask__(this.zindex++); - this.get(name).setZindex(this.zindex++); - this.floatContainer[name].visible(); - var popover = this.get(name); - popover.show && popover.show(); - var W = BI.Widget._renderEngine.createElement(this.options.render).width(), - H = BI.Widget._renderEngine.createElement(this.options.render).height(); - var w = popover.element.width(), h = popover.element.height(); - var left = (W - w) / 2, top = (H - h) / 2; - if (left < 0) { - left = 0; - } - if (top < 0) { - top = 0; - } - popover.element.css({ - // 这里直接用px就可以 - left: left + "px", - top: top + "px" - }); - } - return this; - }, - - close: function (name) { - if (!this.has(name)) { - return this; - } - if (this.floatOpened[name]) { - delete this.floatOpened[name]; - this.floatContainer[name].invisible(); - this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); - } - return this; - }, - - show: function (name) { - return this.open(name); - }, - - hide: function (name) { - return this.close(name); - }, - - isVisible: function (name) { - return this.has(name) && this.floatOpened[name] === true; - }, - - add: function (name, popover, options, context) { - var self = this; - options || (options = {}); - if (this.has(name)) { - return this; - } - this.floatContainer[name] = BI.createWidget({ - type: "bi.absolute", - cls: "bi-popup-view", - items: [{ - el: (this.floatLayer[name] = BI.createWidget({ - type: "bi.absolute", - items: [popover] - }, context)), - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - this.floatManager[name] = popover; - (function (key) { - popover.on(BI.Popover.EVENT_CLOSE, function () { - self.close(key); - }); - })(name); - BI.createWidget({ - type: "bi.absolute", - element: options.container || this.options.render, - items: [{ - el: this.floatContainer[name], - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - return this; - }, - - get: function (name) { - return this.floatManager[name]; - }, - - has: function (name) { - return BI.isNotNull(this.floatManager[name]); - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - this.floatContainer[name].destroy(); - this.modal && this.floatContainer[name].element.__releaseZIndexMask__(this.zindexMap[name]); - delete this.floatManager[name]; - delete this.floatLayer[name]; - delete this.zindexMap[name]; - delete this.floatContainer[name]; - delete this.floatOpened[name]; - return this; - }, - - removeAll: function () { - var self = this; - BI.each(this.floatContainer, function (name, container) { - container.destroy(); - self.modal && self.floatContainer[name].element.__releaseZIndexMask__(self.zindexMap[name]); - }); - this.floatManager = {}; - this.floatLayer = {}; - this.floatContainer = {}; - this.floatOpened = {}; - this.zindexMap = {}; - return this; - }, - - _getZIndex: function () { - return this.zindex++; - } -}); diff --git a/src/core/controller/controller.resizer.js b/src/core/controller/controller.resizer.js deleted file mode 100644 index 900bd3927..000000000 --- a/src/core/controller/controller.resizer.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * window.resize 控制器 - * - * Created by GUY on 2015/6/24. - * @class - */ -BI.ResizeController = BI.inherit(BI.Controller, { - - init: function () { - this.resizerManger = {}; - }, - - _initResizeListener: function () { - var self = this; - this.resizeHandler = BI.debounce(function (ev) { - self._resize(ev); - }, 30); - if ("onorientationchange" in _global) { - _global.onorientationchange = this.resizeHandler; - } else { - BI.Widget._renderEngine.createElement(_global).resize(this.resizeHandler); - } - }, - - _resize: function (ev) { - BI.each(this.resizerManger, function (key, resizer) { - if (resizer instanceof BI.$) { - if (resizer.is(":visible")) { - resizer.trigger("__resize__"); - } - return; - } - if (resizer instanceof BI.Layout) { - resizer.resize(); - return; - } - if (BI.isFunction(resizer)) { - resizer(ev); - } - }); - }, - - add: function (name, resizer) { - var self = this; - BI.isNull(this.resizeHandler) && this._initResizeListener(); - - if (this.has(name)) { - return this; - } - this.resizerManger[name] = resizer; - return function () { - self.remove(name); - }; - }, - - get: function (name) { - return this.resizerManger[name]; - }, - - has: function (name) { - return this.resizerManger[name] != null; - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - delete this.resizerManger[name]; - return this; - } -}); diff --git a/src/core/controller/controller.tooltips.js b/src/core/controller/controller.tooltips.js deleted file mode 100644 index 98f90fb0b..000000000 --- a/src/core/controller/controller.tooltips.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * tooltip控制器 - * 控制tooltip的显示, 且页面中只有一个tooltip显示 - * - * Created by GUY on 2015/9/8. - * @class BI.TooltipsController - * @extends BI.Controller - */ -BI.TooltipsController = BI.inherit(BI.Controller, { - init: function () { - this.tooltipsManager = {}; - this.showingTips = {};// 存储正在显示的tooltip - }, - - /** - * - * @param opt - * @param opt.text {String} 文本 - * @param opt.level {String} 级别, success或warning - * @param opt.textAlign {String} 文本对齐方式, left, center, right - * @returns {*} - * @private - */ - _createTooltip: function (opt) { - return BI.createWidget({ - type: "bi.tooltip", - ...opt, - stopEvent: true - }); - }, - - // opt: {container: '', belowMouse: false} - show: function (e, name, tooltipOpt, context, opt) { - opt || (opt = {}); - var self = this; - BI.each(this.showingTips, function (i, tip) { - self.hide(i); - }); - this.showingTips = {}; - if (!this.has(name)) { - this.create(name, tooltipOpt, document.fullscreenElement ? context : (opt.container || "body")); - } - if (!opt.belowMouse) { - var offset = context.element.offset(); - var bounds = context.element.bounds(); - if (bounds.height === 0 || bounds.width === 0) { - return; - } - var top = offset.top + bounds.height + 5; - } - var tooltip = this.get(name); - tooltip.element.css({ - left: "0px", - top: "0px" - }); - tooltip.visible(); - tooltip.element.height(tooltip.element[0].scrollHeight); - this.showingTips[name] = true; - // scale影响要计算在内 - // var scale = context.element.offset().left / context.element.get(0).getBoundingClientRect().left; - // var x = (e.pageX || e.clientX) * scale + 15, y = (e.pageY || e.clientY) * scale + 15; - var x = (e.pageX || e.clientX) + 15, y = (e.pageY || e.clientY) + 15; - if (x + tooltip.element.outerWidth() > BI.Widget._renderEngine.createElement("body").outerWidth()) { - x -= tooltip.element.outerWidth() + 15; - } - var bodyHeight = BI.Widget._renderEngine.createElement("body").outerHeight(); - if (y + tooltip.element.outerHeight() > bodyHeight || top + tooltip.element.outerHeight() > bodyHeight) { - y -= tooltip.element.outerHeight() + 15; - !opt.belowMouse && (y = Math.min(y, offset.top - tooltip.element.outerHeight() - 5)); - } else { - !opt.belowMouse && (y = Math.max(y, top)); - } - tooltip.element.css({ - // 这里直接用px就可以 - left: x < 0 ? 0 : x + "px", - top: y < 0 ? 0 : y + "px" - }); - tooltip.element.hover(function () { - self.remove(name); - context.element.trigger("mouseleave.title" + context.getName()); - }); - return this; - }, - - hide: function (name, callback) { - if (!this.has(name)) { - return this; - } - delete this.showingTips[name]; - this.get(name).element.hide(0, callback); - this.get(name).invisible(); - return this; - }, - - create: function (name, tooltipOpt, context) { - if (!this.has(name)) { - var tooltip = this._createTooltip(tooltipOpt); - this.add(name, tooltip); - BI.createWidget({ - type: "bi.absolute", - element: context || "body", - items: [{ - el: tooltip - }] - }); - tooltip.invisible(); - } - return this.get(name); - }, - - add: function (name, bubble) { - if (this.has(name)) { - return this; - } - this.set(name, bubble); - return this; - }, - - get: function (name) { - return this.tooltipsManager[name]; - }, - - set: function (name, bubble) { - this.tooltipsManager[name] = bubble; - }, - - has: function (name) { - return this.tooltipsManager[name] != null; - }, - - remove: function (name) { - if (!this.has(name)) { - return this; - } - this.tooltipsManager[name].destroy(); - delete this.tooltipsManager[name]; - return this; - }, - - removeAll: function () { - BI.each(this.tooltipsManager, function (name, tooltip) { - tooltip.destroy(); - }); - this.tooltipsManager = {}; - this.showingTips = {}; - return this; - } -}); diff --git a/src/core/controller/popper.js b/src/core/controller/popper.js deleted file mode 100644 index 2c6f613fd..000000000 --- a/src/core/controller/popper.js +++ /dev/null @@ -1,2012 +0,0 @@ -/** - * @popperjs/core v2.11.6 - MIT License - */ - -(function (global, factory) { - factory(global.Popper = {}); -}(BI, (function (exports) { - 'use strict'; - - function getWindow(node) { - if (node == null) { - return window; - } - - if (node.toString() !== '[object Window]') { - var ownerDocument = node.ownerDocument; - return ownerDocument ? ownerDocument.defaultView || window : window; - } - - return node; - } - - function isElement(node) { - var OwnElement = getWindow(node).Element; - return node instanceof OwnElement || node instanceof Element; - } - - function isHTMLElement(node) { - var OwnElement = getWindow(node).HTMLElement; - return node instanceof OwnElement || node instanceof HTMLElement; - } - - function isShadowRoot(node) { - // IE 11 has no ShadowRoot - if (typeof ShadowRoot === 'undefined') { - return false; - } - - var OwnElement = getWindow(node).ShadowRoot; - return node instanceof OwnElement || node instanceof ShadowRoot; - } - - var max = Math.max; - var min = Math.min; - var round = Math.round; - - function getUAString() { - var uaData = navigator.userAgentData; - - if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { - return uaData.brands.map(function (item) { - return item.brand + "/" + item.version; - }).join(' '); - } - - return navigator.userAgent; - } - - function isLayoutViewport() { - return !/^((?!chrome|android).)*safari/i.test(getUAString()); - } - - function getBoundingClientRect(element, includeScale, isFixedStrategy) { - if (includeScale === void 0) { - includeScale = false; - } - - if (isFixedStrategy === void 0) { - isFixedStrategy = false; - } - - var clientRect = element.getBoundingClientRect(); - var scaleX = 1; - var scaleY = 1; - - if (includeScale && isHTMLElement(element)) { - scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; - scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; - } - - var _ref = isElement(element) ? getWindow(element) : window, - visualViewport = _ref.visualViewport; - - var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; - var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; - var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; - var width = clientRect.width / scaleX; - var height = clientRect.height / scaleY; - return { - width: width, - height: height, - top: y, - right: x + width, - bottom: y + height, - left: x, - x: x, - y: y - }; - } - - function getWindowScroll(node) { - var win = getWindow(node); - var scrollLeft = win.pageXOffset; - var scrollTop = win.pageYOffset; - return { - scrollLeft: scrollLeft, - scrollTop: scrollTop - }; - } - - function getHTMLElementScroll(element) { - return { - scrollLeft: element.scrollLeft, - scrollTop: element.scrollTop - }; - } - - function getNodeScroll(node) { - if (node === getWindow(node) || !isHTMLElement(node)) { - return getWindowScroll(node); - } else { - return getHTMLElementScroll(node); - } - } - - function getNodeName(element) { - return element ? (element.nodeName || '').toLowerCase() : null; - } - - function getDocumentElement(element) { - // $FlowFixMe[incompatible-return]: assume body is always available - return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] - element.document) || window.document).documentElement; - } - - function getWindowScrollBarX(element) { - // If has a CSS width greater than the viewport, then this will be - // incorrect for RTL. - // Popper 1 is broken in this case and never had a bug report so let's assume - // it's not an issue. I don't think anyone ever specifies width on - // anyway. - // Browsers where the left scrollbar doesn't cause an issue report `0` for - // this (e.g. Edge 2019, IE11, Safari) - return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; - } - - function getComputedStyle(element) { - return getWindow(element).getComputedStyle(element); - } - - function isScrollParent(element) { - // Firefox wants us to check `-x` and `-y` variations as well - var _getComputedStyle = getComputedStyle(element), - overflow = _getComputedStyle.overflow, - overflowX = _getComputedStyle.overflowX, - overflowY = _getComputedStyle.overflowY; - - return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); - } - - function isElementScaled(element) { - var rect = element.getBoundingClientRect(); - var scaleX = round(rect.width) / element.offsetWidth || 1; - var scaleY = round(rect.height) / element.offsetHeight || 1; - return scaleX !== 1 || scaleY !== 1; - } // Returns the composite rect of an element relative to its offsetParent. - // Composite means it takes into account transforms as well as layout. - - - function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { - if (isFixed === void 0) { - isFixed = false; - } - - var isOffsetParentAnElement = isHTMLElement(offsetParent); - var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); - var documentElement = getDocumentElement(offsetParent); - var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); - var scroll = { - scrollLeft: 0, - scrollTop: 0 - }; - var offsets = { - x: 0, - y: 0 - }; - - if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { - if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 - isScrollParent(documentElement)) { - scroll = getNodeScroll(offsetParent); - } - - if (isHTMLElement(offsetParent)) { - offsets = getBoundingClientRect(offsetParent, true); - offsets.x += offsetParent.clientLeft; - offsets.y += offsetParent.clientTop; - } else if (documentElement) { - offsets.x = getWindowScrollBarX(documentElement); - } - } - - return { - x: rect.left + scroll.scrollLeft - offsets.x, - y: rect.top + scroll.scrollTop - offsets.y, - width: rect.width, - height: rect.height - }; - } - - // means it doesn't take into account transforms. - - function getLayoutRect(element) { - var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed. - // Fixes https://github.com/popperjs/popper-core/issues/1223 - - var width = element.offsetWidth; - var height = element.offsetHeight; - - if (Math.abs(clientRect.width - width) <= 1) { - width = clientRect.width; - } - - if (Math.abs(clientRect.height - height) <= 1) { - height = clientRect.height; - } - - return { - x: element.offsetLeft, - y: element.offsetTop, - width: width, - height: height - }; - } - - function getParentNode(element) { - if (getNodeName(element) === 'html') { - return element; - } - - return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle - // $FlowFixMe[incompatible-return] - // $FlowFixMe[prop-missing] - element.assignedSlot || // step into the shadow DOM of the parent of a slotted node - element.parentNode || ( // DOM Element detected - isShadowRoot(element) ? element.host : null) || // ShadowRoot detected - // $FlowFixMe[incompatible-call]: HTMLElement is a Node - getDocumentElement(element) // fallback - - ); - } - - function getScrollParent(node) { - if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { - // $FlowFixMe[incompatible-return]: assume body is always available - return node.ownerDocument.body; - } - - if (isHTMLElement(node) && isScrollParent(node)) { - return node; - } - - return getScrollParent(getParentNode(node)); - } - - /* - given a DOM element, return the list of all scroll parents, up the list of ancesors - until we get to the top window object. This list is what we attach scroll listeners - to, because if any of these parent elements scroll, we'll need to re-calculate the - reference element's position. - */ - - function listScrollParents(element, list) { - var _element$ownerDocumen; - - if (list === void 0) { - list = []; - } - - var scrollParent = getScrollParent(element); - var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); - var win = getWindow(scrollParent); - var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; - var updatedList = list.concat(target); - return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here - updatedList.concat(listScrollParents(getParentNode(target))); - } - - function isTableElement(element) { - return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; - } - - function getTrueOffsetParent(element) { - if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 - getComputedStyle(element).position === 'fixed') { - return null; - } - - return element.offsetParent; - } // `.offsetParent` reports `null` for fixed elements, while absolute elements - // return the containing block - - - function getContainingBlock(element) { - var isFirefox = /firefox/i.test(getUAString()); - var isIE = /Trident/i.test(getUAString()); - - if (isIE && isHTMLElement(element)) { - // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport - var elementCss = getComputedStyle(element); - - if (elementCss.position === 'fixed') { - return null; - } - } - - var currentNode = getParentNode(element); - - if (isShadowRoot(currentNode)) { - currentNode = currentNode.host; - } - - while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { - var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that - // create a containing block. - // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block - - if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { - return currentNode; - } else { - currentNode = currentNode.parentNode; - } - } - - return null; - } // Gets the closest ancestor positioned element. Handles some edge cases, - // such as table ancestors and cross browser bugs. - - - function getOffsetParent(element) { - var window = getWindow(element); - var offsetParent = getTrueOffsetParent(element); - - while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') { - offsetParent = getTrueOffsetParent(offsetParent); - } - - if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) { - return window; - } - - return offsetParent || getContainingBlock(element) || window; - } - - var top = 'top'; - var bottom = 'bottom'; - var right = 'right'; - var left = 'left'; - var auto = 'auto'; - var basePlacements = [top, bottom, right, left]; - var start = 'start'; - var end = 'end'; - var clippingParents = 'clippingParents'; - var viewport = 'viewport'; - var popper = 'popper'; - var reference = 'reference'; - var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { - return acc.concat([placement + "-" + start, placement + "-" + end]); - }, []); - var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { - return acc.concat([placement, placement + "-" + start, placement + "-" + end]); - }, []); // modifiers that need to read the DOM - - var beforeRead = 'beforeRead'; - var read = 'read'; - var afterRead = 'afterRead'; // pure-logic modifiers - - var beforeMain = 'beforeMain'; - var main = 'main'; - var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) - - var beforeWrite = 'beforeWrite'; - var write = 'write'; - var afterWrite = 'afterWrite'; - var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; - - function order(modifiers) { - var map = new Map(); - var visited = new Set(); - var result = []; - modifiers.forEach(function (modifier) { - map.set(modifier.name, modifier); - }); // On visiting object, check for its dependencies and visit them recursively - - function sort(modifier) { - visited.add(modifier.name); - var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); - requires.forEach(function (dep) { - if (!visited.has(dep)) { - var depModifier = map.get(dep); - - if (depModifier) { - sort(depModifier); - } - } - }); - result.push(modifier); - } - - modifiers.forEach(function (modifier) { - if (!visited.has(modifier.name)) { - // check for visited object - sort(modifier); - } - }); - return result; - } - - function orderModifiers(modifiers) { - // order based on dependencies - var orderedModifiers = order(modifiers); // order based on phase - - return modifierPhases.reduce(function (acc, phase) { - return acc.concat(orderedModifiers.filter(function (modifier) { - return modifier.phase === phase; - })); - }, []); - } - - function debounce(fn) { - var pending; - return function () { - if (!pending) { - pending = new Promise(function (resolve) { - Promise.resolve().then(function () { - pending = undefined; - resolve(fn()); - }); - }); - } - - return pending; - }; - } - - function format(str) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return [].concat(args).reduce(function (p, c) { - return p.replace(/%s/, c); - }, str); - } - - var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; - var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; - var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options']; - - function validateModifiers(modifiers) { - modifiers.forEach(function (modifier) { - [].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)` - .filter(function (value, index, self) { - return self.indexOf(value) === index; - }).forEach(function (key) { - switch (key) { - case 'name': - if (typeof modifier.name !== 'string') { - console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\"")); - } - - break; - - case 'enabled': - if (typeof modifier.enabled !== 'boolean') { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\"")); - } - - break; - - case 'phase': - if (modifierPhases.indexOf(modifier.phase) < 0) { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\"")); - } - - break; - - case 'fn': - if (typeof modifier.fn !== 'function') { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\"")); - } - - break; - - case 'effect': - if (modifier.effect != null && typeof modifier.effect !== 'function') { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\"")); - } - - break; - - case 'requires': - if (modifier.requires != null && !Array.isArray(modifier.requires)) { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\"")); - } - - break; - - case 'requiresIfExists': - if (!Array.isArray(modifier.requiresIfExists)) { - console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\"")); - } - - break; - - case 'options': - case 'data': - break; - - default: - console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) { - return "\"" + s + "\""; - }).join(', ') + "; but \"" + key + "\" was provided."); - } - - modifier.requires && modifier.requires.forEach(function (requirement) { - if (modifiers.find(function (mod) { - return mod.name === requirement; - }) == null) { - console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); - } - }); - }); - }); - } - - function uniqueBy(arr, fn) { - var identifiers = new Set(); - return arr.filter(function (item) { - var identifier = fn(item); - - if (!identifiers.has(identifier)) { - identifiers.add(identifier); - return true; - } - }); - } - - function getBasePlacement(placement) { - return placement.split('-')[0]; - } - - function mergeByName(modifiers) { - var merged = modifiers.reduce(function (merged, current) { - var existing = merged[current.name]; - merged[current.name] = existing ? Object.assign({}, existing, current, { - options: Object.assign({}, existing.options, current.options), - data: Object.assign({}, existing.data, current.data) - }) : current; - return merged; - }, {}); // IE11 does not support Object.values - - return Object.keys(merged).map(function (key) { - return merged[key]; - }); - } - - function getViewportRect(element, strategy) { - var win = getWindow(element); - var html = getDocumentElement(element); - var visualViewport = win.visualViewport; - var width = html.clientWidth; - var height = html.clientHeight; - var x = 0; - var y = 0; - - if (visualViewport) { - width = visualViewport.width; - height = visualViewport.height; - var layoutViewport = isLayoutViewport(); - - if (layoutViewport || !layoutViewport && strategy === 'fixed') { - x = visualViewport.offsetLeft; - y = visualViewport.offsetTop; - } - } - - return { - width: width, - height: height, - x: x + getWindowScrollBarX(element), - y: y - }; - } - - // of the `` and `` rect bounds if horizontally scrollable - - function getDocumentRect(element) { - var _element$ownerDocumen; - - var html = getDocumentElement(element); - var winScroll = getWindowScroll(element); - var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; - var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); - var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); - var x = -winScroll.scrollLeft + getWindowScrollBarX(element); - var y = -winScroll.scrollTop; - - if (getComputedStyle(body || html).direction === 'rtl') { - x += max(html.clientWidth, body ? body.clientWidth : 0) - width; - } - - return { - width: width, - height: height, - x: x, - y: y - }; - } - - function contains(parent, child) { - var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method - - if (parent.contains(child)) { - return true; - } // then fallback to custom implementation with Shadow DOM support - else if (rootNode && isShadowRoot(rootNode)) { - var next = child; - - do { - if (next && parent.isSameNode(next)) { - return true; - } // $FlowFixMe[prop-missing]: need a better way to handle this... - - - next = next.parentNode || next.host; - } while (next); - } // Give up, the result is false - - - return false; - } - - function rectToClientRect(rect) { - return Object.assign({}, rect, { - left: rect.x, - top: rect.y, - right: rect.x + rect.width, - bottom: rect.y + rect.height - }); - } - - function getInnerBoundingClientRect(element, strategy) { - var rect = getBoundingClientRect(element, false, strategy === 'fixed'); - rect.top = rect.top + element.clientTop; - rect.left = rect.left + element.clientLeft; - rect.bottom = rect.top + element.clientHeight; - rect.right = rect.left + element.clientWidth; - rect.width = element.clientWidth; - rect.height = element.clientHeight; - rect.x = rect.left; - rect.y = rect.top; - return rect; - } - - function getClientRectFromMixedType(element, clippingParent, strategy) { - return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); - } // A "clipping parent" is an overflowable container with the characteristic of - // clipping (or hiding) overflowing elements with a position different from - // `initial` - - - function getClippingParents(element) { - var clippingParents = listScrollParents(getParentNode(element)); - var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0; - var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; - - if (!isElement(clipperElement)) { - return []; - } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 - - - return clippingParents.filter(function (clippingParent) { - return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; - }); - } // Gets the maximum area that the element is visible in due to any number of - // clipping parents - - - function getClippingRect(element, boundary, rootBoundary, strategy) { - var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); - var clippingParents = [].concat(mainClippingParents, [rootBoundary]); - var firstClippingParent = clippingParents[0]; - var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { - var rect = getClientRectFromMixedType(element, clippingParent, strategy); - accRect.top = max(rect.top, accRect.top); - accRect.right = min(rect.right, accRect.right); - accRect.bottom = min(rect.bottom, accRect.bottom); - accRect.left = max(rect.left, accRect.left); - return accRect; - }, getClientRectFromMixedType(element, firstClippingParent, strategy)); - clippingRect.width = clippingRect.right - clippingRect.left; - clippingRect.height = clippingRect.bottom - clippingRect.top; - clippingRect.x = clippingRect.left; - clippingRect.y = clippingRect.top; - return clippingRect; - } - - function getVariation(placement) { - return placement.split('-')[1]; - } - - function getMainAxisFromPlacement(placement) { - return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; - } - - function computeOffsets(_ref) { - var reference = _ref.reference, - element = _ref.element, - placement = _ref.placement; - var basePlacement = placement ? getBasePlacement(placement) : null; - var variation = placement ? getVariation(placement) : null; - var commonX = reference.x + reference.width / 2 - element.width / 2; - var commonY = reference.y + reference.height / 2 - element.height / 2; - var offsets; - - switch (basePlacement) { - case top: - offsets = { - x: commonX, - y: reference.y - element.height - }; - break; - - case bottom: - offsets = { - x: commonX, - y: reference.y + reference.height - }; - break; - - case right: - offsets = { - x: reference.x + reference.width, - y: commonY - }; - break; - - case left: - offsets = { - x: reference.x - element.width, - y: commonY - }; - break; - - default: - offsets = { - x: reference.x, - y: reference.y - }; - } - - var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; - - if (mainAxis != null) { - var len = mainAxis === 'y' ? 'height' : 'width'; - - switch (variation) { - case start: - offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); - break; - - case end: - offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); - break; - } - } - - return offsets; - } - - function getFreshSideObject() { - return { - top: 0, - right: 0, - bottom: 0, - left: 0 - }; - } - - function mergePaddingObject(paddingObject) { - return Object.assign({}, getFreshSideObject(), paddingObject); - } - - function expandToHashMap(value, keys) { - return keys.reduce(function (hashMap, key) { - hashMap[key] = value; - return hashMap; - }, {}); - } - - function detectOverflow(state, options) { - if (options === void 0) { - options = {}; - } - - var _options = options, - _options$placement = _options.placement, - placement = _options$placement === void 0 ? state.placement : _options$placement, - _options$strategy = _options.strategy, - strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, - _options$boundary = _options.boundary, - boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, - _options$rootBoundary = _options.rootBoundary, - rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, - _options$elementConte = _options.elementContext, - elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, - _options$altBoundary = _options.altBoundary, - altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, - _options$padding = _options.padding, - padding = _options$padding === void 0 ? 0 : _options$padding; - var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); - var altContext = elementContext === popper ? reference : popper; - var popperRect = state.rects.popper; - var element = state.elements[altBoundary ? altContext : elementContext]; - var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); - var referenceClientRect = getBoundingClientRect(state.elements.reference); - var popperOffsets = computeOffsets({ - reference: referenceClientRect, - element: popperRect, - strategy: 'absolute', - placement: placement - }); - var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets)); - var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect - // 0 or negative = within the clipping rect - - var overflowOffsets = { - top: clippingClientRect.top - elementClientRect.top + paddingObject.top, - bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, - left: clippingClientRect.left - elementClientRect.left + paddingObject.left, - right: elementClientRect.right - clippingClientRect.right + paddingObject.right - }; - var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element - - if (elementContext === popper && offsetData) { - var offset = offsetData[placement]; - Object.keys(overflowOffsets).forEach(function (key) { - var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; - var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; - overflowOffsets[key] += offset[axis] * multiply; - }); - } - - return overflowOffsets; - } - - var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.'; - var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.'; - var DEFAULT_OPTIONS = { - placement: 'bottom', - modifiers: [], - strategy: 'absolute' - }; - - function areValidElements() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return !args.some(function (element) { - return !(element && typeof element.getBoundingClientRect === 'function'); - }); - } - - function popperGenerator(generatorOptions) { - if (generatorOptions === void 0) { - generatorOptions = {}; - } - - var _generatorOptions = generatorOptions, - _generatorOptions$def = _generatorOptions.defaultModifiers, - defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, - _generatorOptions$def2 = _generatorOptions.defaultOptions, - defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; - return function createPopper(reference, popper, options) { - if (options === void 0) { - options = defaultOptions; - } - - var state = { - placement: 'bottom', - orderedModifiers: [], - options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), - modifiersData: {}, - elements: { - reference: reference, - popper: popper - }, - attributes: {}, - styles: {} - }; - var effectCleanupFns = []; - var isDestroyed = false; - var instance = { - state: state, - setOptions: function setOptions(setOptionsAction) { - var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; - cleanupModifierEffects(); - state.options = Object.assign({}, defaultOptions, state.options, options); - state.scrollParents = { - reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], - popper: listScrollParents(popper) - }; // Orders the modifiers based on their dependencies and `phase` - // properties - - var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers - - state.orderedModifiers = orderedModifiers.filter(function (m) { - return m.enabled; - }); // Validate the provided modifiers so that the consumer will get warned - // if one of the modifiers is invalid for any reason - - { - var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) { - var name = _ref.name; - return name; - }); - validateModifiers(modifiers); - - if (getBasePlacement(state.options.placement) === auto) { - var flipModifier = state.orderedModifiers.find(function (_ref2) { - var name = _ref2.name; - return name === 'flip'; - }); - - if (!flipModifier) { - console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' ')); - } - } - - var _getComputedStyle = getComputedStyle(popper), - marginTop = _getComputedStyle.marginTop, - marginRight = _getComputedStyle.marginRight, - marginBottom = _getComputedStyle.marginBottom, - marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can - // cause bugs with positioning, so we'll warn the consumer - - - if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) { - return parseFloat(margin); - })) { - console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' ')); - } - } - - runModifierEffects(); - return instance.update(); - }, - // Sync update – it will always be executed, even if not necessary. This - // is useful for low frequency updates where sync behavior simplifies the - // logic. - // For high frequency updates (e.g. `resize` and `scroll` events), always - // prefer the async Popper#update method - forceUpdate: function forceUpdate() { - if (isDestroyed) { - return; - } - - var _state$elements = state.elements, - reference = _state$elements.reference, - popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements - // anymore - - if (!areValidElements(reference, popper)) { - { - console.error(INVALID_ELEMENT_ERROR); - } - - return; - } // Store the reference and popper rects to be read by modifiers - - - state.rects = { - reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), - popper: getLayoutRect(popper) - }; // Modifiers have the ability to reset the current update cycle. The - // most common use case for this is the `flip` modifier changing the - // placement, which then needs to re-run all the modifiers, because the - // logic was previously ran for the previous placement and is therefore - // stale/incorrect - - state.reset = false; - state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier - // is filled with the initial data specified by the modifier. This means - // it doesn't persist and is fresh on each update. - // To ensure persistent data, use `${name}#persistent` - - state.orderedModifiers.forEach(function (modifier) { - return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); - }); - var __debug_loops__ = 0; - - for (var index = 0; index < state.orderedModifiers.length; index++) { - { - __debug_loops__ += 1; - - if (__debug_loops__ > 100) { - console.error(INFINITE_LOOP_ERROR); - break; - } - } - - if (state.reset === true) { - state.reset = false; - index = -1; - continue; - } - - var _state$orderedModifie = state.orderedModifiers[index], - fn = _state$orderedModifie.fn, - _state$orderedModifie2 = _state$orderedModifie.options, - _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, - name = _state$orderedModifie.name; - - if (typeof fn === 'function') { - state = fn({ - state: state, - options: _options, - name: name, - instance: instance - }) || state; - } - } - }, - // Async and optimistically optimized update – it will not be executed if - // not necessary (debounced to run at most once-per-tick) - update: debounce(function () { - return new Promise(function (resolve) { - instance.forceUpdate(); - resolve(state); - }); - }), - destroy: function destroy() { - cleanupModifierEffects(); - isDestroyed = true; - } - }; - - if (!areValidElements(reference, popper)) { - { - console.error(INVALID_ELEMENT_ERROR); - } - - return instance; - } - - instance.setOptions(options).then(function (state) { - if (!isDestroyed && options.onFirstUpdate) { - options.onFirstUpdate(state); - } - }); // Modifiers have the ability to execute arbitrary code before the first - // update cycle runs. They will be executed in the same order as the update - // cycle. This is useful when a modifier adds some persistent data that - // other modifiers need to use, but the modifier is run after the dependent - // one. - - function runModifierEffects() { - state.orderedModifiers.forEach(function (_ref3) { - var name = _ref3.name, - _ref3$options = _ref3.options, - options = _ref3$options === void 0 ? {} : _ref3$options, - effect = _ref3.effect; - - if (typeof effect === 'function') { - var cleanupFn = effect({ - state: state, - name: name, - instance: instance, - options: options - }); - - var noopFn = function noopFn() { - }; - - effectCleanupFns.push(cleanupFn || noopFn); - } - }); - } - - function cleanupModifierEffects() { - effectCleanupFns.forEach(function (fn) { - return fn(); - }); - effectCleanupFns = []; - } - - return instance; - }; - } - - var passive = { - passive: true - }; - - function effect$2(_ref) { - var state = _ref.state, - instance = _ref.instance, - options = _ref.options; - var _options$scroll = options.scroll, - scroll = _options$scroll === void 0 ? true : _options$scroll, - _options$resize = options.resize, - resize = _options$resize === void 0 ? true : _options$resize; - var window = getWindow(state.elements.popper); - var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); - - if (scroll) { - scrollParents.forEach(function (scrollParent) { - scrollParent.addEventListener('scroll', instance.update, passive); - }); - } - - if (resize) { - window.addEventListener('resize', instance.update, passive); - } - - return function () { - if (scroll) { - scrollParents.forEach(function (scrollParent) { - scrollParent.removeEventListener('scroll', instance.update, passive); - }); - } - - if (resize) { - window.removeEventListener('resize', instance.update, passive); - } - }; - } // eslint-disable-next-line import/no-unused-modules - - - var eventListeners = { - name: 'eventListeners', - enabled: true, - phase: 'write', - fn: function fn() { - }, - effect: effect$2, - data: {} - }; - - function popperOffsets(_ref) { - var state = _ref.state, - name = _ref.name; - // Offsets are the actual position the popper needs to have to be - // properly positioned near its reference element - // This is the most basic placement, and will be adjusted by - // the modifiers in the next step - state.modifiersData[name] = computeOffsets({ - reference: state.rects.reference, - element: state.rects.popper, - strategy: 'absolute', - placement: state.placement - }); - } // eslint-disable-next-line import/no-unused-modules - - - var popperOffsets$1 = { - name: 'popperOffsets', - enabled: true, - phase: 'read', - fn: popperOffsets, - data: {} - }; - - var unsetSides = { - top: 'auto', - right: 'auto', - bottom: 'auto', - left: 'auto' - }; // Round the offsets to the nearest suitable subpixel based on the DPR. - // Zooming can change the DPR, but it seems to report a value that will - // cleanly divide the values into the appropriate subpixels. - - function roundOffsetsByDPR(_ref) { - var x = _ref.x, - y = _ref.y; - var win = window; - var dpr = win.devicePixelRatio || 1; - return { - x: round(x * dpr) / dpr || 0, - y: round(y * dpr) / dpr || 0 - }; - } - - function mapToStyles(_ref2) { - var _Object$assign2; - - var popper = _ref2.popper, - popperRect = _ref2.popperRect, - placement = _ref2.placement, - variation = _ref2.variation, - offsets = _ref2.offsets, - position = _ref2.position, - gpuAcceleration = _ref2.gpuAcceleration, - adaptive = _ref2.adaptive, - roundOffsets = _ref2.roundOffsets, - isFixed = _ref2.isFixed; - var _offsets$x = offsets.x, - x = _offsets$x === void 0 ? 0 : _offsets$x, - _offsets$y = offsets.y, - y = _offsets$y === void 0 ? 0 : _offsets$y; - - var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({ - x: x, - y: y - }) : { - x: x, - y: y - }; - - x = _ref3.x; - y = _ref3.y; - var hasX = offsets.hasOwnProperty('x'); - var hasY = offsets.hasOwnProperty('y'); - var sideX = left; - var sideY = top; - var win = window; - - if (adaptive) { - var offsetParent = getOffsetParent(popper); - var heightProp = 'clientHeight'; - var widthProp = 'clientWidth'; - - if (offsetParent === getWindow(popper)) { - offsetParent = getDocumentElement(popper); - - if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') { - heightProp = 'scrollHeight'; - widthProp = 'scrollWidth'; - } - } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it - - - offsetParent = offsetParent; - - if (placement === top || (placement === left || placement === right) && variation === end) { - sideY = bottom; - var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing] - offsetParent[heightProp]; - y -= offsetY - popperRect.height; - y *= gpuAcceleration ? 1 : -1; - } - - if (placement === left || (placement === top || placement === bottom) && variation === end) { - sideX = right; - var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing] - offsetParent[widthProp]; - x -= offsetX - popperRect.width; - x *= gpuAcceleration ? 1 : -1; - } - } - - var commonStyles = Object.assign({ - position: position - }, adaptive && unsetSides); - - var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ - x: x, - y: y - }) : { - x: x, - y: y - }; - - x = _ref4.x; - y = _ref4.y; - - if (gpuAcceleration) { - var _Object$assign; - - return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); - } - - return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); - } - - function computeStyles(_ref5) { - var state = _ref5.state, - options = _ref5.options; - var _options$gpuAccelerat = options.gpuAcceleration, - gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, - _options$adaptive = options.adaptive, - adaptive = _options$adaptive === void 0 ? true : _options$adaptive, - _options$roundOffsets = options.roundOffsets, - roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; - - { - var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || ''; - - if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) { - return transitionProperty.indexOf(property) >= 0; - })) { - console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' ')); - } - } - - var commonStyles = { - placement: getBasePlacement(state.placement), - variation: getVariation(state.placement), - popper: state.elements.popper, - popperRect: state.rects.popper, - gpuAcceleration: gpuAcceleration, - isFixed: state.options.strategy === 'fixed' - }; - - if (state.modifiersData.popperOffsets != null) { - state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.popperOffsets, - position: state.options.strategy, - adaptive: adaptive, - roundOffsets: roundOffsets - }))); - } - - if (state.modifiersData.arrow != null) { - state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.arrow, - position: 'absolute', - adaptive: false, - roundOffsets: roundOffsets - }))); - } - - state.attributes.popper = Object.assign({}, state.attributes.popper, { - 'data-popper-placement': state.placement - }); - } // eslint-disable-next-line import/no-unused-modules - - - var computeStyles$1 = { - name: 'computeStyles', - enabled: true, - phase: 'beforeWrite', - fn: computeStyles, - data: {} - }; - - // and applies them to the HTMLElements such as popper and arrow - - function applyStyles(_ref) { - var state = _ref.state; - Object.keys(state.elements).forEach(function (name) { - var style = state.styles[name] || {}; - var attributes = state.attributes[name] || {}; - var element = state.elements[name]; // arrow is optional + virtual elements - - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } // Flow doesn't support to extend this property, but it's the most - // effective way to apply styles to an HTMLElement - // $FlowFixMe[cannot-write] - - - Object.assign(element.style, style); - Object.keys(attributes).forEach(function (name) { - var value = attributes[name]; - - if (value === false) { - element.removeAttribute(name); - } else { - element.setAttribute(name, value === true ? '' : value); - } - }); - }); - } - - function effect$1(_ref2) { - var state = _ref2.state; - var initialStyles = { - popper: { - position: state.options.strategy, - left: '0', - top: '0', - margin: '0' - }, - arrow: { - position: 'absolute' - }, - reference: {} - }; - Object.assign(state.elements.popper.style, initialStyles.popper); - state.styles = initialStyles; - - if (state.elements.arrow) { - Object.assign(state.elements.arrow.style, initialStyles.arrow); - } - - return function () { - Object.keys(state.elements).forEach(function (name) { - var element = state.elements[name]; - var attributes = state.attributes[name] || {}; - var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them - - var style = styleProperties.reduce(function (style, property) { - style[property] = ''; - return style; - }, {}); // arrow is optional + virtual elements - - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } - - Object.assign(element.style, style); - Object.keys(attributes).forEach(function (attribute) { - element.removeAttribute(attribute); - }); - }); - }; - } // eslint-disable-next-line import/no-unused-modules - - - var applyStyles$1 = { - name: 'applyStyles', - enabled: true, - phase: 'write', - fn: applyStyles, - effect: effect$1, - requires: ['computeStyles'] - }; - - function distanceAndSkiddingToXY(placement, rects, offset) { - var basePlacement = getBasePlacement(placement); - var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; - - var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { - placement: placement - })) : offset, - skidding = _ref[0], - distance = _ref[1]; - - skidding = skidding || 0; - distance = (distance || 0) * invertDistance; - return [left, right].indexOf(basePlacement) >= 0 ? { - x: distance, - y: skidding - } : { - x: skidding, - y: distance - }; - } - - function offset(_ref2) { - var state = _ref2.state, - options = _ref2.options, - name = _ref2.name; - var _options$offset = options.offset, - offset = _options$offset === void 0 ? [0, 0] : _options$offset; - var data = placements.reduce(function (acc, placement) { - acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); - return acc; - }, {}); - var _data$state$placement = data[state.placement], - x = _data$state$placement.x, - y = _data$state$placement.y; - - if (state.modifiersData.popperOffsets != null) { - state.modifiersData.popperOffsets.x += x; - state.modifiersData.popperOffsets.y += y; - } - - state.modifiersData[name] = data; - } // eslint-disable-next-line import/no-unused-modules - - - var offset$1 = { - name: 'offset', - enabled: true, - phase: 'main', - requires: ['popperOffsets'], - fn: offset - }; - - var hash$1 = { - left: 'right', - right: 'left', - bottom: 'top', - top: 'bottom' - }; - - function getOppositePlacement(placement) { - return placement.replace(/left|right|bottom|top/g, function (matched) { - return hash$1[matched]; - }); - } - - var hash = { - start: 'end', - end: 'start' - }; - - function getOppositeVariationPlacement(placement) { - return placement.replace(/start|end/g, function (matched) { - return hash[matched]; - }); - } - - function computeAutoPlacement(state, options) { - if (options === void 0) { - options = {}; - } - - var _options = options, - placement = _options.placement, - boundary = _options.boundary, - rootBoundary = _options.rootBoundary, - padding = _options.padding, - flipVariations = _options.flipVariations, - _options$allowedAutoP = _options.allowedAutoPlacements, - allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; - var variation = getVariation(placement); - var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { - return getVariation(placement) === variation; - }) : basePlacements; - var allowedPlacements = placements$1.filter(function (placement) { - return allowedAutoPlacements.indexOf(placement) >= 0; - }); - - if (allowedPlacements.length === 0) { - allowedPlacements = placements$1; - - { - console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' ')); - } - } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... - - - var overflows = allowedPlacements.reduce(function (acc, placement) { - acc[placement] = detectOverflow(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding - })[getBasePlacement(placement)]; - return acc; - }, {}); - return Object.keys(overflows).sort(function (a, b) { - return overflows[a] - overflows[b]; - }); - } - - function getExpandedFallbackPlacements(placement) { - if (getBasePlacement(placement) === auto) { - return []; - } - - var oppositePlacement = getOppositePlacement(placement); - return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; - } - - function flip(_ref) { - var state = _ref.state, - options = _ref.options, - name = _ref.name; - - if (state.modifiersData[name]._skip) { - return; - } - - var _options$mainAxis = options.mainAxis, - checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, - _options$altAxis = options.altAxis, - checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, - specifiedFallbackPlacements = options.fallbackPlacements, - padding = options.padding, - boundary = options.boundary, - rootBoundary = options.rootBoundary, - altBoundary = options.altBoundary, - _options$flipVariatio = options.flipVariations, - flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, - allowedAutoPlacements = options.allowedAutoPlacements; - var preferredPlacement = state.options.placement; - var basePlacement = getBasePlacement(preferredPlacement); - var isBasePlacement = basePlacement === preferredPlacement; - var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); - var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { - return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - flipVariations: flipVariations, - allowedAutoPlacements: allowedAutoPlacements - }) : placement); - }, []); - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var checksMap = new Map(); - var makeFallbackChecks = true; - var firstFittingPlacement = placements[0]; - - for (var i = 0; i < placements.length; i++) { - var placement = placements[i]; - - var _basePlacement = getBasePlacement(placement); - - var isStartVariation = getVariation(placement) === start; - var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; - var len = isVertical ? 'width' : 'height'; - var overflow = detectOverflow(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - altBoundary: altBoundary, - padding: padding - }); - var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; - - if (referenceRect[len] > popperRect[len]) { - mainVariationSide = getOppositePlacement(mainVariationSide); - } - - var altVariationSide = getOppositePlacement(mainVariationSide); - var checks = []; - - if (checkMainAxis) { - checks.push(overflow[_basePlacement] <= 0); - } - - if (checkAltAxis) { - checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); - } - - if (checks.every(function (check) { - return check; - })) { - firstFittingPlacement = placement; - makeFallbackChecks = false; - break; - } - - checksMap.set(placement, checks); - } - - if (makeFallbackChecks) { - // `2` may be desired in some cases – research later - var numberOfChecks = flipVariations ? 3 : 1; - - var _loop = function _loop(_i) { - var fittingPlacement = placements.find(function (placement) { - var checks = checksMap.get(placement); - - if (checks) { - return checks.slice(0, _i).every(function (check) { - return check; - }); - } - }); - - if (fittingPlacement) { - firstFittingPlacement = fittingPlacement; - return "break"; - } - }; - - for (var _i = numberOfChecks; _i > 0; _i--) { - var _ret = _loop(_i); - - if (_ret === "break") break; - } - } - - if (state.placement !== firstFittingPlacement) { - state.modifiersData[name]._skip = true; - state.placement = firstFittingPlacement; - state.reset = true; - } - } // eslint-disable-next-line import/no-unused-modules - - - var flip$1 = { - name: 'flip', - enabled: true, - phase: 'main', - fn: flip, - requiresIfExists: ['offset'], - data: { - _skip: false - } - }; - - function getAltAxis(axis) { - return axis === 'x' ? 'y' : 'x'; - } - - function within(min$1, value, max$1) { - return max(min$1, min(value, max$1)); - } - - function withinMaxClamp(min, value, max) { - var v = within(min, value, max); - return v > max ? max : v; - } - - function preventOverflow(_ref) { - var state = _ref.state, - options = _ref.options, - name = _ref.name; - var _options$mainAxis = options.mainAxis, - checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, - _options$altAxis = options.altAxis, - checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, - boundary = options.boundary, - rootBoundary = options.rootBoundary, - altBoundary = options.altBoundary, - padding = options.padding, - _options$tether = options.tether, - tether = _options$tether === void 0 ? true : _options$tether, - _options$tetherOffset = options.tetherOffset, - tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; - var overflow = detectOverflow(state, { - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - altBoundary: altBoundary - }); - var basePlacement = getBasePlacement(state.placement); - var variation = getVariation(state.placement); - var isBasePlacement = !variation; - var mainAxis = getMainAxisFromPlacement(basePlacement); - var altAxis = getAltAxis(mainAxis); - var popperOffsets = state.modifiersData.popperOffsets; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { - placement: state.placement - })) : tetherOffset; - var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? { - mainAxis: tetherOffsetValue, - altAxis: tetherOffsetValue - } : Object.assign({ - mainAxis: 0, - altAxis: 0 - }, tetherOffsetValue); - var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; - var data = { - x: 0, - y: 0 - }; - - if (!popperOffsets) { - return; - } - - if (checkMainAxis) { - var _offsetModifierState$; - - var mainSide = mainAxis === 'y' ? top : left; - var altSide = mainAxis === 'y' ? bottom : right; - var len = mainAxis === 'y' ? 'height' : 'width'; - var offset = popperOffsets[mainAxis]; - var min$1 = offset + overflow[mainSide]; - var max$1 = offset - overflow[altSide]; - var additive = tether ? -popperRect[len] / 2 : 0; - var minLen = variation === start ? referenceRect[len] : popperRect[len]; - var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go - // outside the reference bounds - - var arrowElement = state.elements.arrow; - var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { - width: 0, - height: 0 - }; - var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); - var arrowPaddingMin = arrowPaddingObject[mainSide]; - var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want - // to include its full size in the calculation. If the reference is small - // and near the edge of a boundary, the popper can overflow even if the - // reference is not overflowing as well (e.g. virtual elements with no - // width or height) - - var arrowLen = within(0, referenceRect[len], arrowRect[len]); - var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; - var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; - var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); - var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; - var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; - var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; - var tetherMax = offset + maxOffset - offsetModifierValue; - var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1); - popperOffsets[mainAxis] = preventedOffset; - data[mainAxis] = preventedOffset - offset; - } - - if (checkAltAxis) { - var _offsetModifierState$2; - - var _mainSide = mainAxis === 'x' ? top : left; - - var _altSide = mainAxis === 'x' ? bottom : right; - - var _offset = popperOffsets[altAxis]; - - var _len = altAxis === 'y' ? 'height' : 'width'; - - var _min = _offset + overflow[_mainSide]; - - var _max = _offset - overflow[_altSide]; - - var isOriginSide = [top, left].indexOf(basePlacement) !== -1; - - var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; - - var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; - - var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; - - var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); - - popperOffsets[altAxis] = _preventedOffset; - data[altAxis] = _preventedOffset - _offset; - } - - state.modifiersData[name] = data; - } // eslint-disable-next-line import/no-unused-modules - - - var preventOverflow$1 = { - name: 'preventOverflow', - enabled: true, - phase: 'main', - fn: preventOverflow, - requiresIfExists: ['offset'] - }; - - var toPaddingObject = function toPaddingObject(padding, state) { - padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { - placement: state.placement - })) : padding; - return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); - }; - - function arrow(_ref) { - var _state$modifiersData$; - - var state = _ref.state, - name = _ref.name, - options = _ref.options; - var arrowElement = state.elements.arrow; - var popperOffsets = state.modifiersData.popperOffsets; - var basePlacement = getBasePlacement(state.placement); - var axis = getMainAxisFromPlacement(basePlacement); - var isVertical = [left, right].indexOf(basePlacement) >= 0; - var len = isVertical ? 'height' : 'width'; - - if (!arrowElement || !popperOffsets) { - return; - } - - var paddingObject = toPaddingObject(options.padding, state); - var arrowRect = getLayoutRect(arrowElement); - var minProp = axis === 'y' ? top : left; - var maxProp = axis === 'y' ? bottom : right; - var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; - var startDiff = popperOffsets[axis] - state.rects.reference[axis]; - var arrowOffsetParent = getOffsetParent(arrowElement); - var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; - var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is - // outside of the popper bounds - - var min = paddingObject[minProp]; - var max = clientSize - arrowRect[len] - paddingObject[maxProp]; - var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; - var offset = within(min, center, max); // Prevents breaking syntax highlighting... - - var axisProp = axis; - state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); - } - - function effect(_ref2) { - var state = _ref2.state, - options = _ref2.options; - var _options$element = options.element, - arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; - - if (arrowElement == null) { - return; - } // CSS selector - - - if (typeof arrowElement === 'string') { - arrowElement = state.elements.popper.querySelector(arrowElement); - - if (!arrowElement) { - return; - } - } - - { - if (!isHTMLElement(arrowElement)) { - console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' ')); - } - } - - if (!contains(state.elements.popper, arrowElement)) { - { - console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' ')); - } - - return; - } - - state.elements.arrow = arrowElement; - } // eslint-disable-next-line import/no-unused-modules - - - var arrow$1 = { - name: 'arrow', - enabled: true, - phase: 'main', - fn: arrow, - effect: effect, - requires: ['popperOffsets'], - requiresIfExists: ['preventOverflow'] - }; - - function getSideOffsets(overflow, rect, preventedOffsets) { - if (preventedOffsets === void 0) { - preventedOffsets = { - x: 0, - y: 0 - }; - } - - return { - top: overflow.top - rect.height - preventedOffsets.y, - right: overflow.right - rect.width + preventedOffsets.x, - bottom: overflow.bottom - rect.height + preventedOffsets.y, - left: overflow.left - rect.width - preventedOffsets.x - }; - } - - function isAnySideFullyClipped(overflow) { - return [top, right, bottom, left].some(function (side) { - return overflow[side] >= 0; - }); - } - - function hide(_ref) { - var state = _ref.state, - name = _ref.name; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var preventedOffsets = state.modifiersData.preventOverflow; - var referenceOverflow = detectOverflow(state, { - elementContext: 'reference' - }); - var popperAltOverflow = detectOverflow(state, { - altBoundary: true - }); - var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); - var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); - var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); - var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); - state.modifiersData[name] = { - referenceClippingOffsets: referenceClippingOffsets, - popperEscapeOffsets: popperEscapeOffsets, - isReferenceHidden: isReferenceHidden, - hasPopperEscaped: hasPopperEscaped - }; - state.attributes.popper = Object.assign({}, state.attributes.popper, { - 'data-popper-reference-hidden': isReferenceHidden, - 'data-popper-escaped': hasPopperEscaped - }); - } // eslint-disable-next-line import/no-unused-modules - - - var hide$1 = { - name: 'hide', - enabled: true, - phase: 'main', - requiresIfExists: ['preventOverflow'], - fn: hide - }; - - var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; - var createPopper$1 = /*#__PURE__*/popperGenerator({ - defaultModifiers: defaultModifiers$1 - }); // eslint-disable-next-line import/no-unused-modules - - var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; - var createPopper = /*#__PURE__*/popperGenerator({ - defaultModifiers: defaultModifiers - }); // eslint-disable-next-line import/no-unused-modules - - exports.applyStyles = applyStyles$1; - exports.arrow = arrow$1; - exports.computeStyles = computeStyles$1; - exports.createPopper = createPopper; - exports.createPopperLite = createPopper$1; - exports.defaultModifiers = defaultModifiers; - exports.detectOverflow = detectOverflow; - exports.eventListeners = eventListeners; - exports.flip = flip$1; - exports.hide = hide$1; - exports.offset = offset$1; - exports.popperGenerator = popperGenerator; - exports.popperOffsets = popperOffsets$1; - exports.preventOverflow = preventOverflow$1; - - Object.defineProperty(exports, '__esModule', { value: true }); - -}))); diff --git a/src/core/element/element.js b/src/core/element/element.js deleted file mode 100644 index 7bf1c9d4a..000000000 --- a/src/core/element/element.js +++ /dev/null @@ -1,74 +0,0 @@ -import { registFunction } from './plugins'; - -export function Element(widget, attribs) { - this.l = this.r = this.t = this.b = 0; // 边框 - this.marginLeft = this.marginRight = this.marginTop = this.marginBottom = 0; //间距 - this.position = {}; - this.classMap = {}; - this.classList = []; - this.children = []; - this.attribs = attribs || {}; - this.styles = {}; - // 兼容处理 - this['0'] = this; - this.style = {}; - if (!widget) { - this.nodeName = 'body'; - this.position.x = 0; - this.position.y = 0; - this.attribs.id = 'body'; - } else if (BI.isWidget(widget)) { - this.widget = widget; - this.nodeName = widget.options.tagName; - this.textBaseLine = widget.options.textBaseLine; - } else if (BI.isString(widget)) { - this.nodeName = widget; - } -} - -initElement(Element); -registFunction(Element); - -function initElement(element) { - element.prototype = { - appendChild(child) { - child.parent = this; - if (this.children.push(child) !== 1) { - var sibling = this.children[this.children.length - 2]; - sibling.next = child; - child.prev = sibling; - child.next = null; - } - }, - append(child) { - child.parent = this; - if (this.children.push(child) !== 1) { - var sibling = this.children[this.children.length - 2]; - sibling.next = child; - child.prev = sibling; - child.next = null; - } - }, - getParent() { - return this.parent; - }, - getSiblings() { - var parent = this.getParent(); - return parent ? parent.getChildren() : [this]; - }, - getChildren() { - return this.children; - }, - - getBounds() { - return {}; - }, - - width() { - - }, - height() { - - } - }; -} diff --git a/src/core/element/index.js b/src/core/element/index.js deleted file mode 100644 index bbc4eb926..000000000 --- a/src/core/element/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Element } from './element'; - -BI.Element = Element; -BI.Element.renderEngine = { - createElement: (widget) => { - // eslint-disable-next-line no-undef - if (BI.isWidget(widget)) { - var o = widget.options; - if (o.element instanceof Element) { - return o.element; - } - if (typeof o.element === 'string' && o.element !== 'body') { - o.root = false; - return new Element(widget); - } - - if (o.root === true) { - return new Element(); - } - } - // eslint-disable-next-line no-undef - if (BI.isString(widget)) { - return new Element(widget); - } - return new Element(widget); - }, - - createFragment() { - return new Element(); - } -} diff --git a/src/core/element/plugins/attr.js b/src/core/element/plugins/attr.js deleted file mode 100644 index 3ae918f29..000000000 --- a/src/core/element/plugins/attr.js +++ /dev/null @@ -1,22 +0,0 @@ -export const registAttrFun = (Element) => { - Element.registerFunction('attr', function (key, value) { - var self = this; - if (BI.isObject(key)) { - BI.each(key, (k, v) => { - self.attr(k, v); - }); - return this; - } - if (BI.isNull(value)) { - return this.attribs[key]; - } - this.attribs[key] = value; - return this; - }); - Element.registerFunction('hasAttrib', function (key) { - return this.attribs[key] != null; - }); - Element.registerFunction('removeAttr', function (key) { - delete this.attribs[key]; - }); -}; diff --git a/src/core/element/plugins/class.js b/src/core/element/plugins/class.js deleted file mode 100644 index ce46e6864..000000000 --- a/src/core/element/plugins/class.js +++ /dev/null @@ -1,23 +0,0 @@ -export const registClassFun = (Element) => { - Element.registerFunction('addClass', function (classList) { - var self = this; - BI.each(classList.split(' '), (i, cls) => { - if (cls && !self.classMap[cls]) { - self.classList.push(cls); - } - cls && (self.classMap[cls] = true); - }); - return this; - }); - - Element.registerFunction('removeClass', function (classList) { - var self = this; - BI.each(classList.split(' '), (i, cls) => { - if (cls && self.classMap[cls]) { - delete self.classMap[cls]; - self.classList.splice(self.classList.indexOf(cls), 1); - } - }); - return this; - }); -}; diff --git a/src/core/element/plugins/css.js b/src/core/element/plugins/css.js deleted file mode 100644 index e1826a155..000000000 --- a/src/core/element/plugins/css.js +++ /dev/null @@ -1,22 +0,0 @@ -export const registCssFun = (Element) => { - Element.registerFunction('css', function (key, value) { - var self = this; - if (BI.isObject(key)) { - BI.each(key, (k, v) => { - self.css(k, v); - }); - return this; - } - key = BI.trim(BI.camelize(key)); - return css(this, key, value); - }); -}; - -const css = (elem, key, value) => { - key = BI.trim(BI.camelize(key)); - if (BI.isNull(value)) { - return elem.styles[key]; - } - elem.styles[key] = value; - return elem; -}; diff --git a/src/core/element/plugins/data.js b/src/core/element/plugins/data.js deleted file mode 100644 index e141c96c3..000000000 --- a/src/core/element/plugins/data.js +++ /dev/null @@ -1,12 +0,0 @@ -export const registDataFun = (Element) => { - Element.registerFunction('data', function (key, value) { - if (!this._data) { - this._data = {}; - } - if (BI.isNull(value)) { - return this._data[key]; - } - this._data[key] = value; - return this; - }); -}; diff --git a/src/core/element/plugins/empty.js b/src/core/element/plugins/empty.js deleted file mode 100644 index dbe5e0c1d..000000000 --- a/src/core/element/plugins/empty.js +++ /dev/null @@ -1,9 +0,0 @@ -export const registEmptyFun = (Element) => { - Element.registerFunction('empty', function (text) { - this.children = []; - return this; - }); - Element.registerFunction('destroy', function (text) { - return this; - }); -}; diff --git a/src/core/element/plugins/event.js b/src/core/element/plugins/event.js deleted file mode 100644 index 38004ed88..000000000 --- a/src/core/element/plugins/event.js +++ /dev/null @@ -1,32 +0,0 @@ -var returnThis = function () { - return this; -}; -export const registEventFun = (Element) => { - [ - 'mousedown', - 'mouseup', - 'mousewheel', - 'keydown', - 'keyup', - 'focus', - 'focusin', - 'focusout', - 'click', - 'on', - 'off', - 'bind', - 'unbind', - 'trigger', - 'hover', - 'scroll', - 'scrollLeft', - 'scrollTop', - 'resize', - 'show', - 'hide', - 'dblclick', - 'blur', - ].forEach((event) => { - Element.registerFunction(event, returnThis); - }); -}; diff --git a/src/core/element/plugins/html.js b/src/core/element/plugins/html.js deleted file mode 100644 index b115f9388..000000000 --- a/src/core/element/plugins/html.js +++ /dev/null @@ -1,15 +0,0 @@ -export const registHtmlFun = (Element) => { - Element.registerFunction('html', function (text) { - if (text && text.charAt(0) === '<') { - BI.createWidget({ - type: 'bi.html', - element: this.widget, - html: text, - }); - this.originalHtml = text; - } else { - this.text = BI.htmlDecode(text); - } - return this; - }); -}; diff --git a/src/core/element/plugins/index.js b/src/core/element/plugins/index.js deleted file mode 100644 index c32aab4dc..000000000 --- a/src/core/element/plugins/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { registAttrFun } from './attr'; -import { registClassFun } from './class'; -import { registCssFun } from './css'; -import { registDataFun } from './data'; -import { registEmptyFun } from './empty'; -import { registEventFun } from './event'; -import { registHtmlFun } from './html'; -import { registKeywordMarkFun } from './keywordMark'; -import { registRenderToHtmlFun } from './renderToHtml'; -import { registRenderToStringFun } from './renderToString'; -import { registTextFun } from './text'; -import { registValFun } from './val'; - -export const registFunction = (Element) => { - var functionMap = {}; - Element.registerFunction = (key, fn) => { - Element.prototype[key] = functionMap[key] = fn; - }; - registAttrFun(Element); - registClassFun(Element); - registCssFun(Element); - registDataFun(Element); - registEmptyFun(Element); - registEventFun(Element); - registHtmlFun(Element); - registKeywordMarkFun(Element); - registRenderToStringFun(Element); - registRenderToHtmlFun(Element); - registTextFun(Element); - registValFun(Element); -}; diff --git a/src/core/element/plugins/keywordMark.js b/src/core/element/plugins/keywordMark.js deleted file mode 100644 index a7eab83dd..000000000 --- a/src/core/element/plugins/keywordMark.js +++ /dev/null @@ -1,6 +0,0 @@ -export const registKeywordMarkFun = (Element) => { - Element.registerFunction('__textKeywordMarked__', function (text) { - this[0].textContent = text; - return this; - }); -}; diff --git a/src/core/element/plugins/renderToHtml.js b/src/core/element/plugins/renderToHtml.js deleted file mode 100644 index 525afe062..000000000 --- a/src/core/element/plugins/renderToHtml.js +++ /dev/null @@ -1,65 +0,0 @@ -var skipArray = []; -var pxStyle = ['font-size', 'width', 'height']; -var _renderToHtml = function (root) { - var str = ''; - if (BI.isNull(root.originalHtml)) { - if (root.tag !== 'body') { - str += `<${root.tag}`; - if (root.classList.length > 0) { - str += ' class="'; - BI.each(root.classList, (i, cls) => { - str += ` ${cls}`; - }); - str += '"'; - } - str += ' style="'; - BI.each(root.originalStyles, (key, stl) => { - if ( - skipArray.contains(key) || - (key == 'height' && root.classList.contains('bi-design-components-data-data-table-cell')) - ) { - return; - } - key = BI.hyphenate(key); - if (key === 'font-family') { - stl = stl.replace(/\"/g, ''); - } - if (pxStyle.contains(key) && BI.isNumeric(stl)) { - stl += 'px'; - } - if (BI.isKey(stl)) { - str += ` ${key}:${stl};`; - } - }); - str += '"'; - BI.each(root.attribs, (key, attr) => { - if (BI.isKey(attr)) { - str += ` ${key}=${attr}`; - } - }); - if (root.textContent) { - str += ` title=${root.textContent}`; - } - str += '>'; - } - // 特殊处理,spread_table的行列元素是不取配置里的高度的,使用stretch拉伸的(leaves取了高度),但是功能代码里给单元格默认高度了,导致拉伸不了 - // 而spread_grid_table的行列元素是取配置里的高度的,拉不拉伸都一样 - BI.each(root.children, (i, child) => { - str += _renderToHtml(child); - }); - } else { - str += root.originalHtml; - } - if (root.tag !== 'body') { - if (root.textContent) { - str += root.textContent; - } - str += ``; - } - return str; -}; -export const registRenderToHtmlFun = (Element) => { - Element.registerFunction('renderToHtml', function () { - return _renderToHtml(this); - }); -}; diff --git a/src/core/element/plugins/renderToString.js b/src/core/element/plugins/renderToString.js deleted file mode 100644 index f0073f258..000000000 --- a/src/core/element/plugins/renderToString.js +++ /dev/null @@ -1,50 +0,0 @@ -var skipArray = ['width', 'height']; -var _renderToString = function (root) { - var str = ''; - if (root.nodeName !== 'body') { - str += `<${root.nodeName}`; - if (root.classList.length > 0) { - str += ' class="'; - BI.each(root.classList, (i, cls) => { - str += ` ${cls}`; - }); - str += '"'; - } - str += ' style="'; - BI.each(root.styles, (key, stl) => { - if (skipArray.includes(key)) { - return; - } - key = BI.hyphenate(key); - str += ` ${key}:${stl};`; - }); - str += ` width:${root.width}px;`; - str += ` height:${root.height}px;`; - str += ' position: fixed;'; - str += ` left: ${root.position.x}px;`; - str += ` top: ${root.position.y}px;`; - str += '"'; - BI.each(root.attribs, (key, attr) => { - str += ` ${key}:${attr}`; - }); - str += '>'; - } - BI.each(root.children, (i, child) => { - str += _renderToString(child); - }); - // if (root.htmlContent) { - // str += root.htmlContent; - // } - if (root.nodeName !== 'body') { - if (root.text) { - str += root.text; - } - str += ``; - } - return str; -}; -export const registRenderToStringFun = (Element) => { - Element.registerFunction('renderToString', function () { - return _renderToString(this); - }); -}; diff --git a/src/core/element/plugins/text.js b/src/core/element/plugins/text.js deleted file mode 100644 index 555195251..000000000 --- a/src/core/element/plugins/text.js +++ /dev/null @@ -1,10 +0,0 @@ -export const registTextFun = (Element) => { - Element.registerFunction('setText', function (text) { - this.text = text; - return this; - }); - Element.registerFunction('setValue', function (text) { - this.text = text; - return this; - }); -}; diff --git a/src/core/element/plugins/val.js b/src/core/element/plugins/val.js deleted file mode 100644 index f4b868918..000000000 --- a/src/core/element/plugins/val.js +++ /dev/null @@ -1,9 +0,0 @@ -export const registValFun = (Element) => { - Element.registerFunction('val', function (value) { - if (BI.isNotNull(value)) { - this.text = `${value}`; - return this; - } - return this.text; - }); -}; diff --git a/src/core/func/__test__/function.test.js b/src/core/func/__test__/function.test.js deleted file mode 100644 index 388af5fe6..000000000 --- a/src/core/func/__test__/function.test.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @Author: lei.wang - * @Maintainers: lei.wang - * @Date: 2019-04-16 - */ -describe("core-function-test", function () { - /** - * test_author_lei.wang - */ - it("createDistinctName-支持字符串数组", function () { - var names = ["name", "name1"]; - expect(BI.Func.createDistinctName(names, "name")).to.equal("name2"); - expect(BI.Func.createDistinctName(names, "name2")).to.equal("name2"); - }); - - /** - * test_author_lei.wang - */ - it("createDistinctName-支持对象数组数组", function () { - var names = [{ name: "name" }, { name: "name1" }]; - expect(BI.Func.createDistinctName(names, "name")).to.equal("name2"); - expect(BI.Func.createDistinctName(names, "name2")).to.equal("name2"); - }); -}); \ No newline at end of file diff --git a/src/core/func/alias.js b/src/core/func/alias.js deleted file mode 100644 index 2884e492b..000000000 --- a/src/core/func/alias.js +++ /dev/null @@ -1,938 +0,0 @@ -(function () { - var _global; - if (typeof window !== "undefined") { - _global = window; - } else if (typeof global !== "undefined") { - _global = global; - } else if (typeof self !== "undefined") { - _global = self; - } else { - _global = this; - } - if (!_global.BI) { - _global.BI = {}; - } - - function isEmpty (value) { - // 判断是否为空值 - var result = value === "" || value === null || value === undefined; - return result; - } - - // 判断是否是无效的日期 - function isInvalidDate (date) { - return date == "Invalid Date" || date == "NaN"; - } - - /** - * CHART-1400 - * 使用数值计算的方式来获取任意数值的科学技术表示值。 - * 科学计数格式 - */ - function _eFormat (text, fmt) { - text = +text; - - return eFormat(text, fmt); - - /** - * 科学计数格式具体计算过程 - * @param num - * @param format {String}有两种形式, - * 1、"0.00E00"这样的字符串表示正常的科学计数表示,只不过规定了数值精确到百分位, - * 而数量级的绝对值如果是10以下的时候在前面补零。 - * 2、 "##0.0E0"这样的字符串则规定用科学计数法表示之后的数值的整数部分是三位,精确到十分位, - * 数量级没有规定,因为没见过实数里有用科学计数法表示之后E的后面会小于一位的情况(0无所谓)。 - * @returns {*} - */ - function eFormat (num, format) { - var neg = num < 0 ? (num *= -1, "-") : "", - magnitudeNeg = ""; - - var funcName = num > 0 && num < 1 ? "floor" : "ceil"; // -0.9999->-1 - // 数量级 - var magnitude = Math[funcName](Math.log(num) / Math.log(10)); - - if (!isFinite(magnitude)) { - return format.replace(/#/ig, "").replace(/\.e/ig, "E"); - } - - num = num / Math.pow(10, magnitude); - - // 让num转化成[1, 10)区间上的数 - if (num > 0 && num < 1) { - num *= 10; - magnitude -= 1; - } - - // 计算出format中需要显示的整数部分的位数,然后更新这个数值,也更新数量级 - var integerLen = getInteger(magnitude, format); - integerLen > 1 && (magnitude -= integerLen - 1, num *= Math.pow(10, integerLen - 1)); - - magnitude < 0 && (magnitudeNeg = "-", magnitude *= -1); - - // 获取科学计数法精确到的位数 - var precision = getPrecision(format); - // 判断num经过四舍五入之后是否有进位 - var isValueCarry = isValueCarried(num); - - num *= Math.pow(10, precision); - num = Math.round(num); - // 如果出现进位的情况,将num除以10 - isValueCarry && (num /= 10, magnitude += magnitudeNeg === "-" ? -1 : 1); - num /= Math.pow(10, precision); - - // 小数部分保留precision位 - num = num.toFixed(precision); - // 格式化指数的部分 - magnitude = formatExponential(format, magnitude, magnitudeNeg); - - return neg + num + "E" + magnitude; - } - - // 获取format格式规定的数量级的形式 - function formatExponential (format, num, magnitudeNeg) { - num += ""; - if (!/e/ig.test(format)) { - return num; - } - format = format.split(/e/ig)[1]; - - while (num.length < format.length) { - num = "0" + num; - } - - // 如果magnitudeNeg是一个"-",而且num正好全是0,那么就别显示负号了 - var isAllZero = true; - for (var i = 0, len = num.length; i < len; i++) { - if (!isAllZero) { - continue; - } - isAllZero = num.charAt(i) === "0"; - } - magnitudeNeg = isAllZero ? "" : magnitudeNeg; - - return magnitudeNeg + num; - } - - // 获取format规定的科学计数法精确到的位数 - function getPrecision (format) { - if (!/e/ig.test(format)) { - return 0; - } - var arr = format.split(/e/ig)[0].split("."); - - return arr.length > 1 ? arr[1].length : 0; - } - - // 获取数值科学计数法表示之后整数的位数 - // 这边我们还需要考虑#和0的问题 - function getInteger (magnitude, format) { - if (!/e/ig.test(format)) { - return 0; - } - // return format.split(/e/ig)[0].split(".")[0].length; - - var formatLeft = format.split(/e/ig)[0].split(".")[0], i, f, len = formatLeft.length; - var valueLeftLen = 0; - - for (i = 0; i < len; i++) { - f = formatLeft.charAt(i); - // "#"所在的位置到末尾长度小于等于值的整数部分长度,那么这个#才可以占位 - if (f == 0 || (f == "#" && (len - i <= magnitude + 1))) { - valueLeftLen++; - } - } - - return valueLeftLen; - } - - // 判断num通过round函数之后是否有进位 - function isValueCarried (num) { - var roundNum = Math.round(num); - num = (num + "").split(".")[0]; - roundNum = (roundNum + "").split(".")[0]; - return num.length !== roundNum.length; - } - } - - //'#.##'之类的格式处理 1.324e-18 这种的科学数字 - function _dealNumberPrecision (text, fright) { - if (/[eE]/.test(text)) { - var precision = 0, i = 0, ch; - - if (/[%‰]$/.test(fright)) { - precision = /[%]$/.test(fright) ? 2 : 3; - } - - for (var len = fright.length; i < len; i++) { - if ((ch = fright.charAt(i)) == "0" || ch == "#") { - precision++; - } - } - return Number(text).toFixed(precision); - } - - return text; - } - - /** - * 数字格式 - */ - function _numberFormat (text, format) { - var text = text + ""; - - //在调用数字格式的时候如果text里没有任何数字则不处理 - if (!(/[0-9]/.test(text)) || !format) { - return text; - } - - // 数字格式,区分正负数 - var numMod = format.indexOf(";"); - if (numMod > -1) { - if (text >= 0) { - return _numberFormat(text + "", format.substring(0, numMod)); - } - return _numberFormat((-text) + "", format.substr(numMod + 1)); - - } else { - // 兼容格式处理负数的情况(copy:fr-jquery.format.js) - if (+text < 0 && format.charAt(0) !== "-") { - return _numberFormat((-text) + "", "-" + format); - } - } - - var fp = format.split("."), fleft = fp[0] || "", fright = fp[1] || ""; - text = _dealNumberPrecision(text, fright); - var tp = text.split("."), tleft = tp[0] || "", tright = tp[1] || ""; - - // 百分比,千分比的小数点移位处理 - if (/[%‰]$/.test(format)) { - var paddingZero = /[%]$/.test(format) ? "00" : "000"; - tright += paddingZero; - tleft += tright.substr(0, paddingZero.length); - tleft = tleft.replace(/^0+/gi, ""); - tright = tright.substr(paddingZero.length).replace(/0+$/gi, ""); - } - var right = _dealWithRight(tright, fright); - if (right.leftPlus) { - // 小数点后有进位 - tleft = parseInt(tleft) + 1 + ""; - - tleft = isNaN(tleft) ? "1" : tleft; - } - right = right.num; - var left = _dealWithLeft(tleft, fleft); - if (!(/[0-9]/.test(left))) { - left = left + "0"; - } - if (!(/[0-9]/.test(right))) { - return left + right; - } else { - return left + "." + right; - } - } - - /** - * 处理小数点右边小数部分 - * @param tright 右边内容 - * @param fright 右边格式 - * @returns {JSON} 返回处理结果和整数部分是否需要进位 - * @private - */ - function _dealWithRight (tright, fright) { - var right = "", j = 0, i = 0; - for (var len = fright.length; i < len; i++) { - var ch = fright.charAt(i); - var c = tright.charAt(j); - switch (ch) { - case "0": - if (isEmpty(c)) { - c = "0"; - } - right += c; - j++; - break; - case "#": - right += c; - j++; - break; - default : - right += ch; - break; - } - } - var rll = tright.substr(j); - var result = {}; - if (!isEmpty(rll) && rll.charAt(0) > 4) { - // 有多余字符,需要四舍五入 - result.leftPlus = true; - var numReg = right.match(/^[0-9]+/); - if (numReg) { - var num = numReg[0]; - var orilen = num.length; - var newnum = parseInt(num) + 1 + ""; - // 进位到整数部分 - if (newnum.length > orilen) { - newnum = newnum.substr(1); - } else { - newnum = BI.leftPad(newnum, orilen, "0"); - result.leftPlus = false; - } - right = right.replace(/^[0-9]+/, newnum); - } - } - result.num = right; - return result; - } - - /** - * 处理小数点左边整数部分 - * @param tleft 左边内容 - * @param fleft 左边格式 - * @returns {string} 返回处理结果 - * @private - */ - function _dealWithLeft (tleft, fleft) { - var left = ""; - var j = tleft.length - 1; - var combo = -1, last = -1; - var i = fleft.length - 1; - for (; i >= 0; i--) { - var ch = fleft.charAt(i); - var c = tleft.charAt(j); - switch (ch) { - case "0": - if (isEmpty(c)) { - c = "0"; - } - last = -1; - left = c + left; - j--; - break; - case "#": - last = i; - left = c + left; - j--; - break; - case ",": - if (!isEmpty(c)) { - // 计算一个,分隔区间的长度 - var com = fleft.match(/,[#0]+/); - if (com) { - combo = com[0].length - 1; - } - left = "," + left; - } - break; - default : - left = ch + left; - break; - } - } - if (last > -1) { - // 处理剩余字符 - var tll = tleft.substr(0, j + 1); - left = left.substr(0, last) + tll + left.substr(last); - } - if (combo > 0) { - // 处理,分隔区间 - var res = left.match(/[0-9]+,/); - if (res) { - res = res[0]; - var newstr = "", n = res.length - 1 - combo; - for (; n >= 0; n = n - combo) { - newstr = res.substr(n, combo) + "," + newstr; - } - var lres = res.substr(0, n + combo); - if (!isEmpty(lres)) { - newstr = lres + "," + newstr; - } - } - left = left.replace(/[0-9]+,/, newstr); - } - return left; - } - - - BI.cjkEncode = function (text) { - // alex:如果非字符串,返回其本身(cjkEncode(234) 返回 ""是不对的) - if (typeof text !== "string") { - return text; - } - - var newText = ""; - for (var i = 0; i < text.length; i++) { - var code = text.charCodeAt(i); - if (code >= 128 || code === 91 || code === 93) {// 91 is "[", 93 is "]". - newText += "[" + code.toString(16) + "]"; - } else { - newText += text.charAt(i); - } - } - - return newText; - }; - - /** - * 将cjkEncode处理过的字符串转化为原始字符串 - * - * @static - * @param text 需要做解码的字符串 - * @return {String} 解码后的字符串 - */ - BI.cjkDecode = function (text) { - if (text == null) { - return ""; - } - // 查找没有 "[", 直接返回. kunsnat:数字的时候, 不支持indexOf方法, 也是直接返回. - if (!isNaN(text) || text.indexOf("[") == -1) { - return text; - } - - var newText = ""; - for (var i = 0; i < text.length; i++) { - var ch = text.charAt(i); - if (ch == "[") { - var rightIdx = text.indexOf("]", i + 1); - if (rightIdx > i + 1) { - var subText = text.substring(i + 1, rightIdx); - // james:主要是考虑[CDATA[]]这样的值的出现 - if (subText.length > 0) { - ch = String.fromCharCode(eval("0x" + subText)); - } - - i = rightIdx; - } - } - - newText += ch; - } - - return newText; - }; - - // replace the html special tags - var SPECIAL_TAGS = { - "&": "&", - "\"": """, - "<": "<", - ">": ">", - "\x20": " ", - "\n": " " - }; - BI.htmlEncode = function (text) { - return BI.isNull(text) ? "" : BI.replaceAll(text + "", BI.keys(SPECIAL_TAGS).join("|"), function (v) { - return SPECIAL_TAGS[v] ? SPECIAL_TAGS[v] : v; - }); - }; - // html decode - BI.htmlDecode = function (text) { - return BI.isNull(text) ? "" : BI.replaceAll(text + "", BI.values(SPECIAL_TAGS).join("|"), function (v) { - switch (v) { - case "&": - return "&"; - case """: - return "\""; - case "<": - return "<"; - case ">": - return ">"; - case " ": - return " "; - case " ": - return "\n"; - default: - return v; - } - }); - }; - - BI.cjkEncodeDO = function (o) { - if (BI.isPlainObject(o)) { - var result = {}; - BI._.each(o, function (v, k) { - if (!(typeof v === "string")) { - v = BI.jsonEncode(v); - } - // wei:bug 43338,如果key是中文,cjkencode后o的长度就加了1,ie9以下版本死循环,所以新建对象result。 - k = BI.cjkEncode(k); - result[k] = BI.cjkEncode(v); - }); - return result; - } - return o; - }; - - BI.jsonEncode = function (o) { - // james:这个Encode是抄的EXT的 - var useHasOwn = !!{}.hasOwnProperty; - - // crashes Safari in some instances - // var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/; - - var m = { - "\b": "\\b", - "\t": "\\t", - "\n": "\\n", - "\f": "\\f", - "\r": "\\r", - "\"": "\\\"", - "\\": "\\\\" - }; - - var encodeString = function (s) { - if (/["\\\x00-\x1f]/.test(s)) { - return "\"" + s.replace(/([\x00-\x1f\\"])/g, function (a, b) { - var c = m[b]; - if (c) { - return c; - } - c = b.charCodeAt(); - return "\\u00" + - Math.floor(c / 16).toString(16) + - (c % 16).toString(16); - }) + "\""; - } - return "\"" + s + "\""; - }; - - var encodeArray = function (o) { - var a = ["["], b, i, l = o.length, v; - for (i = 0; i < l; i += 1) { - v = o[i]; - switch (typeof v) { - case "undefined": - case "function": - case "unknown": - break; - default: - if (b) { - a.push(","); - } - a.push(v === null ? "null" : BI.jsonEncode(v)); - b = true; - } - } - a.push("]"); - return a.join(""); - }; - - if (typeof o === "undefined" || o === null) { - return "null"; - } else if (BI.isArray(o)) { - return encodeArray(o); - } else if (o instanceof Date) { - /* - * alex:原来只是把年月日时分秒简单地拼成一个String,无法decode - * 现在这么处理就可以decode了,但是JS.jsonDecode和Java.JSONObject也要跟着改一下 - */ - return BI.jsonEncode({ - __time__: o.getTime() - }); - } else if (typeof o === "string") { - return encodeString(o); - } else if (typeof o === "number") { - return isFinite(o) ? String(o) : "null"; - } else if (typeof o === "boolean") { - return String(o); - } else if (BI.isFunction(o)) { - return String(o); - } - var a = ["{"], b, i, v; - for (i in o) { - if (!useHasOwn || o.hasOwnProperty(i)) { - v = o[i]; - switch (typeof v) { - case "undefined": - case "unknown": - break; - default: - if (b) { - a.push(","); - } - a.push(BI.jsonEncode(i), ":", - v === null ? "null" : BI.jsonEncode(v)); - b = true; - } - } - } - a.push("}"); - return a.join(""); - - }; - - BI.jsonDecode = function (text) { - - try { - // 注意0啊 - // var jo = $.parseJSON(text) || {}; - var jo = BI.$ ? BI.$.parseJSON(text) : _global.JSON.parse(text); - if (jo == null) { - jo = {}; - } - } catch (e) { - /* - * richie:浏览器只支持标准的JSON字符串转换,而jQuery会默认调用浏览器的window.JSON.parse()函数进行解析 - * 比如:var str = "{'a':'b'}",这种形式的字符串转换为JSON就会抛异常 - */ - try { - jo = new Function("return " + text)() || {}; - } catch (e) { - // do nothing - } - if (jo == null) { - jo = []; - } - } - if (!_hasDateInJson(text)) { - return jo; - } - - function _hasDateInJson (json) { - if (!json || typeof json !== "string") { - return false; - } - return json.indexOf("__time__") != -1; - } - - return (function (o) { - if (typeof o === "string") { - return o; - } - if (o && o.__time__ != null) { - return new Date(o.__time__); - } - for (var a in o) { - if (o[a] == o || typeof o[a] === "object" || BI._.isFunction(o[a])) { - break; - } - o[a] = arguments.callee(o[a]); - } - - return o; - })(jo); - }; - - /** - * 获取编码后的url - * @param urlTemplate url模板 - * @param param 参数 - * @returns {*|String} - * @example - * BI.getEncodeURL("design/{tableName}/{fieldName}",{tableName: "A", fieldName: "a"}) // design/A/a - */ - BI.getEncodeURL = function (urlTemplate, param) { - return BI.replaceAll(urlTemplate, "\\{(.*?)\\}", function (ori, str) { - return BI.encodeURIComponent(BI.isObject(param) ? param[str] : param); - }); - }; - - BI.encodeURIComponent = function (url) { - BI.specialCharsMap = BI.specialCharsMap || {}; - url = url || ""; - url = BI.replaceAll(url + "", BI.keys(BI.specialCharsMap || []).join("|"), function (str) { - switch (str) { - case "\\": - return BI.specialCharsMap["\\\\"] || str; - default: - return BI.specialCharsMap[str] || str; - } - }); - return _global.encodeURIComponent(url); - }; - - BI.decodeURIComponent = function (url) { - var reserveSpecialCharsMap = {}; - BI.each(BI.specialCharsMap, function (initialChar, encodeChar) { - reserveSpecialCharsMap[encodeChar] = initialChar === "\\\\" ? "\\" : initialChar; - }); - url = url || ""; - url = BI.replaceAll(url + "", BI.keys(reserveSpecialCharsMap || []).join("|"), function (str) { - return reserveSpecialCharsMap[str] || str; - }); - return _global.decodeURIComponent(url); - }; - - BI.contentFormat = function (cv, fmt) { - if (isEmpty(cv)) { - // 原值为空,返回空字符 - return ""; - } - var text = cv.toString(); - if (isEmpty(fmt)) { - // 格式为空,返回原字符 - return text; - } - if (fmt.match(/^T/)) { - // T - 文本格式 - return text; - } else if (fmt.match(/^D/)) { - // D - 日期(时间)格式 - if (!(cv instanceof Date)) { - if (typeof cv === "number") { - // 毫秒数类型 - cv = new Date(cv); - } else { - //字符串类型转化为date类型 - cv = new Date(Date.parse(("" + cv).replace(/-|\./g, "/"))); - } - } - if (!isInvalidDate(cv) && !BI.isNull(cv)) { - var needTrim = fmt.match(/^DT/); - text = BI.date2Str(cv, fmt.substring(needTrim ? 2 : 1)); - } - } else if (fmt.match(/E/)) { - // 科学计数格式 - text = _eFormat(text, fmt); - } else { - // 数字格式 - text = _numberFormat(text, fmt); - } - // ¤ - 货币格式 - text = text.replace(/¤/g, "¥"); - return text; - }; - - /** - * 将Java提供的日期格式字符串装换为JS识别的日期格式字符串 - * @class FR.parseFmt - * @param fmt 日期格式 - * @returns {String} - */ - BI.parseFmt = function (fmt) { - if (!fmt) { - return ""; - } - //日期 - fmt = String(fmt) - //年 - .replace(/y{4,}/g, "%Y")//yyyy的时候替换为Y - .replace(/y{2}/g, "%y")//yy的时候替换为y - //月 - .replace(/M{4,}/g, "%b")//MMMM的时候替换为b,八 - .replace(/M{3}/g, "%B")//MMM的时候替换为M,八月 - .replace(/M{2}/g, "%X")//MM的时候替换为X,08 - .replace(/M{1}/g, "%x")//M的时候替换为x,8 - .replace(/a{1}/g, "%p"); - //天 - if (new RegExp("d{2,}", "g").test(fmt)) { - fmt = fmt.replace(/d{2,}/g, "%d");//dd的时候替换为d - } else { - fmt = fmt.replace(/d{1}/g, "%e");//d的时候替换为j - } - //时 - if (new RegExp("h{2,}", "g").test(fmt)) {//12小时制 - fmt = fmt.replace(/h{2,}/g, "%I"); - } else { - fmt = fmt.replace(/h{1}/g, "%I"); - } - if (new RegExp("H{2,}", "g").test(fmt)) {//24小时制 - fmt = fmt.replace(/H{2,}/g, "%H"); - } else { - fmt = fmt.replace(/H{1}/g, "%H"); - } - fmt = fmt.replace(/m{2,}/g, "%M")//分 - //秒 - .replace(/s{2,}/g, "%S"); - - return fmt; - }; - - /** - * 把字符串按照对应的格式转化成日期对象 - * - * @example - * var result = BI.str2Date('2013-12-12', 'yyyy-MM-dd');//Thu Dec 12 2013 00:00:00 GMT+0800 - * - * @class BI.str2Date - * @param str 字符串 - * @param format 日期格式 - * @returns {*} - */ - BI.str2Date = function (str, format) { - if (typeof str != "string" || typeof format != "string") { - return null; - } - var fmt = BI.parseFmt(format); - return BI.parseDateTime(str, fmt); - }; - - /** - * 把日期对象按照指定格式转化成字符串 - * - * @example - * var date = new Date('Thu Dec 12 2013 00:00:00 GMT+0800'); - * var result = BI.date2Str(date, 'yyyy-MM-dd');//2013-12-12 - * - * @class BI.date2Str - * @param date 日期 - * @param format 日期格式 - * @returns {String} - */ - BI.date2Str = function (date, format) { - if (!date) { - return ""; - } - // O(len(format)) - var len = format.length, result = ""; - if (len > 0) { - var flagch = format.charAt(0), start = 0, str = flagch; - for (var i = 1; i < len; i++) { - var ch = format.charAt(i); - if (flagch !== ch) { - result += compileJFmt({ - char: flagch, - str: str, - len: i - start - }, date); - flagch = ch; - start = i; - str = flagch; - } else { - str += ch; - } - } - result += compileJFmt({ - char: flagch, - str: str, - len: len - start - }, date); - } - return result; - - function compileJFmt (jfmt, date) { - var str = jfmt.str, len = jfmt.len, ch = jfmt["char"]; - switch (ch) { - case "E": // 星期 - str = BI.getFullDayName(date.getDay()); - break; - case "y": // 年 - if (len <= 3) { - str = (date.getFullYear() + "").slice(2, 4); - } else { - str = date.getFullYear(); - } - break; - case "M": // 月 - if (len > 2) { - str = BI.getMonthName(date.getMonth()); - } else if (len < 2) { - str = date.getMonth() + 1; - } else { - str = BI.leftPad(date.getMonth() + 1 + "", 2, "0"); - } - break; - case "d": // 日 - if (len > 1) { - str = BI.leftPad(date.getDate() + "", 2, "0"); - } else { - str = date.getDate(); - } - break; - case "h": // 时(12) - var hour = date.getHours() % 12; - if (hour === 0) { - hour = 12; - } - if (len > 1) { - str = BI.leftPad(hour + "", 2, "0"); - } else { - str = hour; - } - break; - case "H": // 时(24) - if (len > 1) { - str = BI.leftPad(date.getHours() + "", 2, "0"); - } else { - str = date.getHours(); - } - break; - case "m": - if (len > 1) { - str = BI.leftPad(date.getMinutes() + "", 2, "0"); - } else { - str = date.getMinutes(); - } - break; - case "s": - if (len > 1) { - str = BI.leftPad(date.getSeconds() + "", 2, "0"); - } else { - str = date.getSeconds(); - } - break; - case "a": - str = date.getHours() < 12 ? "am" : "pm"; - break; - case "z": - str = BI.getTimezone(date); - break; - default: - str = jfmt.str; - break; - } - return str; - } - }; - - BI.object2Number = function (value) { - if (value == null) { - return 0; - } - if (typeof value === "number") { - return value; - } - var str = value + ""; - if (str.indexOf(".") === -1) { - return parseInt(str); - } - return parseFloat(str); - }; - - BI.object2Date = function (obj) { - if (obj == null) { - return new Date(); - } - if (obj instanceof Date) { - return obj; - } else if (typeof obj === "number") { - return new Date(obj); - } - var str = obj + ""; - str = str.replace(/-/g, "/"); - var dt = new Date(str); - if (!isInvalidDate(dt)) { - return dt; - } - - return new Date(); - - }; - - BI.object2Time = function (obj) { - if (obj == null) { - return new Date(); - } - if (obj instanceof Date) { - return obj; - } - var str = obj + ""; - str = str.replace(/-/g, "/"); - var dt = new Date(str); - if (!isInvalidDate(dt)) { - return dt; - } - if (str.indexOf("/") === -1 && str.indexOf(":") !== -1) { - dt = new Date("1970/01/01 " + str); - if (!isInvalidDate(dt)) { - return dt; - } - } - dt = BI.parseDateTime(str, "HH:mm:ss"); - if (!isInvalidDate(dt)) { - return dt; - } - return new Date(); - - }; -})(); diff --git a/src/core/func/array.js b/src/core/func/array.js deleted file mode 100644 index a96292352..000000000 --- a/src/core/func/array.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 对数组对象的扩展 - * @class Array - */ -BI._.extend(BI, { - - pushArray: function (sArray, array) { - for (var i = 0; i < array.length; i++) { - sArray.push(array[i]); - } - }, - pushDistinct: function (sArray, obj) { - if (!BI.contains(sArray, obj)) { - sArray.push(obj); - } - }, - pushDistinctArray: function (sArray, array) { - for (var i = 0, len = array.length; i < len; i++) { - BI.pushDistinct(sArray, array[i]); - } - } -}); diff --git a/src/core/func/date.js b/src/core/func/date.js deleted file mode 100644 index d603d235c..000000000 --- a/src/core/func/date.js +++ /dev/null @@ -1,312 +0,0 @@ -/** Constants used for time computations */ -BI.Date = BI.Date || {}; -BI.Date.SECOND = 1000; -BI.Date.MINUTE = 60 * BI.Date.SECOND; -BI.Date.HOUR = 60 * BI.Date.MINUTE; -BI.Date.DAY = 24 * BI.Date.HOUR; -BI.Date.WEEK = 7 * BI.Date.DAY; - -// Monday first, etc. -BI.Date._FD = 1; - -// short month names -BI.Date._SMN = [0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11]; - -/** Adds the number of days array to the Date object. */ -BI.Date._MD = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - -// 实际上无论周几作为一周的第一天,周初周末都是在-6-0间做偏移,用一个数组就可以 -BI.Date._OFFSET = [0, -1, -2, -3, -4, -5, -6]; - -BI._.extend(BI, { - /** - * 获取时区 - * @returns {String} - */ - getTimezone: function (date) { - return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, ""); - }, - - /** Returns the number of days in the current month */ - getMonthDays: function (date, month) { - var year = date.getFullYear(); - if (typeof month === "undefined") { - month = date.getMonth(); - } - if (((0 == (year % 4)) && ((0 != (year % 100)) || (0 == (year % 400)))) && month == 1) { - return 29; - } - return BI.Date._MD[month]; - - }, - - /** - * 获取每月的最后一天 - * @returns {Date} - */ - getLastDateOfMonth: function (date) { - return BI.getDate(date.getFullYear(), date.getMonth(), BI.getMonthDays(date)); - }, - - /** Returns the number of day in the year. */ - getDayOfYear: function (date) { - var now = BI.getDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); - var then = BI.getDate(date.getFullYear(), 0, 0, 0, 0, 0); - var time = now - then; - return Math.floor(time / BI.Date.DAY); - }, - - /** Returns the number of the week in year, as defined in ISO 8601. */ - getWeekNumber: function (date) { - var d = BI.getDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); - var week = d.getDay(); - var startOfWeek = BI.StartOfWeek % 7; - var middleDay = (startOfWeek + 3) % 7; - middleDay = middleDay || 7; - // 偏移到周周首之前需要多少天 - var offsetWeekStartCount = week < startOfWeek ? (7 + week - startOfWeek) : (week - startOfWeek); - var offsetWeekMiddleCount = middleDay < startOfWeek ? (7 + middleDay - startOfWeek) : (middleDay - startOfWeek); - d.setDate(d.getDate() - offsetWeekStartCount + offsetWeekMiddleCount); - var ms = d.valueOf(); - d.setMonth(0); - d.setDate(1); - return Math.floor((ms - d.valueOf()) / (7 * 864e5)) + 1; - }, - - getQuarter: function (date) { - return Math.floor(date.getMonth() / 3) + 1; - }, - - // 离当前时间多少天的时间 - getOffsetDate: function (date, offset) { - return BI.getDate(BI.getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()) + offset * 864e5); - }, - - getOffsetQuarter: function (date, n) { - var dt = BI.getDate(BI.getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); - var day = dt.getDate(); - var monthDay = BI.getMonthDays(BI.getDate(dt.getFullYear(), dt.getMonth() + BI.parseInt(n) * 3, 1)); - if (day > monthDay) { - day = monthDay; - } - dt.setDate(day); - dt.setMonth(dt.getMonth() + parseInt(n) * 3); - return dt; - }, - - // 得到本季度的起始月份 - getQuarterStartMonth: function (date) { - var quarterStartMonth = 0; - var nowMonth = date.getMonth(); - if (nowMonth < 3) { - quarterStartMonth = 0; - } - if (2 < nowMonth && nowMonth < 6) { - quarterStartMonth = 3; - } - if (5 < nowMonth && nowMonth < 9) { - quarterStartMonth = 6; - } - if (nowMonth > 8) { - quarterStartMonth = 9; - } - return quarterStartMonth; - }, - // 获得本季度的起始日期 - getQuarterStartDate: function (date) { - return BI.getDate(date.getFullYear(), BI.getQuarterStartMonth(date), 1); - }, - // 得到本季度的结束日期 - getQuarterEndDate: function (date) { - var quarterEndMonth = BI.getQuarterStartMonth(date) + 2; - return BI.getDate(date.getFullYear(), quarterEndMonth, BI.getMonthDays(date, quarterEndMonth)); - }, - - // 指定日期n个月之前或之后的日期 - getOffsetMonth: function (date, n) { - var dt = BI.getDate(BI.getTime(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); - var day = dt.getDate(); - var monthDay = BI.getMonthDays(BI.getDate(dt.getFullYear(), dt.getMonth() + parseInt(n), 1)); - if (day > monthDay) { - day = monthDay; - } - dt.setDate(day); - dt.setMonth(dt.getMonth() + parseInt(n)); - return dt; - }, - - // 获得本周的起始日期 - getWeekStartDate: function (date) { - var w = date.getDay(); - var startOfWeek = BI.StartOfWeek % 7; - return BI.getOffsetDate(date, BI.Date._OFFSET[w < startOfWeek ? (7 + w - startOfWeek) : (w - startOfWeek)]); - }, - // 得到本周的结束日期 - getWeekEndDate: function (date) { - var w = date.getDay(); - var startOfWeek = BI.StartOfWeek % 7; - return BI.getOffsetDate(date, BI.Date._OFFSET[w < startOfWeek ? (7 + w - startOfWeek) : (w - startOfWeek)] + 6); - }, - - getFullDayName: function (index) { - return [BI.i18nText("BI-Basic_Sunday"), - BI.i18nText("BI-Basic_Monday"), - BI.i18nText("BI-Basic_Tuesday"), - BI.i18nText("BI-Basic_Wednesday"), - BI.i18nText("BI-Basic_Thursday"), - BI.i18nText("BI-Basic_Friday"), - BI.i18nText("BI-Basic_Saturday"), - BI.i18nText("BI-Basic_Sunday")][index]; - }, - - getShortDayName: function (index) { - return [BI.i18nText("BI-Basic_Simple_Sunday"), - BI.i18nText("BI-Basic_Simple_Monday"), - BI.i18nText("BI-Basic_Simple_Tuesday"), - BI.i18nText("BI-Basic_Simple_Wednesday"), - BI.i18nText("BI-Basic_Simple_Thursday"), - BI.i18nText("BI-Basic_Simple_Friday"), - BI.i18nText("BI-Basic_Simple_Saturday"), - BI.i18nText("BI-Basic_Simple_Sunday")][index]; - }, - - getMonthName: function (index) { - return [BI.i18nText("BI-Basic_January"), - BI.i18nText("BI-Basic_February"), - BI.i18nText("BI-Basic_March"), - BI.i18nText("BI-Basic_April"), - BI.i18nText("BI-Basic_May"), - BI.i18nText("BI-Basic_June"), - BI.i18nText("BI-Basic_July"), - BI.i18nText("BI-Basic_August"), - BI.i18nText("BI-Basic_September"), - BI.i18nText("BI-Basic_October"), - BI.i18nText("BI-Basic_November"), - BI.i18nText("BI-Basic_December")][index] - }, - - getQuarterName: function (index) { - return ["", BI.i18nText("BI-Quarter_1"), - BI.i18nText("BI-Quarter_2"), - BI.i18nText("BI-Quarter_3"), - BI.i18nText("BI-Quarter_4")][index]; - }, - - // 格式化打印日期 - print: function (date, str) { - var m = date.getMonth(); - var d = date.getDate(); - var y = date.getFullYear(); - var yWith4number = y + ""; - while (yWith4number.length < 4) { - yWith4number = "0" + yWith4number; - } - var wn = BI.getWeekNumber(date); - var qr = BI.getQuarter(date); - var w = date.getDay(); - var s = {}; - var hr = date.getHours(); - var pm = (hr >= 12); - var ir = (pm) ? (hr - 12) : hr; - var dy = BI.getDayOfYear(date); - if (ir == 0) { - ir = 12; - } - var min = date.getMinutes(); - var sec = date.getSeconds(); - s["%a"] = BI.getShortDayName(w); // abbreviated weekday name [FIXME: I18N] - s["%A"] = BI.getFullDayName(w); // full weekday name - s["%b"] = BI.Date._SMN[m]; // abbreviated month name [FIXME: I18N] - s["%B"] = BI.getMonthName(m); // full month name - // FIXME: %c : preferred date and time representation for the current locale - s["%C"] = 1 + Math.floor(y / 100); // the century number - s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) - s["%e"] = d; // the day of the month (range 1 to 31) - // FIXME: %D : american date style: %m/%d/%y - // FIXME: %E, %F, %G, %g, %h (man strftime) - s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) - s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) - s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) - s["%k"] = hr + ""; // hour, range 0 to 23 (24h format) - s["%l"] = ir + ""; // hour, range 1 to 12 (12h format) - s["%X"] = (m < 9) ? ("0" + (1 + m)) : (1 + m); // month, range 01 to 12 - s["%x"] = m + 1; // month, range 1 to 12 - s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 - s["%n"] = "\n"; // a newline character - s["%p"] = pm ? "PM" : "AM"; - s["%P"] = pm ? "pm" : "am"; - // FIXME: %r : the time in am/pm notation %I:%M:%S %p - // FIXME: %R : the time in 24-hour notation %H:%M - s["%s"] = Math.floor(date.getTime() / 1000); - s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 - s["%t"] = "\t"; // a tab character - // FIXME: %T : the time in 24-hour notation (%H:%M:%S) - s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; - s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) - s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) - // FIXME: %x : preferred date representation for the current locale without the time - // FIXME: %X : preferred time representation for the current locale without the date - s["%y"] = yWith4number.substr(2, 2); // year without the century (range 00 to 99) - s["%Y"] = yWith4number; // year with the century - s["%%"] = "%"; // a literal '%' character - s["%q"] = "0" + qr; - s["%Q"] = qr; - - var re = /%./g; - BI.isKhtml = BI.isKhtml || function () { - if(!_global.navigator) { - return false; - } - return /Konqueror|Safari|KHTML/i.test(navigator.userAgent); - }; - - // 包含年周的格式化,ISO8601标准周的计数会影响年 - if ((str.indexOf("%Y") !== -1 || str.indexOf("%y") !== -1) && (str.indexOf("%W") !== -1 || str.indexOf("%U") !== -1 || str.indexOf("%V") !== -1)) { - switch (wn) { - // 如果周数是1,但是当前却在12月,表示此周数为下一年的 - case 1: - if (m === 11) { - s["%y"] = parseInt(s["%y"]) + 1; - s["%Y"] = parseInt(s["%Y"]) + 1; - } - break; - // 如果周数是53,但是当前却在1月,表示此周数为上一年的 - case 53: - if (m === 0) { - s["%y"] = parseInt(s["%y"]) - 1; - s["%Y"] = parseInt(s["%Y"]) - 1; - } - break; - default: - break; - } - } - - if (!BI.isKhtml()) { - return str.replace(re, function (par) { - return s[par] || par; - }); - } - var a = str.match(re); - for (var i = 0; i < a.length; i++) { - var tmp = s[a[i]]; - if (tmp) { - re = new RegExp(a[i], "g"); - str = str.replace(re, tmp); - } - } - - return str; - } -}); diff --git a/src/core/func/function.js b/src/core/func/function.js deleted file mode 100644 index 83d58c5ec..000000000 --- a/src/core/func/function.js +++ /dev/null @@ -1,168 +0,0 @@ -/** - * 基本的函数 - * Created by GUY on 2015/6/24. - */ -BI.Func = BI.Func || {}; -BI._.extend(BI.Func, { - /** - * 创建唯一的名字 - * @param array - * @param name - * @returns {*} - */ - createDistinctName: function (array, name) { - var src = name, idx = 1; - name = name || ""; - while (true) { - if (BI.every(array, function (i, item) { - return BI.isKey(item) ? item !== name : item.name !== name; - })) { - break; - } - name = src + (idx++); - } - return name; - }, - - /** - * 获取字符宽度 - * @param str - * @return {number} - */ - getGBWidth: function (str) { - str = str + ""; - str = str.replace(/[^\x00-\xff]/g, "xx"); - return Math.ceil(str.length / 2); - }, - - /** - * 获取搜索结果 - * @param items - * @param keyword - * @param param 搜索哪个属性 - */ - getSearchResult: function (items, keyword, param) { - var isArray = BI.isArray(items); - items = isArray ? BI.flatten(items) : items; - param || (param = "text"); - if (!BI.isKey(keyword)) { - return { - find: items, - match: isArray ? [] : {} - }; - } - var t, text, py; - keyword = BI.toUpperCase(keyword); - var matched = isArray ? [] : {}, find = isArray ? [] : {}; - BI.each(items, function (i, item) { - // 兼容item为null的处理 - if (BI.isNull(item)) { - return; - } - t = BI.stripEL(item); - text = BI.find([t[param], t.text, t.value, t.name, t], function (index, val) { - return BI.isNotNull(val); - }); - - if (BI.isNull(text) || BI.isObject(text)) return; - - py = BI.makeFirstPY(text, { - splitChar: "\u200b" - }); - text = BI.toUpperCase(text); - py = BI.toUpperCase(py); - var pidx; - if (text.indexOf(keyword) > -1) { - if (text === keyword) { - isArray ? matched.push(item) : (matched[i] = item); - } else { - isArray ? find.push(item) : (find[i] = item); - } - // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 - } else if (pidx = py.indexOf(keyword), (pidx > -1)) { - if (text === keyword || keyword.length === text.length) { - isArray ? matched.push(item) : (matched[i] = item); - } else { - isArray ? find.push(item) : (find[i] = item); - } - } - }); - return { - match: matched, - find: find - }; - }, - - /** - * 获取按GB2312排序的结果 - * @param items - * @param key - * @return {any[]} - */ - getSortedResult: function (items, key) { - var getTextOfItem = BI.isFunction(key) ? key : - function (item, key) { - if (BI.isNotNull(key)) { - return item[key]; - } - if (BI.isNotNull(item.text)) { - return item.text; - } - if (BI.isNotNull(item.value)) { - return item.value; - } - return item; - }; - - return items.sort(function (item1, item2) { - var str1 = getTextOfItem(item1, key); - var str2 = getTextOfItem(item2, key); - if (BI.isNull(str1) && BI.isNull(str2)) { - return 0; - } - if (BI.isNull(str1)) { - return -1; - } - if (BI.isNull(str2)) { - return 1; - } - if (str1 === str2) { - return 0; - } - var len1 = str1.length, len2 = str2.length; - for (var i = 0; i < len1 && i < len2; i++) { - var char1 = str1[i]; - var char2 = str2[i]; - if (char1 !== char2) { - // 找不到的字符都往后面放 - return (BI.isNull(BI.CODE_INDEX[char1]) ? BI.MAX : BI.CODE_INDEX[char1]) - (BI.isNull(BI.CODE_INDEX[char2]) ? BI.MAX : BI.CODE_INDEX[char2]); - } - } - return len1 - len2; - }); - } -}); - -BI._.extend(BI, { - beforeFunc: function (sFunc, func) { - var __self = sFunc; - return function () { - if (func.apply(sFunc, arguments) === false) { - return false; - } - return __self.apply(sFunc, arguments); - }; - }, - - afterFunc: function (sFunc, func) { - var __self = sFunc; - return function () { - var ret = __self.apply(sFunc, arguments); - if (ret === false) { - return false; - } - func.apply(sFunc, arguments); - return ret; - }; - } -}); diff --git a/src/core/func/number.js b/src/core/func/number.js deleted file mode 100644 index 59021349f..000000000 --- a/src/core/func/number.js +++ /dev/null @@ -1,156 +0,0 @@ -BI._.extend(BI, { - // 给Number类型增加一个add方法,调用起来更加方便。 - add: function (num, arg) { - return accAdd(arg, num); - - /** - ** 加法函数,用来得到精确的加法结果 - ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 - ** 调用:accAdd(arg1,arg2) - ** 返回值:arg1加上arg2的精确结果 - **/ - function accAdd (arg1, arg2) { - var r1, r2, m, c; - try { - r1 = arg1.toString().split(".")[1].length; - } catch (e) { - r1 = 0; - } - try { - r2 = arg2.toString().split(".")[1].length; - } catch (e) { - r2 = 0; - } - c = Math.abs(r1 - r2); - m = Math.pow(10, Math.max(r1, r2)); - if (c > 0) { - var cm = Math.pow(10, c); - if (r1 > r2) { - arg1 = Number(arg1.toString().replace(".", "")); - arg2 = Number(arg2.toString().replace(".", "")) * cm; - } else { - arg1 = Number(arg1.toString().replace(".", "")) * cm; - arg2 = Number(arg2.toString().replace(".", "")); - } - } else { - arg1 = Number(arg1.toString().replace(".", "")); - arg2 = Number(arg2.toString().replace(".", "")); - } - return (arg1 + arg2) / m; - } - }, - - // 给Number类型增加一个sub方法,调用起来更加方便。 - sub: function (num, arg) { - return accSub(num, arg); - - /** - ** 减法函数,用来得到精确的减法结果 - ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 - ** 调用:accSub(arg1,arg2) - ** 返回值:arg1加上arg2的精确结果 - **/ - function accSub (arg1, arg2) { - var r1, r2, m, n; - try { - r1 = arg1.toString().split(".")[1].length; - } catch (e) { - r1 = 0; - } - try { - r2 = arg2.toString().split(".")[1].length; - } catch (e) { - r2 = 0; - } - m = Math.pow(10, Math.max(r1, r2)); // last modify by deeka //动态控制精度长度 - n = (r1 >= r2) ? r1 : r2; - return ((arg1 * m - arg2 * m) / m).toFixed(n); - } - }, - - // 给Number类型增加一个mul方法,调用起来更加方便。 - mul: function (num, arg) { - return accMul(arg, num); - - /** - ** 乘法函数,用来得到精确的乘法结果 - ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 - ** 调用:accMul(arg1,arg2) - ** 返回值:arg1乘以 arg2的精确结果 - **/ - function accMul (arg1, arg2) { - var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); - try { - m += s1.split(".")[1].length; - } catch (e) { - } - try { - m += s2.split(".")[1].length; - } catch (e) { - } - return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); - } - }, - - // 给Number类型增加一个div方法,调用起来更加方便。 - div: function (num, arg) { - return accDivide(num, arg); - - /** - * Return digits length of a number - * @param {*number} num Input number - */ - function digitLength (num) { - // Get digit length of e - var eSplit = num.toString().split(/[eE]/); - var len = (eSplit[0].split(".")[1] || "").length - (+(eSplit[1] || 0)); - return len > 0 ? len : 0; - } - /** - * 把小数转成整数,支持科学计数法。如果是小数则放大成整数 - * @param {*number} num 输入数 - */ - function float2Fixed (num) { - if (num.toString().indexOf("e") === -1) { - return Number(num.toString().replace(".", "")); - } - var dLen = digitLength(num); - return dLen > 0 ? num * Math.pow(10, dLen) : num; - } - - /** - * 精确乘法 - */ - function times (num1, num2) { - var others = []; - for (var _i = 2; _i < arguments.length; _i++) { - others[_i - 2] = arguments[_i]; - } - if (others.length > 0) { - return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1))); - } - var num1Changed = float2Fixed(num1); - var num2Changed = float2Fixed(num2); - var baseNum = digitLength(num1) + digitLength(num2); - var leftValue = num1Changed * num2Changed; - return leftValue / Math.pow(10, baseNum); - } - - /** - * 精确除法 - */ - function accDivide (num1, num2) { - var others = []; - for (var _i = 2; _i < arguments.length; _i++) { - others[_i - 2] = arguments[_i]; - } - if (others.length > 0) { - return accDivide.apply(void 0, [accDivide(num1, num2), others[0]].concat(others.slice(1))); - } - var num1Changed = float2Fixed(num1); - var num2Changed = float2Fixed(num2); - return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1))); - } - } - -}); \ No newline at end of file diff --git a/src/core/func/string.js b/src/core/func/string.js deleted file mode 100644 index 55a89e63f..000000000 --- a/src/core/func/string.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * 对字符串对象的扩展 - * @class String - */ -BI._.extend(BI, { - - /** - * 判断字符串是否已指定的字符串开始 - * @param str source字符串 - * @param {String} startTag 指定的开始字符串 - * @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false - */ - startWith: function (str, startTag) { - str = str || ""; - if (startTag == null || startTag == "" || str.length === 0 || startTag.length > str.length) { - return false; - } - return str.substr(0, startTag.length) == startTag; - }, - /** - * 判断字符串是否以指定的字符串结束 - * @param str source字符串 - * @param {String} endTag 指定的字符串 - * @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false - */ - endWith: function (str, endTag) { - if (endTag == null || endTag == "" || str.length === 0 || endTag.length > str.length) { - return false; - } - return str.substring(str.length - endTag.length) == endTag; - }, - - /** - * 获取url中指定名字的参数 - * @param str source字符串 - * @param {String} name 参数的名字 - * @return {String} 参数的值 - */ - getQuery: function (str, name) { - var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); - var r = str.substr(str.indexOf("?") + 1).match(reg); - if (r) { - return unescape(r[2]); - } - return null; - }, - - /** - * 给url加上给定的参数 - * @param str source字符串 - * @param {Object} paras 参数对象,是一个键值对对象 - * @return {String} 添加了给定参数的url - */ - appendQuery: function (str, paras) { - if (!paras) { - return str; - } - var src = str; - // 没有问号说明还没有参数 - if (src.indexOf("?") === -1) { - src += "?"; - } - // 如果以问号结尾,说明没有其他参数 - if (BI.endWith(src, "?") !== false) { - } else { - src += "&"; - } - BI._.each(paras, function (value, name) { - if (typeof(name) === "string") { - src += name + "=" + value + "&"; - } - }); - src = src.substr(0, src.length - 1); - return src; - }, - /** - * 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 - * @param str source字符串 - * @param {String} s1 要替换的字符串的正则表达式 - * @param {String} s2 替换的结果字符串 - * @returns {String} 替换后的字符串 - */ - replaceAll: function (str, s1, s2) { - return BI.isString(str) ? str.replace(new RegExp(s1, "gm"), s2) : str; - }, - /** - * 总是让字符串以指定的字符开头 - * @param str source字符串 - * @param {String} start 指定的字符 - * @returns {String} 以指定字符开头的字符串 - */ - perfectStart: function (str, start) { - if (BI.startWith(str, start)) { - return str; - } - return start + str; - - }, - - /** - * 获取字符串中某字符串的所有项位置数组 - * @param str source字符串 - * @param {String} sub 子字符串 - * @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 - */ - allIndexOf: function (str, sub) { - if (typeof sub !== "string") { - return []; - } - var location = []; - var offset = 0; - while (str.length > 0) { - var loc = str.indexOf(sub); - if (loc === -1) { - break; - } - location.push(offset + loc); - str = str.substring(loc + sub.length, str.length); - offset += loc + sub.length; - } - return location; - } -}); \ No newline at end of file diff --git a/src/core/h.js b/src/core/h.js deleted file mode 100644 index b768b1415..000000000 --- a/src/core/h.js +++ /dev/null @@ -1,58 +0,0 @@ -BI.Fragment = function () { -}; - -BI.h = function (type, props, children) { - if (children != null) { - if (!BI.isArray(children)) { - children = [children]; - } - } else { - children = []; - } - if (arguments.length > 3) { - for (var i = 3; i < arguments.length; i++) { - if (BI.isArray(arguments[i])) { - children = children.concat(arguments[i]); - } else { - children.push(arguments[i]); - } - } - } - if (type === BI.Fragment) { - return children; - } - if (BI.isFunction(type)) { - type = type.xtype || type; - } - if (type === "el") { - return BI.extend({ - el: children[0] - }, props); - } - if (type === "left") { - return BI.extend({ - left: children - }, props); - } - if (type === "right") { - return BI.extend({ - right: children - }, props); - } - if (children.length === 1) { - if (BI.isKey(children[0])) { - return BI.extend({ - type: type - }, { text: children[0] }, props); - } - if (BI.isFunction(children[0])) { - return BI.extend({ - type: type - }, { items: children[0] }, props); - } - } - - return BI.extend({ - type: type - }, children.length > 0 ? { items: children } : {}, props); -}; diff --git a/src/core/listener/listener.show.js b/src/core/listener/listener.show.js deleted file mode 100644 index 569461bda..000000000 --- a/src/core/listener/listener.show.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * guy - * 检测某个Widget的EventChange事件然后去show某个card - * @type {*|void|Object} - * @class BI.ShowListener - * @extends BI.OB - */ -BI.ShowListener = BI.inherit(BI.OB, { - props: function () { - return { - eventObj: BI.createWidget(), - cardLayout: null, - cardNameCreator: function (v) { - return v; - }, - cardCreator: BI.emptyFn, - afterCardCreated: BI.emptyFn, - afterCardShow: BI.emptyFn - }; - }, - - init: function () { - var self = this, o = this.options; - if (o.eventObj) { - o.eventObj.on(BI.Controller.EVENT_CHANGE, function (type, v, ob) { - if (type === BI.Events.CLICK) { - v = v || o.eventObj.getValue(); - v = BI.isArray(v) ? (v.length > 1 ? v.toString() : v[0]) : v; - if (BI.isNull(v)) { - throw new Error("canot be null"); - } - var cardName = o.cardNameCreator(v); - if (!o.cardLayout.isCardExisted(cardName)) { - var card = o.cardCreator(cardName); - o.cardLayout.addCardByName(cardName, card); - o.afterCardCreated(cardName); - } - o.cardLayout.showCardByName(cardName); - BI.nextTick(function () { - o.afterCardShow(cardName); - self.fireEvent(BI.ShowListener.EVENT_CHANGE, cardName); - }); - } - }); - } - } -}); -BI.ShowListener.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/core/loader/loader.style.js b/src/core/loader/loader.style.js deleted file mode 100644 index ad5500ee5..000000000 --- a/src/core/loader/loader.style.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * style加载管理器 - * - * Created by GUY on 2015/9/7. - * @class - */ -BI.StyleLoaderManager = BI.inherit(BI.OB, { - _defaultConfig: function () { - return BI.extend(BI.StyleLoaderManager.superclass._defaultConfig.apply(this, arguments), {}); - }, - - _init: function () { - BI.StyleLoaderManager.superclass._init.apply(this, arguments); - this.stylesManager = {}; - }, - - loadStyle: function (name, styleString) { - if(!_global.document) { - return; - } - var d = document, styles = d.createElement("style"); - d.getElementsByTagName("head")[0].appendChild(styles); - styles.setAttribute("type", "text/css"); - if (styles.styleSheet) { - styles.styleSheet.cssText = styleString; - } else { - styles.appendChild(document.createTextNode(styleString)); - } - this.stylesManager[name] = styles; - - return this; - }, - - get: function (name) { - return this.stylesManager[name]; - }, - - has: function (name) { - return this.stylesManager[name] != null; - }, - - removeStyle: function (name) { - if (!this.has(name)) { - return this; - } - this.stylesManager[name].parentNode.removeChild(this.stylesManager[name]); - delete this.stylesManager[name]; - return this; - } -}); \ No newline at end of file diff --git a/src/core/logic/logic.js b/src/core/logic/logic.js deleted file mode 100644 index fab052e19..000000000 --- a/src/core/logic/logic.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @class BI.Logic - * @extends BI.OB - */ -BI.Logic = BI.inherit(BI.OB, { - createLogic: function () { - return this.options || {}; - } -}); - -BI.LogicFactory = { - Type: { - Vertical: "vertical", - Horizontal: "horizontal", - Table: "table", - HorizontalFill: "horizontal_fill" - }, - createLogic: function (key, options) { - var logic; - switch (key) { - case BI.LogicFactory.Type.Vertical: - logic = BI.VerticalLayoutLogic; - break; - case BI.LogicFactory.Type.Horizontal: - logic = BI.HorizontalLayoutLogic; - break; - case BI.LogicFactory.Type.Table: - logic = BI.TableLayoutLogic; - break; - case BI.LogicFactory.Type.HorizontalFill: - logic = BI.HorizontalFillLayoutLogic; - break; - default: - logic = BI.Logic; - break; - } - return new logic(options).createLogic(); - }, - - createLogicTypeByDirection: function (direction) { - switch (direction) { - case BI.Direction.Top: - case BI.Direction.Bottom: - case BI.Direction.Custom: - return BI.LogicFactory.Type.Vertical; - case BI.Direction.Left: - case BI.Direction.Right: - return BI.LogicFactory.Type.Horizontal; - } - }, - - createLogicItemsByDirection: function (direction) { - var layout; - var items = Array.prototype.slice.call(arguments, 1); - items = BI.map(items, function (i, item) { - if (BI.isWidget(item)) { - return { - el: item, - width: item.options.width, - height: item.options.height - }; - } - return item; - }); - switch (direction) { - case BI.Direction.Bottom: - layout = BI.LogicFactory.Type.Vertical; - items.reverse(); - break; - case BI.Direction.Right: - layout = BI.LogicFactory.Type.Horizontal; - items.reverse(); - break; - case BI.Direction.Custom: - items = items.slice(1); - break; - } - return items; - } -}; diff --git a/src/core/logic/logic.layout.js b/src/core/logic/logic.layout.js deleted file mode 100644 index babd2306c..000000000 --- a/src/core/logic/logic.layout.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * guy - * 上下布局逻辑 - * 上下布局的时候要考虑到是动态布局还是静态布局 - * - * @class BI.VerticalLayoutLogic - * @extends BI.Logic - */ -BI.VerticalLayoutLogic = BI.inherit(BI.Logic, { - props: function () { - return { - dynamic: false, - scrollable: null, - scrolly: false, - scrollx: false, - items: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - innerVgap: 0, - innerHgap: 0 - }; - }, - - createLogic: function () { - var layout, o = this.options; - if (o.dynamic) { - layout = "bi.vertical"; - } else { - layout = "bi.vtape"; - } - return BI._.pickBy({ - type: layout, - scrollable: o.scrollable, - scrolly: o.scrolly, - scrollx: o.scrollx, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize - }, BI.isNotNull); - } -}); - - -/** - * guy - * 左右布局逻辑 - * 左右布局的时候要考虑到是动态布局还是静态布局 - * - * @class BI.HorizontalLayoutLogic - * @extends BI.Logic - */ -BI.HorizontalLayoutLogic = BI.inherit(BI.Logic, { - props: function () { - return { - dynamic: false, - scrollable: null, - scrolly: false, - scrollx: false, - items: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - innerVgap: 0, - innerHgap: 0 - }; - }, - - createLogic: function () { - var layout, o = this.options; - if (o.dynamic) { - layout = "bi.vertical_adapt"; - } else { - layout = "bi.htape"; - } - return BI._.pickBy({ - type: layout, - scrollable: o.scrollable, - scrolly: o.scrolly, - scrollx: o.scrollx, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize - }, BI.isNotNull); - } -}); - -/** - * guy - * 表格布局逻辑 - * 表格布局的时候要考虑到是动态布局还是静态布局 - * - * @class BI.TableLayoutLogic - * @extends BI.OB - */ -BI.TableLayoutLogic = BI.inherit(BI.Logic, { - props: function () { - return { - dynamic: false, - scrollable: null, - scrolly: false, - scrollx: false, - columns: 0, - rows: 0, - columnSize: [], - rowSize: [], - hgap: 0, - vgap: 0, - items: [] - }; - }, - - createLogic: function () { - var layout, o = this.options; - if (o.dynamic) { - layout = "bi.table"; - } else { - layout = "bi.window"; - } - return BI._.pickBy({ - type: layout, - scrollable: o.scrollable, - scrolly: o.scrolly, - scrollx: o.scrollx, - columns: o.columns, - rows: o.rows, - hgap: o.hgap, - vgap: o.vgap, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize - }, BI.isNotNull); - } -}); - -/** - * guy - * 左右充满布局逻辑 - * - * @class BI.HorizontalFillLayoutLogic - * @extends BI.Logic - */ -BI.HorizontalFillLayoutLogic = BI.inherit(BI.Logic, { - props: function () { - return { - dynamic: false, - scrollable: null, - scrolly: false, - scrollx: false, - items: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - innerVgap: 0, - innerHgap: 0 - }; - }, - - createLogic: function () { - var layout, o = this.options; - var columnSize = []; - BI.each(o.items, function (i, item) { - columnSize.push(item.width || 0); - }); - if (o.dynamic) { - layout = "bi.horizontal_fill"; - } else { - layout = "bi.htape"; - } - return BI._.pickBy({ - type: layout, - scrollable: o.scrollable, - scrolly: o.scrolly, - scrollx: o.scrollx, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: columnSize, - rowSize: o.rowSize - }, BI.isNotNull); - } -}); diff --git a/src/core/platform/web/config.js b/src/core/platform/web/config.js deleted file mode 100644 index 66440ccf8..000000000 --- a/src/core/platform/web/config.js +++ /dev/null @@ -1,286 +0,0 @@ -// 工程配置 -!(function () { - // 注册布局 - // adapt类布局优先级规则 - // 1、支持flex的浏览器下使用flex布局 - // 2、不支持flex的浏览器下使用inline布局 - // 3、当列宽既需要自动列宽又需要自适应列宽时,inline布局也处理不了了。当横向出滚动条时使用table布局,不出滚动条时使用float布局 - var _isSupportFlex, _isSupportGrid; - var isSupportFlex = function () { - if (_isSupportFlex == null) { - _isSupportFlex = !!(BI.isSupportCss3 && BI.isSupportCss3("flex")); - } - return _isSupportFlex; - }; - var isSupportGrid = function () { - if (_isSupportGrid == null) { - _isSupportGrid = !!(BI.isSupportCss3 && BI.isSupportCss3("grid")); - } - return _isSupportGrid; - }; - // 判断浏览器是否支持sticky 属性 - var isSupportSticky = (function () { - var vendorList = ["", "-webkit-", "-ms-", "-moz-", "-o-"], - vendorListLength = vendorList.length, - stickyElement = document.createElement("div"); - for (var i = 0; i < vendorListLength; i++) { - stickyElement.style.position = vendorList[i] + "sticky"; - if (stickyElement.style.position !== "") { - return true; - } - } - return false; - })(); - BI.Plugin.configWidget("bi.horizontal", function (ob) { - var supportFlex = isSupportFlex(); - // // 在横向自适应场景下我们需要使用table的自适应撑出滚动条的特性(flex处理不了这种情况) - // // 主要出现在center_adapt或者horizontal_adapt的场景,或者主动设置horizontalAlign的场景 - // if (ob.horizontalAlign === BI.HorizontalAlign.Center || ob.horizontalAlign === BI.HorizontalAlign.Stretch) { - // return BI.extend({}, ob, {type: "bi.table_adapt"}); - // } - if (supportFlex) { - return BI.extend({}, ob, { type: "bi.flex_horizontal" }); - } - return BI.extend({ - scrollx: true - }, ob, { type: "bi.inline" }); - }); - BI.Plugin.configWidget("bi.vertical", function (ob) { - if (ob.horizontalAlign === BI.HorizontalAlign.Left || ob.horizontalAlign === BI.HorizontalAlign.Right) { - if (isSupportFlex()) { - return BI.extend({}, ob, { type: "bi.flex_vertical" }); - } - return BI.extend({}, ob, { - horizontalAlign: BI.HorizontalAlign.Stretch, - type: "bi.vertical", - items: BI.map(ob.items, function (i, item) { - return { - type: "bi.inline", - horizontalAlign: ob.horizontalAlign, - items: [item] - }; - }) - }); - } - if (ob.verticalAlign === BI.VerticalAlign.Stretch) { - if (isSupportFlex()) { - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Stretch, - }, ob, { type: "bi.flex_vertical" }); - } - } - return ob; - }); - BI.Plugin.configWidget("bi.inline", function (ob) { - // 当列宽既需要自动列宽又需要自适应列宽时,inline布局也处理不了了,降级table处理吧 - var hasAutoAndFillColumnSize = false; - if (ob.columnSize && ob.columnSize.length > 0) { - if ((ob.columnSize.indexOf("") >= 0 || ob.columnSize.indexOf("auto") >= 0) && ob.columnSize.indexOf("fill") >= 0) { - hasAutoAndFillColumnSize = true; - } - } else { - var hasAuto = false, hasFill = false; - BI.each(ob.items, function (i, item) { - if (item.width === "fill") { - hasFill = true; - } else if (BI.isNull(item.width) || item.width === "" || item.width === "auto") { - hasAuto = true; - } - }); - hasAutoAndFillColumnSize = hasAuto && hasFill; - } - - if (hasAutoAndFillColumnSize) { - // 宽度是不是受限 - if ((ob.scrollable !== true && ob.scrollx !== true) || ob.horizontalAlign === BI.HorizontalAlign.Stretch) { - return BI.extend({ - verticalAlign: BI.VerticalAlign.Top - }, ob, { type: "bi.horizontal_float_fill" }); - } - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Stretch - }, ob, { type: "bi.table_adapt" }); - } - if (BI.Providers.getProvider("bi.provider.system").getResponsiveMode()) { - return BI.extend({}, ob, { type: "bi.responsive_inline" }); - } - return ob; - }); - BI.Plugin.configWidget("bi.center_adapt", function (ob) { - var supportFlex = isSupportFlex(); - // var isAdapt = !ob.horizontalAlign || ob.horizontalAlign === BI.HorizontalAlign.Center || ob.horizontalAlign === BI.HorizontalAlign.Stretch; - // if (!isAdapt || justOneItem) { - if (supportFlex) { - return BI.extend({}, ob, { type: "bi.flex_center_adapt" }); - } - return BI.extend({}, ob, { type: "bi.inline_center_adapt" }); - // } - // return ob; - }); - BI.Plugin.configWidget("bi.vertical_adapt", function (ob) { - var supportFlex = isSupportFlex(); - // var isAdapt = ob.horizontalAlign === BI.HorizontalAlign.Center || ob.horizontalAlign === BI.HorizontalAlign.Stretch; - // if (!isAdapt || justOneItem) { - if (supportFlex) { - return BI.extend({}, ob, { type: "bi.flex_vertical_center_adapt" }); - } - return BI.extend({}, ob, { type: "bi.inline_vertical_adapt" }); - // } - // return ob; - }); - BI.Plugin.configWidget("bi.horizontal_adapt", function (ob) { - var justOneItem = (ob.items && ob.items.length <= 1); - var isAdapt = !ob.horizontalAlign || ob.horizontalAlign === BI.HorizontalAlign.Center || ob.horizontalAlign === BI.HorizontalAlign.Stretch; - var verticalAlignTop = !ob.verticalAlign || ob.verticalAlign === BI.VerticalAlign.TOP; - if (verticalAlignTop && justOneItem) { - return BI.extend({}, ob, { type: "bi.horizontal_auto" }); - } - var supportFlex = isSupportFlex(); - // 在横向自适应场景下我们需要使用table的自适应撑出滚动条的特性(flex处理不了这种情况) - // 主要出现在center_adapt或者horizontal_adapt的场景,或者主动设置horizontalAlign的场景 - if (isAdapt) { - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Center - }, ob, { type: "bi.table_adapt" }); - } - if (supportFlex) { - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Center, - scrollx: false - }, ob, { type: "bi.flex_horizontal" }); - } - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Center - }, ob, { type: "bi.table_adapt" }); - }); - BI.Plugin.configWidget("bi.horizontal_float", function (ob) { - if (isSupportFlex()) { - return BI.extend({}, ob, { type: "bi.flex_horizontal_adapt" }); - } - if (ob.items && ob.items.length <= 1) { - return BI.extend({}, ob, { type: "bi.inline_horizontal_adapt" }); - } - return ob; - }); - - BI.Plugin.configWidget("bi.horizontal_fill", function (ob) { - if (isSupportFlex()) { - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch, - scrollx: false - }, ob, { type: "bi.flex_horizontal" }); - } - if ((ob.horizontalAlign && ob.horizontalAlign !== BI.HorizontalAlign.Stretch) || (ob.scrollable === true || ob.scrollx === true)) { - // 宽度不受限,要用table布局 - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch - }, ob, { type: "bi.table_adapt" }); - } - return BI.extend({}, ob, { type: "bi.horizontal_float_fill" }); - }); - BI.Plugin.configWidget("bi.vertical_fill", function (ob) { - if (isSupportFlex()) { - return BI.extend({ - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch, - scrolly: false - }, ob, { type: "bi.flex_vertical" }); - } - if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { - // 有滚动条,降级到table布局处理 - return BI.extend({}, ob, { - type: "bi.td", - items: BI.map(ob.items, function (i, item) { - return [item]; - }) - }); - } - var hasAuto = false; - if (ob.rowSize && ob.rowSize.length > 0) { - if (ob.rowSize.indexOf("") >= 0 || ob.rowSize.indexOf("auto") >= 0) { - hasAuto = true; - } - } else { - BI.each(ob.items, function (i, item) { - if (BI.isNull(item.height) || item.height === "") { - hasAuto = true; - } - }); - } - if (hasAuto) { - // 有自动高的时候 - return BI.extend({}, ob, { type: "bi.vtape_auto" }); - } - return BI.extend({}, ob, { type: "bi.vtape" }); - }); - BI.Plugin.configWidget("bi.horizontal_sticky", function (ob) { - if (!isSupportSticky) { - return BI.extend({ scrollx: true }, ob, { type: "bi.horizontal_fill" }); - } - }); - BI.Plugin.configWidget("bi.vertical_sticky", function (ob) { - if (!isSupportSticky) { - return BI.extend({ scrolly: true }, ob, { type: "bi.vertical_fill" }); - } - }); - - BI.Plugin.configWidget("bi.left_right_vertical_adapt", function (ob) { - if (isSupportFlex()) { - // IE下其实也是可以使用flex布局的,只要排除掉出现滚动条的情况 - // if (!BI.isIE() || (ob.scrollable !== true && ob.scrolly !== true)) { - return BI.extend({}, ob, { type: "bi.flex_left_right_vertical_adapt" }); - // } - } - return ob; - }); - BI.Plugin.configWidget("bi.flex_horizontal", function (ob) { - if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { - if (ob.hgap > 0 || ob.lgap > 0 || ob.rgap > 0) { - if (BI.Providers.getProvider("bi.provider.system").getResponsiveMode()) { - return BI.extend({}, ob, { type: "bi.responsive_flex_scrollable_horizontal" }); - } - return BI.extend({}, ob, { type: "bi.flex_scrollable_horizontal" }); - } - } - if (BI.Providers.getProvider("bi.provider.system").getResponsiveMode()) { - return BI.extend({}, ob, { type: "bi.responsive_flex_horizontal" }); - } - }); - BI.Plugin.configWidget("bi.flex_vertical", function (ob) { - if (ob.scrollable === true || ob.scrollx === true || ob.scrolly === true) { - if (ob.hgap > 0 || ob.lgap > 0 || ob.rgap > 0) { - return BI.extend({}, ob, { type: "bi.flex_scrollable_vertical" }); - } - } - }); - - BI.Plugin.configWidget("bi.table", function (ob) { - if (!isSupportGrid()) { - return BI.extend({}, ob, { type: "bi.td" }); - } - return ob; - }); - - BI.Plugin.configWidget("bi.radio", function (ob) { - if (BI.isIE() && BI.getIEVersion() <= 9) { - return BI.extend({}, ob, { type: "bi.image_radio" }); - } - return ob; - }); - - BI.Plugin.configWidget("bi.checkbox", function (ob) { - if (BI.isIE() && BI.getIEVersion() <= 9) { - return BI.extend({}, ob, { type: "bi.image_checkbox" }); - } - return ob; - }); - - BI.Plugin.configWidget("bi.half_icon_button", function (ob) { - if (BI.isIE() && BI.getIEVersion() < 9) { - return ob; - } - return BI.extend({}, ob, { type: "bi.half_button" }); - }); -}()); diff --git a/src/core/platform/web/detectElementResize.js b/src/core/platform/web/detectElementResize.js deleted file mode 100644 index 3183a57c4..000000000 --- a/src/core/platform/web/detectElementResize.js +++ /dev/null @@ -1,597 +0,0 @@ -/** - * Detect Element Resize. - * A minimal library which polyfills the ResizeObserver API and is entirely based on the latest Draft Specification. - * https://github.com/juggle/resize-observer - * version: 3.4.0 - **/ -var ResizeObserverPolyfill = (function (exports) { - 'use strict'; - - var resizeObservers = []; - - var hasActiveObservations = function () { - return resizeObservers.some(function (ro) { - return ro.activeTargets.length > 0; - }); - }; - - var hasSkippedObservations = function () { - return resizeObservers.some(function (ro) { - return ro.skippedTargets.length > 0; - }); - }; - - var msg = 'ResizeObserver loop completed with undelivered notifications.'; - var deliverResizeLoopError = function () { - var event; - if (typeof ErrorEvent === 'function') { - event = new ErrorEvent('error', { - message: msg - }); - } else { - event = document.createEvent('Event'); - event.initEvent('error', false, false); - event.message = msg; - } - window.dispatchEvent(event); - }; - - var ResizeObserverBoxOptions; - (function (ResizeObserverBoxOptions) { - ResizeObserverBoxOptions["BORDER_BOX"] = "border-box"; - ResizeObserverBoxOptions["CONTENT_BOX"] = "content-box"; - ResizeObserverBoxOptions["DEVICE_PIXEL_CONTENT_BOX"] = "device-pixel-content-box"; - })(ResizeObserverBoxOptions || (ResizeObserverBoxOptions = {})); - - var freeze = function (obj) { - return Object.freeze(obj); - }; - - var ResizeObserverSize = (function () { - function ResizeObserverSize(inlineSize, blockSize) { - this.inlineSize = inlineSize; - this.blockSize = blockSize; - freeze(this); - } - - return ResizeObserverSize; - }()); - - var DOMRectReadOnly = (function () { - function DOMRectReadOnly(x, y, width, height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - this.top = this.y; - this.left = this.x; - this.bottom = this.top + this.height; - this.right = this.left + this.width; - return freeze(this); - } - - DOMRectReadOnly.prototype.toJSON = function () { - var _a = this, x = _a.x, y = _a.y, top = _a.top, right = _a.right, bottom = _a.bottom, left = _a.left, - width = _a.width, height = _a.height; - return { x: x, y: y, top: top, right: right, bottom: bottom, left: left, width: width, height: height }; - }; - DOMRectReadOnly.fromRect = function (rectangle) { - return new DOMRectReadOnly(rectangle.x, rectangle.y, rectangle.width, rectangle.height); - }; - return DOMRectReadOnly; - }()); - - var isSVG = function (target) { - return target instanceof SVGElement && 'getBBox' in target; - }; - var isHidden = function (target) { - if (isSVG(target)) { - var _a = target.getBBox(), width = _a.width, height = _a.height; - return !width && !height; - } - var _b = target, offsetWidth = _b.offsetWidth, offsetHeight = _b.offsetHeight; - return !(offsetWidth || offsetHeight || target.getClientRects().length); - }; - var isElement = function (obj) { - var _a; - if (obj instanceof Element) { - return true; - } - var scope = (_a = obj === null || obj === void 0 ? void 0 : obj.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView; - return !!(scope && obj instanceof scope.Element); - }; - var isReplacedElement = function (target) { - switch (target.tagName) { - case 'INPUT': - if (target.type !== 'image') { - break; - } - case 'VIDEO': - case 'AUDIO': - case 'EMBED': - case 'OBJECT': - case 'CANVAS': - case 'IFRAME': - case 'IMG': - return true; - } - return false; - }; - - var global = typeof window !== 'undefined' ? window : {}; - - var cache = new WeakMap(); - var scrollRegexp = /auto|scroll/; - var verticalRegexp = /^tb|vertical/; - var IE = (/msie|trident/i).test(global.navigator && global.navigator.userAgent); - var parseDimension = function (pixel) { - return parseFloat(pixel || '0'); - }; - var size = function (inlineSize, blockSize, switchSizes) { - if (inlineSize === void 0) { - inlineSize = 0; - } - if (blockSize === void 0) { - blockSize = 0; - } - if (switchSizes === void 0) { - switchSizes = false; - } - return new ResizeObserverSize((switchSizes ? blockSize : inlineSize) || 0, (switchSizes ? inlineSize : blockSize) || 0); - }; - var zeroBoxes = freeze({ - devicePixelContentBoxSize: size(), - borderBoxSize: size(), - contentBoxSize: size(), - contentRect: new DOMRectReadOnly(0, 0, 0, 0) - }); - var calculateBoxSizes = function (target, forceRecalculation) { - if (forceRecalculation === void 0) { - forceRecalculation = false; - } - if (cache.has(target) && !forceRecalculation) { - return cache.get(target); - } - if (isHidden(target)) { - cache.set(target, zeroBoxes); - return zeroBoxes; - } - var cs = getComputedStyle(target); - var svg = isSVG(target) && target.ownerSVGElement && target.getBBox(); - var removePadding = !IE && cs.boxSizing === 'border-box'; - var switchSizes = verticalRegexp.test(cs.writingMode || ''); - var canScrollVertically = !svg && scrollRegexp.test(cs.overflowY || ''); - var canScrollHorizontally = !svg && scrollRegexp.test(cs.overflowX || ''); - var paddingTop = svg ? 0 : parseDimension(cs.paddingTop); - var paddingRight = svg ? 0 : parseDimension(cs.paddingRight); - var paddingBottom = svg ? 0 : parseDimension(cs.paddingBottom); - var paddingLeft = svg ? 0 : parseDimension(cs.paddingLeft); - var borderTop = svg ? 0 : parseDimension(cs.borderTopWidth); - var borderRight = svg ? 0 : parseDimension(cs.borderRightWidth); - var borderBottom = svg ? 0 : parseDimension(cs.borderBottomWidth); - var borderLeft = svg ? 0 : parseDimension(cs.borderLeftWidth); - var horizontalPadding = paddingLeft + paddingRight; - var verticalPadding = paddingTop + paddingBottom; - var horizontalBorderArea = borderLeft + borderRight; - var verticalBorderArea = borderTop + borderBottom; - var horizontalScrollbarThickness = !canScrollHorizontally ? 0 : target.offsetHeight - verticalBorderArea - target.clientHeight; - var verticalScrollbarThickness = !canScrollVertically ? 0 : target.offsetWidth - horizontalBorderArea - target.clientWidth; - var widthReduction = removePadding ? horizontalPadding + horizontalBorderArea : 0; - var heightReduction = removePadding ? verticalPadding + verticalBorderArea : 0; - var contentWidth = svg ? svg.width : parseDimension(cs.width) - widthReduction - verticalScrollbarThickness; - var contentHeight = svg ? svg.height : parseDimension(cs.height) - heightReduction - horizontalScrollbarThickness; - var borderBoxWidth = contentWidth + horizontalPadding + verticalScrollbarThickness + horizontalBorderArea; - var borderBoxHeight = contentHeight + verticalPadding + horizontalScrollbarThickness + verticalBorderArea; - var boxes = freeze({ - devicePixelContentBoxSize: size(Math.round(contentWidth * devicePixelRatio), Math.round(contentHeight * devicePixelRatio), switchSizes), - borderBoxSize: size(borderBoxWidth, borderBoxHeight, switchSizes), - contentBoxSize: size(contentWidth, contentHeight, switchSizes), - contentRect: new DOMRectReadOnly(paddingLeft, paddingTop, contentWidth, contentHeight) - }); - cache.set(target, boxes); - return boxes; - }; - var calculateBoxSize = function (target, observedBox, forceRecalculation) { - var _a = calculateBoxSizes(target, forceRecalculation), borderBoxSize = _a.borderBoxSize, - contentBoxSize = _a.contentBoxSize, devicePixelContentBoxSize = _a.devicePixelContentBoxSize; - switch (observedBox) { - case ResizeObserverBoxOptions.DEVICE_PIXEL_CONTENT_BOX: - return devicePixelContentBoxSize; - case ResizeObserverBoxOptions.BORDER_BOX: - return borderBoxSize; - default: - return contentBoxSize; - } - }; - - var ResizeObserverEntry = (function () { - function ResizeObserverEntry(target) { - var boxes = calculateBoxSizes(target); - this.target = target; - this.contentRect = boxes.contentRect; - this.borderBoxSize = freeze([boxes.borderBoxSize]); - this.contentBoxSize = freeze([boxes.contentBoxSize]); - this.devicePixelContentBoxSize = freeze([boxes.devicePixelContentBoxSize]); - } - - return ResizeObserverEntry; - }()); - - var calculateDepthForNode = function (node) { - if (isHidden(node)) { - return Infinity; - } - var depth = 0; - var parent = node.parentNode; - while (parent) { - depth += 1; - parent = parent.parentNode; - } - return depth; - }; - - var broadcastActiveObservations = function () { - var shallowestDepth = Infinity; - var callbacks = []; - resizeObservers.forEach(function processObserver(ro) { - if (ro.activeTargets.length === 0) { - return; - } - var entries = []; - ro.activeTargets.forEach(function processTarget(ot) { - var entry = new ResizeObserverEntry(ot.target); - var targetDepth = calculateDepthForNode(ot.target); - entries.push(entry); - ot.lastReportedSize = calculateBoxSize(ot.target, ot.observedBox); - if (targetDepth < shallowestDepth) { - shallowestDepth = targetDepth; - } - }); - callbacks.push(function resizeObserverCallback() { - ro.callback.call(ro.observer, entries, ro.observer); - }); - ro.activeTargets.splice(0, ro.activeTargets.length); - }); - for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) { - var callback = callbacks_1[_i]; - callback(); - } - return shallowestDepth; - }; - - var gatherActiveObservationsAtDepth = function (depth) { - resizeObservers.forEach(function processObserver(ro) { - ro.activeTargets.splice(0, ro.activeTargets.length); - ro.skippedTargets.splice(0, ro.skippedTargets.length); - ro.observationTargets.forEach(function processTarget(ot) { - if (ot.isActive()) { - if (calculateDepthForNode(ot.target) > depth) { - ro.activeTargets.push(ot); - } else { - ro.skippedTargets.push(ot); - } - } - }); - }); - }; - - var process = function () { - var depth = 0; - gatherActiveObservationsAtDepth(depth); - while (hasActiveObservations()) { - depth = broadcastActiveObservations(); - gatherActiveObservationsAtDepth(depth); - } - if (hasSkippedObservations()) { - deliverResizeLoopError(); - } - return depth > 0; - }; - - var trigger; - var callbacks = []; - var notify = function () { - return callbacks.splice(0).forEach(function (cb) { - return cb(); - }); - }; - var queueMicroTask = function (callback) { - if (!trigger) { - var toggle_1 = 0; - var el_1 = document.createTextNode(''); - var config = { characterData: true }; - new MutationObserver(function () { - return notify(); - }).observe(el_1, config); - trigger = function () { - el_1.textContent = "".concat(toggle_1 ? toggle_1-- : toggle_1++); - }; - } - callbacks.push(callback); - trigger(); - }; - - var queueResizeObserver = function (cb) { - queueMicroTask(function ResizeObserver() { - requestAnimationFrame(cb); - }); - }; - - var watching = 0; - var isWatching = function () { - return !!watching; - }; - var CATCH_PERIOD = 250; - var observerConfig = { attributes: true, characterData: true, childList: true, subtree: true }; - var events = ['resize', 'load', 'transitionend', 'animationend', 'animationstart', 'animationiteration', 'keyup', 'keydown', 'mouseup', 'mousedown', 'mouseover', 'mouseout', 'blur', 'focus']; - var time = function (timeout) { - if (timeout === void 0) { - timeout = 0; - } - return Date.now() + timeout; - }; - var scheduled = false; - var Scheduler = (function () { - function Scheduler() { - var _this = this; - this.stopped = true; - this.listener = function () { - return _this.schedule(); - }; - } - - Scheduler.prototype.run = function (timeout) { - var _this = this; - if (timeout === void 0) { - timeout = CATCH_PERIOD; - } - if (scheduled) { - return; - } - scheduled = true; - var until = time(timeout); - queueResizeObserver(function () { - var elementsHaveResized = false; - try { - elementsHaveResized = process(); - } finally { - scheduled = false; - timeout = until - time(); - if (!isWatching()) { - return; - } - if (elementsHaveResized) { - _this.run(1000); - } else if (timeout > 0) { - _this.run(timeout); - } else { - _this.start(); - } - } - }); - }; - Scheduler.prototype.schedule = function () { - this.stop(); - this.run(); - }; - Scheduler.prototype.observe = function () { - var _this = this; - var cb = function () { - return _this.observer && _this.observer.observe(document.body, observerConfig); - }; - document.body ? cb() : global.addEventListener('DOMContentLoaded', cb); - }; - Scheduler.prototype.start = function () { - var _this = this; - if (this.stopped) { - this.stopped = false; - this.observer = new MutationObserver(this.listener); - this.observe(); - events.forEach(function (name) { - return global.addEventListener(name, _this.listener, true); - }); - } - }; - Scheduler.prototype.stop = function () { - var _this = this; - if (!this.stopped) { - this.observer && this.observer.disconnect(); - events.forEach(function (name) { - return global.removeEventListener(name, _this.listener, true); - }); - this.stopped = true; - } - }; - return Scheduler; - }()); - var scheduler = new Scheduler(); - var updateCount = function (n) { - !watching && n > 0 && scheduler.start(); - watching += n; - !watching && scheduler.stop(); - }; - - var skipNotifyOnElement = function (target) { - return !isSVG(target) && !isReplacedElement(target) && getComputedStyle(target).display === 'inline'; - }; - var ResizeObservation = (function () { - function ResizeObservation(target, observedBox) { - this.target = target; - this.observedBox = observedBox || ResizeObserverBoxOptions.CONTENT_BOX; - this.lastReportedSize = { - inlineSize: -1, blockSize: -1 - }; - } - - ResizeObservation.prototype.isActive = function () { - var size = calculateBoxSize(this.target, this.observedBox, true); - if (skipNotifyOnElement(this.target)) { - this.lastReportedSize = size; - } - if (this.lastReportedSize.inlineSize !== size.inlineSize || this.lastReportedSize.blockSize !== size.blockSize) { - return true; - } - return false; - }; - return ResizeObservation; - }()); - - var ResizeObserverDetail = (function () { - function ResizeObserverDetail(resizeObserver, callback) { - this.activeTargets = []; - this.skippedTargets = []; - this.observationTargets = []; - this.observer = resizeObserver; - this.callback = callback; - } - - return ResizeObserverDetail; - }()); - - var observerMap = new WeakMap(); - var getObservationIndex = function (observationTargets, target) { - for (var i = 0; i < observationTargets.length; i += 1) { - if (observationTargets[i].target === target) { - return i; - } - } - return -1; - }; - var ResizeObserverController = (function () { - function ResizeObserverController() { - } - - ResizeObserverController.connect = function (resizeObserver, callback) { - var detail = new ResizeObserverDetail(resizeObserver, callback); - observerMap.set(resizeObserver, detail); - }; - ResizeObserverController.observe = function (resizeObserver, target, options) { - var detail = observerMap.get(resizeObserver); - var firstObservation = detail.observationTargets.length === 0; - if (getObservationIndex(detail.observationTargets, target) < 0) { - firstObservation && resizeObservers.push(detail); - detail.observationTargets.push(new ResizeObservation(target, options && options.box)); - updateCount(1); - scheduler.schedule(); - } - }; - ResizeObserverController.unobserve = function (resizeObserver, target) { - var detail = observerMap.get(resizeObserver); - var index = getObservationIndex(detail.observationTargets, target); - var lastObservation = detail.observationTargets.length === 1; - if (index >= 0) { - lastObservation && resizeObservers.splice(resizeObservers.indexOf(detail), 1); - detail.observationTargets.splice(index, 1); - updateCount(-1); - } - }; - ResizeObserverController.disconnect = function (resizeObserver) { - var _this = this; - var detail = observerMap.get(resizeObserver); - detail.observationTargets.slice().forEach(function (ot) { - return _this.unobserve(resizeObserver, ot.target); - }); - detail.activeTargets.splice(0, detail.activeTargets.length); - }; - return ResizeObserverController; - }()); - - var ResizeObserver = (function () { - function ResizeObserver(callback) { - if (arguments.length === 0) { - throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present."); - } - if (typeof callback !== 'function') { - throw new TypeError("Failed to construct 'ResizeObserver': The callback provided as parameter 1 is not a function."); - } - ResizeObserverController.connect(this, callback); - } - - ResizeObserver.prototype.observe = function (target, options) { - if (arguments.length === 0) { - throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': 1 argument required, but only 0 present."); - } - if (!isElement(target)) { - throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element"); - } - ResizeObserverController.observe(this, target, options); - }; - ResizeObserver.prototype.unobserve = function (target) { - if (arguments.length === 0) { - throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': 1 argument required, but only 0 present."); - } - if (!isElement(target)) { - throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element"); - } - ResizeObserverController.unobserve(this, target); - }; - ResizeObserver.prototype.disconnect = function () { - ResizeObserverController.disconnect(this); - }; - ResizeObserver.toString = function () { - return 'function ResizeObserver () { [polyfill code] }'; - }; - return ResizeObserver; - }()); - - exports.ResizeObserver = ResizeObserver; - exports.ResizeObserverEntry = ResizeObserverEntry; - exports.ResizeObserverSize = ResizeObserverSize; - - Object.defineProperty(exports, '__esModule', { value: true }); - - return exports; - -})({}); - -var ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill.ResizeObserver; - -!(function () { - - var addResizeListener = function (element, fn) { - if (ResizeObserver) { - if (!element.__resizeObserver__) { - var resizeObserver = new ResizeObserver(function () { - element.__resizeListeners__.forEach(function (listener) { - BI.$(element).is(":visible") && listener(); - }); - }); - resizeObserver.observe(element); - element.__resizeObserver__ = resizeObserver; - } - if (!element.__resizeListeners__) { - element.__resizeListeners__ = []; - } - element.__resizeListeners__.push(fn); - } - }; - var removeResizeListener = function (element, fn) { - if (ResizeObserver) { - if (BI.isNull(fn)) { - element.__resizeListeners__ = []; - element.__resizeObserver__ && element.__resizeObserver__.unobserve(element); - element.__resizeObserver__ = null; - return; - } - var index = element.__resizeListeners__.indexOf(fn); - if (index >= 0) { - element.__resizeListeners__.splice(index, 1); - if (!element.__resizeListeners__.length) { - element.__resizeObserver__ && element.__resizeObserver__.unobserve(element); - element.__resizeObserver__ = null; - } - } - } - }; - - BI.ResizeDetector = { - addResizeListener: function (widget, fn) { - addResizeListener(widget.element[0], fn); - return function () { - removeResizeListener(widget.element[0], fn); - }; - }, removeResizeListener: function (widget, fn) { - removeResizeListener(widget.element[0], fn); - } - }; -})(); diff --git a/src/core/platform/web/dom.js b/src/core/platform/web/dom.js deleted file mode 100644 index a74f1ff10..000000000 --- a/src/core/platform/web/dom.js +++ /dev/null @@ -1,760 +0,0 @@ -/** - * 对DOM操作的通用函数 - * @type {{}} - */ -!(function () { - BI.DOM = BI.DOM || {}; - - BI.extend(BI.DOM, { - ready: function (fn) { - BI.Widget._renderEngine.createElement(document).ready(fn); - } - }); - - BI.extend(BI.DOM, { - - patchProps: function (fromElement, toElement) { - var elemData = BI.jQuery._data(fromElement[0]); - var events = elemData.events; - BI.each(events, function (eventKey, event) { - BI.each(event, function (i, handler) { - toElement.on(eventKey + (handler.namespace ? ("." + handler.namespace) : ""), handler); - }); - }); - var fromChildren = fromElement.children(), toChildren = toElement.children(); - if (fromChildren.length !== toChildren.length) { - throw new Error("don't match"); - } - BI.each(fromChildren, function (i, child) { - BI.DOM.patchProps(BI.jQuery(child), BI.jQuery(toChildren[i])); - }); - BI.each(fromElement.data("__widgets"), function (i, widget) { - widget.element = toElement; - }); - }, - /** - * 把dom数组或元素悬挂起来,使其不对html产生影响 - * @param dom - */ - hang: function (doms) { - if (BI.isEmpty(doms)) { - return; - } - var frag = BI.Widget._renderEngine.createFragment(); - BI.each(doms, function (i, dom) { - dom instanceof BI.Widget && (dom = dom.element); - dom instanceof BI.$ && dom[0] && frag.appendChild(dom[0]); - }); - return frag; - }, - - isExist: function (obj) { - return BI.Widget._renderEngine.createElement("body").find(obj.element).length > 0; - }, - - // 预加载图片 - preloadImages: function (srcArray, onload) { - var count = 0, images = []; - - function complete() { - count++; - if (count >= srcArray.length) { - onload(); - } - } - - BI.each(srcArray, function (i, src) { - images[i] = new Image(); - images[i].src = src; - images[i].onload = function () { - complete(); - }; - images[i].onerror = function () { - complete(); - }; - }); - }, - - getTextSizeWidth: function (text, fontSize) { - var span = BI.Widget._renderEngine.createElement("").addClass("text-width-span").appendTo("body"); - - if (fontSize == null) { - fontSize = 12; - } - fontSize = fontSize + "px"; - - span.css("font-size", fontSize).text(text); - - var width = span.width(); - span.remove(); - - return width; - }, - - getTextSizeHeight: function (text, fontSize) { - var span = BI.Widget._renderEngine.createElement("").addClass("text-width-span").appendTo("body"); - - if (fontSize == null) { - fontSize = 12; - } - fontSize = fontSize + "px"; - - span.css("font-size", fontSize).text(text); - - var height = span.height(); - span.remove(); - - return height; - }, - - // 获取滚动条的宽度,页面display: none时候获取到的为0 - getScrollWidth: function (css) { - if (BI.isNull(this._scrollWidth) || BI.isNotNull(css) || this._scrollWidth === 0) { - var ul = BI.Widget._renderEngine.createElement("
    ").width(50).height(50).css({ - position: "absolute", - top: "-9999px", - overflow: "scroll", - ...css - }).appendTo("body"); - this._scrollWidth = ul[0].offsetWidth - ul[0].clientWidth; - ul.destroy(); - } - return this._scrollWidth; - }, - - getImage: function (param, fillStyle, backgroundColor) { - var canvas = document.createElement("canvas"); - var ratio = 2; - BI.Widget._renderEngine.createElement("body").append(canvas); - - var ctx = canvas.getContext("2d"); - ctx.font = "12px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif"; - var w = ctx.measureText(param).width + 4; - canvas.width = w * ratio; - canvas.height = 16 * ratio; - ctx.font = 12 * ratio + "px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif"; - ctx.fillStyle = fillStyle || "#3685f2"; - ctx.textBaseline = "middle"; - // ctx.fillStyle = "#EAF2FD"; - ctx.fillText(param, 2 * ratio, 9 * ratio); - BI.Widget._renderEngine.createElement(canvas).destroy(); - var backColor = backgroundColor || "rgba(54, 133, 242, 0.1)"; - // IE可以放大缩小所以要固定最大最小宽高 - return { - width: w, - height: 16, - src: canvas.toDataURL("image/png"), - style: "background-color: " + backColor + ";vertical-align: middle; margin: 0 1px; width:" + w + "px;height: 16px; max-width:" + w + "px;max-height: 16px; min-width:" + w + "px;min-height: 16px", - param: param - }; - } - }); - - BI.extend(BI.DOM, { - - getLeftPosition: function (combo, popup, extraWidth, container) { - var el = combo.element; - var popupEl = popup.element; - var elRect = el[0].getBoundingClientRect(); - var popupElRect = popupEl[0].getBoundingClientRect(); - var containerRect = container ? container.getBoundingClientRect() : {left: 0}; - - return { - left: elRect.left - containerRect.left - popupElRect.width - (extraWidth || 0) - }; - }, - - getInnerLeftPosition: function (combo, popup, extraWidth) { - return { - left: combo.element.offset().left + (extraWidth || 0) - }; - }, - - getRightPosition: function (combo, popup, extraWidth, container) { - var el = combo.element; - var elRect = el[0].getBoundingClientRect(); - var containerRect = container ? container.getBoundingClientRect() : {left: 0}; - - return { - left: elRect.left + elRect.width - containerRect.left + (extraWidth || 0) - }; - }, - - getInnerRightPosition: function (combo, popup, extraWidth) { - var el = combo.element, viewBounds = popup.element.bounds(); - return { - left: el.offset().left + el.outerWidth() - viewBounds.width - (extraWidth || 0) - }; - }, - - getTopPosition: function (combo, popup, extraHeight, container) { - var el = combo.element; - var popupEl = popup.element; - var elRect = el[0].getBoundingClientRect(); - var popupElRect = popupEl[0].getBoundingClientRect(); - var containerRect = container ? container.getBoundingClientRect() : {top: 0}; - - return { - top: elRect.top - containerRect.top - popupElRect.height - (extraHeight || 0) - }; - }, - - getBottomPosition: function (combo, popup, extraHeight, container) { - var el = combo.element; - var elRect = el[0].getBoundingClientRect(); - var containerRect = container ? container.getBoundingClientRect() : {top: 0}; - - return { - top: elRect.top - containerRect.top + elRect.height + (extraHeight || 0) - }; - }, - - isLeftSpaceEnough: function (combo, popup, extraWidth) { - return BI.DOM.getLeftPosition(combo, popup, extraWidth).left >= 0; - }, - - isInnerLeftSpaceEnough: function (combo, popup, extraWidth) { - var viewBounds = popup.element.bounds(), - windowBounds = BI.Widget._renderEngine.createElement("body").bounds(); - return BI.DOM.getInnerLeftPosition(combo, popup, extraWidth).left + viewBounds.width <= windowBounds.width; - }, - - isRightSpaceEnough: function (combo, popup, extraWidth) { - var viewBounds = popup.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - return BI.DOM.getRightPosition(combo, popup, extraWidth).left + viewBounds.width <= viewportBounds.width; - }, - - isInnerRightSpaceEnough: function (combo, popup, extraWidth) { - return BI.DOM.getInnerRightPosition(combo, popup, extraWidth).left >= 0; - }, - - isTopSpaceEnough: function (combo, popup, extraHeight) { - return BI.DOM.getTopPosition(combo, popup, extraHeight).top >= 0; - }, - - isBottomSpaceEnough: function (combo, popup, extraHeight) { - var viewBounds = popup.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - return BI.DOM.getBottomPosition(combo, popup, extraHeight).top + viewBounds.height <= viewportBounds.height; - }, - - isRightSpaceLarger: function (combo) { - var comboBounds = combo.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - return viewportBounds.width - comboBounds.right >= comboBounds.left; - }, - - isBottomSpaceLarger: function (combo) { - var comboBounds = combo.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - return viewportBounds.height - comboBounds.bottom >= comboBounds.top; - }, - - _getLeftAlignPosition: function (combo, popup, extraWidth, container) { - var comboRect = combo.element[0].getBoundingClientRect(), - popupRect = popup.element[0].getBoundingClientRect(), - viewportRect = document.documentElement.getBoundingClientRect(), - containerRect = container ? container.getBoundingClientRect() : {left: 0}; - var left = comboRect.left - containerRect.left + extraWidth; - - if (comboRect.left + popupRect.width > viewportRect.width) { - left = viewportRect.width - popupRect.width - containerRect.left; - } - return left; - }, - - getLeftAlignPosition: function (combo, popup, extraWidth, container) { - var left = this._getLeftAlignPosition(combo, popup, extraWidth, container); - var dir = ""; - // 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0 - var containerRect = container ? container.getBoundingClientRect() : {left: 0}; - if (left + containerRect.left < 0) { - left = this._getRightAlignPosition(combo, popup, extraWidth); - dir = "left"; - } - if (left + containerRect.left < 0) { - left = 0 - containerRect.left; - } - return { - left: left, - dir: dir || "right" - }; - }, - - getLeftAdaptPosition: function (combo, popup, extraWidth, container) { - if (BI.DOM.isLeftSpaceEnough(combo, popup, extraWidth, container)) { - return BI.DOM.getLeftPosition(combo, popup, extraWidth, container); - } - return { - left: 0 - }; - }, - - _getRightAlignPosition: function (combo, popup, extraWidth, container) { - var comboBounds = combo.element[0].getBoundingClientRect(), - viewBounds = popup.element[0].getBoundingClientRect(), - containerRect = container ? container.getBoundingClientRect() : {left: 0}; - return comboBounds.left + comboBounds.width - viewBounds.width - extraWidth - containerRect.left; - }, - - getRightAlignPosition: function (combo, popup, extraWidth, container) { - var left = this._getRightAlignPosition(combo, popup, extraWidth, container); - var dir = ""; - // 如果放不下,优先使用LeftAlign, 如果LeftAlign也放不下, 再使用left=0 - if (left < 0) { - left = this._getLeftAlignPosition(combo, popup, extraWidth, container); - dir = "right"; - } - if (left < 0) { - left = 0; - } - return { - left: left, - dir: dir || "left" - }; - }, - - getRightAdaptPosition: function (combo, popup, extraWidth, container) { - if (BI.DOM.isRightSpaceEnough(combo, popup, extraWidth, container)) { - return BI.DOM.getRightPosition(combo, popup, extraWidth, container); - } - return { - left: document.documentElement.getBoundingClientRect().width - popup.element[0].getBoundingClientRect().width - container.getBoundingClientRect().left - }; - }, - - getTopAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { - var comboBounds = combo.element[0].getBoundingClientRect(), - popupBounds = popup.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(), - containerBounds = container ? container.getBoundingClientRect() : {top: 0}; - var top, adaptHeight, dir; - if (BI.DOM.isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { - top = comboBounds.top - containerBounds.top + extraHeight; - } else if (needAdaptHeight) { - top = comboBounds.top - containerBounds.top + extraHeight; - adaptHeight = viewportBounds.height - comboBounds.top; - } else if (BI.DOM.isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { - // 下方空间不足且不允许调整高度的情况下,优先使用上对齐 - top = comboBounds.top + comboBounds.height - popupBounds.height - containerBounds.top - extraHeight; - dir = "top"; - } else { - top = viewportBounds.height - popupBounds.height; - if (top < extraHeight) { - adaptHeight = viewportBounds.height - extraHeight; - } - } - if (top < extraHeight) { - top = extraHeight; - } - return adaptHeight ? { - top: top, - adaptHeight: adaptHeight, - dir: dir || "bottom" - } : { - top: top, - dir: dir || "bottom" - }; - }, - - getTopAdaptPosition: function (combo, popup, extraHeight, needAdaptHeight, positionRelativeElement) { - var comboBounds = combo.element[0].getBoundingClientRect(), - popupBounds = popup.element[0].getBoundingClientRect(), - positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - if (BI.DOM.isTopSpaceEnough(combo, popup, extraHeight)) { - return BI.DOM.getTopPosition(combo, popup, extraHeight); - } - if (needAdaptHeight) { - return { - top: 0 - positionRelativeElementRect.top, - adaptHeight: comboBounds.top - extraHeight - }; - } - if (popupBounds.height + extraHeight > viewportBounds.height) { - return { - top: 0 - positionRelativeElementRect.top, - adaptHeight: viewportBounds.height - extraHeight - }; - } - return { - top: 0 - positionRelativeElementRect.top - }; - }, - - getBottomAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { - var comboBounds = combo.element[0].getBoundingClientRect(), - popupBounds = popup.element[0].getBoundingClientRect(), - windowBounds = BI.Widget._renderEngine.createElement("body").bounds(), - containerBounds = container ? container.getBoundingClientRect() : {top: 0}; - var top, adaptHeight, dir; - if (BI.DOM.isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { - top = comboBounds.top + comboBounds.height - containerBounds.top - popupBounds.height; - } else if (needAdaptHeight) { - top = 0 - containerBounds.top; - adaptHeight = comboBounds.top + comboBounds.height - extraHeight; - } else if (BI.DOM.isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { - // 上方空间不足且不允许调整高度的情况下,优先使用下对齐 - top = comboBounds.top - containerBounds.top + extraHeight; - dir = "bottom"; - } else { - top = 0; - if (popupBounds.height + extraHeight > windowBounds.height) { - adaptHeight = windowBounds.height - extraHeight; - } - } - if (top + containerBounds.top < 0) { - top = 0; - } - return adaptHeight ? { - top: top, - adaptHeight: adaptHeight, - dir: dir || "top" - } : { - top: top, - dir: dir || "top" - }; - }, - - getBottomAdaptPosition: function (combo, popup, extraHeight, needAdaptHeight, positionRelativeElement) { - var comboBounds = combo.element[0].getBoundingClientRect(), - popupBounds = popup.element[0].getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(), - positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(); - if (BI.DOM.isBottomSpaceEnough(combo, popup, extraHeight)) { - return BI.DOM.getBottomPosition(combo, popup, extraHeight, positionRelativeElement); - } - if (needAdaptHeight) { - return { - top: comboBounds.top + comboBounds.height + extraHeight - positionRelativeElementRect.top, - adaptHeight: viewportBounds.height - comboBounds.top - comboBounds.height - extraHeight - }; - } - if (popupBounds.height + extraHeight > viewportBounds.height) { - return { - top: extraHeight - positionRelativeElementRect.top, - adaptHeight: viewportBounds.height - extraHeight - }; - } - return { - top: viewportBounds.height - popupBounds.height - extraHeight - positionRelativeElementRect.top - }; - }, - - getCenterAdaptPosition: function (combo, popup, positionRelativeElement) { - var comboRect = combo.element[0].getBoundingClientRect(), - popupRect = popup.element[0].getBoundingClientRect(), - positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - var left; - if (comboRect.left + comboRect.width / 2 + popupRect.width / 2 > viewportBounds.width) { - left = viewportBounds.width - popupRect.width - positionRelativeElementRect.left; - } else { - left = comboRect.left + (comboRect.width - popupRect.width) / 2 - positionRelativeElementRect.left; - } - if (left + positionRelativeElementRect.left < 0) { - left = 0; - } - return { - left: left - }; - }, - - getMiddleAdaptPosition: function (combo, popup, positionRelativeElement) { - var comboRect = combo.element[0].getBoundingClientRect(), - popupRect = popup.element[0].getBoundingClientRect(), - positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), - viewportBounds = document.documentElement.getBoundingClientRect(); - - var top; - if (comboRect.top + comboRect.height / 2 + popupRect.height / 2 > viewportBounds.height) { - top = viewportBounds.height - popupRect.height - positionRelativeElementRect.top; - } else { - top = comboRect.top + (comboRect.height - popupRect.height) / 2 - positionRelativeElementRect.top; - } - if (top + positionRelativeElementRect.top < 0) { - top = 0; - } - return { - top: top - }; - }, - - getComboPositionByDirections: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, container) { - extraWidth || (extraWidth = 0); - extraHeight || (extraHeight = 0); - var i, direct; - var leftRight = [], topBottom = [], innerLeftRight = []; - var isNeedAdaptHeight = false, tbFirst = false, lrFirst = false; - var left, top, pos, firstDir = directions[0]; - for (i = 0; i < directions.length; i++) { - direct = directions[i]; - switch (direct) { - case "left": - leftRight.push(direct); - break; - case "right": - leftRight.push(direct); - break; - case "top": - topBottom.push(direct); - break; - case "bottom": - topBottom.push(direct); - break; - case "innerLeft": - innerLeftRight.push(direct); - break; - case "innerRight": - innerLeftRight.push(direct); - break; - } - } - for (i = 0; i < directions.length; i++) { - direct = directions[i]; - switch (direct) { - case "left": - if (!isNeedAdaptHeight) { - var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; - if (BI.DOM.isLeftSpaceEnough(combo, popup, tW)) { - left = BI.DOM.getLeftPosition(combo, popup, tW, container).left; - if (topBottom[0] === "bottom") { - pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); - } else { - pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); - } - pos.dir = "left," + pos.dir; - if (tbFirst) { - pos.change = "left"; - } - pos.left = left; - return pos; - } - } - lrFirst = true; - break; - case "right": - if (!isNeedAdaptHeight) { - var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; - if (BI.DOM.isRightSpaceEnough(combo, popup, tW)) { - left = BI.DOM.getRightPosition(combo, popup, tW, container).left; - if (topBottom[0] === "bottom") { - pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); - } else { - pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); - } - pos.dir = "right," + pos.dir; - if (tbFirst) { - pos.change = "right"; - } - pos.left = left; - return pos; - } - } - lrFirst = true; - break; - case "top": - var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; - if (BI.DOM.isTopSpaceEnough(combo, popup, tH)) { - top = BI.DOM.getTopPosition(combo, popup, tH, container).top; - if (leftRight[0] === "right") { - pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container); - } else { - pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container); - } - pos.dir = "top," + pos.dir; - if (lrFirst) { - pos.change = "top"; - } - pos.top = top; - return pos; - } - if (needAdaptHeight) { - isNeedAdaptHeight = true; - } - tbFirst = true; - break; - case "bottom": - var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; - if (BI.DOM.isBottomSpaceEnough(combo, popup, tH)) { - top = BI.DOM.getBottomPosition(combo, popup, tH, container).top; - if (leftRight[0] === "right") { - pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container); - } else { - pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container); - } - pos.dir = "bottom," + pos.dir; - if (lrFirst) { - pos.change = "bottom"; - } - pos.top = top; - return pos; - } - if (needAdaptHeight) { - isNeedAdaptHeight = true; - } - tbFirst = true; - break; - case "innerLeft": - if (!isNeedAdaptHeight) { - var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; - if (BI.DOM.isInnerLeftSpaceEnough(combo, popup, tW)) { - left = BI.DOM.getInnerLeftPosition(combo, popup, tW).left; - if (topBottom[0] === "bottom") { - pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight); - } else { - pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight); - } - pos.dir = "innerLeft," + pos.dir; - if (tbFirst) { - pos.change = "innerLeft"; - } - pos.left = left; - return pos; - } - } - lrFirst = true; - break; - case "innerRight": - if (!isNeedAdaptHeight) { - var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; - if (BI.DOM.isInnerRightSpaceEnough(combo, popup, tW)) { - left = BI.DOM.getInnerRightPosition(combo, popup, tW).left; - if (topBottom[0] === "bottom") { - pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight); - } else { - pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight); - } - pos.dir = "innerLeft," + pos.dir; - if (tbFirst) { - pos.change = "innerRight"; - } - pos.left = left; - return pos; - } - } - break; - - } - } - - // 此处为四个方向放不下时挑空间最大的方向去放置, 也就是说我设置了弹出方向为"bottom,left", - // 最后发现实际弹出方向可能是"top,left",那么此时外界获取popup的方向应该是"top,left" - switch (directions[0]) { - case "left": - case "right": - if (BI.DOM.isRightSpaceLarger(combo)) { - left = BI.DOM.getRightAdaptPosition(combo, popup, extraWidth, container).left; - firstDir = "right"; - } else { - left = BI.DOM.getLeftAdaptPosition(combo, popup, extraWidth, container).left; - firstDir = "left"; - } - if (topBottom[0] === "bottom") { - pos = BI.DOM.getTopAlignPosition(combo, popup, extraHeight, needAdaptHeight); - pos.left = left; - pos.dir = firstDir + "," + pos.dir; - return pos; - } - pos = BI.DOM.getBottomAlignPosition(combo, popup, extraHeight, needAdaptHeight); - pos.left = left; - pos.dir = firstDir + "," + pos.dir; - return pos; - default : - if (BI.DOM.isBottomSpaceLarger(combo)) { - top = BI.DOM.getBottomAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; - firstDir = "bottom"; - } else { - top = BI.DOM.getTopAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; - firstDir = "top"; - } - if (leftRight[0] === "right") { - pos = BI.DOM.getLeftAlignPosition(combo, popup, extraWidth, container); - pos.top = top; - pos.dir = firstDir + "," + pos.dir; - return pos; - } - pos = BI.DOM.getRightAlignPosition(combo, popup, extraWidth, container); - pos.top = top; - pos.dir = firstDir + "," + pos.dir; - return pos; - } - }, - - - getComboPosition: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, offsetStyle, positionRelativeElement) { - extraWidth || (extraWidth = 0); - extraHeight || (extraHeight = 0); - var viewportBounds = document.documentElement.getBoundingClientRect(); - var maxHeight = Math.min(popup.attr("maxHeight") || viewportBounds.height, viewportBounds.height); - popup.resetHeight && popup.resetHeight(maxHeight); - var position = BI.DOM.getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions || ["bottom", "top", "right", "left"], positionRelativeElement); - switch (offsetStyle) { - case "center": - if (position.change) { - var p = BI.DOM.getMiddleAdaptPosition(combo, popup, positionRelativeElement); - position.top = p.top; - } else { - var p = BI.DOM.getCenterAdaptPosition(combo, popup, positionRelativeElement); - position.left = p.left; - } - break; - case "middle": - if (position.change) { - var p = BI.DOM.getCenterAdaptPosition(combo, popup, positionRelativeElement); - position.left = p.left; - } else { - var p = BI.DOM.getMiddleAdaptPosition(combo, popup, positionRelativeElement); - position.top = p.top; - } - break; - } - if (needAdaptHeight === true) { - popup.resetHeight && popup.resetHeight(Math.min(viewportBounds.height - position.top - (positionRelativeElement ? positionRelativeElement.getBoundingClientRect().top : 0), maxHeight)); - } - return position; - }, - - /** - * 获取position:fixed相对定位的元素 - */ - getPositionRelativeContainingBlock: function (element) { - if (BI.isIE() || ['html', 'body', '#document'].indexOf((element.nodeName || '').toLowerCase()) >= 0) { - // $FlowFixMe[incompatible-return]: assume body is always available - return element.ownerDocument.body; - } - - function isExcept(node) { - var _computedStyle = getComputedStyle(node); - var transform = _computedStyle.transform; - var perspective = _computedStyle.perspective; - var filter = _computedStyle.filter; - var willChange = _computedStyle["will-change"]; - - return [transform, perspective, filter].some(value => value !== 'none') || (willChange === "transform"); - } - - if (isExcept(element)) { - return element; - } - - return BI.DOM.getPositionRelativeContainingBlock(element.parentNode); - }, - - /** - * 获取position:fixed相对定位的元素的clientRect - */ - getPositionRelativeContainingBlockRect: function (element) { - const positionRelativeElement = BI.DOM.getPositionRelativeContainingBlock(element); - const {top, right, bottom, left, width, height, x, y} = positionRelativeElement.getBoundingClientRect(); - - - return { - top, right, bottom, left, width, height, x, y, - scaleX: width / positionRelativeElement.offsetWidth, - scaleY: height / positionRelativeElement.offsetHeight, - }; - }, - }); -})(); diff --git a/src/core/platform/web/function.js b/src/core/platform/web/function.js deleted file mode 100644 index f05ef923d..000000000 --- a/src/core/platform/web/function.js +++ /dev/null @@ -1,151 +0,0 @@ -// 浏览器相关方法 -BI._.extend(BI, { - isIE: function () { - if(!_global.navigator) { - return false; - } - if (this.__isIE == null) { - this.__isIE = /(msie|trident)/i.test(navigator.userAgent.toLowerCase()); - } - return this.__isIE; - }, - - getIEVersion: function () { - if(!_global.navigator) { - return 0; - } - if (this.__IEVersion != null) { - return this.__IEVersion; - } - var version = 0; - var agent = navigator.userAgent.toLowerCase(); - var v1 = agent.match(/(?:msie\s([\w.]+))/); - var v2 = agent.match(/(?:trident.*rv:([\w.]+))/); - if (v1 && v2 && v1[1] && v2[1]) { - version = Math.max(v1[1] * 1, v2[1] * 1); - } else if (v1 && v1[1]) { - version = v1[1] * 1; - } else if (v2 && v2[1]) { - version = v2[1] * 1; - } else { - version = 0; - } - return this.__IEVersion = version; - }, - - isIE9Below: function () { - if (!BI.isIE()) { - return false; - } - return this.getIEVersion() < 9; - }, - - isEdge: function () { - if(!_global.navigator) { - return false; - } - return /edg/i.test(navigator.userAgent.toLowerCase()); - }, - - isChrome: function () { - if(!_global.navigator) { - return false; - } - return /chrome/i.test(navigator.userAgent.toLowerCase()); - }, - - isFireFox: function () { - if(!_global.navigator) { - return false; - } - return /firefox/i.test(navigator.userAgent.toLowerCase()); - }, - - isOpera: function () { - if(!_global.navigator) { - return false; - } - return /opera/i.test(navigator.userAgent.toLowerCase()); - }, - - isSafari: function () { - if(!_global.navigator) { - return false; - } - return /safari/i.test(navigator.userAgent.toLowerCase()) && !/chrome/i.test(navigator.userAgent.toLowerCase()); - }, - - isKhtml: function () { - if(!_global.navigator) { - return false; - } - return /Konqueror|Safari|KHTML/i.test(navigator.userAgent); - }, - - isMac: function () { - if(!_global.navigator) { - return false; - } - return /macintosh|mac os x/i.test(navigator.userAgent); - }, - - isWindows: function () { - if(!_global.navigator) { - return false; - } - return /windows|win32/i.test(navigator.userAgent); - }, - - isSupportCss3: function (style) { - if(!_global.document) { - return false; - } - var prefix = ["webkit", "Moz", "ms", "o"], - i, len, - humpString = [], - htmlStyle = document.documentElement.style, - _toHumb = function (string) { - if (!BI.isString(string)) { - return ""; - } - - return string.replace(/-(\w)/g, function ($0, $1) { - return $1.toUpperCase(); - }); - }; - - for ( i = 0; i < prefix.length; i++) { - humpString.push(_toHumb(prefix[i] + "-" + style)); - } - humpString.push(_toHumb(style)); - - for (i = 0, len = humpString.length; i < len; i++) { - if (humpString[i] in htmlStyle) { - return true; - } - } - return false; - }, - - getSafariVersion: function () { - if (!_global.navigator) { - return 0; - } - var agent = navigator.userAgent.toLowerCase(); - var version = agent.match(/version\/([\d.]+)/); - if (version && version[1]) { - return version[1] * 1; - } - return 0; - }, - - getMinimumFontSize: function () { - // not work for firefox - const el = document.createElement('div'); - el.style.fontSize = "1px"; - document.body.appendChild(el); - const size = getComputedStyle(el).fontSize; - el.remove(); - return parseInt(size); - } -}); diff --git a/src/core/platform/web/jquery/_jquery.js b/src/core/platform/web/jquery/_jquery.js deleted file mode 100644 index a0e0ca2a7..000000000 --- a/src/core/platform/web/jquery/_jquery.js +++ /dev/null @@ -1,3 +0,0 @@ -import jQuery from "jquery"; - -BI.jQuery = BI.$ = jQuery; diff --git a/src/core/platform/web/jquery/event.js b/src/core/platform/web/jquery/event.js deleted file mode 100644 index b7a9500f3..000000000 --- a/src/core/platform/web/jquery/event.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 给jQuery.Event对象添加的工具方法 - */ -BI.$.extend(BI.$.Event.prototype, { - // event.stopEvent - stopEvent: function () { - this.stopPropagation(); - this.preventDefault(); - } -}); \ No newline at end of file diff --git a/src/core/platform/web/jquery/fn.js b/src/core/platform/web/jquery/fn.js deleted file mode 100644 index 33584d838..000000000 --- a/src/core/platform/web/jquery/fn.js +++ /dev/null @@ -1,247 +0,0 @@ -if (BI.jQuery) { - (function ($) { - // richer:容器在其各个边缘留出的空间 - if (!$.fn.insets) { - $.fn.insets = function () { - var p = this.padding(), - b = this.border(); - return { - top: p.top, - bottom: p.bottom + b.bottom + b.top, - left: p.left, - right: p.right + b.right + b.left - }; - }; - } - - // richer:获取 && 设置jQuery元素的边界 - if (!$.fn.bounds) { - $.fn.bounds = function (value) { - var tmp = {hasIgnoredBounds: true}; - - if (value) { - if (!isNaN(value.x)) { - tmp.left = value.x; - } - if (!isNaN(value.y)) { - tmp.top = value.y; - } - if (value.width != null) { - tmp.width = (value.width - (this.outerWidth(true) - this.width())); - tmp.width = (tmp.width >= 0) ? tmp.width : value.width; - // fix chrome - // tmp.width = (tmp.width >= 0) ? tmp.width : 0; - } - if (value.height != null) { - tmp.height = value.height - (this.outerHeight(true) - this.height()); - tmp.height = (tmp.height >= 0) ? tmp.height : value.height; - // fix chrome - // tmp.height = (tmp.height >= 0) ? tmp.height : value.0; - } - this.css(tmp); - return this; - } - - // richer:注意此方法只对可见元素有效 - tmp = this.position(); - return { - x: tmp.left, - y: tmp.top, - // richer:这里计算外部宽度和高度的时候,都不包括边框 - width: this.outerWidth(), - height: this.outerHeight() - }; - - }; - } - })(BI.jQuery); - - BI.extend(BI.jQuery.fn, { - - destroy: function () { - this.remove(); - if (BI.isIE() === true) { - this[0].outerHTML = ""; - } - }, - /** - * 高亮显示 - * @param text 必需 - * @param keyword - * @param py - * @returns {*} - * @private - * 原理: - * 1、得到text的拼音py, 分别看是否匹配关键字keyword, 得到匹配索引tidx和pidx - * 2、比较tidx和pidx, 取大于-1且较小的索引,标红[索引,索引 + keyword.length - 1]的文本 - * 3、text和py各自取tidx/pidx + keyword.length索引开始的子串作为新的text和py, 重复1, 直到text和py有一个为"" - */ - __textKeywordMarked__: function (text, keyword, py) { - if (BI.isNull(text)) { - text = ""; - } - if (!BI.isKey(keyword) || (text + "").length > 100) { - if (BI.isIE9Below()) { - return this.html(BI.htmlEncode(text)); - } - // textContent性能更好,并且原生防xss - this[0].textContent = text; - return this; - } - keyword = keyword + ""; - keyword = BI.toUpperCase(keyword); - var textLeft = text + ""; - py = (py || BI.makeFirstPY(text, { - splitChar: "\u200b" - })) + ""; - py = BI.toUpperCase(py); - this.empty(); - // BI-48487 性能: makeFirstPY出来的py中包含多音字是必要的,但虽然此方法中做了限制。但是对于一个长度为60,包含14个多音字的字符串 - // 获取的的py长度将达到1966080, 远超过text的长度,到后面都是在做"".substring的无用功,所以此循环应保证py和textLeft长度不为0 - while (py.length > 0 && textLeft.length > 0) { - var tidx = BI.toUpperCase(textLeft).indexOf(keyword); - var pidx = py.indexOf(keyword); - if (pidx >= 0) { - pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length; - } - - // BI-56945 场景: 对'啊a'标红, a为keyword, 此时tidx为1, pidx为0, 此时使用tidx显然'啊'就无法标红了 - if (tidx >= 0 && (pidx > tidx || pidx === -1)) { - // 标红的text未encode - this.append(BI.htmlEncode(textLeft.substr(0, tidx))); - this.append(BI.$("").addClass("bi-keyword-red-mark") - .html(BI.htmlEncode(textLeft.substr(tidx, keyword.length)))); - - textLeft = textLeft.substr(tidx + keyword.length); - if (BI.isNotEmptyString(py)) { - // 每一组拼音都应该前进,而不是只是当前的 - py = BI.map(py.split("\u200b"), function (idx, ps) { - return ps.slice(tidx + keyword.length); - }).join("\u200b"); - } - } else if (pidx >= 0) { - // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 - // 标红的text未encode - this.append(BI.htmlEncode(textLeft.substr(0, pidx))); - this.append(BI.$("").addClass("bi-keyword-red-mark") - .html(BI.htmlEncode(textLeft.substr(pidx, keyword.length)))); - if (BI.isNotEmptyString(py)) { - // 每一组拼音都应该前进,而不是只是当前的 - py = BI.map(py.split("\u200b"), function (idx, ps) { - return ps.slice(pidx + keyword.length); - }).join("\u200b"); - } - textLeft = textLeft.substr(pidx + keyword.length); - } else { - // 标红的text未encode - this.append(BI.htmlEncode(textLeft)); - break; - } - } - - return this; - }, - - getDomHeight: function (parent) { - var clone = BI.$(this).clone(); - clone.appendTo(BI.$(parent || "body")); - var height = clone.height(); - clone.remove(); - return height; - }, - - // 是否有竖直滚动条 - hasVerticalScroll: function () { - return this.height() > 0 && this[0].clientWidth < this[0].offsetWidth; - }, - - // 是否有水平滚动条 - hasHorizonScroll: function () { - return this.width() > 0 && this[0].clientHeight < this[0].offsetHeight; - }, - - // 获取计算后的样式 - getStyle: function (name) { - var node = this[0]; - var computedStyle = void 0; - - // W3C Standard - if (_global.getComputedStyle) { - // In certain cases such as within an iframe in FF3, this returns null. - computedStyle = _global.getComputedStyle(node, null); - if (computedStyle) { - return computedStyle.getPropertyValue(BI.hyphenate(name)); - } - } - // Safari - if (document.defaultView && document.defaultView.getComputedStyle) { - computedStyle = document.defaultView.getComputedStyle(node, null); - // A Safari bug causes this to return null for `display: none` elements. - if (computedStyle) { - return computedStyle.getPropertyValue(BI.hyphenate(name)); - } - if (name === "display") { - return "none"; - } - } - // Internet Explorer - if (node.currentStyle) { - if (name === "float") { - return node.currentStyle.cssFloat || node.currentStyle.styleFloat; - } - return node.currentStyle[BI.camelize(name)]; - } - return node.style && node.style[BI.camelize(name)]; - }, - - __isMouseInBounds__: function (e) { - var offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); - var width = offset2Body.width || this.outerWidth(); - var height = offset2Body.height || this.outerHeight(); - // offset2Body.left的值可能会有小数,导致某点出现false - return !(e.pageX < Math.floor(offset2Body.left) || e.pageX > offset2Body.left + width - || e.pageY < Math.floor(offset2Body.top) || e.pageY > offset2Body.top + height); - }, - - __hasZIndexMask__: function (zindex) { - return zindex && this.zIndexMask[zindex] != null; - }, - - __buildZIndexMask__: function (zindex, domArray) { - this.zIndexMask = this.zIndexMask || {};// 存储z-index的mask - this.indexMask = this.indexMask || [];// 存储mask - var mask = BI.createWidget({ - type: "bi.center_adapt", - cls: "bi-z-index-mask", - items: domArray - }); - - mask.element.css({"z-index": zindex}); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: mask, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - this.indexMask.push(mask); - zindex && (this.zIndexMask[zindex] = mask); - return mask.element; - }, - - __releaseZIndexMask__: function (zindex) { - if (zindex && this.zIndexMask[zindex]) { - BI.remove(this.indexMask, this.zIndexMask[zindex]); - this.zIndexMask[zindex].destroy(); - return; - } - this.indexMask = this.indexMask || []; - var indexMask = this.indexMask.pop(); - indexMask && indexMask.destroy(); - } - }); -} diff --git a/src/core/platform/web/jquery/jquery.mousewheel.js b/src/core/platform/web/jquery/jquery.mousewheel.js deleted file mode 100644 index 557fe35e4..000000000 --- a/src/core/platform/web/jquery/jquery.mousewheel.js +++ /dev/null @@ -1,204 +0,0 @@ -/* ! - * jQuery Mousewheel 3.1.13 - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - */ - -(function (factory) { - // Browser globals - factory(BI.jQuery); - // if ( typeof define === "function" && define.amd ) { - // // AMD. Register as an anonymous module. - // define(["../core/jquery"], factory); - // } else if (typeof exports === "object") { - // // Node/CommonJS style for Browserify - // module.exports = factory; - // } else { - // // Browser globals - // factory(BI.jQuery); - // } -}(function ($) { - - var toFix = ["wheel", "mousewheel", "DOMMouseScroll", "MozMousePixelScroll"], - toBind = ( "onwheel" in document || document.documentMode >= 9 ) ? - ["wheel"] : ["mousewheel", "DomMouseScroll", "MozMousePixelScroll"], - slice = Array.prototype.slice, - nullLowestDeltaTimeout, lowestDelta; - - if ( $.event.fixHooks ) { - for ( var i = toFix.length; i; ) { - $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; - } - } - - var special = $.event.special.mousewheel = { - version: "3.1.12", - - setup: function () { - if ( this.addEventListener ) { - for ( var i = toBind.length; i; ) { - this.addEventListener( toBind[--i], handler, false ); - } - } else { - this.onmousewheel = handler; - } - }, - - teardown: function () { - if ( this.removeEventListener ) { - for ( var i = toBind.length; i; ) { - this.removeEventListener( toBind[--i], handler, false ); - } - } else { - this.onmousewheel = null; - } - }, - - settings: { - adjustOldDeltas: true, // see shouldAdjustOldDeltas() below - normalizeOffset: true // calls getBoundingClientRect for each event - } - }; - - $.fn.extend({ - mousewheel: function (fn) { - return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); - }, - - unmousewheel: function (fn) { - return this.unbind("mousewheel", fn); - } - }); - - - function handler (event) { - var orgEvent = event || _global.event, - args = slice.call(arguments, 1), - delta = 0, - deltaX = 0, - deltaY = 0, - absDelta = 0, - offsetX = 0, - offsetY = 0; - event = $.event.fix(orgEvent); - event.type = "mousewheel"; - - // Old school scrollwheel delta - if ( "detail" in orgEvent ) { deltaY = orgEvent.detail * -1; } - if ( "wheelDelta" in orgEvent ) { deltaY = orgEvent.wheelDelta; } - if ( "wheelDeltaY" in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } - if ( "wheelDeltaX" in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } - - // Firefox < 17 horizontal scrolling related to DOMMouseScroll event - if ( "axis" in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { - deltaX = deltaY * -1; - deltaY = 0; - } - - // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy - delta = deltaY === 0 ? deltaX : deltaY; - - // New school wheel delta (wheel event) - if ( "deltaY" in orgEvent ) { - deltaY = orgEvent.deltaY * -1; - delta = deltaY; - } - if ( "deltaX" in orgEvent ) { - deltaX = orgEvent.deltaX; - if ( deltaY === 0 ) { delta = deltaX * -1; } - } - - // No change actually happened, no reason to go any further - if ( deltaY === 0 && deltaX === 0 ) { return; } - - // Need to convert lines and pages to pixels if we aren't already in pixels - // There are three delta modes: - // * deltaMode 0 is by pixels, nothing to do - // * deltaMode 1 is by lines - // * deltaMode 2 is by pages - if ( orgEvent.deltaMode === 1 ) { - var lineHeight = 40; - delta *= lineHeight; - deltaY *= lineHeight; - deltaX *= lineHeight; - } else if ( orgEvent.deltaMode === 2 ) { - var pageHeight = 800; - delta *= pageHeight; - deltaY *= pageHeight; - deltaX *= pageHeight; - } - - // Store lowest absolute delta to normalize the delta values - absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); - - if ( !lowestDelta || absDelta < lowestDelta ) { - lowestDelta = absDelta; - - // Adjust older deltas if necessary - if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { - lowestDelta /= 40; - } - } - - // Adjust older deltas if necessary - if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { - // Divide all the things by 40! - delta /= 40; - deltaX /= 40; - deltaY /= 40; - } - - // Get a whole, normalized value for the deltas - delta = Math[ delta >= 1 ? "floor" : "ceil" ](delta / lowestDelta); - deltaX = Math[ deltaX >= 1 ? "floor" : "ceil" ](deltaX / lowestDelta); - deltaY = Math[ deltaY >= 1 ? "floor" : "ceil" ](deltaY / lowestDelta); - - // Normalise offsetX and offsetY properties - if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { - var boundingRect = this.getBoundingClientRect(); - offsetX = event.clientX - boundingRect.left; - offsetY = event.clientY - boundingRect.top; - } - - // Add information to the event object - event.deltaX = deltaX; - event.deltaY = deltaY; - event.deltaFactor = lowestDelta; - event.offsetX = offsetX; - event.offsetY = offsetY; - // Go ahead and set deltaMode to 0 since we converted to pixels - // Although this is a little odd since we overwrite the deltaX/Y - // properties with normalized deltas. - event.deltaMode = 0; - - // Add event and delta to the front of the arguments - args.unshift(event, delta, deltaX, deltaY); - - // Clearout lowestDelta after sometime to better - // handle multiple device types that give different - // a different lowestDelta - // Ex: trackpad = 3 and mouse wheel = 120 - if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } - nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); - - return ($.event.dispatch || $.event.handle).apply(this, args); - } - - function nullLowestDelta () { - lowestDelta = null; - } - - function shouldAdjustOldDeltas (orgEvent, absDelta) { - // If this is an older event and the delta is divisable by 120, - // then we are assuming that the browser is treating this as an - // older mouse wheel event and that we should divide the deltas - // by 40 to try and get a more usable deltaFactor. - // Side note, this actually impacts the reported scroll distance - // in older browsers and can cause scrolling to be slower than native. - // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. - return special.settings.adjustOldDeltas && orgEvent.type === "mousewheel" && absDelta % 120 === 0; - } - -})); \ No newline at end of file diff --git a/src/core/platform/web/load.js b/src/core/platform/web/load.js deleted file mode 100644 index f367b8cf6..000000000 --- a/src/core/platform/web/load.js +++ /dev/null @@ -1,55 +0,0 @@ -BI._.extend(BI, { - $import: function () { - var _LOADED = {}; // alex:保存加载过的 - function loadReady (src, must) { - var $scripts = BI.$("head script, body script"); - BI.$.each($scripts, function (i, item) { - if (item.src.indexOf(src) != -1) { - _LOADED[src] = true; - } - }); - var $links = BI.$("head link"); - BI.$.each($links, function (i, item) { - if (item.href.indexOf(src) != -1 && must) { - _LOADED[src] = false; - BI.$(item).remove(); - } - }); - } - - // must=true 强行加载 - return function (src, ext, must) { - loadReady(src, must); - // alex:如果已经加载过了的,直接return - if (_LOADED[src] === true) { - return; - } - if (ext === "css") { - var link = document.createElement("link"); - link.rel = "stylesheet"; - link.type = "text/css"; - link.href = src; - var head = document.getElementsByTagName("head")[0]; - head.appendChild(link); - _LOADED[src] = true; - } else { - // alex:这里用同步调用的方式,必须等待ajax完成 - BI.$.ajax({ - url: src, - dataType: "script", // alex:指定dataType为script,jquery会帮忙做globalEval的事情 - async: false, - cache: true, - complete: function (res, status) { - /* - * alex:发现jquery会很智能地判断一下返回的数据类型是不是script,然后做一个globalEval - * 所以当status为success时就不需要再把其中的内容加到script里面去了 - */ - if (status == "success") { - _LOADED[src] = true; - } - } - }); - } - }; - }() -}); \ No newline at end of file diff --git a/src/core/structure/aes.js b/src/core/structure/aes.js deleted file mode 100644 index ec5d6b86a..000000000 --- a/src/core/structure/aes.js +++ /dev/null @@ -1,2346 +0,0 @@ -!(function () { - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - /** - * CryptoJS core components. - */ - BI.CRYPT_TYPE = BI.CRYPT_TYPE || {}; - BI.CRYPT_TYPE.AES = "aes"; - - var CryptoJS = CryptoJS || (function (Math, undefined) { - /** - * CryptoJS namespace. - */ - var C = {}; - - /** - * Library namespace. - */ - var C_lib = C.lib = {}; - - /** - * Base object for prototypal inheritance. - */ - var Base = C_lib.Base = (function () { - function F () { - } - - return { - /** - * Creates a new object that inherits from this object. - * - * @param {Object} overrides Properties to copy into the new object. - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * field: 'value', - * - * method: function () { - * } - * }); - */ - extend: function (overrides) { - // Spawn - F.prototype = this; - var subtype = new F(); - - // Augment - if (overrides) { - subtype.mixIn(overrides); - } - - // Create default initializer - if (!subtype.hasOwnProperty('init')) { - subtype.init = function () { - subtype.$super.init.apply(this, arguments); - }; - } - - // Initializer's prototype is the subtype object - subtype.init.prototype = subtype; - - // Reference supertype - subtype.$super = this; - - return subtype; - }, - - /** - * Extends this object and runs the init method. - * Arguments to create() will be passed to init(). - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var instance = MyType.create(); - */ - create: function () { - var instance = this.extend(); - instance.init.apply(instance, arguments); - - return instance; - }, - - /** - * Initializes a newly created object. - * Override this method to add some logic when your objects are created. - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * init: function () { - * // ... - * } - * }); - */ - init: function () { - }, - - /** - * Copies properties into this object. - * - * @param {Object} properties The properties to mix in. - * - * @example - * - * MyType.mixIn({ - * field: 'value' - * }); - */ - mixIn: function (properties) { - for (var propertyName in properties) { - if (properties.hasOwnProperty(propertyName)) { - this[propertyName] = properties[propertyName]; - } - } - - // IE won't copy toString using the loop above - if (properties.hasOwnProperty('toString')) { - this.toString = properties.toString; - } - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = instance.clone(); - */ - clone: function () { - return this.init.prototype.extend(this); - } - }; - }()); - - /** - * An array of 32-bit words. - * - * @property {Array} words The array of 32-bit words. - * @property {number} sigBytes The number of significant bytes in this word array. - */ - var WordArray = C_lib.WordArray = Base.extend({ - /** - * Initializes a newly created word array. - * - * @param {Array} words (Optional) An array of 32-bit words. - * @param {number} sigBytes (Optional) The number of significant bytes in the words. - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.create(); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); - */ - init: function (words, sigBytes) { - words = this.words = words || []; - - if (sigBytes != undefined) { - this.sigBytes = sigBytes; - } else { - this.sigBytes = words.length * 4; - } - }, - - /** - * Converts this word array to a string. - * - * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex - * - * @return {string} The stringified word array. - * - * @example - * - * var string = wordArray + ''; - * var string = wordArray.toString(); - * var string = wordArray.toString(CryptoJS.enc.Utf8); - */ - toString: function (encoder) { - return (encoder || Hex).stringify(this); - }, - - /** - * Concatenates a word array to this word array. - * - * @param {WordArray} wordArray The word array to append. - * - * @return {WordArray} This word array. - * - * @example - * - * wordArray1.concat(wordArray2); - */ - concat: function (wordArray) { - // Shortcuts - var thisWords = this.words; - var thatWords = wordArray.words; - var thisSigBytes = this.sigBytes; - var thatSigBytes = wordArray.sigBytes; - - // Clamp excess bits - this.clamp(); - - // Concat - if (thisSigBytes % 4) { - // Copy one byte at a time - for (var i = 0; i < thatSigBytes; i++) { - var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); - } - } else if (thatWords.length > 0xffff) { - // Copy one word at a time - for (var i = 0; i < thatSigBytes; i += 4) { - thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; - } - } else { - // Copy all words at once - thisWords.push.apply(thisWords, thatWords); - } - this.sigBytes += thatSigBytes; - - // Chainable - return this; - }, - - /** - * Removes insignificant bits. - * - * @example - * - * wordArray.clamp(); - */ - clamp: function () { - // Shortcuts - var words = this.words; - var sigBytes = this.sigBytes; - - // Clamp - words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); - words.length = Math.ceil(sigBytes / 4); - }, - - /** - * Creates a copy of this word array. - * - * @return {WordArray} The clone. - * - * @example - * - * var clone = wordArray.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone.words = this.words.slice(0); - - return clone; - }, - - /** - * Creates a word array filled with random bytes. - * - * @param {number} nBytes The number of random bytes to generate. - * - * @return {WordArray} The random word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.random(16); - */ - random: function (nBytes) { - var words = []; - for (var i = 0; i < nBytes; i += 4) { - words.push((Math.random() * 0x100000000) | 0); - } - - return new WordArray.init(words, nBytes); - } - }); - - /** - * Encoder namespace. - */ - var C_enc = C.enc = {}; - - /** - * Hex encoding strategy. - */ - var Hex = C_enc.Hex = { - /** - * Converts a word array to a hex string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The hex string. - * - * @static - * - * @example - * - * var hexString = CryptoJS.enc.Hex.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var hexChars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - hexChars.push((bite >>> 4).toString(16)); - hexChars.push((bite & 0x0f).toString(16)); - } - - return hexChars.join(''); - }, - - /** - * Converts a hex string to a word array. - * - * @param {string} hexStr The hex string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Hex.parse(hexString); - */ - parse: function (hexStr) { - // Shortcut - var hexStrLength = hexStr.length; - - // Convert - var words = []; - for (var i = 0; i < hexStrLength; i += 2) { - words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); - } - - return new WordArray.init(words, hexStrLength / 2); - } - }; - - /** - * Latin1 encoding strategy. - */ - var Latin1 = C_enc.Latin1 = { - /** - * Converts a word array to a Latin1 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The Latin1 string. - * - * @static - * - * @example - * - * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var latin1Chars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - latin1Chars.push(String.fromCharCode(bite)); - } - - return latin1Chars.join(''); - }, - - /** - * Converts a Latin1 string to a word array. - * - * @param {string} latin1Str The Latin1 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); - */ - parse: function (latin1Str) { - // Shortcut - var latin1StrLength = latin1Str.length; - - // Convert - var words = []; - for (var i = 0; i < latin1StrLength; i++) { - words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); - } - - return new WordArray.init(words, latin1StrLength); - } - }; - - /** - * UTF-8 encoding strategy. - */ - var Utf8 = C_enc.Utf8 = { - /** - * Converts a word array to a UTF-8 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The UTF-8 string. - * - * @static - * - * @example - * - * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); - */ - stringify: function (wordArray) { - try { - return decodeURIComponent(escape(Latin1.stringify(wordArray))); - } catch (e) { - throw new Error('Malformed UTF-8 data'); - } - }, - - /** - * Converts a UTF-8 string to a word array. - * - * @param {string} utf8Str The UTF-8 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); - */ - parse: function (utf8Str) { - return Latin1.parse(unescape(encodeURIComponent(utf8Str))); - } - }; - - /** - * Abstract buffered block algorithm template. - * - * The property blockSize must be implemented in a concrete subtype. - * - * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 - */ - var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ - /** - * Resets this block algorithm's data buffer to its initial state. - * - * @example - * - * bufferedBlockAlgorithm.reset(); - */ - reset: function () { - // Initial values - this._data = new WordArray.init(); - this._nDataBytes = 0; - }, - - /** - * Adds new data to this block algorithm's buffer. - * - * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. - * - * @example - * - * bufferedBlockAlgorithm._append('data'); - * bufferedBlockAlgorithm._append(wordArray); - */ - _append: function (data) { - // Convert string to WordArray, else assume WordArray already - if (typeof data == 'string') { - data = Utf8.parse(data); - } - - // Append - this._data.concat(data); - this._nDataBytes += data.sigBytes; - }, - - /** - * Processes available data blocks. - * - * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. - * - * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. - * - * @return {WordArray} The processed data. - * - * @example - * - * var processedData = bufferedBlockAlgorithm._process(); - * var processedData = bufferedBlockAlgorithm._process(!!'flush'); - */ - _process: function (doFlush) { - // Shortcuts - var data = this._data; - var dataWords = data.words; - var dataSigBytes = data.sigBytes; - var blockSize = this.blockSize; - var blockSizeBytes = blockSize * 4; - - // Count blocks ready - var nBlocksReady = dataSigBytes / blockSizeBytes; - if (doFlush) { - // Round up to include partial blocks - nBlocksReady = Math.ceil(nBlocksReady); - } else { - // Round down to include only full blocks, - // less the number of blocks that must remain in the buffer - nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); - } - - // Count words ready - var nWordsReady = nBlocksReady * blockSize; - - // Count bytes ready - var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); - - // Process blocks - if (nWordsReady) { - for (var offset = 0; offset < nWordsReady; offset += blockSize) { - // Perform concrete-algorithm logic - this._doProcessBlock(dataWords, offset); - } - - // Remove processed words - var processedWords = dataWords.splice(0, nWordsReady); - data.sigBytes -= nBytesReady; - } - - // Return processed words - return new WordArray.init(processedWords, nBytesReady); - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = bufferedBlockAlgorithm.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone._data = this._data.clone(); - - return clone; - }, - - _minBufferSize: 0 - }); - - /** - * Abstract hasher template. - * - * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) - */ - var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ - /** - * Configuration options. - */ - cfg: Base.extend(), - - /** - * Initializes a newly created hasher. - * - * @param {Object} cfg (Optional) The configuration options to use for this hash computation. - * - * @example - * - * var hasher = CryptoJS.algo.SHA256.create(); - */ - init: function (cfg) { - // Apply config defaults - this.cfg = this.cfg.extend(cfg); - - // Set initial values - this.reset(); - }, - - /** - * Resets this hasher to its initial state. - * - * @example - * - * hasher.reset(); - */ - reset: function () { - // Reset data buffer - BufferedBlockAlgorithm.reset.call(this); - - // Perform concrete-hasher logic - this._doReset(); - }, - - /** - * Updates this hasher with a message. - * - * @param {WordArray|string} messageUpdate The message to append. - * - * @return {Hasher} This hasher. - * - * @example - * - * hasher.update('message'); - * hasher.update(wordArray); - */ - update: function (messageUpdate) { - // Append - this._append(messageUpdate); - - // Update the hash - this._process(); - - // Chainable - return this; - }, - - /** - * Finalizes the hash computation. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} messageUpdate (Optional) A final message update. - * - * @return {WordArray} The hash. - * - * @example - * - * var hash = hasher.finalize(); - * var hash = hasher.finalize('message'); - * var hash = hasher.finalize(wordArray); - */ - finalize: function (messageUpdate) { - // Final message update - if (messageUpdate) { - this._append(messageUpdate); - } - - // Perform concrete-hasher logic - var hash = this._doFinalize(); - - return hash; - }, - - blockSize: 512 / 32, - - /** - * Creates a shortcut function to a hasher's object interface. - * - * @param {Hasher} hasher The hasher to create a helper for. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); - */ - _createHelper: function (hasher) { - return function (message, cfg) { - return new hasher.init(cfg).finalize(message); - }; - }, - - /** - * Creates a shortcut function to the HMAC's object interface. - * - * @param {Hasher} hasher The hasher to use in this HMAC helper. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); - */ - _createHmacHelper: function (hasher) { - return function (message, key) { - return new C_algo.HMAC.init(hasher, key).finalize(message); - }; - } - }); - - /** - * Algorithm namespace. - */ - var C_algo = C.algo = {}; - - return C; - }(Math)); - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var C_enc = C.enc; - - /** - * Base64 encoding strategy. - */ - var Base64 = C_enc.Base64 = { - /** - * Converts a word array to a Base64 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The Base64 string. - * - * @static - * - * @example - * - * var base64String = CryptoJS.enc.Base64.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - var map = this._map; - - // Clamp excess bits - wordArray.clamp(); - - // Convert - var base64Chars = []; - for (var i = 0; i < sigBytes; i += 3) { - var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; - var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; - - var triplet = (byte1 << 16) | (byte2 << 8) | byte3; - - for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { - base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); - } - } - - // Add padding - var paddingChar = map.charAt(64); - if (paddingChar) { - while (base64Chars.length % 4) { - base64Chars.push(paddingChar); - } - } - - return base64Chars.join(''); - }, - - /** - * Converts a Base64 string to a word array. - * - * @param {string} base64Str The Base64 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Base64.parse(base64String); - */ - parse: function (base64Str) { - // Shortcuts - var base64StrLength = base64Str.length; - var map = this._map; - - // Ignore padding - var paddingChar = map.charAt(64); - if (paddingChar) { - var paddingIndex = base64Str.indexOf(paddingChar); - if (paddingIndex != -1) { - base64StrLength = paddingIndex; - } - } - - // Convert - var words = []; - var nBytes = 0; - for (var i = 0; i < base64StrLength; i++) { - if (i % 4) { - var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2); - var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2); - words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); - nBytes++; - } - } - - return WordArray.create(words, nBytes); - }, - - _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' - }; - }()); - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - (function (Math) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var Hasher = C_lib.Hasher; - var C_algo = C.algo; - - // Constants table - var T = []; - - // Compute constants - (function () { - for (var i = 0; i < 64; i++) { - T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; - } - }()); - - /** - * MD5 hash algorithm. - */ - var MD5 = C_algo.MD5 = Hasher.extend({ - _doReset: function () { - this._hash = new WordArray.init([ - 0x67452301, 0xefcdab89, - 0x98badcfe, 0x10325476 - ]); - }, - - _doProcessBlock: function (M, offset) { - // Swap endian - for (var i = 0; i < 16; i++) { - // Shortcuts - var offset_i = offset + i; - var M_offset_i = M[offset_i]; - - M[offset_i] = ( - (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | - (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) - ); - } - - // Shortcuts - var H = this._hash.words; - - var M_offset_0 = M[offset + 0]; - var M_offset_1 = M[offset + 1]; - var M_offset_2 = M[offset + 2]; - var M_offset_3 = M[offset + 3]; - var M_offset_4 = M[offset + 4]; - var M_offset_5 = M[offset + 5]; - var M_offset_6 = M[offset + 6]; - var M_offset_7 = M[offset + 7]; - var M_offset_8 = M[offset + 8]; - var M_offset_9 = M[offset + 9]; - var M_offset_10 = M[offset + 10]; - var M_offset_11 = M[offset + 11]; - var M_offset_12 = M[offset + 12]; - var M_offset_13 = M[offset + 13]; - var M_offset_14 = M[offset + 14]; - var M_offset_15 = M[offset + 15]; - - // Working varialbes - var a = H[0]; - var b = H[1]; - var c = H[2]; - var d = H[3]; - - // Computation - a = FF(a, b, c, d, M_offset_0, 7, T[0]); - d = FF(d, a, b, c, M_offset_1, 12, T[1]); - c = FF(c, d, a, b, M_offset_2, 17, T[2]); - b = FF(b, c, d, a, M_offset_3, 22, T[3]); - a = FF(a, b, c, d, M_offset_4, 7, T[4]); - d = FF(d, a, b, c, M_offset_5, 12, T[5]); - c = FF(c, d, a, b, M_offset_6, 17, T[6]); - b = FF(b, c, d, a, M_offset_7, 22, T[7]); - a = FF(a, b, c, d, M_offset_8, 7, T[8]); - d = FF(d, a, b, c, M_offset_9, 12, T[9]); - c = FF(c, d, a, b, M_offset_10, 17, T[10]); - b = FF(b, c, d, a, M_offset_11, 22, T[11]); - a = FF(a, b, c, d, M_offset_12, 7, T[12]); - d = FF(d, a, b, c, M_offset_13, 12, T[13]); - c = FF(c, d, a, b, M_offset_14, 17, T[14]); - b = FF(b, c, d, a, M_offset_15, 22, T[15]); - - a = GG(a, b, c, d, M_offset_1, 5, T[16]); - d = GG(d, a, b, c, M_offset_6, 9, T[17]); - c = GG(c, d, a, b, M_offset_11, 14, T[18]); - b = GG(b, c, d, a, M_offset_0, 20, T[19]); - a = GG(a, b, c, d, M_offset_5, 5, T[20]); - d = GG(d, a, b, c, M_offset_10, 9, T[21]); - c = GG(c, d, a, b, M_offset_15, 14, T[22]); - b = GG(b, c, d, a, M_offset_4, 20, T[23]); - a = GG(a, b, c, d, M_offset_9, 5, T[24]); - d = GG(d, a, b, c, M_offset_14, 9, T[25]); - c = GG(c, d, a, b, M_offset_3, 14, T[26]); - b = GG(b, c, d, a, M_offset_8, 20, T[27]); - a = GG(a, b, c, d, M_offset_13, 5, T[28]); - d = GG(d, a, b, c, M_offset_2, 9, T[29]); - c = GG(c, d, a, b, M_offset_7, 14, T[30]); - b = GG(b, c, d, a, M_offset_12, 20, T[31]); - - a = HH(a, b, c, d, M_offset_5, 4, T[32]); - d = HH(d, a, b, c, M_offset_8, 11, T[33]); - c = HH(c, d, a, b, M_offset_11, 16, T[34]); - b = HH(b, c, d, a, M_offset_14, 23, T[35]); - a = HH(a, b, c, d, M_offset_1, 4, T[36]); - d = HH(d, a, b, c, M_offset_4, 11, T[37]); - c = HH(c, d, a, b, M_offset_7, 16, T[38]); - b = HH(b, c, d, a, M_offset_10, 23, T[39]); - a = HH(a, b, c, d, M_offset_13, 4, T[40]); - d = HH(d, a, b, c, M_offset_0, 11, T[41]); - c = HH(c, d, a, b, M_offset_3, 16, T[42]); - b = HH(b, c, d, a, M_offset_6, 23, T[43]); - a = HH(a, b, c, d, M_offset_9, 4, T[44]); - d = HH(d, a, b, c, M_offset_12, 11, T[45]); - c = HH(c, d, a, b, M_offset_15, 16, T[46]); - b = HH(b, c, d, a, M_offset_2, 23, T[47]); - - a = II(a, b, c, d, M_offset_0, 6, T[48]); - d = II(d, a, b, c, M_offset_7, 10, T[49]); - c = II(c, d, a, b, M_offset_14, 15, T[50]); - b = II(b, c, d, a, M_offset_5, 21, T[51]); - a = II(a, b, c, d, M_offset_12, 6, T[52]); - d = II(d, a, b, c, M_offset_3, 10, T[53]); - c = II(c, d, a, b, M_offset_10, 15, T[54]); - b = II(b, c, d, a, M_offset_1, 21, T[55]); - a = II(a, b, c, d, M_offset_8, 6, T[56]); - d = II(d, a, b, c, M_offset_15, 10, T[57]); - c = II(c, d, a, b, M_offset_6, 15, T[58]); - b = II(b, c, d, a, M_offset_13, 21, T[59]); - a = II(a, b, c, d, M_offset_4, 6, T[60]); - d = II(d, a, b, c, M_offset_11, 10, T[61]); - c = II(c, d, a, b, M_offset_2, 15, T[62]); - b = II(b, c, d, a, M_offset_9, 21, T[63]); - - // Intermediate hash value - H[0] = (H[0] + a) | 0; - H[1] = (H[1] + b) | 0; - H[2] = (H[2] + c) | 0; - H[3] = (H[3] + d) | 0; - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - - var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); - var nBitsTotalL = nBitsTotal; - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( - (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | - (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) - ); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( - (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | - (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) - ); - - data.sigBytes = (dataWords.length + 1) * 4; - - // Hash final blocks - this._process(); - - // Shortcuts - var hash = this._hash; - var H = hash.words; - - // Swap endian - for (var i = 0; i < 4; i++) { - // Shortcut - var H_i = H[i]; - - H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | - (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); - } - - // Return final computed hash - return hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - } - }); - - function FF (a, b, c, d, x, s, t) { - var n = a + ((b & c) | (~b & d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function GG (a, b, c, d, x, s, t) { - var n = a + ((b & d) | (c & ~d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function HH (a, b, c, d, x, s, t) { - var n = a + (b ^ c ^ d) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function II (a, b, c, d, x, s, t) { - var n = a + (c ^ (b | ~d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.MD5('message'); - * var hash = CryptoJS.MD5(wordArray); - */ - C.MD5 = Hasher._createHelper(MD5); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacMD5(message, key); - */ - C.HmacMD5 = Hasher._createHmacHelper(MD5); - }(Math)); - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var WordArray = C_lib.WordArray; - var C_algo = C.algo; - var MD5 = C_algo.MD5; - - /** - * This key derivation function is meant to conform with EVP_BytesToKey. - * www.openssl.org/docs/crypto/EVP_BytesToKey.html - */ - var EvpKDF = C_algo.EvpKDF = Base.extend({ - /** - * Configuration options. - * - * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) - * @property {Hasher} hasher The hash algorithm to use. Default: MD5 - * @property {number} iterations The number of iterations to perform. Default: 1 - */ - cfg: Base.extend({ - keySize: 128 / 32, - hasher: MD5, - iterations: 1 - }), - - /** - * Initializes a newly created key derivation function. - * - * @param {Object} cfg (Optional) The configuration options to use for the derivation. - * - * @example - * - * var kdf = CryptoJS.algo.EvpKDF.create(); - * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); - * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); - */ - init: function (cfg) { - this.cfg = this.cfg.extend(cfg); - }, - - /** - * Derives a key from a password. - * - * @param {WordArray|string} password The password. - * @param {WordArray|string} salt A salt. - * - * @return {WordArray} The derived key. - * - * @example - * - * var key = kdf.compute(password, salt); - */ - compute: function (password, salt) { - // Shortcut - var cfg = this.cfg; - - // Init hasher - var hasher = cfg.hasher.create(); - - // Initial values - var derivedKey = WordArray.create(); - - // Shortcuts - var derivedKeyWords = derivedKey.words; - var keySize = cfg.keySize; - var iterations = cfg.iterations; - - // Generate key - while (derivedKeyWords.length < keySize) { - if (block) { - hasher.update(block); - } - var block = hasher.update(password).finalize(salt); - hasher.reset(); - - // Iterations - for (var i = 1; i < iterations; i++) { - block = hasher.finalize(block); - hasher.reset(); - } - - derivedKey.concat(block); - } - derivedKey.sigBytes = keySize * 4; - - return derivedKey; - } - }); - - /** - * Derives a key from a password. - * - * @param {WordArray|string} password The password. - * @param {WordArray|string} salt A salt. - * @param {Object} cfg (Optional) The configuration options to use for this computation. - * - * @return {WordArray} The derived key. - * - * @static - * - * @example - * - * var key = CryptoJS.EvpKDF(password, salt); - * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); - * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); - */ - C.EvpKDF = function (password, salt, cfg) { - return EvpKDF.create(cfg).compute(password, salt); - }; - }()); - - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - /** - * Cipher core components. - */ - CryptoJS.lib.Cipher || (function (undefined) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var WordArray = C_lib.WordArray; - var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; - var C_enc = C.enc; - var Utf8 = C_enc.Utf8; - var Base64 = C_enc.Base64; - var C_algo = C.algo; - var EvpKDF = C_algo.EvpKDF; - - /** - * Abstract base cipher template. - * - * @property {number} keySize This cipher's key size. Default: 4 (128 bits) - * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) - * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. - * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. - */ - var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ - /** - * Configuration options. - * - * @property {WordArray} iv The IV to use for this operation. - */ - cfg: Base.extend(), - - /** - * Creates this cipher in encryption mode. - * - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {Cipher} A cipher instance. - * - * @static - * - * @example - * - * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); - */ - createEncryptor: function (key, cfg) { - return this.create(this._ENC_XFORM_MODE, key, cfg); - }, - - /** - * Creates this cipher in decryption mode. - * - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {Cipher} A cipher instance. - * - * @static - * - * @example - * - * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); - */ - createDecryptor: function (key, cfg) { - return this.create(this._DEC_XFORM_MODE, key, cfg); - }, - - /** - * Initializes a newly created cipher. - * - * @param {number} xformMode Either the encryption or decryption transormation mode constant. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @example - * - * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); - */ - init: function (xformMode, key, cfg) { - // Apply config defaults - this.cfg = this.cfg.extend(cfg); - - // Store transform mode and key - this._xformMode = xformMode; - this._key = key; - - // Set initial values - this.reset(); - }, - - /** - * Resets this cipher to its initial state. - * - * @example - * - * cipher.reset(); - */ - reset: function () { - // Reset data buffer - BufferedBlockAlgorithm.reset.call(this); - - // Perform concrete-cipher logic - this._doReset(); - }, - - /** - * Adds data to be encrypted or decrypted. - * - * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. - * - * @return {WordArray} The data after processing. - * - * @example - * - * var encrypted = cipher.process('data'); - * var encrypted = cipher.process(wordArray); - */ - process: function (dataUpdate) { - // Append - this._append(dataUpdate); - - // Process available blocks - return this._process(); - }, - - /** - * Finalizes the encryption or decryption process. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. - * - * @return {WordArray} The data after final processing. - * - * @example - * - * var encrypted = cipher.finalize(); - * var encrypted = cipher.finalize('data'); - * var encrypted = cipher.finalize(wordArray); - */ - finalize: function (dataUpdate) { - // Final data update - if (dataUpdate) { - this._append(dataUpdate); - } - - // Perform concrete-cipher logic - var finalProcessedData = this._doFinalize(); - - return finalProcessedData; - }, - - keySize: 128 / 32, - - ivSize: 128 / 32, - - _ENC_XFORM_MODE: 1, - - _DEC_XFORM_MODE: 2, - - /** - * Creates shortcut functions to a cipher's object interface. - * - * @param {Cipher} cipher The cipher to create a helper for. - * - * @return {Object} An object with encrypt and decrypt shortcut functions. - * - * @static - * - * @example - * - * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); - */ - _createHelper: (function () { - function selectCipherStrategy (key) { - if (typeof key == 'string') { - return PasswordBasedCipher; - } else { - return SerializableCipher; - } - } - - return function (cipher) { - return { - encrypt: function (message, key, cfg) { - return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); - }, - - decrypt: function (ciphertext, key, cfg) { - return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); - } - }; - }; - }()) - }); - - /** - * Abstract base stream cipher template. - * - * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) - */ - var StreamCipher = C_lib.StreamCipher = Cipher.extend({ - _doFinalize: function () { - // Process partial blocks - var finalProcessedBlocks = this._process(!!'flush'); - - return finalProcessedBlocks; - }, - - blockSize: 1 - }); - - /** - * Mode namespace. - */ - var C_mode = C.mode = {}; - - /** - * Abstract base block cipher mode template. - */ - var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ - /** - * Creates this mode for encryption. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @static - * - * @example - * - * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); - */ - createEncryptor: function (cipher, iv) { - return this.Encryptor.create(cipher, iv); - }, - - /** - * Creates this mode for decryption. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @static - * - * @example - * - * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); - */ - createDecryptor: function (cipher, iv) { - return this.Decryptor.create(cipher, iv); - }, - - /** - * Initializes a newly created mode. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @example - * - * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); - */ - init: function (cipher, iv) { - this._cipher = cipher; - this._iv = iv; - } - }); - - /** - * Cipher Block Chaining mode. - */ - var CBC = C_mode.CBC = (function () { - /** - * Abstract base CBC mode. - */ - var CBC = BlockCipherMode.extend(); - - /** - * CBC encryptor. - */ - CBC.Encryptor = CBC.extend({ - /** - * Processes the data block at offset. - * - * @param {Array} words The data words to operate on. - * @param {number} offset The offset where the block starts. - * - * @example - * - * mode.processBlock(data.words, offset); - */ - processBlock: function (words, offset) { - // Shortcuts - var cipher = this._cipher; - var blockSize = cipher.blockSize; - - // XOR and encrypt - xorBlock.call(this, words, offset, blockSize); - cipher.encryptBlock(words, offset); - - // Remember this block to use with next block - this._prevBlock = words.slice(offset, offset + blockSize); - } - }); - - /** - * CBC decryptor. - */ - CBC.Decryptor = CBC.extend({ - /** - * Processes the data block at offset. - * - * @param {Array} words The data words to operate on. - * @param {number} offset The offset where the block starts. - * - * @example - * - * mode.processBlock(data.words, offset); - */ - processBlock: function (words, offset) { - // Shortcuts - var cipher = this._cipher; - var blockSize = cipher.blockSize; - - // Remember this block to use with next block - var thisBlock = words.slice(offset, offset + blockSize); - - // Decrypt and XOR - cipher.decryptBlock(words, offset); - xorBlock.call(this, words, offset, blockSize); - - // This block becomes the previous block - this._prevBlock = thisBlock; - } - }); - - function xorBlock (words, offset, blockSize) { - // Shortcut - var iv = this._iv; - - // Choose mixing block - if (iv) { - var block = iv; - - // Remove IV for subsequent blocks - this._iv = undefined; - } else { - var block = this._prevBlock; - } - - // XOR blocks - for (var i = 0; i < blockSize; i++) { - words[offset + i] ^= block[i]; - } - } - - return CBC; - }()); - - /** - * Padding namespace. - */ - var C_pad = C.pad = {}; - - /** - * PKCS #5/7 padding strategy. - */ - var Pkcs7 = C_pad.Pkcs7 = { - /** - * Pads data using the algorithm defined in PKCS #5/7. - * - * @param {WordArray} data The data to pad. - * @param {number} blockSize The multiple that the data should be padded to. - * - * @static - * - * @example - * - * CryptoJS.pad.Pkcs7.pad(wordArray, 4); - */ - pad: function (data, blockSize) { - // Shortcut - var blockSizeBytes = blockSize * 4; - - // Count padding bytes - var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; - - // Create padding word - var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; - - // Create padding - var paddingWords = []; - for (var i = 0; i < nPaddingBytes; i += 4) { - paddingWords.push(paddingWord); - } - var padding = WordArray.create(paddingWords, nPaddingBytes); - - // Add padding - data.concat(padding); - }, - - /** - * Unpads data that had been padded using the algorithm defined in PKCS #5/7. - * - * @param {WordArray} data The data to unpad. - * - * @static - * - * @example - * - * CryptoJS.pad.Pkcs7.unpad(wordArray); - */ - unpad: function (data) { - // Get number of padding bytes from last byte - var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; - - // Remove padding - data.sigBytes -= nPaddingBytes; - } - }; - - /** - * Abstract base block cipher template. - * - * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) - */ - var BlockCipher = C_lib.BlockCipher = Cipher.extend({ - /** - * Configuration options. - * - * @property {Mode} mode The block mode to use. Default: CBC - * @property {Padding} padding The padding strategy to use. Default: Pkcs7 - */ - cfg: Cipher.cfg.extend({ - mode: CBC, - padding: Pkcs7 - }), - - reset: function () { - // Reset cipher - Cipher.reset.call(this); - - // Shortcuts - var cfg = this.cfg; - var iv = cfg.iv; - var mode = cfg.mode; - - // Reset block mode - if (this._xformMode == this._ENC_XFORM_MODE) { - var modeCreator = mode.createEncryptor; - } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { - var modeCreator = mode.createDecryptor; - - // Keep at least one block in the buffer for unpadding - this._minBufferSize = 1; - } - this._mode = modeCreator.call(mode, this, iv && iv.words); - }, - - _doProcessBlock: function (words, offset) { - this._mode.processBlock(words, offset); - }, - - _doFinalize: function () { - // Shortcut - var padding = this.cfg.padding; - - // Finalize - if (this._xformMode == this._ENC_XFORM_MODE) { - // Pad data - padding.pad(this._data, this.blockSize); - - // Process final blocks - var finalProcessedBlocks = this._process(!!'flush'); - } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { - // Process final blocks - var finalProcessedBlocks = this._process(!!'flush'); - - // Unpad data - padding.unpad(finalProcessedBlocks); - } - - return finalProcessedBlocks; - }, - - blockSize: 128 / 32 - }); - - /** - * A collection of cipher parameters. - * - * @property {WordArray} ciphertext The raw ciphertext. - * @property {WordArray} key The key to this ciphertext. - * @property {WordArray} iv The IV used in the ciphering operation. - * @property {WordArray} salt The salt used with a key derivation function. - * @property {Cipher} algorithm The cipher algorithm. - * @property {Mode} mode The block mode used in the ciphering operation. - * @property {Padding} padding The padding scheme used in the ciphering operation. - * @property {number} blockSize The block size of the cipher. - * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. - */ - var CipherParams = C_lib.CipherParams = Base.extend({ - /** - * Initializes a newly created cipher params object. - * - * @param {Object} cipherParams An object with any of the possible cipher parameters. - * - * @example - * - * var cipherParams = CryptoJS.lib.CipherParams.create({ - * ciphertext: ciphertextWordArray, - * key: keyWordArray, - * iv: ivWordArray, - * salt: saltWordArray, - * algorithm: CryptoJS.algo.AES, - * mode: CryptoJS.mode.CBC, - * padding: CryptoJS.pad.PKCS7, - * blockSize: 4, - * formatter: CryptoJS.format.OpenSSL - * }); - */ - init: function (cipherParams) { - this.mixIn(cipherParams); - }, - - /** - * Converts this cipher params object to a string. - * - * @param {Format} formatter (Optional) The formatting strategy to use. - * - * @return {string} The stringified cipher params. - * - * @throws Error If neither the formatter nor the default formatter is set. - * - * @example - * - * var string = cipherParams + ''; - * var string = cipherParams.toString(); - * var string = cipherParams.toString(CryptoJS.format.OpenSSL); - */ - toString: function (formatter) { - return (formatter || this.formatter).stringify(this); - } - }); - - /** - * Format namespace. - */ - var C_format = C.format = {}; - - /** - * OpenSSL formatting strategy. - */ - var OpenSSLFormatter = C_format.OpenSSL = { - /** - * Converts a cipher params object to an OpenSSL-compatible string. - * - * @param {CipherParams} cipherParams The cipher params object. - * - * @return {string} The OpenSSL-compatible string. - * - * @static - * - * @example - * - * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); - */ - stringify: function (cipherParams) { - // Shortcuts - var ciphertext = cipherParams.ciphertext; - var salt = cipherParams.salt; - - // Format - if (salt) { - var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); - } else { - var wordArray = ciphertext; - } - - return wordArray.toString(Base64); - }, - - /** - * Converts an OpenSSL-compatible string to a cipher params object. - * - * @param {string} openSSLStr The OpenSSL-compatible string. - * - * @return {CipherParams} The cipher params object. - * - * @static - * - * @example - * - * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); - */ - parse: function (openSSLStr) { - // Parse base64 - var ciphertext = Base64.parse(openSSLStr); - - // Shortcut - var ciphertextWords = ciphertext.words; - - // Test for salt - if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { - // Extract salt - var salt = WordArray.create(ciphertextWords.slice(2, 4)); - - // Remove salt from ciphertext - ciphertextWords.splice(0, 4); - ciphertext.sigBytes -= 16; - } - - return CipherParams.create({ciphertext: ciphertext, salt: salt}); - } - }; - - /** - * A cipher wrapper that returns ciphertext as a serializable cipher params object. - */ - var SerializableCipher = C_lib.SerializableCipher = Base.extend({ - /** - * Configuration options. - * - * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL - */ - cfg: Base.extend({ - format: OpenSSLFormatter - }), - - /** - * Encrypts a message. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {WordArray|string} message The message to encrypt. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {CipherParams} A cipher params object. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - */ - encrypt: function (cipher, message, key, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Encrypt - var encryptor = cipher.createEncryptor(key, cfg); - var ciphertext = encryptor.finalize(message); - - // Shortcut - var cipherCfg = encryptor.cfg; - - // Create and return serializable cipher params - return CipherParams.create({ - ciphertext: ciphertext, - key: key, - iv: cipherCfg.iv, - algorithm: cipher, - mode: cipherCfg.mode, - padding: cipherCfg.padding, - blockSize: cipher.blockSize, - formatter: cfg.format - }); - }, - - /** - * Decrypts serialized ciphertext. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {CipherParams|string} ciphertext The ciphertext to decrypt. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {WordArray} The plaintext. - * - * @static - * - * @example - * - * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - */ - decrypt: function (cipher, ciphertext, key, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Convert string to CipherParams - ciphertext = this._parse(ciphertext, cfg.format); - - // Decrypt - var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); - - return plaintext; - }, - - /** - * Converts serialized ciphertext to CipherParams, - * else assumed CipherParams already and returns ciphertext unchanged. - * - * @param {CipherParams|string} ciphertext The ciphertext. - * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. - * - * @return {CipherParams} The unserialized ciphertext. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); - */ - _parse: function (ciphertext, format) { - if (typeof ciphertext == 'string') { - return format.parse(ciphertext, this); - } else { - return ciphertext; - } - } - }); - - /** - * Key derivation function namespace. - */ - var C_kdf = C.kdf = {}; - - /** - * OpenSSL key derivation function. - */ - var OpenSSLKdf = C_kdf.OpenSSL = { - /** - * Derives a key and IV from a password. - * - * @param {string} password The password to derive from. - * @param {number} keySize The size in words of the key to generate. - * @param {number} ivSize The size in words of the IV to generate. - * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. - * - * @return {CipherParams} A cipher params object with the key, IV, and salt. - * - * @static - * - * @example - * - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); - */ - execute: function (password, keySize, ivSize, salt) { - // Generate random salt - if (!salt) { - salt = WordArray.random(64 / 8); - } - - // Derive key and IV - var key = EvpKDF.create({keySize: keySize + ivSize}).compute(password, salt); - - // Separate key and IV - var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); - key.sigBytes = keySize * 4; - - // Return params - return CipherParams.create({key: key, iv: iv, salt: salt}); - } - }; - - /** - * A serializable cipher wrapper that derives the key from a password, - * and returns ciphertext as a serializable cipher params object. - */ - var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ - /** - * Configuration options. - * - * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL - */ - cfg: SerializableCipher.cfg.extend({ - kdf: OpenSSLKdf - }), - - /** - * Encrypts a message using a password. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {WordArray|string} message The message to encrypt. - * @param {string} password The password. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {CipherParams} A cipher params object. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); - * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); - */ - encrypt: function (cipher, message, password, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Derive key and other params - var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); - - // Add IV to config - cfg.iv = derivedParams.iv; - - // Encrypt - var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); - - // Mix in derived params - ciphertext.mixIn(derivedParams); - - return ciphertext; - }, - - /** - * Decrypts serialized ciphertext using a password. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {CipherParams|string} ciphertext The ciphertext to decrypt. - * @param {string} password The password. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {WordArray} The plaintext. - * - * @static - * - * @example - * - * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); - * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); - */ - decrypt: function (cipher, ciphertext, password, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Convert string to CipherParams - ciphertext = this._parse(ciphertext, cfg.format); - - // Derive key and other params - var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); - - // Add IV to config - cfg.iv = derivedParams.iv; - - // Decrypt - var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); - - return plaintext; - } - }); - }()); - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - /** - * Electronic Codebook block mode. - */ - CryptoJS.mode.ECB = (function () { - var ECB = CryptoJS.lib.BlockCipherMode.extend(); - - ECB.Encryptor = ECB.extend({ - processBlock: function (words, offset) { - this._cipher.encryptBlock(words, offset); - } - }); - - ECB.Decryptor = ECB.extend({ - processBlock: function (words, offset) { - this._cipher.decryptBlock(words, offset); - } - }); - - return ECB; - }()); - - - /* - CryptoJS v3.1.2 - code.google.com/p/crypto-js - (c) 2009-2013 by Jeff Mott. All rights reserved. - code.google.com/p/crypto-js/wiki/License - */ - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var BlockCipher = C_lib.BlockCipher; - var C_algo = C.algo; - - // Lookup tables - var SBOX = []; - var INV_SBOX = []; - var SUB_MIX_0 = []; - var SUB_MIX_1 = []; - var SUB_MIX_2 = []; - var SUB_MIX_3 = []; - var INV_SUB_MIX_0 = []; - var INV_SUB_MIX_1 = []; - var INV_SUB_MIX_2 = []; - var INV_SUB_MIX_3 = []; - - // Compute lookup tables - (function () { - // Compute double table - var d = []; - for (var i = 0; i < 256; i++) { - if (i < 128) { - d[i] = i << 1; - } else { - d[i] = (i << 1) ^ 0x11b; - } - } - - // Walk GF(2^8) - var x = 0; - var xi = 0; - for (var i = 0; i < 256; i++) { - // Compute sbox - var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); - sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; - SBOX[x] = sx; - INV_SBOX[sx] = x; - - // Compute multiplication - var x2 = d[x]; - var x4 = d[x2]; - var x8 = d[x4]; - - // Compute sub bytes, mix columns tables - var t = (d[sx] * 0x101) ^ (sx * 0x1010100); - SUB_MIX_0[x] = (t << 24) | (t >>> 8); - SUB_MIX_1[x] = (t << 16) | (t >>> 16); - SUB_MIX_2[x] = (t << 8) | (t >>> 24); - SUB_MIX_3[x] = t; - - // Compute inv sub bytes, inv mix columns tables - var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); - INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); - INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); - INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); - INV_SUB_MIX_3[sx] = t; - - // Compute next counter - if (!x) { - x = xi = 1; - } else { - x = x2 ^ d[d[d[x8 ^ x2]]]; - xi ^= d[d[xi]]; - } - } - }()); - - // Precomputed Rcon lookup - var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; - - /** - * AES block cipher algorithm. - */ - var AES = C_algo.AES = BlockCipher.extend({ - _doReset: function () { - // Shortcuts - var key = this._key; - var keyWords = key.words; - var keySize = key.sigBytes / 4; - - // Compute number of rounds - var nRounds = this._nRounds = keySize + 6; - - // Compute number of key schedule rows - var ksRows = (nRounds + 1) * 4; - - // Compute key schedule - var keySchedule = this._keySchedule = []; - for (var ksRow = 0; ksRow < ksRows; ksRow++) { - if (ksRow < keySize) { - keySchedule[ksRow] = keyWords[ksRow]; - } else { - var t = keySchedule[ksRow - 1]; - - if (!(ksRow % keySize)) { - // Rot word - t = (t << 8) | (t >>> 24); - - // Sub word - t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; - - // Mix Rcon - t ^= RCON[(ksRow / keySize) | 0] << 24; - } else if (keySize > 6 && ksRow % keySize == 4) { - // Sub word - t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; - } - - keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; - } - } - - // Compute inv key schedule - var invKeySchedule = this._invKeySchedule = []; - for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { - var ksRow = ksRows - invKsRow; - - if (invKsRow % 4) { - var t = keySchedule[ksRow]; - } else { - var t = keySchedule[ksRow - 4]; - } - - if (invKsRow < 4 || ksRow <= 4) { - invKeySchedule[invKsRow] = t; - } else { - invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ - INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; - } - } - }, - - encryptBlock: function (M, offset) { - this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); - }, - - decryptBlock: function (M, offset) { - // Swap 2nd and 4th rows - var t = M[offset + 1]; - M[offset + 1] = M[offset + 3]; - M[offset + 3] = t; - - this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); - - // Inv swap 2nd and 4th rows - var t = M[offset + 1]; - M[offset + 1] = M[offset + 3]; - M[offset + 3] = t; - }, - - _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { - // Shortcut - var nRounds = this._nRounds; - - // Get input, add round key - var s0 = M[offset] ^ keySchedule[0]; - var s1 = M[offset + 1] ^ keySchedule[1]; - var s2 = M[offset + 2] ^ keySchedule[2]; - var s3 = M[offset + 3] ^ keySchedule[3]; - - // Key schedule row counter - var ksRow = 4; - - // Rounds - for (var round = 1; round < nRounds; round++) { - // Shift rows, sub bytes, mix columns, add round key - var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; - var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; - var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; - var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; - - // Update state - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - } - - // Shift rows, sub bytes, add round key - var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; - var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; - var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; - var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; - - // Set output - M[offset] = t0; - M[offset + 1] = t1; - M[offset + 2] = t2; - M[offset + 3] = t3; - }, - - keySize: 256 / 32 - }); - - /** - * Shortcut functions to the cipher's object interface. - * - * @example - * - * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); - * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); - */ - C.AES = BlockCipher._createHelper(AES); - }()); - - - BI._.extend(BI, { - /** - * aes加密方法 - * aes-128-ecb - * - * @example - * - * var ciphertext = BI.aesEncrypt(text, key); - */ - aesEncrypt: function (text, key) { - key = CryptoJS.enc.Utf8.parse(key); - var cipher = CryptoJS.AES.encrypt(text, key, { - mode: CryptoJS.mode.ECB, - padding: CryptoJS.pad.Pkcs7 - }); - - var base64Cipher = cipher.ciphertext.toString(CryptoJS.enc.Base64); - return base64Cipher; - }, - - /** - * aes解密方法 - * @param {String} text - * @param {String} key - */ - aesDecrypt: function (text, key) { - key = CryptoJS.enc.Utf8.parse(key); - var decipher = CryptoJS.AES.decrypt(text, key, { - mode: CryptoJS.mode.ECB, - padding: CryptoJS.pad.Pkcs7 - }); - - return CryptoJS.enc.Utf8.stringify(decipher); - } - }); -}()); \ No newline at end of file diff --git a/src/core/structure/aspect.js b/src/core/structure/aspect.js deleted file mode 100644 index a104c12ca..000000000 --- a/src/core/structure/aspect.js +++ /dev/null @@ -1,63 +0,0 @@ -!(function () { - function aspect (type) { - return function (target, methodName, advice) { - var exist = target[methodName], - dispatcher; - - if (!exist || exist.target != target) { - dispatcher = target[methodName] = function () { - // before methods - var beforeArr = dispatcher.before; - var args = arguments, next; - for (var l = beforeArr.length; l--;) { - next = beforeArr[l].advice.apply(this, args); - if (next === false) { - return false; - } - args = next || args; - } - // target method - var rs = dispatcher.method.apply(this, args); - // after methods - var afterArr = dispatcher.after; - for (var i = 0, ii = afterArr.length; i < ii; i++) { - next = afterArr[i].advice.call(this, rs, args); - if (rs === false) { - return false; - } - args = next || args; - } - return rs; - }; - - dispatcher.before = []; - dispatcher.after = []; - - if (exist) { - dispatcher.method = exist; - } - dispatcher.target = target; - } - - var aspectArr = (dispatcher || exist)[type]; - var obj = { - advice: advice, - _index: aspectArr.length, - remove: function () { - aspectArr.splice(this._index, 1); - } - }; - aspectArr.push(obj); - - return obj; - }; - } - - BI.aspect = { - before: aspect("before"), - after: aspect("after") - }; - - return BI.aspect; - -})(); \ No newline at end of file diff --git a/src/core/structure/base64.js b/src/core/structure/base64.js deleted file mode 100644 index 976fbab9e..000000000 --- a/src/core/structure/base64.js +++ /dev/null @@ -1,130 +0,0 @@ - -!(function () { - - var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - - // private method for UTF-8 encoding - var _utf8_encode = function (string) { - string = string.replace(/\r\n/g, "\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }; - - // private method for UTF-8 decoding - var _utf8_decode = function (utftext) { - var string = ""; - var i = 0; - var c = 0, c3 = 0, c2 = 0; - - while (i < utftext.length) { - - c = utftext.charCodeAt(i); - - if (c < 128) { - string += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i + 1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i + 1); - c3 = utftext.charCodeAt(i + 2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - - } - return string; - }; - - BI._.extend(BI, { - - encode: function (input) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - - input = _utf8_encode(input); - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); - - } - - return output; - }, - - // public method for decoding - decode: function (input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = _keyStr.indexOf(input.charAt(i++)); - enc2 = _keyStr.indexOf(input.charAt(i++)); - enc3 = _keyStr.indexOf(input.charAt(i++)); - enc4 = _keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - - } - - output = _utf8_decode(output); - - return output; - - } - }); -})(); \ No newline at end of file diff --git a/src/core/structure/cache.js b/src/core/structure/cache.js deleted file mode 100644 index 5f17bd630..000000000 --- a/src/core/structure/cache.js +++ /dev/null @@ -1,77 +0,0 @@ - -BI.Cache = { - _prefix: "bi", - setUsername: function (username) { - localStorage.setItem(BI.Cache._prefix + ".username", (username + "" || "").toUpperCase()); - }, - getUsername: function () { - return localStorage.getItem(BI.Cache._prefix + ".username") || ""; - }, - _getKeyPrefix: function () { - return BI.Cache.getUsername() + "." + BI.Cache._prefix + "."; - }, - _generateKey: function (key) { - return BI.Cache._getKeyPrefix() + (key || ""); - }, - getItem: function (key) { - return localStorage.getItem(BI.Cache._generateKey(key)); - }, - setItem: function (key, value) { - localStorage.setItem(BI.Cache._generateKey(key), value); - }, - removeItem: function (key) { - localStorage.removeItem(BI.Cache._generateKey(key)); - }, - clear: function () { - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - if (key.indexOf(BI.Cache._getKeyPrefix()) === 0) { - localStorage.removeItem(key); - } - } - } - }, - keys: function () { - var result = []; - for (var i = localStorage.length; i >= 0; i--) { - var key = localStorage.key(i); - if (key) { - var prefix = BI.Cache._getKeyPrefix(); - if (key.indexOf(prefix) === 0) { - result[result.length] = key.substring(prefix.length); - } - } - } - return result; - }, - - addCookie: function (name, value, path, expiresHours) { - var cookieString = name + "=" + encodeURI(value); - // 判断是否设置过期时间 - if (expiresHours && expiresHours > 0) { - var date = new Date(); - // expires是标准GMT格式时间,应该使用时间戳作为起始时间 - date.setTime(date.getTime() + expiresHours * 3600 * 1000); - cookieString = cookieString + "; expires=" + date.toUTCString(); - } - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - }, - getCookie: function (name) { - var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); - if (arr = document.cookie.match(reg)) {return decodeURI(arr[2]);} - return null; - }, - deleteCookie: function (name, path) { - var date = new Date(); - date.setTime(date.getTime() - 10000); - var cookieString = name + "=v; expires=" + date.toUTCString(); - if (path) { - cookieString = cookieString + "; path=" + path; - } - document.cookie = cookieString; - } -}; diff --git a/src/core/structure/cellSizeAndPositionManager.js b/src/core/structure/cellSizeAndPositionManager.js deleted file mode 100644 index 9c30fdfdd..000000000 --- a/src/core/structure/cellSizeAndPositionManager.js +++ /dev/null @@ -1,271 +0,0 @@ -BI.CellSizeAndPositionManager = function (cellCount, cellSizeGetter, estimatedCellSize) { - this._cellSizeGetter = cellSizeGetter; - this._cellCount = cellCount; - this._estimatedCellSize = estimatedCellSize; - this._cellSizeAndPositionData = {}; - this._lastMeasuredIndex = -1; -}; - -BI.CellSizeAndPositionManager.prototype = { - constructor: BI.CellSizeAndPositionManager, - configure: function (cellCount, estimatedCellSize) { - this._cellCount = cellCount; - this._estimatedCellSize = estimatedCellSize; - }, - - getCellCount: function () { - return this._cellCount; - }, - - getEstimatedCellSize: function () { - return this._estimatedCellSize; - }, - - getLastMeasuredIndex: function () { - return this._lastMeasuredIndex; - }, - - getSizeAndPositionOfCell: function (index) { - if (index < 0 || index >= this._cellCount) { - return; - } - if (index > this._lastMeasuredIndex) { - var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); - var offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; - - for (var i = this._lastMeasuredIndex + 1; i <= index; i++) { - var size = this._cellSizeGetter(i); - - if (size == null || isNaN(size)) { - continue; - } - - this._cellSizeAndPositionData[i] = { - offset: offset, - size: size - }; - - offset += size; - } - - this._lastMeasuredIndex = index; - } - return this._cellSizeAndPositionData[index]; - }, - - getSizeAndPositionOfLastMeasuredCell: function () { - return this._lastMeasuredIndex >= 0 - ? this._cellSizeAndPositionData[this._lastMeasuredIndex] - : { - offset: 0, - size: 0 - }; - }, - - getTotalSize: function () { - var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); - return lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size + (this._cellCount - this._lastMeasuredIndex - 1) * this._estimatedCellSize; - }, - - getUpdatedOffsetForIndex: function (align, containerSize, currentOffset, targetIndex) { - var datum = this.getSizeAndPositionOfCell(targetIndex); - var maxOffset = datum.offset; - var minOffset = maxOffset - containerSize + datum.size; - - var idealOffset; - - switch (align) { - case "start": - idealOffset = maxOffset; - break; - case "end": - idealOffset = minOffset; - break; - case "center": - idealOffset = maxOffset - ((containerSize - datum.size) / 2); - break; - default: - idealOffset = Math.max(minOffset, Math.min(maxOffset, currentOffset)); - break; - } - - var totalSize = this.getTotalSize(); - - return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); - }, - - getVisibleCellRange: function (containerSize, offset) { - var totalSize = this.getTotalSize(); - - if (totalSize === 0) { - return {}; - } - - var maxOffset = offset + containerSize; - var start = this._findNearestCell(offset); - - var datum = this.getSizeAndPositionOfCell(start); - offset = datum.offset + datum.size; - - var stop = start; - - while (offset < maxOffset && stop < this._cellCount - 1) { - stop++; - offset += this.getSizeAndPositionOfCell(stop).size; - } - - return { - start: start, - stop: stop - }; - }, - - resetCell: function (index) { - this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); - }, - - _binarySearch: function (high, low, offset) { - var middle; - var currentOffset; - - while (low <= high) { - middle = low + Math.floor((high - low) / 2); - currentOffset = this.getSizeAndPositionOfCell(middle).offset; - - if (currentOffset === offset) { - return middle; - } else if (currentOffset < offset) { - low = middle + 1; - } else if (currentOffset > offset) { - high = middle - 1; - } - } - - if (low > 0) { - return low - 1; - } - }, - - _exponentialSearch: function (index, offset) { - var interval = 1; - - while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) { - index += interval; - interval *= 2; - } - - return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); - }, - - _findNearestCell: function (offset) { - if (isNaN(offset)) { - return; - } - - offset = Math.max(0, offset); - - var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); - var lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); - - if (lastMeasuredCellSizeAndPosition.offset >= offset) { - return this._binarySearch(lastMeasuredIndex, 0, offset); - } - return this._exponentialSearch(lastMeasuredIndex, offset); - - } -}; - -BI.ScalingCellSizeAndPositionManager = function (cellCount, cellSizeGetter, estimatedCellSize, maxScrollSize) { - this._cellSizeAndPositionManager = new BI.CellSizeAndPositionManager(cellCount, cellSizeGetter, estimatedCellSize); - this._maxScrollSize = maxScrollSize || 10000000; -}; - -BI.ScalingCellSizeAndPositionManager.prototype = { - constructor: BI.ScalingCellSizeAndPositionManager, - - configure: function () { - this._cellSizeAndPositionManager.configure.apply(this._cellSizeAndPositionManager, arguments); - }, - - getCellCount: function () { - return this._cellSizeAndPositionManager.getCellCount(); - }, - - getEstimatedCellSize: function () { - return this._cellSizeAndPositionManager.getEstimatedCellSize(); - }, - - getLastMeasuredIndex: function () { - return this._cellSizeAndPositionManager.getLastMeasuredIndex(); - }, - - getOffsetAdjustment: function (containerSize, offset) { - var totalSize = this._cellSizeAndPositionManager.getTotalSize(); - var safeTotalSize = this.getTotalSize(); - var offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); - - return Math.round(offsetPercentage * (safeTotalSize - totalSize)); - }, - - getSizeAndPositionOfCell: function (index) { - return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); - }, - - getSizeAndPositionOfLastMeasuredCell: function () { - return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); - }, - - getTotalSize: function () { - return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); - }, - - getUpdatedOffsetForIndex: function (align, containerSize, currentOffset, targetIndex) { - currentOffset = this._safeOffsetToOffset(containerSize, currentOffset); - - var offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex); - - return this._offsetToSafeOffset(containerSize, offset); - }, - - getVisibleCellRange: function (containerSize, offset) { - offset = this._safeOffsetToOffset(containerSize, offset); - - return this._cellSizeAndPositionManager.getVisibleCellRange(containerSize, offset); - }, - - resetCell: function (index) { - this._cellSizeAndPositionManager.resetCell(index); - }, - - _getOffsetPercentage: function (containerSize, offset, totalSize) { - return totalSize <= containerSize - ? 0 - : offset / (totalSize - containerSize); - }, - - _offsetToSafeOffset: function (containerSize, offset) { - var totalSize = this._cellSizeAndPositionManager.getTotalSize(); - var safeTotalSize = this.getTotalSize(); - - if (totalSize === safeTotalSize) { - return offset; - } - var offsetPercentage = this._getOffsetPercentage(containerSize, offset, totalSize); - - return Math.round(offsetPercentage * (safeTotalSize - containerSize)); - - }, - - _safeOffsetToOffset: function (containerSize, offset) { - var totalSize = this._cellSizeAndPositionManager.getTotalSize(); - var safeTotalSize = this.getTotalSize(); - - if (totalSize === safeTotalSize) { - return offset; - } - var offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); - - return Math.round(offsetPercentage * (totalSize - containerSize)); - - } -}; \ No newline at end of file diff --git a/src/core/structure/heap.js b/src/core/structure/heap.js deleted file mode 100644 index b9ac4f890..000000000 --- a/src/core/structure/heap.js +++ /dev/null @@ -1,115 +0,0 @@ - -(function () { - function defaultComparator (a, b) { - return a < b; - } - - BI.Heap = function (items, comparator) { - this._items = items || []; - this._size = this._items.length; - this._comparator = comparator || defaultComparator; - this._heapify(); - }; - - BI.Heap.prototype = { - constructor: BI.Heap, - empty: function () { - return this._size === 0; - }, - - pop: function () { - if (this._size === 0) { - return; - } - - var elt = this._items[0]; - - var lastElt = this._items.pop(); - this._size--; - - if (this._size > 0) { - this._items[0] = lastElt; - this._sinkDown(0); - } - - return elt; - }, - - push: function (item) { - this._items[this._size++] = item; - this._bubbleUp(this._size - 1); - }, - - size: function () { - return this._size; - }, - - peek: function () { - if (this._size === 0) { - return; - } - - return this._items[0]; - }, - - _heapify: function () { - for (var index = Math.floor((this._size + 1) / 2); index >= 0; index--) { - this._sinkDown(index); - } - }, - - _bubbleUp: function (index) { - var elt = this._items[index]; - while (index > 0) { - var parentIndex = Math.floor((index + 1) / 2) - 1; - var parentElt = this._items[parentIndex]; - - // if parentElt < elt, stop - if (this._comparator(parentElt, elt)) { - return; - } - - // swap - this._items[parentIndex] = elt; - this._items[index] = parentElt; - index = parentIndex; - } - }, - - _sinkDown: function (index) { - var elt = this._items[index]; - - while (true) { - var leftChildIndex = 2 * (index + 1) - 1; - var rightChildIndex = 2 * (index + 1); - var swapIndex = -1; - - if (leftChildIndex < this._size) { - var leftChild = this._items[leftChildIndex]; - if (this._comparator(leftChild, elt)) { - swapIndex = leftChildIndex; - } - } - - if (rightChildIndex < this._size) { - var rightChild = this._items[rightChildIndex]; - if (this._comparator(rightChild, elt)) { - if (swapIndex === -1 || - this._comparator(rightChild, this._items[swapIndex])) { - swapIndex = rightChildIndex; - } - } - } - - // if we don't have a swap, stop - if (swapIndex === -1) { - return; - } - - this._items[index] = this._items[swapIndex]; - this._items[swapIndex] = elt; - index = swapIndex; - } - } - }; -})(); diff --git a/src/core/structure/linkedHashMap.js b/src/core/structure/linkedHashMap.js deleted file mode 100644 index e9328e591..000000000 --- a/src/core/structure/linkedHashMap.js +++ /dev/null @@ -1,72 +0,0 @@ - -!(function () { - BI.LinkHashMap = function () { - this.array = []; - this.map = {}; - }; - BI.LinkHashMap.prototype = { - constructor: BI.LinkHashMap, - has: function (key) { - if (key in this.map) { - return true; - } - return false; - }, - - add: function (key, value) { - if (typeof key === "undefined") { - return; - } - if (key in this.map) { - this.map[key] = value; - } else { - this.array.push(key); - this.map[key] = value; - } - }, - - remove: function (key) { - if (key in this.map) { - delete this.map[key]; - for (var i = 0; i < this.array.length; i++) { - if (this.array[i] == key) { - this.array.splice(i, 1); - break; - } - } - } - }, - - size: function () { - return this.array.length; - }, - - each: function (fn, scope) { - var scope = scope || window; - var fn = fn || null; - if (fn == null || typeof (fn) !== "function") { - return; - } - for (var i = 0; i < this.array.length; i++) { - var key = this.array[i]; - var value = this.map[key]; - var re = fn.call(scope, key, value, i, this.array, this.map); - if (re == false) { - break; - } - } - }, - - get: function (key) { - return this.map[key]; - }, - - toArray: function () { - var array = []; - this.each(function (key, value) { - array.push(value); - }); - return array; - } - }; -})(); \ No newline at end of file diff --git a/src/core/structure/lru.js b/src/core/structure/lru.js deleted file mode 100644 index 5243d75ca..000000000 --- a/src/core/structure/lru.js +++ /dev/null @@ -1,86 +0,0 @@ - -!(function () { - BI.LRU = function (limit) { - this.size = 0; - this.limit = limit; - this.head = this.tail = undefined; - this._keymap = {}; - }; - - var p = BI.LRU.prototype; - - p.put = function (key, value) { - var removed; - if (this.size === this.limit) { - removed = this.shift(); - } - - var entry = this.get(key, true); - if (!entry) { - entry = { - key: key - }; - this._keymap[key] = entry; - if (this.tail) { - this.tail.newer = entry; - entry.older = this.tail; - } else { - this.head = entry; - } - this.tail = entry; - this.size++; - } - entry.value = value; - - return removed; - }; - - p.shift = function () { - var entry = this.head; - if (entry) { - this.head = this.head.newer; - this.head.older = undefined; - entry.newer = entry.older = undefined; - this._keymap[entry.key] = undefined; - this.size--; - } - return entry; - }; - - - p.get = function (key, returnEntry) { - var entry = this._keymap[key]; - if (entry === undefined) return; - if (entry === this.tail) { - return returnEntry - ? entry - : entry.value; - } - // HEAD--------------TAIL - // <.older .newer> - // <--- add direction -- - // A B C E - if (entry.newer) { - if (entry === this.head) { - this.head = entry.newer; - } - entry.newer.older = entry.older; // C <-- E. - } - if (entry.older) { - entry.older.newer = entry.newer; // C. --> E - } - entry.newer = undefined; // D --x - entry.older = this.tail; // D. --> E - if (this.tail) { - this.tail.newer = entry; // E. <-- D - } - this.tail = entry; - return returnEntry - ? entry - : entry.value; - }; - - p.has = function (key) { - return this._keymap[key] != null; - }; -})(); \ No newline at end of file diff --git a/src/core/structure/prefixIntervalTree.js b/src/core/structure/prefixIntervalTree.js deleted file mode 100644 index 1a180b34d..000000000 --- a/src/core/structure/prefixIntervalTree.js +++ /dev/null @@ -1,180 +0,0 @@ -// 线段树 -(function () { - var parent = function (node) { - return Math.floor(node / 2); - }; - - var Int32Array = _global.Int32Array || function (size) { - var xs = []; - for (var i = size - 1; i >= 0; --i) { - xs[i] = 0; - } - return xs; - }; - - var ceilLog2 = function (x) { - var y = 1; - while (y < x) { - y *= 2; - } - return y; - }; - - BI.PrefixIntervalTree = function (xs) { - this._size = xs.length; - this._half = ceilLog2(this._size); - // _heap是一个_size两倍以上的堆 - this._heap = new Int32Array(2 * this._half); - - var i; - // 初始化 >= _size 的堆空间, 即叶子节点 - for (i = 0; i < this._size; ++i) { - this._heap[this._half + i] = xs[i]; - } - // 初始化 < _size 的堆空间, 即非叶子节点,根节点包含整个区间 - for (i = this._half - 1; i > 0; --i) { - this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1]; - } - }; - - BI.PrefixIntervalTree.prototype = { - constructor: BI.PrefixIntervalTree, - // 往_half之后的空间set值,需要更新其所有祖先节点的值 - set: function (index, value) { - var node = this._half + index; - this._heap[node] = value; - - node = parent(node); - for (; node !== 0; node = parent(node)) { - this._heap[node] = - this._heap[2 * node] + this._heap[2 * node + 1]; - } - }, - - get: function (index) { - var node = this._half + index; - return this._heap[node]; - }, - - getSize: function () { - return this._size; - }, - - /** - * get(0) + get(1) + ... + get(end - 1). - */ - sumUntil: function (end) { - if (end === 0) { - return 0; - } - - var node = this._half + end - 1; - var sum = this._heap[node]; - for (; node !== 1; node = parent(node)) { - if (node % 2 === 1) { - sum += this._heap[node - 1]; - } - } - - return sum; - }, - - /** - * get(0) + get(1) + ... + get(inclusiveEnd). - */ - sumTo: function (inclusiveEnd) { - return this.sumUntil(inclusiveEnd + 1); - }, - - /** - * sum get(begin) + get(begin + 1) + ... + get(end - 1). - */ - sum: function (begin, end) { - return this.sumUntil(end) - this.sumUntil(begin); - }, - - /** - * Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or - * -1 if no such i exists. - */ - greatestLowerBound: function (t) { - if (t < 0) { - return -1; - } - - var node = 1; - if (this._heap[node] <= t) { - return this._size; - } - - while (node < this._half) { - var leftSum = this._heap[2 * node]; - if (t < leftSum) { - node = 2 * node; - } else { - node = 2 * node + 1; - t -= leftSum; - } - } - - return node - this._half; - }, - - /** - * Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or - * -1 if no such i exists. - */ - greatestStrictLowerBound: function (t) { - if (t <= 0) { - return -1; - } - - var node = 1; - if (this._heap[node] < t) { - return this._size; - } - - while (node < this._half) { - var leftSum = this._heap[2 * node]; - if (t <= leftSum) { - node = 2 * node; - } else { - node = 2 * node + 1; - t -= leftSum; - } - } - - return node - this._half; - }, - - /** - * Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or - * size + 1 if no such i exists. - */ - leastUpperBound: function (t) { - return this.greatestStrictLowerBound(t) + 1; - }, - - /** - * Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or - * size + 1 if no such i exists. - */ - leastStrictUpperBound: function (t) { - return this.greatestLowerBound(t) + 1; - } - }; - - BI.PrefixIntervalTree.uniform = function (size, initialValue) { - var xs = []; - for (var i = size - 1; i >= 0; --i) { - xs[i] = initialValue; - } - - return new BI.PrefixIntervalTree(xs); - }; - - BI.PrefixIntervalTree.empty = function (size) { - return BI.PrefixIntervalTree.uniform(size, 0); - }; - -})(); diff --git a/src/core/structure/queue.js b/src/core/structure/queue.js deleted file mode 100644 index 2d8e382e7..000000000 --- a/src/core/structure/queue.js +++ /dev/null @@ -1,89 +0,0 @@ - -!(function () { - BI.Queue = function (capacity) { - this.capacity = capacity; - this.array = []; - }; - BI.Queue.prototype = { - constructor: BI.Queue, - - contains: function (v) { - return BI.contains(this.array, v); - }, - - indexOf: function (v) { - return BI.contains(this.array, v); - }, - - getElementByIndex: function (index) { - return this.array[index]; - }, - - push: function (v) { - this.array.push(v); - if (this.capacity && this.array.length > this.capacity) { - this.array.shift(); - } - }, - - pop: function () { - this.array.pop(); - }, - - shift: function () { - this.array.shift(); - }, - - unshift: function (v) { - this.array.unshift(v); - if (this.capacity && this.array.length > this.capacity) { - this.array.pop(); - } - }, - - remove: function (v) { - BI.remove(this.array, v); - }, - - splice: function () { - this.array.splice.apply(this.array, arguments); - }, - - slice: function () { - this.array.slice.apply(this.array, arguments); - }, - - size: function () { - return this.array.length; - }, - - each: function (fn, scope) { - var scope = scope || window; - var fn = fn || null; - if (fn == null || typeof (fn) !== "function") { - return; - } - for (var i = 0; i < this.array.length; i++) { - var re = fn.call(scope, i, this.array[i], this.array); - if (re == false) { - break; - } - } - }, - - toArray: function () { - return this.array; - }, - - fromArray: function (array) { - var self = this; - BI.each(array, function (i, v) { - self.push(v); - }); - }, - - clear: function () { - this.array.length = 0; - } - }; -})(); \ No newline at end of file diff --git a/src/core/structure/sectionManager.js b/src/core/structure/sectionManager.js deleted file mode 100644 index ee0692072..000000000 --- a/src/core/structure/sectionManager.js +++ /dev/null @@ -1,88 +0,0 @@ -!(function () { - var Section = function (height, width, x, y) { - this.height = height; - this.width = width; - this.x = x; - this.y = y; - - this._indexMap = {}; - this._indices = []; - }; - - Section.prototype = { - constructor: Section, - addCellIndex: function (index) { - if (!this._indexMap[index]) { - this._indexMap[index] = true; - this._indices.push(index); - } - }, - - getCellIndices: function () { - return this._indices; - } - }; - - var SECTION_SIZE = 100; - BI.SectionManager = function (sectionSize) { - this._sectionSize = sectionSize || SECTION_SIZE; - this._cellMetadata = []; - this._sections = {}; - }; - - BI.SectionManager.prototype = { - constructor: BI.SectionManager, - getCellIndices: function (height, width, x, y) { - var indices = {}; - - BI.each(this.getSections(height, width, x, y), function (i, section) { - BI.each(section.getCellIndices(), function (j, index) { - indices[index] = index; - }); - }); - - return BI.map(BI.keys(indices), function (i, index) { - return indices[index]; - }); - }, - - getCellMetadata: function (index) { - return this._cellMetadata[index]; - }, - - getSections: function (height, width, x, y) { - var sectionXStart = Math.floor(x / this._sectionSize); - var sectionXStop = Math.floor((x + width - 1) / this._sectionSize); - var sectionYStart = Math.floor(y / this._sectionSize); - var sectionYStop = Math.floor((y + height - 1) / this._sectionSize); - - var sections = []; - - for (var sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) { - for (var sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) { - var key = sectionX + "." + sectionY; - - if (!this._sections[key]) { - this._sections[key] = new Section(this._sectionSize, this._sectionSize, sectionX * this._sectionSize, sectionY * this._sectionSize); - } - - sections.push(this._sections[key]); - } - } - - return sections; - }, - - getTotalSectionCount: function () { - return BI.size(this._sections); - }, - - registerCell: function (cellMetadatum, index) { - this._cellMetadata[index] = cellMetadatum; - - BI.each(this.getSections(cellMetadatum.height, cellMetadatum.width, cellMetadatum.x, cellMetadatum.y), function (i, section) { - section.addCellIndex(index); - }); - } - }; -})(); \ No newline at end of file diff --git a/src/core/structure/tree.js b/src/core/structure/tree.js deleted file mode 100644 index 62f0e1d71..000000000 --- a/src/core/structure/tree.js +++ /dev/null @@ -1,520 +0,0 @@ -(function () { - BI.Tree = function () { - this.root = new BI.Node(BI.UUID()); - }; - - BI.Tree.prototype = { - constructor: BI.Tree, - addNode: function (node, newNode, index) { - if (BI.isNull(newNode)) { - this.root.addChild(node, index); - } else if (BI.isNull(node)) { - this.root.addChild(newNode, index); - } else { - node.addChild(newNode, index); - } - }, - - isRoot: function (node) { - return node === this.root; - }, - - getRoot: function () { - return this.root; - }, - - clear: function () { - this.root.clear(); - }, - - initTree: function (nodes) { - var self = this; - this.clear(); - var queue = new Set(); - - BI.each(nodes, function (i, node) { - var n = new BI.Node(node); - n.set("data", node); - self.addNode(n); - queue.add(n); - }); - - queue.forEach(parent => { - queue.delete(parent); - - var node = parent.get("data"); - BI.each(node.children, function (i, child) { - var n = new BI.Node(child); - n.set("data", child); - queue.add(n); - self.addNode(parent, n); - }); - }); - }, - - _toJSON: function (node) { - var self = this; - var children = []; - BI.each(node.getChildren(), function (i, child) { - children.push(self._toJSON(child)); - }); - return BI.extend({ - id: node.id - }, BI.deepClone(node.get("data")), (children.length > 0 ? { - children: children - } : {})); - }, - - toJSON: function (node) { - var self = this, result = []; - BI.each((node || this.root).getChildren(), function (i, child) { - result.push(self._toJSON(child)); - }); - return result; - }, - - _toJSONWithNode: function (node) { - var self = this; - var children = []; - BI.each(node.getChildren(), function (i, child) { - children.push(self._toJSONWithNode(child)); - }); - return BI.extend({ - id: node.id - }, BI.deepClone(node.get("data")), { - node: node - }, (children.length > 0 ? { - children: children - } : {})); - }, - - toJSONWithNode: function (node) { - var self = this, result = []; - BI.each((node || this.root).getChildren(), function (i, child) { - result.push(self._toJSONWithNode(child)); - }); - return result; - }, - - search: function (root, target, param) { - if (!(root instanceof BI.Node)) { - return arguments.callee.apply(this, [this.root, root, target]); - } - var self = this, next = null; - - if (BI.isNull(target)) { - return null; - } - if (BI.isEqual(root[param || "id"], target)) { - return root; - } - BI.any(root.getChildren(), function (i, child) { - next = self.search(child, target, param); - if (null !== next) { - return true; - } - }); - return next; - }, - - _traverse: function (node, callback) { - var queue = []; - queue.push(node); - while (!BI.isEmpty(queue)) { - var temp = queue.shift(); - var b = callback && callback(temp); - if (b === false) { - break; - } - if (b === true) { - continue; - } - if (temp != null) { - queue.push(...temp.getChildren()); - } - } - }, - - traverse: function (callback) { - this._traverse(this.root, callback); - }, - - _recursion: function (node, route, callback) { - var self = this; - return BI.every(node.getChildren(), function (i, child) { - var next = BI.clone(route); - next.push(child.id); - var b = callback && callback(child, next); - if (b === false) { - return false; - } - if (b === true) { - return true; - } - return self._recursion(child, next, callback); - }); - }, - - recursion: function (callback) { - this._recursion(this.root, [], callback); - }, - - inOrderTraverse: function (callback) { - this._inOrderTraverse(this.root, callback); - }, - - // 中序遍历(递归) - _inOrderTraverse: function (node, callback) { - if (node != null) { - this._inOrderTraverse(node.getLeft()); - callback && callback(node); - this._inOrderTraverse(node.getRight()); - } - }, - - // 中序遍历(非递归) - nrInOrderTraverse: function (callback) { - - var stack = []; - var node = this.root; - while (node != null || !BI.isEmpty(stack)) { - while (node != null) { - stack.push(node); - node = node.getLeft(); - } - node = stack.pop(); - callback && callback(node); - node = node.getRight(); - } - }, - - preOrderTraverse: function (callback) { - this._preOrderTraverse(this.root, callback); - }, - - // 先序遍历(递归) - _preOrderTraverse: function (node, callback) { - if (node != null) { - callback && callback(node); - this._preOrderTraverse(node.getLeft()); - this._preOrderTraverse(node.getRight()); - } - }, - - // 先序遍历(非递归) - nrPreOrderTraverse: function (callback) { - - var stack = []; - var node = this.root; - - while (node != null || !BI.isEmpty(stack)) { - - while (node != null) { - callback && callback(node); - stack.push(node); - node = node.getLeft(); - } - node = stack.pop(); - node = node.getRight(); - } - }, - - postOrderTraverse: function (callback) { - this._postOrderTraverse(this.root, callback); - }, - - // 后序遍历(递归) - _postOrderTraverse: function (node, callback) { - if (node != null) { - this._postOrderTraverse(node.getLeft()); - this._postOrderTraverse(node.getRight()); - callback && callback(node); - } - }, - - // 后续遍历(非递归) - nrPostOrderTraverse: function (callback) { - - var stack = []; - var node = this.root; - var preNode = null;// 表示最近一次访问的节点 - - while (node != null || !BI.isEmpty(stack)) { - - while (node != null) { - stack.push(node); - node = node.getLeft(); - } - - node = BI.last(stack); - - if (node.getRight() == null || node.getRight() == preNode) { - callback && callback(node); - node = stack.pop(); - preNode = node; - node = null; - } else { - node = node.getRight(); - } - } - } - }; - - BI.Node = function (id) { - if (BI.isObject(id)) { - BI.extend(this, id); - } else { - this.id = id; - } - this.clear.apply(this, arguments); - }; - - BI.Node.prototype = { - constructor: BI.Node, - - set: function (key, value) { - if (BI.isObject(key)) { - BI.extend(this, key); - return; - } - this[key] = value; - }, - - get: function (key) { - return this[key]; - }, - - isLeaf: function () { - return BI.isEmpty(this.children); - }, - - getChildren: function () { - return this.children; - }, - - getChildrenLength: function () { - return this.children.length; - }, - - getFirstChild: function () { - return BI.first(this.children); - }, - - getLastChild: function () { - return BI.last(this.children); - }, - - setLeft: function (left) { - this.left = left; - }, - - getLeft: function () { - return this.left; - }, - - setRight: function (right) { - this.right = right; - }, - - getRight: function () { - return this.right; - }, - - setParent: function (parent) { - this.parent = parent; - }, - - getParent: function () { - return this.parent; - }, - - getChild: function (index) { - return this.children[index]; - }, - - getChildIndex: function (id) { - return BI.findIndex(this.children, function (i, ch) { - return ch.get("id") === id; - }); - }, - - removeChild: function (id) { - this.removeChildByIndex(this.getChildIndex(id)); - }, - - removeChildByIndex: function (index) { - var before = this.getChild(index - 1); - var behind = this.getChild(index + 1); - if (before != null) { - before.setRight(behind || null); - } - if (behind != null) { - behind.setLeft(before || null); - } - this.children.splice(index, 1); - }, - - removeAllChilds: function () { - this.children = []; - }, - - addChild: function (child, index) { - var cur = null; - if (BI.isUndefined(index)) { - cur = this.children.length - 1; - } else { - cur = index - 1; - } - child.setParent(this); - if (cur >= 0) { - this.getChild(cur) && this.getChild(cur).setRight(child); - child.setLeft(this.getChild(cur)); - } - if (BI.isUndefined(index)) { - this.children.push(child); - } else { - this.children.splice(index, 0, child); - } - }, - - equals: function (obj) { - return this === obj || this.id === obj.id; - }, - - clear: function () { - this.parent = null; - this.left = null; - this.right = null; - this.children = []; - } - }; - - BI.extend(BI.Tree, { - transformToArrayFormat: function (nodes, pId, childKey) { - if (!nodes) return []; - var r = []; - childKey = childKey || "children"; - if (BI.isArray(nodes)) { - for (var i = 0, l = nodes.length; i < l; i++) { - var node = BI.clone(nodes[i]); - node.pId = node.pId == null ? pId : node.pId; - delete node.children; - r.push(node); - if (nodes[i][childKey]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes[i][childKey], node.id)); - } - } - } else { - var newNodes = BI.clone(nodes); - newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; - delete newNodes.children; - r.push(newNodes); - if (nodes[childKey]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes[childKey], newNodes.id)); - } - } - return r; - }, - - arrayFormat: function (nodes, pId) { - if (!nodes) { - return []; - } - var r = []; - if (BI.isArray(nodes)) { - for (var i = 0, l = nodes.length; i < l; i++) { - var node = nodes[i]; - node.pId = node.pId == null ? pId : node.pId; - r.push(node); - if (nodes[i]["children"]) { - r = r.concat(BI.Tree.arrayFormat(nodes[i]["children"], node.id)); - } - } - } else { - var newNodes = nodes; - newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; - r.push(newNodes); - if (nodes["children"]) { - r = r.concat(BI.Tree.arrayFormat(nodes["children"], newNodes.id)); - } - } - return r; - }, - - transformToTreeFormat: function (sNodes) { - var i, l; - if (!sNodes) { - return []; - } - - if (BI.isArray(sNodes)) { - var r = []; - var tmpMap = {}; - for (i = 0, l = sNodes.length; i < l; i++) { - if (BI.isNull(sNodes[i].id)) { - return sNodes; - } - tmpMap[sNodes[i].id] = BI.clone(sNodes[i]); - } - for (i = 0, l = sNodes.length; i < l; i++) { - if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { - if (!tmpMap[sNodes[i].pId].children) { - tmpMap[sNodes[i].pId].children = []; - } - tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); - } else { - r.push(tmpMap[sNodes[i].id]); - } - delete tmpMap[sNodes[i].id].pId; - } - return r; - } - return [sNodes]; - - }, - - treeFormat: function (sNodes) { - var i, l; - if (!sNodes) { - return []; - } - - if (BI.isArray(sNodes)) { - var r = []; - var tmpMap = {}; - for (i = 0, l = sNodes.length; i < l; i++) { - if (BI.isNull(sNodes[i].id)) { - return sNodes; - } - tmpMap[sNodes[i].id] = sNodes[i]; - } - for (i = 0, l = sNodes.length; i < l; i++) { - if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { - if (!tmpMap[sNodes[i].pId].children) { - tmpMap[sNodes[i].pId].children = []; - } - tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); - } else { - r.push(tmpMap[sNodes[i].id]); - } - } - return r; - } - return [sNodes]; - - }, - - traversal: function (array, callback, pNode) { - if (BI.isNull(array)) { - return; - } - var self = this; - BI.some(array, function (i, item) { - if (callback(i, item, pNode) === false) { - return true; - } - self.traversal(item.children, callback, item); - }); - } - }); -})(); diff --git a/src/core/structure/vector.js b/src/core/structure/vector.js deleted file mode 100644 index d7ec50e9b..000000000 --- a/src/core/structure/vector.js +++ /dev/null @@ -1,63 +0,0 @@ -// 向量操作 -BI.Vector = function (x, y) { - this.x = x; - this.y = y; -}; -BI.Vector.prototype = { - constructor: BI.Vector, - cross: function (v) { - return (this.x * v.y - this.y * v.x); - }, - length: function (v) { - return (Math.sqrt(this.x * v.x + this.y * v.y)); - } -}; -BI.Region = function (x, y, w, h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; -}; -BI.Region.prototype = { - constructor: BI.Region, - // 判断两个区域是否相交,若相交,则要么顶点互相包含,要么矩形边界(或对角线)相交 - isIntersects: function (obj) { - if (this.isPointInside(obj.x, obj.y) || - this.isPointInside(obj.x + obj.w, obj.y) || - this.isPointInside(obj.x, obj.y + obj.h) || - this.isPointInside(obj.x + obj.w, obj.y + obj.h)) { - return true; - } else if (obj.isPointInside(this.x, this.y) || - obj.isPointInside(this.x + this.w, this.y) || - obj.isPointInside(this.x, this.y + this.h) || - obj.isPointInside(this.x + this.w, this.y + this.h)) { - return true; - } else if (obj.x != null && obj.y != null)// 判断矩形对角线相交 |v1 X v2||v1 X v3| < 0 - { - var vector1 = new BI.Vector(this.w, this.h);// 矩形对角线向量 - var vector2 = new BI.Vector(obj.x - this.x, obj.y - this.y); - var vector3 = new BI.Vector(vector2.x + obj.w, vector2.y + obj.h); - if ((vector1.cross(vector2) * vector1.cross(vector3)) < 0) { - return true; - } - } - return false; - }, - // 判断一个点是否在这个区域内部 - isPointInside: function (x, y) { - if (this.x == null || this.y == null) { - return false; - } - if (x >= this.x && x <= this.x + this.w && y >= this.y && y <= this.y + this.h) { - return true; - } - return false; - }, - // 返回区域的重心,因为是矩形所以返回中点 - getPosition: function () { - var pos = []; - pos.push(this.x + this.w / 2); - pos.push(this.y + this.h / 2); - return pos; - } -}; \ No newline at end of file diff --git a/src/core/system.js b/src/core/system.js deleted file mode 100644 index 545057e49..000000000 --- a/src/core/system.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/6/30 - */ -// 系统参数常量 -!(function () { - var system = { - dependencies: {}, - layoutOptimize: false, - responsiveMode: false, - workerMode: false, - size: { - // 尺寸 - // 通用尺寸 - TOOL_BAR_HEIGHT: 24, - LIST_ITEM_HEIGHT: 24, - TRIGGER_HEIGHT: 24, - TOAST_TOP: 10, - H_GAP_SIZE: "M", - V_GAP_SIZE: "S" - }, - loadingCreator: function(config) { - var loadingSize = (config ? config.loadingSize : "small") || "small"; - - var isIE = BI.isIE(); - - function getSize(v) { - return Math.ceil(v / (loadingSize === "small" ? 2 : 1)); - } - - return { - type: "bi.horizontal", - cls: "bi-loading-widget" + (isIE ? " wave-loading hack" : ""), - height: getSize(60), - width: getSize(60), - hgap: getSize(10), - vgap: 2.5, - items: isIE ? [] : [{ - type: "bi.layout", - cls: "animate-rect rect1", - height: getSize(50), - width: getSize(5) - }, { - type: "bi.layout", - cls: "animate-rect rect2", - height: getSize(50), - width: getSize(5) - }, { - type: "bi.layout", - cls: "animate-rect rect3", - height: getSize(50), - width: getSize(5) - }] - }; - } - }; - - // 具体尺寸还没定,先写着 - var sizeMap = { - "S": 10, - "M": 20, - "L": 24 - }; - - function provider () { - this.SYSTEM = system; - - this.setSize = function (opt) { - BI.deepExtend(system, { size: opt }); - }; - - this.setResponsiveMode = function (mode) { - system.responsiveMode = !!mode; - }; - - this.setWorkerMode = function (mode) { - system.workerMode = !!mode; - }; - - this.setLayoutOptimize = function (layoutOptimize) { - system.layoutOptimize = layoutOptimize; - }; - - this.addDependency = function (moduleId, minVersion, maxVersion) { - system.dependencies[moduleId] = { - min: minVersion, - max: maxVersion - }; - }; - - this.addDependencies = function (moduleConfig) { - BI.extend(system.dependencies, moduleConfig); - }; - - this.setLoadingCreator = function(creator) { - system.loadingCreator = creator; - }; - - this.$get = function () { - return BI.inherit(BI.OB, { - - getSize: function () { - var size = system.size; - var H_GAP_SIZE = sizeMap[size.H_GAP_SIZE]; - var V_GAP_SIZE = sizeMap[size.V_GAP_SIZE]; - - return BI.extend({}, size, { - H_GAP_SIZE: H_GAP_SIZE, - V_GAP_SIZE: V_GAP_SIZE - }); - }, - - getResponsiveMode: function () { - return system.responsiveMode; - }, - - getWorkerMode: function () { - return system.workerMode; - }, - - getLayoutOptimize: function () { - return system.layoutOptimize; - }, - - getDependencies: function () { - return system.dependencies; - }, - - getLoading: function(config) { - return system.loadingCreator(config); - } - }); - }; - } - - BI.provider("bi.provider.system", provider); -}()); - -BI.prepares.push(function () { - BI.SIZE_CONSANTS = BI.Providers.getProvider("bi.provider.system").getSize(); - // 不再增加线型的配置了,之后不维护前置版本直接删掉,都用实线连接线 - BI.STYLE_CONSTANTS = {}; - BI.STYLE_CONSTANTS.LINK_LINE_TYPE = BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT === 24 ? "dashed" : "solid"; -}); diff --git a/src/core/utils/chinesePY.js b/src/core/utils/chinesePY.js deleted file mode 100644 index 392f108b4..000000000 --- a/src/core/utils/chinesePY.js +++ /dev/null @@ -1,444 +0,0 @@ -/** - * 汉字拼音索引 - */ - -!(function () { - var _ChineseFirstPY = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSCYYYNJQYXXGJHHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPCBZJJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZZXNBGNNXBXLZSZSBSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZXYALMELDCCXGZYRJXSDLTYZCQKCNNJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXPJBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQTGLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCSKDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMBDTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCSHZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZASYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNCLLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXHLGTGXBQJDZPYJSJYJCTMRNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJFFFFJCZFMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXKLQSCGJCLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZMLJLLJKYWXMKJLHSKJGBMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJGBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLLSDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJXXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYLJSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXPXJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYLYMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWGYJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPPBFYHZHTJYFDZWKGKZBLDNTSXHQEEGZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBMLSFBHHGYGYYGGBHSCYAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZYGPZSZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMCHKDSCRSWJPWXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCKZXSHMLQXXTTHXWZFKHCCZDYTCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHPYYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTXJCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGGTGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZWGPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWFZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDGCYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGAFFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTLFYQKASDNTCYHBLWDZHBBYDWJRYGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSLCMBJCSZZKYDCZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZSYMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZBYJTZBXHFDXKDASWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZEMMQBSQEHXFZMBMFLZZSRXYMJGSXWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNYNPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMCPJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYXYWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXYYRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZYJZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMTCJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYSXQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDHZGZDWYBSSCSKXSYHYTXXGCQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJYZWZXZDDXJSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWXLYDHLYQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAWHZMLJTWYGXLYQZLJEEYYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZSZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQYTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZQJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYWYWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSBDSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZGMDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQCFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMTYBBCLBJASKYTSSQYYMSZXFJEWLXLLSZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBSDZZTFDMXHCNJZYMQWSRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZXJTCZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHXNWXXKHKFHTSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHHCJYXGLHZXCSNHEKDTGZXQYPKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKTLXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWSZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSLFYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCPMMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQQPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQJSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZKKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQHHHEYTMHLFSBDJSYYSHFYSTCZQLPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBBZPNPPTYZZYBQNYDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJLJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNNWZXQXCDSLQGDSDPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAXYWQCJTLLCKJJTJHGDXDXYQYZZBYWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZKSSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQGYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJXLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJYEMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLLHYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGDXJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXMSZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYSPYMPQZMLPPLFFXJJNZZYLSJEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZSXYFYMNCWDABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYSPMJKHWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCTZQXKYQFPYYRPFFLKQUNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJSWLJMYMMZYHFBJDGYXCCPSHXNZCSBSJYJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLHPFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZBLCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZDQQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYGBDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPHZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZSKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPBYKXRYLYBHKJKSFXTZJMMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRTQZSSTKXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZMMNYTPZSXQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNYXHSZXCGJZYQPYLFHDJSBPCCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZLYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZCQQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXYGYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDESJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLBDJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMHQNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJMQPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXSRGJCWTJTZZQMGWJJTJHTQJBBHWZPXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMBZZLYGHGFMSHPZFZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQPWQLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYHDHRJZSFGXTSYCZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYKQSYSLZDQJMPXYYSSRHZJNYWTQDFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQQQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYSYXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYFJHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYPJYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJSXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWTYYDCHQLXKPZWBGQYBKFCMZWPZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYLMSTDJCYHBZLLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLTYXHQLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJCFPQRYQXCYYYQYGRPYWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXNSQYXMQYWRGYQLXBBZLJSYLPSYTJZYHYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXLYYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCRYLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDPBCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCDJJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZGMYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYSLBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYMCCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXXTXXNBHRMLYJSLTXMRHNLXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYXLSZQYXBEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXDRMJWRHXCJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZDJGTKHSSTCYJLPSWZLXZXRWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZBLZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNTYJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSDCHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLYCYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYMDJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGWHKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLLMQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZMDPJHGCLGMJJPGAEHHBWCQXAXHHHZCHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZQYXXDXXPFDMMSSYMPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPPMHNLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPMLKJXMHLMLQMXCTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNPPLPLPEPSZALLTYLKCKQZKGENQLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYDWQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDFXQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXLDDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZLLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQHZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHTXSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTCTSSYLLGZRZBBQZZKLPKLCZYSSUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYSJYCZTLQZYBBYBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJQJPDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRFKZTJDHCZKLBSDZCFJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXPZXHYZYCLWDXJJHXMFDZPFZHQHQMQGKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDLXBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZLSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHLXZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFLCJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZKJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFSZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZXZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJHZYJFJXRZSDLLLTQSQQZQWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXYWGSYJYZNBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJHZCXZBTYNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJKRDHHGXJLJJTGXJXXSTJTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFXGFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRLFSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLYZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFXPYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXDYLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQYCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDUTJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJFZYNAKRGYWYQPQXXFKJTSZZXSWZDDFBBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJKYHCPSTMCSQTZJYXTPCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJPXGLBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZZGJZZXTZJXYCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCYSCCLDXYCDDQLYJJWMQLLCSGLJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZMYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBGMYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCYXZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJYHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBXGLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJDQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQDSPDJZZGHGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXXNCWCXYPMAELYKKJMZZZBRXYYQJFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCXTLWDQZPCYCYKPPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXMBDZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLYXWJHSNLXYYXHBHAWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXXLYLLJDZBTYMHPFSTTQQWLHOKYBLZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHLJKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZKBXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHGZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFYWLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZWFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGCULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJLLQZYJSWXMZZMMYLMXCLMXCZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLLLPYPSYJYSXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZYPFDWFGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYDTZJYQGGKQTTFZXBDKTYYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJDSZBLPRZTSWSBXBCLLXXLZDJZSJPYLYXXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGYGMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCYZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZYXXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZLJJXLSBHPYXXPSXSHHEZTXFPTLQYZZXHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWDXZSXZDZXLEYJJZQBHZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJHOJYNXELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYDMPXMDSXYBSQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPGNYDMSXHMMMMAMYNBYJTMPXYYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXMJSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZBYZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQSQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQQJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZKZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMTJQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLCTZSXKJZQZPZLBZRBTJDCXFCZDBCCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYCZGJWYXDXFRSKSTQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZFYBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCPZBLLCYBBBBUBBCBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSSTPHNDJXXBYXQTZQDDTJTDYYTGWSCSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZAZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYYLLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJXGNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYMRBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMSLPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZXJCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXTQCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLFNDXQKCZFYWHGQMRDSXYCYTXNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZCZPTQFZMYFLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZTLMLWZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZJYJGMCTXLTGXSZLMLHBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQMSTPXLSKLZYNWRTSQLSZBPSPSGZWYHTLKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCLXXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQJZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKNXJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGYZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQGBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZLPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZNCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPCQDHLXZLYCBLCXZZJADJLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQKTWPXXHCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBBFJLLCXDLMJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPSSYYFNEJDXYZHLXLLLZQZSJNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYADTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDDWRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZPKJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSHCKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQHYWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHHJTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQBSHYLLPJJJTHYJKYPPTHYYKTYEZYENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFSYZYZBJTBCTSBSDHRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZNSDJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQPQJPZYPZJZNJPZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQCZLPTXCDYYZXSQZSLXLZMYCPCQBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJQQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZTDKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBRFERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDDNXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXCYZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSDDTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZSQYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZHLYQQJBEYFXXXWHSRXWQHWPSLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELGLXYDJYTLFBHBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYFLZBYFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJTJTPWJYBJJBXJJTJTEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHYYXWSHCTXRLJHQXHCCYYYJLTKTTYTMXGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYLBLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZGLHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJLJXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQQMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQDCYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTTSSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHWWKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWPYMLGKDLDLGKQQBGYCHJXY"; - - // 此处收录了375个多音字,数据来自于http://www.51windows.net/pages/pinyin.asp - var oMultiDiff = { - 19969: "DZ", - 19975: "WM", - 19988: "QJ", - 20048: "YL", - 20056: "SC", - 20060: "NM", - 20094: "QG", - 20127: "QJ", - 20167: "QC", - 20193: "YG", - 20250: "KH", - 20256: "ZC", - 20282: "SC", - 20285: "QJG", - 20291: "TD", - 20314: "YD", - 20315: "BF", - 20340: "NE", - 20375: "TD", - 20389: "YJ", - 20391: "CZ", - 20415: "PB", - 20446: "YS", - 20447: "SQ", - 20504: "TC", - 20608: "KG", - 20854: "QJ", - 20857: "ZC", - 20911: "PF", - 20985: "AW", - 21032: "PB", - 21048: "XQ", - 21049: "SC", - 21089: "YS", - 21119: "JC", - 21242: "SB", - 21273: "SC", - 21305: "YP", - 21306: "QO", - 21330: "ZC", - 21333: "SDC", - 21345: "QK", - 21378: "CA", - 21397: "SC", - 21414: "XS", - 21442: "SC", - 21477: "JG", - 21480: "TD", - 21484: "ZS", - 21494: "YX", - 21505: "YX", - 21512: "HG", - 21523: "XH", - 21537: "PB", - 21542: "PF", - 21549: "KH", - 21571: "E", - 21574: "DA", - 21588: "TD", - 21589: "O", - 21618: "ZC", - 21621: "KHA", - 21632: "ZJ", - 21654: "KG", - 21679: "LKG", - 21683: "KH", - 21710: "A", - 21719: "YH", - 21734: "WOE", - 21769: "A", - 21780: "WN", - 21804: "XH", - 21834: "A", - 21899: "ZD", - 21903: "RN", - 21908: "WO", - 21939: "ZC", - 21956: "SA", - 21964: "YA", - 21970: "TD", - 22003: "A", - 22031: "JG", - 22040: "XS", - 22060: "ZC", - 22066: "ZC", - 22079: "MH", - 22129: "XJ", - 22179: "XA", - 22237: "NJ", - 22244: "TD", - 22280: "JQ", - 22300: "YH", - 22313: "XW", - 22331: "YQ", - 22343: "YJ", - 22351: "PH", - 22395: "DC", - 22412: "TD", - 22484: "PB", - 22500: "PB", - 22534: "ZD", - 22549: "DH", - 22561: "PB", - 22612: "TD", - 22771: "KQ", - 22831: "HB", - 22841: "JG", - 22855: "QJ", - 22865: "XQ", - 23013: "ML", - 23081: "WM", - 23487: "SX", - 23558: "QJ", - 23561: "YW", - 23586: "YW", - 23614: "YW", - 23615: "SN", - 23631: "PB", - 23646: "ZS", - 23663: "ZT", - 23673: "YG", - 23762: "TD", - 23769: "ZS", - 23780: "QJ", - 23884: "QK", - 24055: "XH", - 24113: "DC", - 24162: "ZC", - 24191: "GA", - 24273: "QJ", - 24324: "NL", - 24377: "TD", - 24378: "QJ", - 24439: "PF", - 24554: "ZS", - 24683: "TD", - 24694: "WE", - 24733: "LK", - 24925: "TN", - 25094: "ZG", - 25100: "XQ", - 25103: "XH", - 25153: "PB", - 25170: "PB", - 25179: "KG", - 25203: "PB", - 25240: "ZS", - 25282: "FB", - 25303: "NA", - 25324: "KG", - 25341: "ZY", - 25373: "WZ", - 25375: "XJ", - 25384: "A", - 25457: "A", - 25528: "SD", - 25530: "SC", - 25552: "TD", - 25774: "ZC", - 25874: "ZC", - 26044: "YW", - 26080: "WM", - 26292: "PB", - 26333: "PB", - 26355: "ZY", - 26366: "CZ", - 26397: "ZC", - 26399: "QJ", - 26415: "ZS", - 26451: "SB", - 26526: "ZC", - 26552: "JG", - 26561: "TD", - 26588: "JG", - 26597: "CZ", - 26629: "ZS", - 26638: "YL", - 26646: "XQ", - 26653: "KG", - 26657: "XJ", - 26727: "HG", - 26894: "ZC", - 26937: "ZS", - 26946: "ZC", - 26999: "KJ", - 27099: "KJ", - 27449: "YQ", - 27481: "XS", - 27542: "ZS", - 27663: "ZS", - 27748: "TS", - 27784: "SC", - 27788: "ZD", - 27795: "TD", - 27812: "O", - 27850: "PB", - 27852: "MB", - 27895: "SL", - 27898: "PL", - 27973: "QJ", - 27981: "KH", - 27986: "HX", - 27994: "XJ", - 28044: "YC", - 28065: "WG", - 28177: "SM", - 28267: "QJ", - 28291: "KH", - 28337: "ZQ", - 28463: "TL", - 28548: "DC", - 28601: "TD", - 28689: "PB", - 28805: "JG", - 28820: "QG", - 28846: "PB", - 28952: "TD", - 28975: "ZC", - 29100: "A", - 29325: "QJ", - 29575: "SL", - 29602: "FB", - 30010: "TD", - 30044: "CX", - 30058: "PF", - 30091: "YSP", - 30111: "YN", - 30229: "XJ", - 30427: "SC", - 30465: "SX", - 30631: "YQ", - 30655: "QJ", - 30684: "QJG", - 30707: "SD", - 30729: "XH", - 30796: "LG", - 30917: "PB", - 31074: "NM", - 31085: "JZ", - 31109: "SC", - 31181: "ZC", - 31192: "MLB", - 31293: "JQ", - 31400: "YX", - 31584: "YJ", - 31896: "ZN", - 31909: "ZY", - 31995: "XJ", - 32321: "PF", - 32327: "ZY", - 32418: "HG", - 32420: "XQ", - 32421: "HG", - 32438: "LG", - 32473: "GJ", - 32488: "TD", - 32521: "QJ", - 32527: "PB", - 32562: "ZSQ", - 32564: "JZ", - 32735: "ZD", - 32793: "PB", - 33071: "PF", - 33098: "XL", - 33100: "YA", - 33152: "PB", - 33261: "CX", - 33324: "BP", - 33333: "TD", - 33406: "YA", - 33426: "WM", - 33432: "PB", - 33445: "JG", - 33486: "ZN", - 33493: "TS", - 33507: "QJ", - 33540: "QJ", - 33544: "ZC", - 33564: "XQ", - 33617: "YT", - 33632: "QJ", - 33636: "XH", - 33637: "YX", - 33694: "WG", - 33705: "PF", - 33728: "YW", - 33882: "SR", - 34067: "WM", - 34074: "YW", - 34121: "QJ", - 34255: "ZC", - 34259: "XL", - 34425: "JH", - 34430: "XH", - 34485: "KH", - 34503: "YS", - 34532: "HG", - 34552: "XS", - 34558: "YE", - 34593: "ZL", - 34660: "YQ", - 34892: "XH", - 34928: "SC", - 34999: "QJ", - 35048: "PB", - 35059: "SC", - 35098: "ZC", - 35203: "TQ", - 35265: "JX", - 35299: "JX", - 35782: "SZ", - 35828: "YS", - 35830: "E", - 35843: "TD", - 35895: "YG", - 35977: "MH", - 36158: "JG", - 36228: "QJ", - 36426: "XQ", - 36466: "DC", - 36710: "CJ", - 36711: "ZYG", - 36767: "PB", - 36866: "SK", - 36951: "YW", - 37034: "YX", - 37063: "XH", - 37218: "ZC", - 37325: "ZC", - 38063: "PB", - 38079: "TD", - 38085: "QY", - 38107: "DC", - 38116: "TD", - 38123: "YD", - 38224: "HG", - 38241: "XTC", - 38271: "ZC", - 38415: "YE", - 38426: "KH", - 38461: "YD", - 38463: "AE", - 38466: "PB", - 38477: "XJ", - 38518: "YT", - 38551: "WK", - 38585: "ZC", - 38704: "XS", - 38739: "LJ", - 38761: "GJ", - 38808: "SQ", - 39048: "JG", - 39049: "XJ", - 39052: "HG", - 39076: "CZ", - 39271: "XT", - 39534: "TD", - 39552: "TD", - 39584: "PB", - 39647: "SB", - 39730: "LG", - 39748: "TPB", - 40109: "ZQ", - 40479: "ND", - 40516: "HG", - 40536: "HG", - 40583: "QJ", - 40765: "YQ", - 40784: "QJ", - 40840: "YK", - 40863: "QJG" - }; - - var _checkPYCh = function (ch) { - var uni = ch.charCodeAt(0); - // 如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数 - if (uni > 40869 || uni < 19968) {return ch;} // dealWithOthers(ch); - return (oMultiDiff[uni] ? oMultiDiff[uni] : (_ChineseFirstPY.charAt(uni - 19968))); - }; - - var _mkPYRslt = function (arr, options) { - var ignoreMulti = options.ignoreMulti; - var splitChar = options.splitChar; - var arrRslt = [""], k, multiLen = 0; - for (var i = 0, len = arr.length; i < len; i++) { - var str = arr[i]; - var strlen = str.length; - // 多音字过多的情况下,指数增长会造成浏览器卡死,超过20完全卡死,18勉强能用,考虑到不同性能最好是16或者14 - // 超过14个多音字之后,后面的都用第一个拼音 - if (strlen == 1 || multiLen > 14 || ignoreMulti) { - var tmpStr = str.substring(0, 1); - for (k = 0; k < arrRslt.length; k++) { - arrRslt[k] += tmpStr; - } - } else { - var tmpArr = arrRslt.slice(0); - arrRslt = []; - multiLen ++; - for (k = 0; k < strlen; k++) { - // 复制一个相同的arrRslt - var tmp = tmpArr.slice(0); - // 把当前字符str[k]添加到每个元素末尾 - for (var j = 0; j < tmp.length; j++) { - tmp[j] += str.charAt(k); - } - // 把复制并修改后的数组连接到arrRslt上 - arrRslt = arrRslt.concat(tmp); - } - } - } - // BI-56386 这边直接将所有多音字组合拼接是有风险的,因为丢失了每一组的起始索引信息, 外部使用indexOf等方法会造成错位 - // 一旦错位就可能认为不符合条件, 但实际上还是有可能符合条件的,故此处以一个无法搜索的不可见字符作为连接 - return arrRslt.join(splitChar || "").toLowerCase(); - }; - - BI._.extend(BI, { - makeFirstPY: function (str, options) { - options = options || {}; - // BI-119441 长字段搜索分叉后数量达百万级,这里控制下字段过长的话不进行多音字分叉 - if (str.length > 100 && BI.isNull(options.ignoreMulti)) { - options.ignoreMulti = true; - } - if (typeof (str) !== "string") {return "" + str;} - var arrResult = []; // 保存中间结果的数组 - for (var i = 0, len = str.length; i < len; i++) { - // 获得unicode码 - var ch = str.charAt(i); - // 检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理 - arrResult.push(_checkPYCh(ch)); - } - // 处理arrResult,返回所有可能的拼音首字母串数组 - return _mkPYRslt(arrResult, options); - } - }); -})(); \ No newline at end of file diff --git a/src/core/utils/color.js b/src/core/utils/color.js deleted file mode 100644 index 1c14c3739..000000000 --- a/src/core/utils/color.js +++ /dev/null @@ -1,190 +0,0 @@ -BI.DOM = BI.DOM || {}; -BI.extend(BI.DOM, { - isColor: function (color) { - return color && (this.isRGBColor(color) || this.isHexColor(color)); - }, - - isRGBColor: function (color) { - if (!color) { - return false; - } - return color.substr(0, 3) === "rgb"; - }, - - isHexColor: function (color) { - if (!color) { - return false; - } - return color[0] === "#" && color.length === 7; - }, - - isDarkColor: function (hex) { - if (!hex || !this.isHexColor(hex)) { - return false; - } - var rgb = this.rgb2json(this.hex2rgb(hex)); - var grayLevel = Math.round(rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114); - if (grayLevel < 192/** 网上给的是140**/) { - return true; - } - return false; - }, - - // 获取对比颜色 - getContrastColor: function (color) { - if (!color || !this.isColor(color)) { - return ""; - } - if (this.isDarkColor(color)) { - return "#FFFFFF"; - } - return "#3D4D66"; - }, - - rgb2hex: function (rgbColour) { - if (!rgbColour || rgbColour.substr(0, 3) != "rgb") { - return ""; - } - var rgbValues = rgbColour.match(/\d+(\.\d+)?/g); - var red = BI.parseInt(rgbValues[0]); - var green = BI.parseInt(rgbValues[1]); - var blue = BI.parseInt(rgbValues[2]); - - var hexColour = "#" + this.int2hex(red) + this.int2hex(green) + this.int2hex(blue); - - return hexColour; - }, - - _hue2rgb: function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - }, - - hsl2rgb: function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - return [this._hue2rgb(m1, m2, h + 0.33333), - this._hue2rgb(m1, m2, h), - this._hue2rgb(m1, m2, h - 0.33333)]; - }, - - rgb2hsl: function (rgb) { - var min, max, delta, h, s, l; - var r = rgb[0], g = rgb[1], b = rgb[2]; - min = Math.min(r, Math.min(g, b)); - max = Math.max(r, Math.max(g, b)); - delta = max - min; - l = (min + max) / 2; - s = 0; - if (l > 0 && l < 1) { - s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); - } - h = 0; - if (delta > 0) { - if (max == r && max != g) h += (g - b) / delta; - if (max == g && max != b) h += (2 + (b - r) / delta); - if (max == b && max != r) h += (4 + (r - g) / delta); - h /= 6; - } - return [h, s, l]; - }, - - rgb2json: function (rgbColour) { - if (!rgbColour) { - return {}; - } - if (!this.isRGBColor(rgbColour)) { - return {}; - } - var rgbValues = rgbColour.match(/\d+(\.\d+)?/g); - return { - r: BI.parseInt(rgbValues[0]), - g: BI.parseInt(rgbValues[1]), - b: BI.parseInt(rgbValues[2]) - }; - }, - - rgba2json: function (rgbColour) { - if (!rgbColour) { - return {}; - } - var rgbValues = rgbColour.match(/\d+(\.\d+)?/g); - return { - r: BI.parseInt(rgbValues[0]), - g: BI.parseInt(rgbValues[1]), - b: BI.parseInt(rgbValues[2]), - a: BI.parseFloat(rgbValues[3]) - }; - }, - - json2rgb: function (rgb) { - if (!BI.isKey(rgb.r) || !BI.isKey(rgb.g) || !BI.isKey(rgb.b)) { - return ""; - } - return "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")"; - }, - - json2rgba: function (rgba) { - if (!BI.isKey(rgba.r) || !BI.isKey(rgba.g) || !BI.isKey(rgba.b)) { - return ""; - } - return "rgba(" + rgba.r + "," + rgba.g + "," + rgba.b + "," + rgba.a + ")"; - }, - - int2hex: function (strNum) { - var hexdig = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; - - return hexdig[strNum >>> 4] + "" + hexdig[strNum & 15]; - }, - - hex2rgb: function (color) { - if (!color) { - return ""; - } - if (!this.isHexColor(color)) { - return color; - } - var tempValue = "rgb(", colorArray; - - if (color.length === 7) { - colorArray = [BI.parseInt("0x" + color.substring(1, 3)), - BI.parseInt("0x" + color.substring(3, 5)), - BI.parseInt("0x" + color.substring(5, 7))]; - } else if (color.length === 4) { - colorArray = [BI.parseInt("0x" + color.substring(1, 2)), - BI.parseInt("0x" + color.substring(2, 3)), - BI.parseInt("0x" + color.substring(3, 4))]; - } - tempValue += colorArray[0] + ","; - tempValue += colorArray[1] + ","; - tempValue += colorArray[2] + ")"; - - return tempValue; - }, - - rgba2rgb: function (rgbColor, bgColor) { - if (BI.isNull(bgColor)) { - bgColor = 1; - } - if (rgbColor.substr(0, 4) != "rgba") { - return ""; - } - var rgbValues = rgbColor.match(/\d+(\.\d+)?/g); - if (rgbValues.length < 4) { - return ""; - } - var R = BI.parseFloat(rgbValues[0]); - var G = BI.parseFloat(rgbValues[1]); - var B = BI.parseFloat(rgbValues[2]); - var A = BI.parseFloat(rgbValues[3]); - - return "rgb(" + Math.floor(255 * (bgColor * (1 - A)) + R * A) + "," + - Math.floor(255 * (bgColor * (1 - A)) + G * A) + "," + - Math.floor(255 * (bgColor * (1 - A)) + B * A) + ")"; - } -}); diff --git a/src/core/utils/events/eventlistener.js b/src/core/utils/events/eventlistener.js deleted file mode 100644 index 5b8201dca..000000000 --- a/src/core/utils/events/eventlistener.js +++ /dev/null @@ -1,37 +0,0 @@ -BI.EventListener = { - listen: function listen (target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function remove () { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent("on" + eventType, callback); - return { - remove: function remove () { - target.detachEvent("on" + eventType, callback); - } - }; - } - }, - - capture: function capture (target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, true); - return { - remove: function remove () { - target.removeEventListener(eventType, callback, true); - } - }; - } - return { - remove: BI.emptyFn - }; - - }, - - registerDefault: function registerDefault () { - } -}; \ No newline at end of file diff --git a/src/core/utils/events/mousemovetracker.js b/src/core/utils/events/mousemovetracker.js deleted file mode 100644 index 8b8936e76..000000000 --- a/src/core/utils/events/mousemovetracker.js +++ /dev/null @@ -1,107 +0,0 @@ -!(function () { - var cancelAnimationFrame = - _global.cancelAnimationFrame || - _global.webkitCancelAnimationFrame || - _global.mozCancelAnimationFrame || - _global.oCancelAnimationFrame || - _global.msCancelAnimationFrame || - _global.clearTimeout; - - var requestAnimationFrame = _global.requestAnimationFrame || _global.webkitRequestAnimationFrame || _global.mozRequestAnimationFrame || _global.oRequestAnimationFrame || _global.msRequestAnimationFrame || _global.setTimeout; - - - BI.MouseMoveTracker = function (onMove, onMoveEnd, domNode) { - this._isDragging = false; - this._animationFrameID = null; - this._domNode = domNode; - this._onMove = onMove; - this._onMoveEnd = onMoveEnd; - - this._onMouseMove = BI.bind(this._onMouseMove, this); - this._onMouseUp = BI.bind(this._onMouseUp, this); - this._didMouseMove = BI.bind(this._didMouseMove, this); - }; - BI.MouseMoveTracker.prototype = { - constructor: BI.MouseMoveTracker, - captureMouseMoves: function (/* object*/ event) { - if (!this._eventMoveToken && !this._eventUpToken) { - this._eventMoveToken = BI.EventListener.listen( - this._domNode, - "mousemove", - this._onMouseMove - ); - this._eventUpToken = BI.EventListener.listen( - this._domNode, - "mouseup", - this._onMouseUp - ); - } - - if (!this._isDragging) { - this._deltaX = 0; - this._deltaY = 0; - this._isDragging = true; - this._x = event.clientX; - this._y = event.clientY; - } - // event.preventDefault ? event.preventDefault() : (event.returnValue = false); - }, - - releaseMouseMoves: function () { - if (this._eventMoveToken && this._eventUpToken) { - this._eventMoveToken.remove(); - this._eventMoveToken = null; - this._eventUpToken.remove(); - this._eventUpToken = null; - } - - if (this._animationFrameID !== null) { - cancelAnimationFrame(this._animationFrameID); - this._animationFrameID = null; - } - - if (this._isDragging) { - this._isDragging = false; - this._x = null; - this._y = null; - } - }, - - isDragging: function () /* boolean*/ { - return this._isDragging; - }, - - _onMouseMove: function (/* object*/ event) { - var x = event.clientX; - var y = event.clientY; - - this._deltaX += (x - this._x); - this._deltaY += (y - this._y); - - if (this._animationFrameID === null) { - // The mouse may move faster then the animation frame does. - // Use `requestAnimationFrame` to avoid over-updating. - this._animationFrameID = - requestAnimationFrame(() => this._didMouseMove(event)); - } - - this._x = x; - this._y = y; - event.preventDefault ? event.preventDefault() : (event.returnValue = false); - }, - - _didMouseMove: function (event) { - this._animationFrameID = null; - this._onMove(this._deltaX, this._deltaY, event); - this._deltaX = 0; - this._deltaY = 0; - }, - - _onMouseUp: function (event) { - if (this._animationFrameID) { - this._didMouseMove(event); - } - this._onMoveEnd(event); - } - }; -})(); diff --git a/src/core/utils/events/wheelhandler.js b/src/core/utils/events/wheelhandler.js deleted file mode 100644 index 4d3ea6588..000000000 --- a/src/core/utils/events/wheelhandler.js +++ /dev/null @@ -1,149 +0,0 @@ -!(function () { - var PIXEL_STEP = 10; - var LINE_HEIGHT = 40; - var PAGE_HEIGHT = 800; - var requestAnimationFrame = _global.requestAnimationFrame || _global.webkitRequestAnimationFrame || _global.mozRequestAnimationFrame || _global.oRequestAnimationFrame || _global.msRequestAnimationFrame || _global.setTimeout; - - function normalizeWheel (/* object*/event) /* object*/ { - var sX = 0, - sY = 0, - // spinX, spinY - pX = 0, - pY = 0; // pixelX, pixelY - - // Legacy - if ("detail" in event) { - sY = event.detail; - } - if ("wheelDelta" in event) { - sY = -event.wheelDelta / 120; - } - if ("wheelDeltaY" in event) { - sY = -event.wheelDeltaY / 120; - } - if ("wheelDeltaX" in event) { - sX = -event.wheelDeltaX / 120; - } - - // side scrolling on FF with DOMMouseScroll - if ("axis" in event && event.axis === event.HORIZONTAL_AXIS) { - sX = sY; - sY = 0; - } - - pX = sX * PIXEL_STEP; - pY = sY * PIXEL_STEP; - - if ("deltaY" in event) { - pY = event.deltaY; - } - if ("deltaX" in event) { - pX = event.deltaX; - } - - if ((pX || pY) && event.deltaMode) { - if (event.deltaMode === 1) { - // delta in LINE units - pX *= LINE_HEIGHT; - pY *= LINE_HEIGHT; - } else { - // delta in PAGE units - pX *= PAGE_HEIGHT; - pY *= PAGE_HEIGHT; - } - } - - // Fall-back if spin cannot be determined - if (pX && !sX) { - sX = pX < 1 ? -1 : 1; - } - if (pY && !sY) { - sY = pY < 1 ? -1 : 1; - } - - return { - spinX: sX, - spinY: sY, - pixelX: pX, - pixelY: pY - }; - } - - BI.WheelHandler = function (onWheel, handleScrollX, handleScrollY, stopPropagation) { - this._animationFrameID = null; - this._deltaX = 0; - this._deltaY = 0; - this._didWheel = BI.bind(this._didWheel, this); - if (typeof handleScrollX !== "function") { - handleScrollX = handleScrollX ? - function () { - return true; - } : - function () { - return false; - }; - } - - if (typeof handleScrollY !== "function") { - handleScrollY = handleScrollY ? - function () { - return true; - } : - function () { - return false; - }; - } - - if (typeof stopPropagation !== "function") { - stopPropagation = stopPropagation ? - function () { - return true; - } : - function () { - return false; - }; - } - - this._handleScrollX = handleScrollX; - this._handleScrollY = handleScrollY; - this._stopPropagation = stopPropagation; - this._onWheelCallback = onWheel; - this.onWheel = BI.bind(this.onWheel, this); - }; - BI.WheelHandler.prototype = { - constructor: BI.WheelHandler, - onWheel: function (/* object*/ event) { - var normalizedEvent = normalizeWheel(event); - var deltaX = this._deltaX + normalizedEvent.pixelX; - var deltaY = this._deltaY + normalizedEvent.pixelY; - var handleScrollX = this._handleScrollX(deltaX, deltaY); - var handleScrollY = this._handleScrollY(deltaY, deltaX); - if (!handleScrollX && !handleScrollY) { - return; - } - - this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0; - this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0; - event.preventDefault ? event.preventDefault() : (event.returnValue = false); - - var changed; - if (this._deltaX !== 0 || this._deltaY !== 0) { - if (this._stopPropagation()) { - event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true); - } - changed = true; - } - - if (changed === true && this._animationFrameID === null) { - this._animationFrameID = requestAnimationFrame(this._didWheel); - } - }, - - _didWheel: function () { - this._animationFrameID = null; - this._onWheelCallback(this._deltaX, this._deltaY); - this._deltaX = 0; - this._deltaY = 0; - } - }; -})(); \ No newline at end of file diff --git a/src/core/utils/i18n.js b/src/core/utils/i18n.js deleted file mode 100644 index 8611ec0a9..000000000 --- a/src/core/utils/i18n.js +++ /dev/null @@ -1,51 +0,0 @@ -!(function () { - var i18nStore = {}; - - var i18nFormatters = {}; - - BI._.extend(BI, { - changeI18n: function (i18n) { - if (i18n) { - i18nStore = i18n; - } - }, - addI18n: function (i18n) { - BI.extend(i18nStore, i18n); - }, - - i18nText: function (key) { - var localeText = i18nStore[key] || (BI.i18n && BI.i18n[key]) || ""; - if (!localeText) { - localeText = key; - } - var len = arguments.length; - if (len > 1) { - if (localeText.indexOf("{R1") > -1) { - for (var i = 1; i < len; i++) { - var reg = new RegExp(`{R${i},(.*?)}`, "g"); - - var result = reg.exec(localeText); - - if (result) { - var formatName = result[1]; - localeText = BI.replaceAll(localeText, reg, i18nFormatters[formatName](key, arguments[i])); - } else { - localeText = BI.replaceAll(localeText, `{R${i}}`, arguments[i] + ""); - } - } - } else { - var args = Array.prototype.slice.call(arguments); - var count = 1; - return BI.replaceAll(localeText, "\\{\\s*\\}", function () { - return args[count++] + ""; - }); - } - } - return localeText; - }, - - addI18nFormatter: function (formatName, fn) { - i18nFormatters[formatName] = fn; - } - }); -})(); diff --git a/src/core/version.js b/src/core/version.js deleted file mode 100644 index a850da743..000000000 --- a/src/core/version.js +++ /dev/null @@ -1 +0,0 @@ -BI.version = "2.0"; \ No newline at end of file diff --git a/src/core/worker.js b/src/core/worker.js deleted file mode 100644 index d3ba08ee4..000000000 --- a/src/core/worker.js +++ /dev/null @@ -1,51 +0,0 @@ -!(function () { - BI.useInWorker = function () { - function createWatcher (model, keyOrFn, cb, options) { - if (BI.isPlainObject(cb)) { - options = cb; - cb = cb.handler; - } - options = options || {}; - return Fix.watch(model, keyOrFn, cb, BI.extend(options, { - store: model - })); - } - - var models = {}, watches = {}; - addEventListener("message", function (e) { - var data = e.data; - switch (data.eventType) { - case "action": - models[data.name][data.action].apply(models[data.name], data.args); - break; - case "destroy": - BI.each(watches[data.name], function (i, unwatches) { - unwatches = BI.isArray(unwatches) ? unwatches : [unwatches]; - BI.each(unwatches, function (j, unwatch) { - unwatch(); - }); - }); - delete models[data.name]; - delete watches[data.name]; - break; - case "create": - var store = models[data.name] = BI.Models.getModel(data.type, data.options); - watches[data.name] = []; - BI.each(data.watches, function (i, key) { - watches[data.name].push(createWatcher(store.model, key, function (newValue, oldValue) { - postMessage(BI.extend({}, data, { - eventType: "watch", - currentWatchType: key - }, {args: [newValue, oldValue]})); - })); - }); - postMessage(BI.extend({}, data, { - eventType: "create" - }, {msg: store.model})); - break; - default: - break; - } - }, false); - }; -}()); diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js deleted file mode 100644 index d2926385d..000000000 --- a/src/core/wrapper/layout.js +++ /dev/null @@ -1,793 +0,0 @@ -/** - * 布局容器类 - * @class BI.Layout - * @extends BI.Widget - * - * @cfg {JSON} options 配置属性 - * @cfg {Boolean} [options.scrollable=false] 子组件超出容器边界之后是否会出现滚动条 - * @cfg {Boolean} [options.scrollx=false] 子组件超出容器边界之后是否会出现横向滚动条 - * @cfg {Boolean} [options.scrolly=false] 子组件超出容器边界之后是否会出现纵向滚动条 - */ -BI.Layout = BI.inherit(BI.Widget, { - props: function () { - return { - scrollable: null, // true, false, null - scrollx: false, // true, false - scrolly: false, // true, false - items: [], - innerHgap: 0, - innerVgap: 0, - }; - }, - - render: function () { - var self = this, o = this.options; - this._init4Margin(); - this._init4Scroll(); - if (BI.isFunction(o.columnSize)) { - var columnSizeFn = o.columnSize; - o.columnSize = this.__watch(columnSizeFn, function (context, newValue) { - o.columnSize = newValue; - self.resize(); - }); - } - if (BI.isFunction(o.rowSize)) { - var rowSizeFn = o.rowSize; - o.rowSize = this.__watch(rowSizeFn, function (context, newValue) { - o.rowSize = newValue; - self.resize(); - }); - } - }, - - _init4Margin: function () { - if (this.options.top) { - this.element.css("top", BI.pixFormat(this.options.top)); - } - if (this.options.left) { - this.element.css("left", BI.pixFormat(this.options.left)); - } - if (this.options.bottom) { - this.element.css("bottom", BI.pixFormat(this.options.bottom)); - } - if (this.options.right) { - this.element.css("right", BI.pixFormat(this.options.right)); - } - }, - - _init4Scroll: function () { - switch (this.options.scrollable) { - case true: - case "xy": - this.element.css("overflow", "auto"); - return; - case false: - this.element.css("overflow", "hidden"); - return; - case "x": - this.element.css({ - "overflow-x": "auto", - "overflow-y": "hidden" - }); - return; - case "y": - this.element.css({ - "overflow-x": "hidden", - "overflow-y": "auto" - }); - return; - default : - break; - } - if (this.options.scrollx) { - this.element.css({ - "overflow-x": "auto", - "overflow-y": "hidden" - }); - return; - } - if (this.options.scrolly) { - this.element.css({ - "overflow-x": "hidden", - "overflow-y": "auto" - }); - } - }, - - appendFragment: function (frag) { - this.element.append(frag); - }, - - _mountChildren: function () { - var self = this; - var frag = BI.Widget._renderEngine.createFragment(); - var hasChild = false; - for (var key in this._children) { - var child = this._children[key]; - if (child.element !== self.element) { - frag.appendChild(child.element[0]); - hasChild = true; - } - } - if (hasChild === true) { - this.appendFragment(frag); - } - }, - - _getChildName: function (index) { - return "" + index; - }, - - _addElement: function (i, item, context, widget) { - var self = this, w; - if (widget) { - return widget; - } - if (!this.hasWidget(this._getChildName(i))) { - w = BI._lazyCreateWidget(item, context); - w.on(BI.Events.DESTROY, function () { - BI.each(self._children, function (name, child) { - if (child === w) { - delete self._children[name]; - self.removeItemAt(name | 0); - } - }); - }); - this.addWidget(this._getChildName(i), w); - } else { - w = this.getWidgetByName(this._getChildName(i)); - } - return w; - }, - - _newElement: function (i, item, context) { - var self = this; - var w = BI._lazyCreateWidget(item, context); - w.on(BI.Events.DESTROY, function () { - BI.each(self._children, function (name, child) { - if (child === w) { - delete self._children[name]; - self.removeItemAt(name | 0); - } - }); - }); - return this._addElement(i, item, context, w); - }, - - _getOptions: function (item) { - if (item instanceof BI.Widget) { - item = item.options; - } - item = BI.stripEL(item); - if (item instanceof BI.Widget) { - item = item.options; - } - return item; - }, - - _compare: function (item1, item2) { - var self = this; - return eq(item1, item2); - - // 不比较函数 - function eq (a, b, aStack, bStack) { - if (a === b) { - return a !== 0 || 1 / a === 1 / b; - } - if (a == null || b == null) { - return a === b; - } - var className = Object.prototype.toString.call(a); - switch (className) { - case "[object RegExp]": - case "[object String]": - return "" + a === "" + b; - case "[object Number]": - if (+a !== +a) { - return +b !== +b; - } - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case "[object Date]": - case "[object Boolean]": - return +a === +b; - } - - var areArrays = className === "[object Array]"; - if (!areArrays) { - if (BI.isFunction(a) && BI.isFunction(b)) { - return true; - } - a = self._getOptions(a); - b = self._getOptions(b); - } - - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - if (aStack[length] === a) { - return bStack[length] === b; - } - } - - aStack.push(a); - bStack.push(b); - - if (areArrays) { - length = a.length; - if (length !== b.length) { - return false; - } - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) { - return false; - } - } - } else { - var keys = BI._.keys(a), key; - length = keys.length; - if (BI._.keys(b).length !== length) { - return false; - } - while (length--) { - key = keys[length]; - if (!(BI._.has(b, key) && eq(a[key], b[key], aStack, bStack))) { - return false; - } - } - } - aStack.pop(); - bStack.pop(); - return true; - } - }, - - _getWrapper: function () { - return this.element; - }, - - // 不依赖于this.options.items进行更新 - _updateItemAt: function (oldIndex, newIndex, item) { - var del = this._children[this._getChildName(oldIndex)]; - var w = this._newElement(newIndex, item); - // 需要有个地方临时存一下新建的组件,否则如果直接使用newIndex的话,newIndex位置的元素可能会被用到 - this._children[this._getChildName(newIndex) + "-temp"] = w; - var nextSibling = del.element.next(); - if (nextSibling.length > 0) { - BI.Widget._renderEngine.createElement(nextSibling).before(w.element); - } else { - w.element.appendTo(this._getWrapper()); - } - del._destroy(); - w._mount(); - return true; - }, - - _addItemAt: function (index, item) { - for (var i = this.options.items.length; i > index; i--) { - this._children[this._getChildName(i)] = this._children[this._getChildName(i - 1)]; - } - delete this._children[this._getChildName(index)]; - this.options.items.splice(index, 0, item); - }, - - _removeItemAt: function (index) { - for (var i = index; i < this.options.items.length - 1; i++) { - this._children[this._getChildName(i)] = this._children[this._getChildName(i + 1)]; - } - delete this._children[this._getChildName(this.options.items.length - 1)]; - this.options.items.splice(index, 1); - }, - - _clearGap: function (w) { - w.element.css({ - "margin-top": "", - "margin-bottom": "", - "margin-left": "", - "margin-right": "" - }); - }, - - _optimiseGap: function (gap) { - return (gap > 0 && gap < 1) ? (gap * 100).toFixed(1) + "%" : BI.pixFormat(gap); - }, - - _optimiseItemLgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._lgap || 0) + (item.lgap || 0)) : item._lgap) || 0; - } - return (item._lgap || 0) + (item.lgap || 0); - }, - _optimiseItemRgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._rgap || 0) + (item.rgap || 0)) : item._rgap) || 0; - } - return (item._rgap || 0) + (item.rgap || 0); - }, - _optimiseItemTgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._tgap || 0) + (item.tgap || 0)) : item._tgap) || 0; - } - return (item._tgap || 0) + (item.tgap || 0); - }, - _optimiseItemBgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._bgap || 0) + (item.bgap || 0)) : item._bgap) || 0; - } - return (item._bgap || 0) + (item.bgap || 0); - }, - _optimiseItemHgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._hgap || 0) + (item.hgap || 0)) : item._hgap) || 0; - } - return (item._hgap || 0) + (item.hgap || 0); - }, - _optimiseItemVgap: function (item) { - if (BI.Providers.getProvider("bi.provider.system").getLayoutOptimize()) { - return ((!item.type && item.el) ? ((item._vgap || 0) + (item.vgap || 0)) : item._vgap) || 0; - } - return (item._vgap || 0) + (item.vgap || 0); - }, - - _handleGap: function (w, item, hIndex, vIndex) { - var o = this.options; - var innerLgap, innerRgap, innerTgap, innerBgap; - if (BI.isNull(vIndex)) { - innerTgap = innerBgap = o.innerVgap; - innerLgap = hIndex === 0 ? o.innerHgap : 0; - innerRgap = hIndex === o.items.length - 1 ? o.innerHgap : 0; - } else { - innerLgap = innerRgap = o.innerHgap; - innerTgap = vIndex === 0 ? o.innerVgap : 0; - innerBgap = vIndex === o.items.length - 1 ? o.innerVgap : 0; - } - if (o.vgap + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { - var top = ((BI.isNull(vIndex) || vIndex === 0) ? o.vgap : 0) + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-top": this._optimiseGap(top) - }); - } - if (o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { - var left = ((BI.isNull(hIndex) || hIndex === 0) ? o.hgap : 0) + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-left": this._optimiseGap(left) - }); - } - if (o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { - var right = o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-right": this._optimiseGap(right) - }); - } - if (o.vgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { - var bottom = o.vgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-bottom": this._optimiseGap(bottom) - }); - } - }, - - // 横向换纵向 - _handleReverseGap: function (w, item, index) { - var o = this.options; - var innerLgap, innerRgap, innerTgap, innerBgap; - innerLgap = innerRgap = o.innerHgap; - innerTgap = index === 0 ? o.innerVgap : 0; - innerBgap = index === o.items.length - 1 ? o.innerVgap : 0; - if (o.vgap + o.tgap + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { - var top = (index === 0 ? o.vgap : 0) + (index === 0 ? o.tgap : 0) + innerTgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-top": this._optimiseGap(top) - }); - } - if (o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { - var left = o.hgap + o.lgap + innerLgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-left": this._optimiseGap(left) - }); - } - if (o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { - var right = o.hgap + o.rgap + innerRgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-right": this._optimiseGap(right) - }); - } - // 这里的代码是关键 - if (o.vgap + o.hgap + o.bgap + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { - var bottom = (index === o.items.length - 1 ? o.vgap : o.hgap) + (index === o.items.length - 1 ? o.bgap : 0) + innerBgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-bottom": this._optimiseGap(bottom) - }); - } - }, - - /** - * 添加一个子组件到容器中 - * @param {JSON/BI.Widget} item 子组件 - */ - addItem: function (item) { - return this.addItemAt(this.options.items.length, item); - }, - - prependItem: function (item) { - return this.addItemAt(0, item); - }, - - addItemAt: function (index, item) { - if (index < 0 || index > this.options.items.length) { - return; - } - this._addItemAt(index, item); - var w = this._addElement(index, item); - // addItemAt 还是用之前的找上个兄弟节点向后插入的方式 - if (index > 0) { - this._children[this._getChildName(index - 1)].element.after(w.element); - } else { - w.element.prependTo(this._getWrapper()); - } - w._mount(); - return w; - }, - - removeItemAt: function (indexes) { - indexes = BI.isArray(indexes) ? indexes : [indexes]; - var deleted = []; - var newItems = [], newChildren = {}; - for (var i = 0, len = this.options.items.length; i < len; i++) { - var child = this._children[this._getChildName(i)]; - if (BI.contains(indexes, i)) { - child && deleted.push(child); - } else { - newChildren[this._getChildName(newItems.length)] = child; - newItems.push(this.options.items[i]); - } - } - this.options.items = newItems; - this._children = newChildren; - BI.each(deleted, function (i, c) { - c._destroy(); - }); - }, - - shouldUpdateItem: function (index, item) { - var child = this._children[this._getChildName(index)]; - if (!child || !child.shouldUpdate) { - return null; - } - return child.shouldUpdate(this._getOptions(item)); - }, - - addItems: function (items, context) { - var self = this, o = this.options; - var fragment = BI.Widget._renderEngine.createFragment(); - var added = []; - BI.each(items, function (i, item) { - var w = self._addElement(o.items.length, item, context); - self._children[self._getChildName(o.items.length)] = w; - o.items.push(item); - added.push(w); - fragment.appendChild(w.element[0]); - }); - if (this._isMounted) { - this._getWrapper().append(fragment); - BI.each(added, function (i, w) { - w._mount(); - }); - } - }, - - prependItems: function (items, context) { - items = items || []; - var fragment = BI.Widget._renderEngine.createFragment(); - var added = []; - for (var i = items.length - 1; i >= 0; i--) { - this._addItemAt(0, items[i]); - var w = this._addElement(0, items[i], context); - this._children[this._getChildName(0)] = w; - this.options.items.unshift(items[i]); - added.push(w); - fragment.appendChild(w.element[0]); - } - if (this._isMounted) { - this._getWrapper().prepend(fragment); - BI.each(added, function (i, w) { - w._mount(); - }); - } - }, - - getValue: function () { - var self = this, value = [], child; - BI.each(this.options.items, function (i) { - if (child = self._children[self._getChildName(i)]) { - var v = child.getValue(); - v = BI.isArray(v) ? v : [v]; - value = value.concat(v); - } - }); - return value; - }, - - setValue: function (v) { - var self = this, child; - BI.each(this.options.items, function (i) { - if (child = self._children[self._getChildName(i)]) { - child.setValue(v); - } - }); - }, - - setText: function (v) { - var self = this, child; - BI.each(this.options.items, function (i) { - if (child = self._children[self._getChildName(i)]) { - child.setText(v); - } - }); - }, - - patchItem: function (oldVnode, vnode, oldIndex, newIndex) { - var shouldUpdate = this.shouldUpdateItem(oldIndex, vnode); - var child = this._children[this._getChildName(oldIndex)]; - if (shouldUpdate) { - this._children[this._getChildName(newIndex) + "-temp"] = child; - return child._update(this._getOptions(vnode), shouldUpdate); - } - if (shouldUpdate === null && !this._compare(oldVnode, vnode)) { - // if (child.update) { - // return child.update(this._getOptions(vnode)); - // } - return this._updateItemAt(oldIndex, newIndex, vnode); - } - }, - - updateChildren: function (oldCh, newCh, context) { - var self = this; - var oldStartIdx = 0, newStartIdx = 0; - var oldEndIdx = oldCh.length - 1; - var oldStartVnode = oldCh[0]; - var oldEndVnode = oldCh[oldEndIdx]; - var newEndIdx = newCh.length - 1; - var newStartVnode = newCh[0]; - var newEndVnode = newCh[newEndIdx]; - var before; - var updated; - var children = {}; - BI.each(oldCh, function (i, child) { - child = self._getOptions(child); - var key = child.key == null ? i : child.key; - if (BI.isKey(key)) { - children[key] = self._children[self._getChildName(i)]; - } - }); - - while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { - if (BI.isNull(oldStartVnode)) { - oldStartVnode = oldCh[++oldStartIdx]; - } else if (BI.isNull(oldEndVnode)) { - oldEndVnode = oldCh[--oldEndIdx]; - } else if (sameVnode(oldStartVnode, newStartVnode, oldStartIdx, newStartIdx)) { - var willUpdate = this.patchItem(oldStartVnode, newStartVnode, oldStartIdx, newStartIdx); - updated = willUpdate || updated; - children[oldStartVnode.key == null ? oldStartIdx : oldStartVnode.key] = willUpdate ? this._children[this._getChildName(newStartIdx) + "-temp"] : this._children[this._getChildName(oldStartIdx)]; - oldStartVnode = oldCh[++oldStartIdx]; - newStartVnode = newCh[++newStartIdx]; - } else if (sameVnode(oldEndVnode, newEndVnode, oldEndIdx, newEndIdx)) { - var willUpdate = this.patchItem(oldEndVnode, newEndVnode, oldEndIdx, newEndIdx); - updated = willUpdate || updated; - children[oldEndVnode.key == null ? oldEndIdx : oldEndVnode.key] = willUpdate ? this._children[this._getChildName(newEndIdx) + "-temp"] : this._children[this._getChildName(oldEndIdx)]; - oldEndVnode = oldCh[--oldEndIdx]; - newEndVnode = newCh[--newEndIdx]; - } else if (sameVnode(oldStartVnode, newEndVnode)) { - var willUpdate = this.patchItem(oldStartVnode, newEndVnode, oldStartIdx, newStartIdx); - updated = willUpdate || updated; - children[oldStartVnode.key == null ? oldStartIdx : oldStartVnode.key] = willUpdate ? this._children[this._getChildName(newStartIdx) + "-temp"] : this._children[this._getChildName(oldStartIdx)]; - insertBefore(oldStartVnode, oldEndVnode, true); - oldStartVnode = oldCh[++oldStartIdx]; - newEndVnode = newCh[--newEndIdx]; - } else if (sameVnode(oldEndVnode, newStartVnode)) { - var willUpdate = this.patchItem(oldEndVnode, newStartVnode, oldEndIdx, newEndIdx); - updated = willUpdate || updated; - children[oldEndVnode.key == null ? oldEndIdx : oldEndVnode.key] = willUpdate ? this._children[this._getChildName(newEndIdx) + "-temp"] : this._children[this._getChildName(oldEndIdx)]; - insertBefore(oldEndVnode, oldStartVnode); - oldEndVnode = oldCh[--oldEndIdx]; - newStartVnode = newCh[++newStartIdx]; - } else { - var sameOldVnode = findOldVnode(oldCh, newStartVnode, oldStartIdx, oldEndIdx); - if (BI.isNull(sameOldVnode[0])) { // 不存在就把新的放到左边 - var node = addNode(newStartVnode, newStartIdx, context); - insertBefore(node, oldStartVnode); - } else { // 如果新节点在旧节点区间中存在就复用一下 - var sameOldIndex = sameOldVnode[1]; - var willUpdate = self.patchItem(sameOldVnode[0], newStartVnode, sameOldIndex, newStartIdx); - updated = willUpdate || updated; - children[sameOldVnode[0].key == null ? newStartIdx : sameOldVnode[0].key] = willUpdate ? this._children[this._getChildName(newStartIdx) + "-temp"] : self._children[self._getChildName(sameOldIndex)]; - oldCh[sameOldIndex] = undefined; - insertBefore(sameOldVnode[0], oldStartVnode); - } - newStartVnode = newCh[++newStartIdx]; - } - } - if (oldStartIdx > oldEndIdx) { - before = BI.isNull(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1]; - addVnodes(before, newCh, newStartIdx, newEndIdx, context); - } else if (newStartIdx > newEndIdx) { - removeVnodes(oldCh, oldStartIdx, oldEndIdx); - } - - this._children = {}; - BI.each(newCh, function (i, child) { - var node = self._getOptions(child); - var key = node.key == null ? i : node.key; - children[key]._setParent && children[key]._setParent(self); - children[key]._mount(); - self._children[self._getChildName(i)] = children[key]; - }); - - function sameVnode (vnode1, vnode2, oldIndex, newIndex) { - vnode1 = self._getOptions(vnode1); - vnode2 = self._getOptions(vnode2); - if (BI.isKey(vnode1.key)) { - return vnode1.key === vnode2.key; - } - if (oldIndex >= 0) { - return oldIndex === newIndex; - } - } - - function addNode (vnode, index, context) { - var opt = self._getOptions(vnode); - var key = opt.key == null ? index : opt.key; - return children[key] = self._newElement(index, vnode, context); - } - - function addVnodes (before, vnodes, startIdx, endIdx, context) { - for (; startIdx <= endIdx; ++startIdx) { - var node = addNode(vnodes[startIdx], startIdx, context); - insertBefore(node, before, false, startIdx); - } - } - - function removeVnodes (vnodes, startIdx, endIdx) { - for (; startIdx <= endIdx; ++startIdx) { - var ch = vnodes[startIdx]; - if (BI.isNotNull(ch)) { - var node = self._getOptions(ch); - var key = node.key == null ? startIdx : node.key; - children[key]._destroy(); - } - } - } - - function insertBefore (insert, before, isNext, index) { - insert = self._getOptions(insert); - before = before && self._getOptions(before); - var insertKey = BI.isKey(insert.key) ? insert.key : index; - if (before && children[before.key]) { - var beforeKey = BI.isKey(before.key) ? before.key : index; - var next; - if (isNext) { - next = children[beforeKey].element.next(); - } else { - next = children[beforeKey].element; - } - if (next.length > 0) { - next.before(children[insertKey].element); - } else { - self._getWrapper().append(children[insertKey].element); - } - } else { - self._getWrapper().append(children[insertKey].element); - } - } - - function findOldVnode (vnodes, vNode, beginIdx, endIdx) { - var i, found, findIndex; - for (i = beginIdx; i <= endIdx; ++i) { - if (vnodes[i] && sameVnode(vnodes[i], vNode)) { - found = vnodes[i]; - findIndex = i; - } - } - return [found, findIndex]; - } - - return updated; - }, - - forceUpdate: function (opt) { - if (this._isMounted) { - BI.each(this._children, function (i, c) { - c.destroy(); - }); - this._children = {}; - this._isMounted = false; - } - this.options.items = opt.items; - this.stroke(opt.items); - this._mount(); - }, - - update: function (opt) { - var o = this.options; - var items = opt.items || []; - var context = opt.context; - var oldItems = o.items; - this.options.items = items; - return this.updateChildren(oldItems, items, context); - }, - - stroke: function (items, options) { - options = options || {}; - var self = this; - BI.each(items, function (i, item) { - if (item) { - self._addElement(i, item, options.context); - } - }); - }, - - getRowColumnCls: function (rowIndex, colIndex, lastRowIndex, lastColIndex) { - var cls = ""; - if (rowIndex === 0) { - cls += " first-row"; - } else if (rowIndex === lastRowIndex) { - cls += " last-row"; - } - if (colIndex === 0) { - cls += " first-col"; - } else if (colIndex === lastColIndex) { - cls += " last-col"; - } - BI.isOdd(rowIndex + 1) ? (cls += " odd-row") : (cls += " even-row"); - BI.isOdd(colIndex + 1) ? (cls += " odd-col") : (cls += " even-col"); - cls += " center-element"; - - return cls; - }, - - removeWidget: function (nameOrWidget) { - var removeIndex, self = this; - if (BI.isWidget(nameOrWidget)) { - BI.each(this._children, function (name, child) { - if (child === nameOrWidget) { - removeIndex = name; - } - }); - } else { - removeIndex = nameOrWidget; - } - if (removeIndex) { - this._removeItemAt(removeIndex | 0); - } - }, - - empty: function () { - BI.Layout.superclass.empty.apply(this, arguments); - this.options.items = []; - }, - - destroy: function () { - BI.Layout.superclass.destroy.apply(this, arguments); - this.options.items = []; - }, - - populate: function (items, options) { - items = items || []; - options = options || {}; - if (this._isMounted) { - this.update({ - items: items, - context: options.context - }); - return; - } - this.options.items = items; - this.stroke(items, options); - }, - - resize: function () { - this.stroke(this.options.items); - } -}); -BI.shortcut("bi.layout", BI.Layout); diff --git a/src/core/wrapper/layout/adapt/absolute.center.js b/src/core/wrapper/layout/adapt/absolute.center.js deleted file mode 100644 index 14a122f00..000000000 --- a/src/core/wrapper/layout/adapt/absolute.center.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.AbsoluteCenterLayout - * @extends BI.Layout - */ -BI.AbsoluteCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-c-a", - hgap: 0, - lgap: 0, - rgap: 0, - vgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - BI.AbsoluteCenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.AbsoluteCenterLayout.superclass._addElement.apply(this, arguments); - w.element.css({ - position: "absolute", - left: this._optimiseGap(o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item)), - right: this._optimiseGap(o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item)), - top: this._optimiseGap(o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item)), - bottom: this._optimiseGap(o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item)), - margin: "auto" - }); - return w; - }, - - populate: function (items) { - BI.AbsoluteCenterLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.absolute_center_adapt", BI.AbsoluteCenterLayout); diff --git a/src/core/wrapper/layout/adapt/absolute.horizontal.js b/src/core/wrapper/layout/adapt/absolute.horizontal.js deleted file mode 100644 index 81bd4d05c..000000000 --- a/src/core/wrapper/layout/adapt/absolute.horizontal.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.AbsoluteHorizontalLayout - * @extends BI.Layout - */ -BI.AbsoluteHorizontalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteHorizontalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-h-a", - horizontalAlign: BI.HorizontalAlign.Center, - rowSize: [], - hgap: 0, - lgap: 0, - rgap: 0, - vgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - BI.AbsoluteHorizontalLayout.superclass.render.apply(this, arguments); - return { - type: "bi.vtape", - horizontalAlign: o.horizontalAlign, - rowSize: o.rowSize, - items: o.items, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - ref: function (_ref) { - self.layout = _ref; - }, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this, arguments); - } -}); -BI.shortcut("bi.absolute_horizontal_adapt", BI.AbsoluteHorizontalLayout); diff --git a/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js b/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js deleted file mode 100644 index 1df1d5c85..000000000 --- a/src/core/wrapper/layout/adapt/absolute.leftrightvertical.js +++ /dev/null @@ -1,159 +0,0 @@ -BI.AbsoluteLeftRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteLeftRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-lr-v-a", - verticalAlign: BI.VerticalAlign.Middle, - items: {}, - llgap: 0, - lrgap: 0, - lhgap: 0, - ltgap: 0, - lbgap: 0, - lvgap: 0, - rlgap: 0, - rrgap: 0, - rhgap: 0, - rtgap: 0, - rbgap: 0, - rvgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.AbsoluteLeftRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - items: this._formatItems(o.items), - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - _formatItems: function (items) { - var self = this, o = this.options; - var left, right; - if (BI.isArray(items)) { - BI.each(items, function (i, item) { - if (item.left) { - left = item.left; - } - if (item.right) { - right = item.right; - } - }); - } - var leftItems = left || items.left || []; - var rightItems = right || items.right || []; - leftItems = BI.map(leftItems, function (i, item) { - var json = { - el: BI.stripEL(item), - width: item.width - }; - if (o.lvgap + o.ltgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) !== 0) { - json.tgap = o.lvgap + o.ltgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item); - } - if (o.lhgap + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item); - } - if (o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - json.rgap = o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item); - } - if (o.lvgap + o.lbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) !== 0) { - json.bgap = o.lvgap + o.lbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item); - } - return json; - }); - rightItems = BI.map(rightItems, function (i, item) { - var json = { - el: BI.stripEL(item), - width: item.width - }; - if (o.rvgap + o.rtgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) !== 0) { - json.tgap = o.rvgap + o.rtgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item); - } - if (o.rhgap + o.rlgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - json.lgap = (i === 0 ? o.rhgap : 0) + o.rlgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item); - } - if (o.rhgap + o.rrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - json.rgap = o.rhgap + o.rrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item); - } - if (o.rvgap + o.rbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) !== 0) { - json.bgap = o.rvgap + o.rbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item); - } - return json; - }); - return leftItems.concat({}, rightItems); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.absolute_left_right_vertical_adapt", BI.AbsoluteLeftRightVerticalAdaptLayout); - -BI.AbsoluteRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-r-v-a", - verticalAlign: BI.VerticalAlign.Middle, - items: [], - lgap: 0, - rgap: 0, - hgap: 0, - tgap: 0, - bgap: 0, - vgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.AbsoluteRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - items: [{}].concat(o.items), - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - resize: function () { - this.layout.stroke([{}].concat(this.options.items)); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate([{}].concat(items)); - } -}); -BI.shortcut("bi.absolute_right_vertical_adapt", BI.AbsoluteRightVerticalAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/absolute.vertical.js b/src/core/wrapper/layout/adapt/absolute.vertical.js deleted file mode 100644 index 94a6e39fe..000000000 --- a/src/core/wrapper/layout/adapt/absolute.vertical.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.AbsoluteVerticalLayout - * @extends BI.Layout - */ -BI.AbsoluteVerticalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteVerticalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-v-a", - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - hgap: 0, - lgap: 0, - rgap: 0, - vgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - BI.AbsoluteVerticalLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - items: o.items, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - ref: function (_ref) { - self.layout = _ref; - }, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this, arguments); - } -}); -BI.shortcut("bi.absolute_vertical_adapt", BI.AbsoluteVerticalLayout); diff --git a/src/core/wrapper/layout/adapt/adapt.center.js b/src/core/wrapper/layout/adapt/adapt.center.js deleted file mode 100644 index fb088c5a9..000000000 --- a/src/core/wrapper/layout/adapt/adapt.center.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 自适应水平和垂直方向都居中容器 - * @class BI.CenterAdaptLayout - * @extends BI.Layout - */ -BI.CenterAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.CenterAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-c-a", - horizontalAlign: BI.HorizontalAlign.Center, - columnSize: [], - scrollx: false, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.CenterAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.horizontal", - verticalAlign: BI.VerticalAlign.Middle, - horizontalAlign: o.horizontalAlign, - columnSize: o.columnSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - items: o.items, - ref: function (_ref) { - self.layout = _ref; - }, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this, arguments); - } -}); -BI.shortcut("bi.center_adapt", BI.CenterAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/adapt.horizontal.js b/src/core/wrapper/layout/adapt/adapt.horizontal.js deleted file mode 100644 index 4d6fbae2a..000000000 --- a/src/core/wrapper/layout/adapt/adapt.horizontal.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * 水平方向居中容器 - * @class BI.HorizontalAdaptLayout - * @extends BI.Layout - */ -BI.HorizontalAdaptLayout = function () { -}; -BI.shortcut("bi.horizontal_adapt", BI.HorizontalAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js b/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js deleted file mode 100644 index 94b533fc3..000000000 --- a/src/core/wrapper/layout/adapt/adapt.leftrightvertical.js +++ /dev/null @@ -1,230 +0,0 @@ -/** - * 左右分离,垂直方向居中容器 - * items:{ - left: [{el:{type:"bi.button"}}], - right:[{el:{type:"bi.button"}}] - } - * @class BI.LeftRightVerticalAdaptLayout - * @extends BI.Layout - */ -BI.LeftRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.LeftRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-lr-v-a", - items: {}, - llgap: 0, - lrgap: 0, - lhgap: 0, - ltgap: 0, - lbgap: 0, - lvgap: 0, - rlgap: 0, - rrgap: 0, - rhgap: 0, - rtgap: 0, - rbgap: 0, - rvgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.LeftRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - var leftRight = this._getLeftRight(o.items); - var layoutArray = []; - if (leftRight.left || "left" in o.items) { - layoutArray.push({ - type: "bi.left", - lgap: o.innerHgap, - vgap: o.innerVgap, - items: [ - { - el: { - type: "bi.vertical_adapt", - ref: function (_ref) { - self.left = _ref; - }, - height: "100%", - items: leftRight.left || o.items.left, - hgap: o.lhgap, - lgap: o.llgap, - rgap: o.lrgap, - tgap: o.ltgap, - bgap: o.lbgap, - vgap: o.lvgap - } - } - ] - }); - } - if (leftRight.right || "right" in o.items) { - layoutArray.push({ - type: "bi.right", - rgap: o.innerHgap, - vgap: o.innerVgap, - items: [ - { - el: { - type: "bi.vertical_adapt", - ref: function (_ref) { - self.right = _ref; - }, - height: "100%", - items: leftRight.right || o.items.right, - hgap: o.rhgap, - lgap: o.rlgap, - rgap: o.rrgap, - tgap: o.rtgap, - bgap: o.rbgap, - vgap: o.rvgap - } - } - ] - }); - } - return layoutArray; - }, - - _getLeftRight: function (items) { - var left, right; - if (BI.isArray(items)) { - BI.each(items, function (i, item) { - if (item.left) { - left = item.left; - } - if (item.right) { - right = item.right; - } - }); - } - return { - left: left, - right: right - }; - }, - - resize: function () { - var leftRight = this._getLeftRight(this.options.items); - this.left.stroke(leftRight.left || this.options.items.left); - this.right.stroke(leftRight.right || this.options.items.right); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - var leftRight = this._getLeftRight(items); - this.left.populate(leftRight.left || items.left); - this.right.populate(leftRight.right || items.right); - } -}); -BI.shortcut("bi.left_right_vertical_adapt", BI.LeftRightVerticalAdaptLayout); - - -BI.LeftVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.LeftRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-l-v-a", - items: [], - columnSize: [], - lgap: 0, - rgap: 0, - hgap: 0, - tgap: 0, - bgap: 0, - vgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.LeftVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.vertical_adapt", - ref: function (_ref) { - self.layout = _ref; - }, - items: o.items, - columnSize: o.columnSize, - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - resize: function () { - this.layout.resize(); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate.apply(this, arguments); - } -}); -BI.shortcut("bi.left_vertical_adapt", BI.LeftVerticalAdaptLayout); - -BI.RightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.RightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-r-v-a", - items: [], - columnSize: [], - lgap: 0, - rgap: 0, - hgap: 0, - tgap: 0, - bgap: 0, - vgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.RightVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.vertical_adapt", - ref: function (_ref) { - self.layout = _ref; - }, - horizontalAlign: BI.HorizontalAlign.Right, - items: o.items, - columnSize: o.columnSize, - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - vgap: o.vgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - resize: function () { - this.layout.resize(); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.right_vertical_adapt", BI.RightVerticalAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/adapt.table.js b/src/core/wrapper/layout/adapt/adapt.table.js deleted file mode 100644 index 5691840af..000000000 --- a/src/core/wrapper/layout/adapt/adapt.table.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 使用display:table和display:table-cell实现的horizontal布局 - * @class BI.TableAdaptLayout - * @extends BI.Layout - */ -BI.TableAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.TableAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-t-a", - columnSize: [], - verticalAlign: BI.VerticalAlign.Top, - horizontalAlign: BI.HorizontalAlign.Left, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.TableAdaptLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.$table = BI.Widget._renderEngine.createElement("
    ").css({ - position: "relative", - display: "table", - width: (o.horizontalAlign === BI.HorizontalAlign.Center || o.horizontalAlign === BI.HorizontalAlign.Stretch || this._hasFill()) ? "100%" : "auto", - height: (o.verticalAlign !== BI.VerticalAlign.Top) ? "100%" : "auto", - "white-space": "nowrap" - }); - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _hasFill: function () { - var o = this.options; - if (o.columnSize.length > 0) { - return o.columnSize.indexOf("fill") >= 0; - } - return BI.some(o.items, function (i, item) { - if (item.width === "fill") { - return true; - } - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var td, width = ""; - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (columnSize > 0) { - width = this._optimiseGap(columnSize + (i === 0 ? o.hgap : 0) + o.hgap + o.lgap + o.rgap); - } - if ((BI.isNull(columnSize) || columnSize === "") && this._hasFill()) { - width = 2; - } - if (!this.hasWidget(this._getChildName(i))) { - var w = BI._lazyCreateWidget(item); - w.element.css({position: "relative", top: "0", left: "0", margin: "0px auto"}); - td = BI._lazyCreateWidget({ - type: "bi.default", - width: width, - items: [w] - }); - this.addWidget(this._getChildName(i), td); - } else { - td = this.getWidgetByName(this._getChildName(i)); - td.element.width(width); - } - if (o.verticalAlign === BI.VerticalAlign.Stretch) { - var top = o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item), - bottom = o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - w.element.css("height", "calc(100% - " + this._optimiseGap(top + bottom) + ")"); - } - // 对于表现为td的元素设置最大宽度,有几点需要注意 - // 1、由于直接对td设置最大宽度是在规范中未定义的, 所以要使用类似td:firstChild来迂回实现 - // 2、不能给多个td设置最大宽度,这样只会平分宽度 - // 3、多百分比宽度就算了 - if (columnSize > 0) { - td.element.css({ - "max-width": width, - "min-width": width - }); - } - if (i === 0) { - td.element.addClass("first-element"); - } - td.element.css({ - position: "relative", - display: "table-cell", - "vertical-align": o.verticalAlign, - height: "100%" - }); - this._handleGap(w, item, i); - return td; - }, - - appendFragment: function (frag) { - this.$table.append(frag); - this.element.append(this.$table); - }, - - populate: function (items) { - BI.TableAdaptLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.table_adapt", BI.TableAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/adapt.vertical.js b/src/core/wrapper/layout/adapt/adapt.vertical.js deleted file mode 100644 index 31c227595..000000000 --- a/src/core/wrapper/layout/adapt/adapt.vertical.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 垂直方向居中容器 - * @class BI.VerticalAdaptLayout - * @extends BI.Layout - */ -BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { - props: { - baseCls: "bi-v-a", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - scrollx: false, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }, - - render: function () { - var self = this, o = this.options; - BI.VerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.horizontal", - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - items: o.items, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - ref: function (_ref) { - self.layout = _ref; - }, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this, arguments); - } -}); -BI.shortcut("bi.vertical_adapt", BI.VerticalAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/auto.horizontal.js b/src/core/wrapper/layout/adapt/auto.horizontal.js deleted file mode 100644 index ed0f5e29c..000000000 --- a/src/core/wrapper/layout/adapt/auto.horizontal.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 水平方向居中自适应容器 - * @class BI.HorizontalAutoLayout - * @extends BI.Layout - */ -BI.HorizontalAutoLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.HorizontalAutoLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-h-o", - hgap: 0, - lgap: 0, - rgap: 0, - vgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - BI.HorizontalAutoLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.HorizontalAutoLayout.superclass._addElement.apply(this, arguments); - w.element.css({ - position: "relative", - margin: "0px auto" - }); - this._handleGap(w, item, null, i); - return w; - }, - - populate: function (items) { - BI.HorizontalAutoLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.horizontal_auto", BI.HorizontalAutoLayout); diff --git a/src/core/wrapper/layout/adapt/inline.center.js b/src/core/wrapper/layout/adapt/inline.center.js deleted file mode 100644 index 5d7d073af..000000000 --- a/src/core/wrapper/layout/adapt/inline.center.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 内联布局 - * @class BI.InlineCenterAdaptLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.InlineCenterAdaptLayout = BI.inherit(BI.Layout, { - - props: function () { - return BI.extend(BI.InlineCenterAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-i-c-a", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.inline", - ref: function (_ref) { - self.layout = _ref; - }, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.inline_center_adapt", BI.InlineCenterAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/inline.horizontal.js b/src/core/wrapper/layout/adapt/inline.horizontal.js deleted file mode 100644 index 09874f1b5..000000000 --- a/src/core/wrapper/layout/adapt/inline.horizontal.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 内联布局 - * @class BI.InlineHorizontalAdaptLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.InlineHorizontalAdaptLayout = BI.inherit(BI.Layout, { - - props: function () { - return BI.extend(BI.InlineHorizontalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-i-h-a", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Top, - columnSize: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.inline", - ref: function (_ref) { - self.layout = _ref; - }, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.inline_horizontal_adapt", BI.InlineHorizontalAdaptLayout); diff --git a/src/core/wrapper/layout/adapt/inline.vertical.js b/src/core/wrapper/layout/adapt/inline.vertical.js deleted file mode 100644 index 09d76592e..000000000 --- a/src/core/wrapper/layout/adapt/inline.vertical.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 内联布局 - * @class BI.InlineVerticalAdaptLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.InlineVerticalAdaptLayout = BI.inherit(BI.Layout, { - - props: function () { - return BI.extend(BI.InlineVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-i-v-a", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.inline", - ref: function (_ref) { - self.layout = _ref; - }, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.inline_vertical_adapt", BI.InlineVerticalAdaptLayout); diff --git a/src/core/wrapper/layout/fill/auto.vtape.js b/src/core/wrapper/layout/fill/auto.vtape.js deleted file mode 100644 index efc784f5d..000000000 --- a/src/core/wrapper/layout/fill/auto.vtape.js +++ /dev/null @@ -1,125 +0,0 @@ -BI.AutoVerticalTapeLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AutoVerticalTapeLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-auto-htape", - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - rowSize: [], - items: [] - }); - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vtape", - ref: function (_ref) { - self.layout = _ref; - }, - items: o.items, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - rowSize: o.rowSize, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - _handleResize: function () { - var self = this, o = this.options; - var items = o.items; - var top = {}, bottom = {}; - top[0] = o.innerVgap; - bottom[items.length - 1] = o.innerVgap; - - BI.any(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.layout.getWidgetByName(self._getChildName(i)); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = item.height; - } - } - if (BI.isNull(top[i])) { - var preRowSize = o.rowSize.length > 0 ? o.rowSize[i - 1] : items[i - 1].height; - if (preRowSize === "") { - preRowSize = self.layout.getWidgetByName(self._getChildName(i - 1)).element.height(); - } - top[i] = top[i - 1] + preRowSize + self._optimiseItemTgap(items[i - 1]) + self._optimiseItemBgap(items[i - 1]) + 2 * self._optimiseItemVgap(items[i - 1]) + o.vgap + o.tgap + o.bgap; - } - w.element.css({ - top: self._optimiseGap(top[i] + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) + o.vgap + o.tgap) - }); - - if (rowSize === "fill") { - return true; - } - }); - BI.backAny(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.layout.getWidgetByName(self._getChildName(i)); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (BI.isNull(bottom[i])) { - var nextRowSize = o.rowSize.length > 0 ? o.rowSize[i + 1] : items[i + 1].height; - if (nextRowSize === "") { - nextRowSize = self.layout.getWidgetByName(self._getChildName(i + 1)).element.height(); - } - bottom[i] = bottom[i + 1] + nextRowSize + self._optimiseItemTgap(items[i + 1]) + self._optimiseItemBgap(items[i + 1]) + 2 * self._optimiseItemVgap(items[i + 1]) + o.vgap + o.tgap + o.bgap; - } - w.element.css({ - bottom: self._optimiseGap(bottom[i] + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) + o.vgap + o.bgap), - }); - - if (rowSize === "fill") { - return true; - } - }); - }, - - mounted: function () { - if (window.ResizeObserver) { - this.resizeObserver = new window.ResizeObserver(this._handleResize.bind(this)); - this.resizeObserver.observe(this.element[0]); - } - if (window.MutationObserver) { - this.mutationObserver = new window.MutationObserver(this._handleResize.bind(this)); - this.mutationObserver.observe(this.element[0], { - attributes: true, - childList: true, - subtree: true - }); - } - this._handleResize(); - }, - - destroyed: function () { - this.resizeObserver && this.resizeObserver.unobserve(this.element[0]); - this.mutationObserver && this.mutationObserver.disconnect(); - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.vtape_auto", BI.AutoVerticalTapeLayout); diff --git a/src/core/wrapper/layout/fill/fill.horizontal.js b/src/core/wrapper/layout/fill/fill.horizontal.js deleted file mode 100644 index 72ce8d393..000000000 --- a/src/core/wrapper/layout/fill/fill.horizontal.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 横向填满布局 - */ -BI.HorizontalFillLayout = function () { -}; -BI.shortcut("bi.horizontal_fill", BI.HorizontalFillLayout); diff --git a/src/core/wrapper/layout/fill/fill.vertical.js b/src/core/wrapper/layout/fill/fill.vertical.js deleted file mode 100644 index 9acd9c307..000000000 --- a/src/core/wrapper/layout/fill/fill.vertical.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 纵向填满布局 - */ -BI.VerticalFillLayout = function () { -}; -BI.shortcut("bi.vertical_fill", BI.VerticalFillLayout); diff --git a/src/core/wrapper/layout/fill/float.fill.horizontal.js b/src/core/wrapper/layout/fill/float.fill.horizontal.js deleted file mode 100644 index a6b4c5be7..000000000 --- a/src/core/wrapper/layout/fill/float.fill.horizontal.js +++ /dev/null @@ -1,144 +0,0 @@ -BI.FloatHorizontalFillLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatHorizontalFillLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-h-float-fill clearfix", - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - columnSize: [], - items: [] - }); - }, - render: function () { - BI.FloatHorizontalFillLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var self = this, o = this.options; - items = BI.compact(items); - var rank = 0; - - function createWidget(i, item, desc) { - if (o.verticalAlign !== BI.VerticalAlign.Stretch) { - var w = BI._lazyCreateWidget({ - type: "bi.vertical_adapt", - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: o.verticalAlign, - columnSize: ["fill"], - items: [item] - }); - } else { - var w = BI._lazyCreateWidget(item); - } - if (o.vgap + o.tgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) !== 0) { - w.element.css({ - "margin-top": self._optimiseGap(o.vgap + o.tgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item)) - }); - } - if (desc) { - if (o.hgap + o.rgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - w.element.css({ - "margin-right": self._optimiseGap((i === o.items.length - 1 ? o.hgap : 0) + o.rgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item)) - }); - } - if (o.hgap + o.lgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - w.element.css({ - "margin-left": self._optimiseGap(o.hgap + o.lgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item)) - }); - } - } else { - if (o.hgap + o.lgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - w.element.css({ - "margin-left": self._optimiseGap((i === 0 ? o.hgap : 0) + o.lgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item)) - }); - } - if (o.hgap + o.rgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - w.element.css({ - "margin-right": self._optimiseGap(o.hgap + o.rgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item)) - }); - } - } - if (o.vgap + o.bgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) !== 0) { - w.element.css({ - "margin-bottom": self._optimiseGap(o.vgap + o.bgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item)) - }); - } - var top = o.vgap + o.tgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item), - bottom = o.vgap + o.bgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item); - if (o.verticalAlign === BI.VerticalAlign.Stretch && BI.isNull(item.height)) { - w.element.css({ - height: "calc(100% - " + self._optimiseGap(top + bottom) + ")" - }); - } - w.element.css({ - position: "relative" - }); - return w; - } - - BI.any(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (columnSize === "fill") { - return true; - } - var w = createWidget(i, item); - self.addWidget(self._getChildName(rank++), w); - w.element.css({ - float: "left" - }); - }); - BI.backAny(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (columnSize === "fill") { - return true; - } - var w = createWidget(i, item, true); - self.addWidget(self._getChildName(rank++), w); - w.element.css({ - float: "right" - }); - }); - BI.each(items, function (i, item) { - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (columnSize === "fill") { - var w = createWidget(i, item); - self.addWidget(self._getChildName(rank++), w); - } - }); - }, - - resize: function () { - // console.log("填充布局不需要resize"); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.FloatHorizontalFillLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.horizontal_float_fill", BI.FloatHorizontalFillLayout); diff --git a/src/core/wrapper/layout/flex/flex.center.js b/src/core/wrapper/layout/flex/flex.center.js deleted file mode 100644 index 8944b3add..000000000 --- a/src/core/wrapper/layout/flex/flex.center.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexCenterLayout - * @extends BI.Layout - */ -BI.FlexCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-c", - verticalAlign: BI.VerticalAlign.Middle, - horizontalAlign: BI.HorizontalAlign.Center, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_horizontal", - ref: function (_ref) { - self.layout = _ref; - }, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - hgap: o.hgap, - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_center_adapt", BI.FlexCenterLayout); diff --git a/src/core/wrapper/layout/flex/flex.horizontal.center.js b/src/core/wrapper/layout/flex/flex.horizontal.center.js deleted file mode 100644 index 220f1f394..000000000 --- a/src/core/wrapper/layout/flex/flex.horizontal.center.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Created by GUY on 2016/12/2. - * - * @class BI.FlexHorizontalCenter - * @extends BI.Layout - */ -BI.FlexHorizontalCenter = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexHorizontalCenter.superclass.props.apply(this, arguments), { - baseCls: "bi-f-h-c", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Top, - rowSize: [], - scrolly: false, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_vertical", - ref: function (_ref) { - self.layout = _ref; - }, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - hgap: o.hgap, - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_horizontal_adapt", BI.FlexHorizontalCenter); -BI.shortcut("bi.flex_horizontal_center_adapt", BI.FlexHorizontalCenter); diff --git a/src/core/wrapper/layout/flex/flex.horizontal.js b/src/core/wrapper/layout/flex/flex.horizontal.js deleted file mode 100644 index 75326335b..000000000 --- a/src/core/wrapper/layout/flex/flex.horizontal.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexHorizontalLayout - * @extends BI.Layout - */ -BI.FlexHorizontalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexHorizontalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-h", - verticalAlign: BI.VerticalAlign.Top, - horizontalAlign: BI.HorizontalAlign.Left, // 如果只有一个子元素且想让该子元素横向撑满,设置成Stretch - columnSize: [], - scrollx: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FlexHorizontalLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.element.addClass("v-" + o.verticalAlign).addClass("h-" + o.horizontalAlign); - if (o.scrollable === true || o.scrollx === true) { - this.element.addClass("f-scroll-x"); - } - if (o.scrollable === true || o.scrolly === true) { - this.element.addClass("f-scroll-y"); - } - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _hasFill: function () { - var o = this.options; - if (o.columnSize.length > 0) { - return o.columnSize.indexOf("fill") >= 0 || o.columnSize.indexOf("auto") >= 0; - } - return BI.some(o.items, function (i, item) { - if (item.width === "fill" || item.width === "auto") { - return true; - } - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FlexHorizontalLayout.superclass._addElement.apply(this, arguments); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = null; - } - } - w.element.css({ - position: "relative" - }); - if (columnSize !== "auto") { - if (columnSize === "fill" || columnSize === "") { - if (o.horizontalAlign !== BI.HorizontalAlign.Stretch) { - if (o.scrollable === true || o.scrollx === true) { - w.element.addClass("f-s-n"); - } - } - // 当既有动态宽度和自适应宽度的时候只压缩自适应 - if (columnSize === "" && this._hasFill()) { - w.element.addClass("f-s-n"); - } - } else { - w.element.addClass("f-s-n"); - } - } - if (columnSize > 0) { - w.element.width(this._optimiseGap(columnSize)); - } - if (columnSize === "fill") { - w.element.addClass("f-f"); - } - if (columnSize === "" || columnSize === "auto") { - w.element.addClass("f-auto"); - } - w.element.addClass("c-e"); - if (i === 0) { - w.element.addClass("f-c"); - } - if (i === o.items.length - 1) { - w.element.addClass("l-c"); - } - this._handleGap(w, item, i); - return w; - }, - - populate: function (items) { - BI.FlexHorizontalLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.flex_horizontal", BI.FlexHorizontalLayout); diff --git a/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js b/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js deleted file mode 100644 index 1fc93a383..000000000 --- a/src/core/wrapper/layout/flex/flex.leftrightvertical.center.js +++ /dev/null @@ -1,104 +0,0 @@ -BI.FlexLeftRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexLeftRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-lr-v-c", - columnSize: [], - items: {}, - llgap: 0, - lrgap: 0, - lhgap: 0, - ltgap: 0, - lbgap: 0, - lvgap: 0, - rlgap: 0, - rrgap: 0, - rhgap: 0, - rtgap: 0, - rbgap: 0, - rvgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.FlexLeftRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - var items = this._formatItems(o.items); - return { - type: "bi.flex_vertical_adapt", - ref: function (_ref) { - self.layout = _ref; - }, - columnSize: o.columnSize.slice(0, (o.items.left || []).length).concat((o.items.right || []).length > 0 ? [""] : []), - items: items, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap - }; - }, - - _formatItems: function (items) { - var self = this, o = this.options; - var left, right; - if (BI.isArray(items)) { - BI.each(items, function (i, item) { - if (item.left) { - left = item.left; - } - if (item.right) { - right = item.right; - } - }); - } - var leftItems = left || items.left || []; - var rightItems = right || items.right || []; - leftItems = BI.map(leftItems, function (i, item) { - var json = { - el: BI.stripEL(item) - }; - if (o.lvgap + o.ltgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) !== 0) { - json.tgap = o.lvgap + o.ltgap + self._optimiseItemTgap(item) + self._optimiseItemVgap(item); - } - if (o.lhgap + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item); - } - if (o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - json.rgap = o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item); - } - if (o.lvgap + o.lbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) !== 0) { - json.bgap = o.lvgap + o.lbgap + self._optimiseItemBgap(item) + self._optimiseItemVgap(item); - } - return json; - }); - return leftItems.concat({ - el: { - type: "bi.flex_vertical_adapt", - columnSize: o.columnSize.slice(leftItems.length), - css: { - "margin-left": "auto" - }, - hgap: o.rhgap, - vgap: o.rvgap, - lgap: o.rlgap, - rgap: o.rrgap, - tgap: o.rtgap, - bgap: o.rbgap, - items: rightItems - } - }); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.flex_left_right_vertical_adapt", BI.FlexLeftRightVerticalAdaptLayout); diff --git a/src/core/wrapper/layout/flex/flex.vertical.center.js b/src/core/wrapper/layout/flex/flex.vertical.center.js deleted file mode 100644 index cf2e55077..000000000 --- a/src/core/wrapper/layout/flex/flex.vertical.center.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexVerticalCenter - * @extends BI.Layout - */ -BI.FlexVerticalCenter = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexVerticalCenter.superclass.props.apply(this, arguments), { - baseCls: "bi-f-v-c", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - scrollx: false, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_horizontal", - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - horizontalAlign: o.horizontalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - hgap: o.hgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_vertical_adapt", BI.FlexVerticalCenter); -BI.shortcut("bi.flex_vertical_center_adapt", BI.FlexVerticalCenter); diff --git a/src/core/wrapper/layout/flex/flex.vertical.js b/src/core/wrapper/layout/flex/flex.vertical.js deleted file mode 100644 index 1c56586cc..000000000 --- a/src/core/wrapper/layout/flex/flex.vertical.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Created by GUY on 2016/12/2. - * - * @class BI.FlexVerticalLayout - * @extends BI.Layout - */ -BI.FlexVerticalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexVerticalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-v", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Top, - rowSize: [], - scrolly: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FlexVerticalLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.element.addClass("h-" + o.horizontalAlign).addClass("v-" + o.verticalAlign); - if (o.scrollable === true || o.scrollx === true) { - this.element.addClass("f-scroll-x"); - } - if (o.scrollable === true || o.scrolly === true) { - this.element.addClass("f-scroll-y"); - } - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _hasFill: function () { - var o = this.options; - if (o.rowSize.length > 0) { - return o.rowSize.indexOf("fill") >= 0 || o.rowSize.indexOf("auto") >= 0; - } - return BI.some(o.items, function (i, item) { - if (item.height === "fill" || item.height === "auto") { - return true; - } - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FlexVerticalLayout.superclass._addElement.apply(this, arguments); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = null; - } - } - w.element.css({ - position: "relative" - }); - if (rowSize !== "auto") { - if (rowSize === "fill" || rowSize === "") { - if (o.verticalAlign !== BI.VerticalAlign.Stretch) { - if (o.scrollable === true || o.scrolly === true) { - w.element.addClass("f-s-n"); - } - } - // 当既有动态宽度和自适应宽度的时候只压缩自适应 - if (rowSize === "" && this._hasFill()) { - w.element.addClass("f-s-n"); - } - } else { - w.element.addClass("f-s-n"); - } - } - if (rowSize > 0) { - w.element.height(this._optimiseGap(rowSize)); - } - if (rowSize === "fill") { - w.element.addClass("f-f"); - } - if (rowSize === "" || rowSize === "auto") { - w.element.addClass("f-auto"); - } - w.element.addClass("c-e"); - if (i === 0) { - w.element.addClass("f-c"); - } - if (i === o.items.length - 1) { - w.element.addClass("l-c"); - } - this._handleGap(w, item, null, i); - return w; - }, - - populate: function (items) { - BI.FlexVerticalLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.flex_vertical", BI.FlexVerticalLayout); diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js deleted file mode 100644 index ee44e9823..000000000 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexWrapperCenterLayout - * @extends BI.Layout - */ -BI.FlexWrapperCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexWrapperCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-s-c", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - scrollx: false, - scrollable: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_scrollable_horizontal", - ref: function (_ref) { - self.layout = _ref; - }, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_scrollable_center_adapt", BI.FlexWrapperCenterLayout); diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js deleted file mode 100644 index 1735c25ff..000000000 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.center.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexVerticalCenter - * @extends BI.Layout - */ -BI.FlexWrapperHorizontalCenter = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexWrapperHorizontalCenter.superclass.props.apply(this, arguments), { - baseCls: "bi-f-s-v-c", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Top, - rowSize: [], - scrollable: true, - scrolly: false, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_scrollable_vertical", - ref: function (_ref) { - self.layout = _ref; - }, - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - hgap: o.hgap, - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_scrollable_horizontal_adapt", BI.FlexWrapperHorizontalCenter); -BI.shortcut("bi.flex_scrollable_horizontal_center_adapt", BI.FlexWrapperHorizontalCenter); diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js deleted file mode 100644 index fa90b0543..000000000 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexHorizontalLayout - * @extends BI.Layout - */ -BI.FlexWrapperHorizontalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexWrapperHorizontalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-s-h", - verticalAlign: BI.VerticalAlign.Top, - horizontalAlign: BI.HorizontalAlign.Left, - columnSize: [], - scrollable: null, - scrollx: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FlexWrapperHorizontalLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.element.addClass("v-" + o.verticalAlign).addClass("h-" + o.horizontalAlign); - this.$wrapper = BI.Widget._renderEngine.createElement("
    ").addClass("f-s-h-w v-" + o.verticalAlign).addClass("h-" + o.horizontalAlign); - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _hasFill: function () { - var o = this.options; - if (o.columnSize.length > 0) { - return o.columnSize.indexOf("fill") >= 0 || o.columnSize.indexOf("auto") >= 0; - } - return BI.some(o.items, function (i, item) { - if (item.width === "fill" || item.width === "auto") { - return true; - } - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FlexWrapperHorizontalLayout.superclass._addElement.apply(this, arguments); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = null; - } - } - w.element.css({ - position: "relative" - }); - if (columnSize !== "auto") { - if (columnSize === "fill" || columnSize === "") { - if (o.horizontalAlign !== BI.HorizontalAlign.Stretch) { - if (o.scrollable === true || o.scrollx === true) { - w.element.addClass("f-s-n"); - } - } - // 当既有动态宽度和自适应宽度的时候只压缩自适应 - if (columnSize === "" && this._hasFill()) { - w.element.addClass("f-s-n"); - } - } else { - w.element.addClass("f-s-n"); - } - } - if (columnSize > 0) { - w.element.width(this._optimiseGap(columnSize)); - } - if (columnSize === "fill") { - w.element.addClass("f-f"); - this.element.addClass("f-f"); - } - if (columnSize === "" || columnSize === "auto") { - w.element.addClass("f-auto"); - this.element.addClass("f-auto"); - } - w.element.addClass("c-e"); - if (i === 0) { - w.element.addClass("f-c"); - } - if (i === o.items.length - 1) { - w.element.addClass("l-c"); - } - this._handleGap(w, item, i); - return w; - }, - - appendFragment: function (frag) { - this.$wrapper.append(frag); - this.element.append(this.$wrapper); - }, - - _getWrapper: function () { - return this.$wrapper; - }, - - populate: function (items) { - BI.FlexWrapperHorizontalLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.flex_scrollable_horizontal", BI.FlexWrapperHorizontalLayout); diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js deleted file mode 100644 index 5b9e7e11d..000000000 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexVerticalCenter - * @extends BI.Layout - */ -BI.FlexWrapperVerticalCenter = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexWrapperVerticalCenter.superclass.props.apply(this, arguments), { - baseCls: "bi-f-s-v-c", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - scrollx: false, - scrollable: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.flex_scrollable_horizontal", - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - horizontalAlign: o.horizontalAlign, - columnSize: o.columnSize, - rowSize: o.rowSize, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - items: o.items - }; - }, - - resize: function () { - this.layout.resize(); - }, - - populate: function (items) { - this.layout.populate(items); - } -}); -BI.shortcut("bi.flex_scrollable_vertical_adapt", BI.FlexWrapperVerticalCenter); -BI.shortcut("bi.flex_scrollable_vertical_center_adapt", BI.FlexWrapperVerticalCenter); diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js deleted file mode 100644 index 76beeb601..000000000 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - *自适应水平和垂直方向都居中容器 - * Created by GUY on 2016/12/2. - * - * @class BI.FlexWrapperVerticalLayout - * @extends BI.Layout - */ -BI.FlexWrapperVerticalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FlexWrapperVerticalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-f-s-v", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Top, - rowSize: [], - scrollable: null, - scrolly: true, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FlexWrapperVerticalLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.element.addClass("v-" + o.verticalAlign).addClass("h-" + o.horizontalAlign); - this.$wrapper = BI.Widget._renderEngine.createElement("
    ").addClass("f-s-v-w h-" + o.horizontalAlign).addClass("v-" + o.verticalAlign); - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _hasFill: function () { - var o = this.options; - if (o.rowSize.length > 0) { - return o.rowSize.indexOf("fill") >= 0 || o.rowSize.indexOf("auto") >= 0; - } - return BI.some(o.items, function (i, item) { - if (item.height === "fill" || item.height === "auto") { - return true; - } - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FlexWrapperVerticalLayout.superclass._addElement.apply(this, arguments); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = null; - } - } - w.element.css({ - position: "relative" - }); - if (rowSize !== "auto") { - if (rowSize === "fill" || rowSize === "") { - if (o.verticalAlign !== BI.VerticalAlign.Stretch) { - if (o.scrollable === true || o.scrolly === true) { - w.element.addClass("f-s-n"); - } - } - // 当既有动态宽度和自适应宽度的时候只压缩自适应 - if (rowSize === "" && this._hasFill()) { - w.element.addClass("f-s-n"); - } - } else { - w.element.addClass("f-s-n"); - } - } - if (rowSize > 0) { - w.element.height(this._optimiseGap(rowSize)); - } - if (rowSize === "fill") { - w.element.addClass("f-f"); - this.element.addClass("f-f"); - } - if (rowSize === "" || rowSize === "auto") { - w.element.addClass("f-auto"); - this.element.addClass("f-auto"); - } - w.element.addClass("c-e"); - if (i === 0) { - w.element.addClass("f-c"); - } - if (i === o.items.length - 1) { - w.element.addClass("l-c"); - } - this._handleGap(w, item, null, i); - return w; - }, - - appendFragment: function (frag) { - this.$wrapper.append(frag); - this.element.append(this.$wrapper); - }, - - _getWrapper: function () { - return this.$wrapper; - }, - - populate: function (items) { - BI.FlexWrapperVerticalLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.flex_scrollable_vertical", BI.FlexWrapperVerticalLayout); diff --git a/src/core/wrapper/layout/float/float.absolute.center.js b/src/core/wrapper/layout/float/float.absolute.center.js deleted file mode 100644 index 08cc5b326..000000000 --- a/src/core/wrapper/layout/float/float.absolute.center.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.FloatAbsoluteCenterLayout - * @extends BI.Layout - */ -BI.FloatAbsoluteCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatAbsoluteCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-c-fl", - }); - }, - - render: function () { - BI.FloatAbsoluteCenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FloatAbsoluteCenterLayout.superclass._addElement.apply(this, arguments); - w.element.addClass("bi-abs-c-item").css({ - position: "absolute", - }); - return w; - }, - - populate: function (items) { - BI.FloatAbsoluteCenterLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.absolute_center_float", BI.FloatAbsoluteCenterLayout); diff --git a/src/core/wrapper/layout/float/float.absolute.horizontal.js b/src/core/wrapper/layout/float/float.absolute.horizontal.js deleted file mode 100644 index b9aae3708..000000000 --- a/src/core/wrapper/layout/float/float.absolute.horizontal.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.FloatAbsoluteHorizontalLayout - * @extends BI.Layout - */ -BI.FloatAbsoluteHorizontalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatAbsoluteHorizontalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-h-fl", - horizontalAlign: BI.HorizontalAlign.Center, - rowSize: [], - vgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - BI.FloatAbsoluteHorizontalLayout.superclass.render.apply(this, arguments); - return { - type: "bi.vtape", - horizontalAlign: o.horizontalAlign, - rowSize: o.rowSize, - items: this._formatItems(o.items), - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - ref: function (_ref) { - self.layout = _ref; - }, - hgap: "50%", - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - // lgap和rgap不传的话内部不会设置left和right - lgap: o.lgap, - rgap: o.rgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - _formatItems: function (items) { - var o = this.options; - if (o.horizontalAlign === BI.HorizontalAlign.Left) { - return items; - } - var cls = o.horizontalAlign === BI.HorizontalAlign.Right ? "bi-abs-r-x-item" : "bi-abs-c-x-item"; - return BI.map(items, function (i, item) { - if (!item || BI.isEmptyObject(item)) { - return item; - } - var el = BI.stripEL(item); - if (BI.isWidget(el)) { - el.element.addClass(cls); - } else { - el.cls = (el.cls || "") + cls; - } - return item; - }); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.absolute_horizontal_float", BI.FloatAbsoluteHorizontalLayout); diff --git a/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js b/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js deleted file mode 100644 index 2539d53c3..000000000 --- a/src/core/wrapper/layout/float/float.absolute.leftrightvertical.js +++ /dev/null @@ -1,189 +0,0 @@ -BI.FloatAbsoluteLeftRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatAbsoluteLeftRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-lr-v-fl", - verticalAlign: BI.VerticalAlign.Middle, - items: {}, - llgap: 0, - lrgap: 0, - lhgap: 0, - ltgap: 0, - lbgap: 0, - lvgap: 0, - rlgap: 0, - rrgap: 0, - rhgap: 0, - rtgap: 0, - rbgap: 0, - rvgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.FloatAbsoluteLeftRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - items: this._formatItems(o.items), - vgap: "50%", - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - _formatItems: function (items) { - var self = this, o = this.options; - var left, right; - if (BI.isArray(items)) { - BI.each(items, function (i, item) { - if (item.left) { - left = item.left; - } - if (item.right) { - right = item.right; - } - }); - } - var leftItems = left || items.left || []; - var rightItems = right || items.right || []; - leftItems = BI.map(leftItems, function (i, item) { - var el = BI.stripEL(item); - if (o.verticalAlign === BI.VerticalAlign.Middle) { - if (BI.isWidget(el)) { - el.element.addClass("bi-abs-c-y-item"); - } else { - el.cls = (el.cls || "") + "bi-abs-c-y-item"; - } - } - var json = { - el: el, - width: item.width - }; - // if (o.lvgap + o.ltgap + (item.tgap || 0) + (item.vgap || 0) !== 0) { - // json.tgap = o.lvgap + o.ltgap + (item.tgap || 0) + (item.vgap || 0); - // } - if (o.lhgap + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - json.lgap = (i === 0 ? o.lhgap : 0) + o.llgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item); - } - if (o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - json.rgap = o.lhgap + o.lrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item); - } - // if (o.lvgap + o.lbgap + (item.bgap || 0) + (item.vgap || 0) !== 0) { - // json.bgap = o.lvgap + o.lbgap + (item.bgap || 0) + (item.vgap || 0); - // } - return json; - }); - rightItems = BI.map(rightItems, function (i, item) { - var el = BI.stripEL(item); - if (o.verticalAlign === BI.VerticalAlign.Middle) { - if (BI.isWidget(el)) { - el.element.addClass("bi-abs-c-y-item"); - } else { - el.cls = (el.cls || "") + "bi-abs-c-y-item"; - } - } - var json = { - el: el, - width: item.width - }; - // if (o.rvgap + o.rtgap + (item.tgap || 0) + (item.vgap || 0) !== 0) { - // json.tgap = o.rvgap + o.rtgap + (item.tgap || 0) + (item.vgap || 0); - // } - if (o.rhgap + o.rlgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) !== 0) { - json.lgap = (i === 0 ? o.rhgap : 0) + o.rlgap + self._optimiseItemLgap(item) + self._optimiseItemHgap(item); - } - if (o.rhgap + o.rrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) !== 0) { - json.rgap = o.rhgap + o.rrgap + self._optimiseItemRgap(item) + self._optimiseItemHgap(item); - } - // if (o.rvgap + o.rbgap + (item.bgap || 0) + (item.vgap || 0) !== 0) { - // json.bgap = o.rvgap + o.rbgap + (item.bgap || 0) + (item.vgap || 0); - // } - return json; - }); - return leftItems.concat({}, rightItems); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.absolute_left_right_vertical_float", BI.FloatAbsoluteLeftRightVerticalAdaptLayout); - -BI.FloatAbsoluteRightVerticalAdaptLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatAbsoluteRightVerticalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-r-v-fl", - verticalAlign: BI.VerticalAlign.Middle, - items: [], - lgap: 0, - rgap: 0, - hgap: 0 - }); - }, - render: function () { - var o = this.options, self = this; - BI.FloatAbsoluteRightVerticalAdaptLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - ref: function (_ref) { - self.layout = _ref; - }, - verticalAlign: o.verticalAlign, - items: [{}].concat(this._formatItems(o.items)), - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - vgap: "50%", - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - _formatItems: function (items) { - if (this.options.verticalAlign !== BI.VerticalAlign.Middle) { - return items; - } - return BI.map(items, function (i, item) { - if (!item || BI.isEmptyObject(item)) { - return item; - } - var el = BI.stripEL(item); - if (BI.isWidget(el)) { - el.element.addClass("bi-abs-c-y-item"); - } else { - el.cls = (el.cls || "") + "bi-abs-c-y-item"; - } - return item; - }); - }, - - resize: function () { - this.layout.stroke([{}].concat(this._formatItems(this.options.items))); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate([{}].concat(this._formatItems(items))); - } -}); -BI.shortcut("bi.absolute_right_vertical_float", BI.FloatAbsoluteRightVerticalAdaptLayout); diff --git a/src/core/wrapper/layout/float/float.absolute.vertical.js b/src/core/wrapper/layout/float/float.absolute.vertical.js deleted file mode 100644 index 01b949b06..000000000 --- a/src/core/wrapper/layout/float/float.absolute.vertical.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * absolute实现的居中布局 - * @class BI.FloatAbsoluteVerticalLayout - * @extends BI.Layout - */ -BI.FloatAbsoluteVerticalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatAbsoluteVerticalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs-h-fl", - verticalAlign: BI.VerticalAlign.Middle, - columnSize: [], - hgap: 0, - lgap: 0, - rgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - BI.FloatAbsoluteVerticalLayout.superclass.render.apply(this, arguments); - return { - type: "bi.htape", - verticalAlign: o.verticalAlign, - columnSize: o.columnSize, - items: this._formatItems(o.items), - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable, - ref: function (_ref) { - self.layout = _ref; - }, - vgap: "50%", - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap, - // tgap和bgap不传的话内部不会设置top和bottom - tgap: o.tgap, - bgap: o.bgap, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - }; - }, - - _formatItems: function (items) { - var o = this.options; - if (o.verticalAlign === BI.VerticalAlign.Top) { - return items; - } - var cls = o.verticalAlign === BI.VerticalAlign.Bottom ? "bi-abs-b-y-item" : "bi-abs-c-y-item"; - return BI.map(items, function (i, item) { - if (!item || BI.isEmptyObject(item)) { - return item; - } - var el = BI.stripEL(item); - if (BI.isWidget(el)) { - el.element.addClass(cls); - } else { - el.cls = (el.cls || "") + cls; - } - return item; - }); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.absolute_vertical_float", BI.FloatAbsoluteVerticalLayout); diff --git a/src/core/wrapper/layout/float/float.horizontal.js b/src/core/wrapper/layout/float/float.horizontal.js deleted file mode 100644 index 97ac66b49..000000000 --- a/src/core/wrapper/layout/float/float.horizontal.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 浮动的水平居中布局 - */ -BI.FloatHorizontalLayout = BI.inherit(BI.Layout, { - - props: function () { - return BI.extend(BI.InlineHorizontalAdaptLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-h-fl", - horizontalAlign: BI.HorizontalAlign.Center, - verticalAlign: BI.VerticalAlign.Top, - rowSize: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - var self = this, o = this.options; - if (o.verticalAlign === BI.VerticalAlign.Top) { - return { - type: "bi.vertical", - ref: function (_ref) { - self.layout = _ref; - }, - items: this._formatItems(o.items), - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - } - return { - type: "bi.inline", - items: [{ - el: { - type: "bi.vertical", - ref: function (_ref) { - self.layout = _ref; - }, - items: this._formatItems(o.items), - vgap: o.vgap, - tgap: o.tgap, - bgap: o.bgap - } - }], - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - innerHgap: o.innerHgap, - innerVgap: o.innerVgap, - scrollx: o.scrollx, - scrolly: o.scrolly, - scrollable: o.scrollable - }; - }, - - _formatItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return { - el: { - type: "bi.inline_horizontal_adapt", - horizontalAlign: o.horizontalAlign, - items: [item], - hgap: o.hgap, - lgap: o.lgap, - rgap: o.rgap - } - }; - }); - }, - - resize: function () { - this.layout.stroke(this._formatItems(this.options.items)); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - } -}); -BI.shortcut("bi.horizontal_float", BI.FloatHorizontalLayout); diff --git a/src/core/wrapper/layout/layout.absolute.js b/src/core/wrapper/layout/layout.absolute.js deleted file mode 100644 index 6333b38a8..000000000 --- a/src/core/wrapper/layout/layout.absolute.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * 固定子组件上下左右的布局容器 - * @class BI.AbsoluteLayout - * @extends BI.Layout - */ -BI.AbsoluteLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AbsoluteLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-abs", - hgap: null, - vgap: null, - lgap: null, - rgap: null, - tgap: null, - bgap: null - }); - }, - render: function () { - BI.AbsoluteLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.AbsoluteLayout.superclass._addElement.apply(this, arguments); - var left = 0, right = 0, top = 0, bottom = 0; - var offsets = BI.pick(item, ["top", "right", "bottom", "left"]); - - if (BI.isKey(item.inset)) { - var insets = BI.map((item.inset + "").split(" "), function (i, str) { - return BI.parseFloat(str); - }); - switch (insets.length) { - case 1: - offsets = {top: insets[0], bottom: insets[0], left: insets[0], right: insets[0]} - break; - case 2: - offsets = {top: insets[0], bottom: insets[0], left: insets[1], right: insets[1]} - break; - case 3: - offsets = {top: insets[0], left: insets[1], right: insets[1], bottom: insets[2]} - break - case 4: - default: - offsets = {top: insets[0], right: insets[1], bottom: insets[2], left: insets[3]} - break; - } - } - if (BI.isNotNull(offsets.left)) { - w.element.css({left: BI.isNumber(offsets.left) ? this._optimiseGap(offsets.left) : offsets.left}); - left += offsets.left; - } - if (BI.isNotNull(offsets.right)) { - w.element.css({right: BI.isNumber(offsets.right) ? this._optimiseGap(offsets.right) : offsets.right}); - right += offsets.right; - } - if (BI.isNotNull(offsets.top)) { - w.element.css({top: BI.isNumber(offsets.top) ? this._optimiseGap(offsets.top) : offsets.top}); - top += offsets.top; - } - if (BI.isNotNull(offsets.bottom)) { - w.element.css({bottom: BI.isNumber(offsets.bottom) ? this._optimiseGap(offsets.bottom) : offsets.bottom}); - bottom += offsets.bottom; - } - - if (BI.isNotNull(o.hgap)) { - left += o.hgap; - w.element.css({left: this._optimiseGap(left)}); - right += o.hgap; - w.element.css({right: this._optimiseGap(right)}); - } - if (BI.isNotNull(o.vgap)) { - top += o.vgap; - w.element.css({top: this._optimiseGap(top)}); - bottom += o.vgap; - w.element.css({bottom: this._optimiseGap(bottom)}); - } - - if (BI.isNotNull(o.lgap)) { - left += o.lgap; - w.element.css({left: this._optimiseGap(left)}); - } - if (BI.isNotNull(o.rgap)) { - right += o.rgap; - w.element.css({right: this._optimiseGap(right)}); - } - if (BI.isNotNull(o.tgap)) { - top += o.tgap; - w.element.css({top: this._optimiseGap(top)}); - } - if (BI.isNotNull(o.bgap)) { - bottom += o.bgap; - w.element.css({bottom: this._optimiseGap(bottom)}); - } - - if (BI.isNotNull(item.width)) { - w.element.css({width: BI.isNumber(item.width) ? this._optimiseGap(item.width) : item.width}); - } - if (BI.isNotNull(item.height)) { - w.element.css({height: BI.isNumber(item.height) ? this._optimiseGap(item.height) : item.height}); - } - w.element.css({position: "absolute"}); - return w; - }, - - populate: function (items) { - BI.AbsoluteLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.absolute", BI.AbsoluteLayout); diff --git a/src/core/wrapper/layout/layout.adaptive.js b/src/core/wrapper/layout/layout.adaptive.js deleted file mode 100644 index 20b758ef4..000000000 --- a/src/core/wrapper/layout/layout.adaptive.js +++ /dev/null @@ -1,63 +0,0 @@ -BI.AdaptiveLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.AdaptiveLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-adaptive", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.AdaptiveLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.AdaptiveLayout.superclass._addElement.apply(this, arguments); - w.element.css({position: "relative"}); - if (BI.isNotNull(item.left)) { - w.element.css({ - left: BI.isNumber(item.left) ? this._optimiseGap(item.left) : item.left - }); - } - if (BI.isNotNull(item.right)) { - w.element.css({ - right: BI.isNumber(item.right) ? this._optimiseGap(item.right) : item.right - }); - } - if (BI.isNotNull(item.top)) { - w.element.css({ - top: BI.isNumber(item.top) ? this._optimiseGap(item.top) : item.top - }); - } - if (BI.isNotNull(item.bottom)) { - w.element.css({ - bottom: BI.isNumber(item.bottom) ? this._optimiseGap(item.bottom) : item.bottom - }); - } - - this._handleGap(w, item); - - if (BI.isNotNull(item.width)) { - w.element.css({width: BI.isNumber(item.width) ? this._optimiseGap(item.width) : item.width}); - } - if (BI.isNotNull(item.height)) { - w.element.css({height: BI.isNumber(item.height) ? this._optimiseGap(item.height) : item.height}); - } - return w; - }, - - populate: function (items) { - BI.AbsoluteLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.adaptive", BI.AdaptiveLayout); diff --git a/src/core/wrapper/layout/layout.border.js b/src/core/wrapper/layout/layout.border.js deleted file mode 100644 index bd133459b..000000000 --- a/src/core/wrapper/layout/layout.border.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - * 上下的高度固定/左右的宽度固定,中间的高度/宽度自适应 - * - * @class BI.BorderLayout - * @extends BI.Layout - */ -BI.BorderLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.BorderLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-border-layout", - items: {} - }); - }, - render: function () { - BI.BorderLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (regions) { - var item; - var top = 0; - var bottom = 0; - var left = 0; - var right = 0; - if ("north" in regions) { - item = regions["north"]; - if (item != null) { - if (item.el) { - if (!this.hasWidget(this._getChildName("north"))) { - var w = BI._lazyCreateWidget(item); - this.addWidget(this._getChildName("north"), w); - } - this.getWidgetByName(this._getChildName("north")).element.height(this._optimiseGap(item.height)) - .css({ - position: "absolute", - top: this._optimiseGap(item.top || 0), - left: this._optimiseGap(item.left || 0), - right: this._optimiseGap(item.right || 0), - bottom: "initial" - }); - } - top = (item.height || 0) + (item.top || 0) + (item.bottom || 0); - } - } - if ("south" in regions) { - item = regions["south"]; - if (item != null) { - if (item.el) { - if (!this.hasWidget(this._getChildName("south"))) { - var w = BI._lazyCreateWidget(item); - this.addWidget(this._getChildName("south"), w); - } - this.getWidgetByName(this._getChildName("south")).element.height(this._optimiseGap(item.height)) - .css({ - position: "absolute", - bottom: this._optimiseGap(item.bottom || 0), - left: this._optimiseGap(item.left || 0), - right: this._optimiseGap(item.right || 0), - top: "initial" - }); - } - bottom = (item.height || 0) + (item.top || 0) + (item.bottom || 0); - } - } - if ("west" in regions) { - item = regions["west"]; - if (item != null) { - if (item.el) { - if (!this.hasWidget(this._getChildName("west"))) { - var w = BI._lazyCreateWidget(item); - this.addWidget(this._getChildName("west"), w); - } - this.getWidgetByName(this._getChildName("west")).element.width(this._optimiseGap(item.width)) - .css({ - position: "absolute", - left: this._optimiseGap(item.left || 0), - top: this._optimiseGap(top), - bottom: this._optimiseGap(bottom), - right: "initial" - }); - } - left = (item.width || 0) + (item.left || 0) + (item.right || 0); - } - } - if ("east" in regions) { - item = regions["east"]; - if (item != null) { - if (item.el) { - if (!this.hasWidget(this._getChildName("east"))) { - var w = BI._lazyCreateWidget(item); - this.addWidget(this._getChildName("east"), w); - } - this.getWidgetByName(this._getChildName("east")).element.width(this._optimiseGap(item.width)) - .css({ - position: "absolute", - right: this._optimiseGap(item.right || 0), - top: this._optimiseGap(top), - bottom: this._optimiseGap(bottom), - left: "initial" - }); - } - right = (item.width || 0) + (item.left || 0) + (item.right || 0); - } - } - if ("center" in regions) { - item = regions["center"]; - if (item != null) { - if (!this.hasWidget(this._getChildName("center"))) { - var w = BI._lazyCreateWidget(item); - this.addWidget(this._getChildName("center"), w); - } - this.getWidgetByName(this._getChildName("center")).element - .css({ - position: "absolute", - top: this._optimiseGap(top), - bottom: this._optimiseGap(bottom), - left: this._optimiseGap(left), - right: this._optimiseGap(right) - }); - } - } - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.BorderLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.border", BI.BorderLayout); diff --git a/src/core/wrapper/layout/layout.card.js b/src/core/wrapper/layout/layout.card.js deleted file mode 100644 index 4209ce375..000000000 --- a/src/core/wrapper/layout/layout.card.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * 卡片布局,可以做到当前只显示一个组件,其他的都隐藏 - * @class BI.CardLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {String} options.defaultShowName 默认展示的子组件名 - */ -BI.CardLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.CardLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-card-layout", - items: [] - }); - }, - - render: function () { - BI.CardLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - stroke: function (items) { - var self = this, o = this.options; - this.showIndex = void 0; - BI.each(items, function (i, item) { - if (item) { - if (!self.hasWidget(item.cardName)) { - var w = BI._lazyCreateWidget(item); - w.on(BI.Events.DESTROY, function () { - var index = BI.findIndex(o.items, function (i, tItem) { - return tItem.cardName == item.cardName; - }); - if (index > -1) { - o.items.splice(index, 1); - } - }); - self.addWidget(self._getChildName(item.cardName), w); - } else { - var w = self.getWidgetByName(self._getChildName(item.cardName)); - } - w.element.css({ - position: "relative", - top: "0", - left: "0", - width: "100%", - height: "100%" - }); - w.setVisible(false); - } - }); - }, - - resize: function () { - // console.log("Card布局不需要resize"); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - empty: function () { - BI.CardLayout.superclass.empty.apply(this, arguments); - this.options.items = []; - }, - - populate: function (items) { - BI.CardLayout.superclass.populate.apply(this, arguments); - this._mount(); - this.options.defaultShowName && this.showCardByName(this.options.defaultShowName); - }, - - isCardExisted: function (cardName) { - return BI.some(this.options.items, function (i, item) { - return item.cardName == cardName && item.el; - }); - }, - - getCardByName: function (cardName) { - if (!this.isCardExisted(cardName)) { - throw new Error("cardName not exist", cardName); - } - return this._children[this._getChildName(cardName)]; - }, - - _deleteCardByName: function (cardName) { - delete this._children[this._getChildName(cardName)]; - var index = BI.findIndex(this.options.items, function (i, item) { - return item.cardName == cardName; - }); - if (index > -1) { - this.options.items.splice(index, 1); - } - }, - - deleteCardByName: function (cardName) { - if (!this.isCardExisted(cardName)) { - throw new Error("cardName not exist", cardName); - } - - var child = this._children[this._getChildName(cardName)]; - this._deleteCardByName(cardName); - child && child._destroy(); - }, - - addCardByName: function (cardName, cardItem) { - if (this.isCardExisted(cardName)) { - throw new Error("cardName already exist", cardName); - } - var widget = BI._lazyCreateWidget(cardItem, this); - widget.element.css({ - position: "relative", - top: "0", - left: "0", - width: "100%", - height: "100%" - }).appendTo(this.element); - widget.invisible(); - this.addWidget(this._getChildName(cardName), widget); - this.options.items.push({ el: cardItem, cardName: cardName }); - return widget; - }, - - showCardByName: function (name, action, callback) { - var self = this; - // name不存在的时候全部隐藏 - var exist = this.isCardExisted(name); - if (this.showIndex != null) { - this.lastShowIndex = this.showIndex; - } - this.showIndex = name; - var flag = false; - BI.each(this.options.items, function (i, item) { - var el = self._children[self._getChildName(item.cardName)]; - if (el) { - if (name != item.cardName) { - // 动画效果只有在全部都隐藏的时候才有意义,且只要执行一次动画操作就够了 - !flag && !exist && (BI.Action && action instanceof BI.Action) ? (action.actionBack(el), flag = true) : el.invisible(); - } else { - (BI.Action && action instanceof BI.Action) ? action.actionPerformed(void 0, el, callback) : (el.visible(), callback && callback()); - } - } - }); - }, - - showLastCard: function () { - var self = this; - this.showIndex = this.lastShowIndex; - BI.each(this.options.items, function (i, item) { - self._children[self._getChildName(item.cardName)].setVisible(self.showIndex == i); - }); - }, - - setDefaultShowName: function (name) { - this.options.defaultShowName = name; - return this; - }, - - getDefaultShowName: function () { - return this.options.defaultShowName; - }, - - getAllCardNames: function () { - return BI.map(this.options.items, function (i, item) { - return item.cardName; - }); - }, - - getShowingCard: function () { - if (!BI.isKey(this.showIndex)) { - return void 0; - } - return this.getWidgetByName(this._getChildName(this.showIndex)); - }, - - deleteAllCard: function () { - var self = this; - BI.each(this.getAllCardNames(), function (i, name) { - self.deleteCardByName(name); - }); - }, - - hideAllCard: function () { - var self = this; - BI.each(this.options.items, function (i, item) { - self._children[self._getChildName(item.cardName)].invisible(); - }); - }, - - isAllCardHide: function () { - var self = this; - var flag = true; - BI.some(this.options.items, function (i, item) { - if (self._children[self._getChildName(item.cardName)].isVisible()) { - flag = false; - return false; - } - }); - return flag; - }, - - removeWidget: function (nameOrWidget) { - var removeName, self = this; - if (BI.isWidget(nameOrWidget)) { - BI.each(this._children, function (name, child) { - if (child === nameOrWidget) { - removeName = name; - } - }); - } else { - removeName = nameOrWidget; - } - if (removeName) { - this._deleteCardByName(removeName); - } - } -}); -BI.shortcut("bi.card", BI.CardLayout); diff --git a/src/core/wrapper/layout/layout.default.js b/src/core/wrapper/layout/layout.default.js deleted file mode 100644 index 90e4bf569..000000000 --- a/src/core/wrapper/layout/layout.default.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 默认的布局方式 - * - * @class BI.DefaultLayout - * @extends BI.Layout - */ -BI.DefaultLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.DefaultLayout.superclass.props.apply(this, arguments), { - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - items: [] - }); - }, - render: function () { - BI.DefaultLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var w = BI.DefaultLayout.superclass._addElement.apply(this, arguments); - this._handleGap(w, item); - return w; - }, - - populate: function (items) { - BI.DefaultLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.default", BI.DefaultLayout); diff --git a/src/core/wrapper/layout/layout.division.js b/src/core/wrapper/layout/layout.division.js deleted file mode 100644 index 65b07e95e..000000000 --- a/src/core/wrapper/layout/layout.division.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 分隔容器的控件,按照宽度和高度所占比平分整个容器 - * - * @class BI.DivisionLayout - * @extends BI.Layout - */ -BI.DivisionLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.DivisionLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-division", - columns: null, - rows: null, - items: [] - }); - }, - render: function () { - BI.DivisionLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var o = this.options, self = this; - var rows = o.rows || o.items.length, columns = o.columns || ((o.items[0] && o.items[0].length) | 0); - var map = BI.makeArray(rows), widths = {}, heights = {}; - - function firstElement(item, cls) { - item.addClass(cls); - - return item; - } - - function firstObject(item, cls) { - item.cls = (item.cls || "") + cls; - - return item; - } - - function first(item, cls) { - if (item instanceof BI.Widget) { - firstElement(item.element, cls); - } else if (item.el instanceof BI.Widget) { - firstElement(item.el.element, cls); - } else if (item.el) { - firstObject(item.el, cls); - } else { - firstObject(item, cls); - } - } - - BI.each(map, function (i) { - map[i] = BI.makeArray(columns); - }); - BI.each(items, function (i, item) { - if (BI.isArray(item)) { - BI.each(item, function (j, el) { - widths[i] = (widths[i] || 0) + item.width; - heights[j] = (heights[j] || 0) + item.height; - map[i][j] = el; - }); - - return; - } - widths[item.row] = (widths[item.row] || 0) + item.width; - heights[item.column] = (heights[item.column] || 0) + item.height; - map[item.row][item.column] = item; - }); - for (var i = 0; i < rows; i++) { - var totalW = 0; - for (var j = 0; j < columns; j++) { - if (!map[i][j]) { - throw new Error("item(" + i + "" + j + ") must exist", map); - } - if (!this.hasWidget(this._getChildName(i + "_" + j))) { - var w = BI._lazyCreateWidget(map[i][j]); - this.addWidget(this._getChildName(i + "_" + j), w); - } else { - w = this.getWidgetByName(this._getChildName(i + "_" + j)); - } - var left = totalW * 100 / widths[i]; - w.element.css({ position: "absolute", left: left + "%" }); - if (j > 0) { - var lastW = this.getWidgetByName(this._getChildName(i + "_" + (j - 1))); - lastW.element.css({ right: (100 - left) + "%" }); - } - if (j == o.columns - 1) { - w.element.css({ right: "0%" }); - } - first(w, self.getRowColumnCls(i, j, rows - 1, columns - 1)); - totalW += map[i][j].width; - } - } - for (var j = 0; j < o.columns; j++) { - var totalH = 0; - for (var i = 0; i < o.rows; i++) { - var w = this.getWidgetByName(this._getChildName(i + "_" + j)); - var top = totalH * 100 / heights[j]; - w.element.css({ top: top + "%" }); - if (i > 0) { - var lastW = this.getWidgetByName(this._getChildName((i - 1) + "_" + j)); - lastW.element.css({ bottom: (100 - top) + "%" }); - } - if (i == o.rows - 1) { - w.element.css({ bottom: "0%" }); - } - totalH += map[i][j].height; - } - } - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.DivisionLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.division", BI.DivisionLayout); diff --git a/src/core/wrapper/layout/layout.flow.js b/src/core/wrapper/layout/layout.flow.js deleted file mode 100644 index 13b9fdb54..000000000 --- a/src/core/wrapper/layout/layout.flow.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * 靠左对齐的自由浮动布局 - * @class BI.FloatLeftLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.FloatLeftLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatLeftLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-left clearfix", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FloatLeftLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - if (o.innerHgap !== 0) { - this.element.css({ - paddingLeft: this._optimiseGap(o.innerHgap), - paddingRight: this._optimiseGap(o.innerHgap) - }) - } - if (o.innerVgap !== 0) { - this.element.css({ - paddingTop: this._optimiseGap(o.innerVgap), - paddingBottom: this._optimiseGap(o.innerVgap) - }) - } - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FloatLeftLayout.superclass._addElement.apply(this, arguments); - w.element.css({position: "relative", float: "left"}); - if (BI.isNotNull(item.left)) { - w.element.css({left: BI.isNumber(item.left) ? this._optimiseGap(item.left) : item.left}); - } - if (BI.isNotNull(item.right)) { - w.element.css({right: BI.isNumber(item.right) ? this._optimiseGap(item.right) : item.right}); - } - if (BI.isNotNull(item.top)) { - w.element.css({top: BI.isNumber(item.top) ? this._optimiseGap(item.top) : item.top}); - } - if (BI.isNotNull(item.bottom)) { - w.element.css({bottom: BI.isNumber(item.bottom) ? this._optimiseGap(item.bottom) : item.bottom}); - } - if (o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { - var top = o.vgap / 2 + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-top": this._optimiseGap(top) - }); - } - if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { - var left = o.hgap / 2 + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-left": this._optimiseGap(left) - }); - } - if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { - var right = o.hgap / 2 + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-right": this._optimiseGap(right) - }); - } - if (o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { - var bottom = o.vgap / 2 + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-bottom": this._optimiseGap(bottom) - }); - } - return w; - }, - - populate: function (items) { - BI.FloatLeftLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.left", BI.FloatLeftLayout); - -/** - * 靠右对齐的自由浮动布局 - * @class BI.FloatRightLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.FloatRightLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatRightLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-right clearfix", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FloatRightLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - if (o.innerHgap !== 0) { - this.element.css({ - paddingLeft: this._optimiseGap(o.innerHgap), - paddingRight: this._optimiseGap(o.innerHgap) - }) - } - if (o.innerVgap !== 0) { - this.element.css({ - paddingTop: this._optimiseGap(o.innerVgap), - paddingBottom: this._optimiseGap(o.innerVgap) - }) - } - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.FloatRightLayout.superclass._addElement.apply(this, arguments); - w.element.css({position: "relative", float: "right"}); - if (BI.isNotNull(item.left)) { - w.element.css({left: BI.pixFormat(item.left)}); - } - if (BI.isNotNull(item.right)) { - w.element.css({right: BI.pixFormat(item.right)}); - } - if (BI.isNotNull(item.top)) { - w.element.css({top: BI.pixFormat(item.top)}); - } - if (BI.isNotNull(item.bottom)) { - w.element.css({bottom: BI.pixFormat(item.bottom)}); - } - if (o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item) !== 0) { - var top = o.vgap / 2 + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-top": this._optimiseGap(top) - }); - } - if (o.hgap + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item) !== 0) { - var left = o.hgap / 2 + o.lgap + this._optimiseItemLgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-left": this._optimiseGap(left) - }); - } - if (o.hgap + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item) !== 0) { - var right = o.hgap / 2 + o.rgap + this._optimiseItemRgap(item) + this._optimiseItemHgap(item); - w.element.css({ - "margin-right": this._optimiseGap(right) - }); - } - if (o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item) !== 0) { - var bottom = o.vgap / 2 + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - w.element.css({ - "margin-bottom": this._optimiseGap(bottom) - }); - } - return w; - }, - - populate: function (items) { - BI.FloatRightLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.right", BI.FloatRightLayout); diff --git a/src/core/wrapper/layout/layout.grid.js b/src/core/wrapper/layout/layout.grid.js deleted file mode 100644 index a954c4f48..000000000 --- a/src/core/wrapper/layout/layout.grid.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 上下的高度固定/左右的宽度固定,中间的高度/宽度自适应 - * - * @class BI.BorderLayout - * @extends BI.Layout - */ -BI.GridLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.GridLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-grid", - columns: null, - rows: null, - items: [] - }); - }, - render: function () { - BI.GridLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function () { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var self = this, o = this.options; - var rows = o.rows || o.items.length, columns = o.columns || ((o.items[0] && o.items[0].length) | 0); - var width = 100 / columns, height = 100 / rows; - var els = []; - for (var i = 0; i < rows; i++) { - els[i] = []; - } - - function firstElement(item, cls) { - item.addClass(cls); - - return item; - } - - function firstObject(item, cls) { - item.cls = (item.cls || "") + cls; - - return item; - } - - function first(item, row, col) { - if (item instanceof BI.Widget) { - firstElement(item.element, row, col); - } else if (item.el instanceof BI.Widget) { - firstElement(item.el.element, row, col); - } else if (item.el) { - firstObject(item.el, row, col); - } else { - firstObject(item, row, col); - } - } - - BI.each(items, function (i, item) { - if (BI.isArray(item)) { - BI.each(item, function (j, el) { - els[i][j] = BI._lazyCreateWidget(el); - }); - return; - } - els[item.row][item.column] = BI._lazyCreateWidget(item); - }); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - if (!els[i][j]) { - els[i][j] = BI._lazyCreateWidget({ - type: "bi.layout" - }); - } - first(els[i][j], self.getRowColumnCls(i, j, rows - 1, columns - 1)); - els[i][j].element.css({ - position: "absolute", - top: height * i + "%", - left: width * j + "%", - right: (100 - (width * (j + 1))) + "%", - bottom: (100 - (height * (i + 1))) + "%" - }); - this.addWidget(this._getChildName(i + "_" + j), els[i][j]); - } - } - }, - - resize: function () { - // console.log("grid布局不需要resize") - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.GridLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.grid", BI.GridLayout); diff --git a/src/core/wrapper/layout/layout.horizontal.js b/src/core/wrapper/layout/layout.horizontal.js deleted file mode 100644 index 525538e92..000000000 --- a/src/core/wrapper/layout/layout.horizontal.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * 水平布局 - * @class BI.HorizontalLayout - * @extends BI.Layout - */ -BI.HorizontalLayout = function () { -}; -BI.shortcut("bi.horizontal", BI.HorizontalLayout); diff --git a/src/core/wrapper/layout/layout.inline.js b/src/core/wrapper/layout/layout.inline.js deleted file mode 100644 index 661a6bf77..000000000 --- a/src/core/wrapper/layout/layout.inline.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 内联布局 - * @class BI.InlineLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.InlineLayout = BI.inherit(BI.Layout, { - - props: function () { - return BI.extend(BI.InlineLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-i", - horizontalAlign: BI.HorizontalAlign.Left, - verticalAlign: BI.VerticalAlign.Top, - columnSize: [], - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - items: [] - }); - }, - - render: function () { - BI.InlineLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.element.css({ - textAlign: o.horizontalAlign - }); - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.InlineLayout.superclass._addElement.apply(this, arguments); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = null; - } - } - if (columnSize > 0) { - w.element.width(columnSize < 1 ? ((columnSize * 100).toFixed(1) + "%") : BI.pixFormat(columnSize)); - } - w.element.css({ - position: "relative", - "vertical-align": o.verticalAlign - }); - w.element.addClass("i-item"); - if (columnSize === "fill" || columnSize === "") { - var length = 0, gap = o.hgap + o.innerHgap; - var fillCount = 0, autoCount = 0; - for (var k = 0, len = o.columnSize.length || o.items.length; k < len; k++) { - var cz = o.columnSize.length > 0 ? o.columnSize[k] : o.items[k].width; - if (cz === "fill") { - fillCount++; - cz = 0; - } else if (cz === "" || BI.isNull(cz)) { - autoCount++; - cz = 0; - } - gap += o.hgap + o.lgap + o.rgap + this._optimiseItemLgap(o.items[k]) + this._optimiseItemRgap(o.items[k]) + this._optimiseItemHgap(o.items[k]); - length += cz; - } - length = length > 0 && length < 1 ? (length * 100).toFixed(1) + "%" : BI.pixFormat(length); - gap = gap > 0 && gap < 1 ? (gap * 100).toFixed(1) + "%" : BI.pixFormat(gap); - if (columnSize === "fill") { - w.element.css("min-width", "calc((100% - " + length + " - " + gap + ")" + (fillCount > 1 ? "/" + fillCount : "") + ")"); - } - if (o.horizontalAlign === BI.HorizontalAlign.Stretch || !(o.scrollable === true || o.scrollx === true)) { - if (columnSize === "fill") { - w.element.css("max-width", "calc((100% - " + length + " - " + gap + ")" + (fillCount > 1 ? "/" + fillCount : "") + ")"); - } else { - w.element.css("max-width", "calc((100% - " + length + " - " + gap + ")" + (autoCount > 1 ? "/" + autoCount : "") + ")"); - } - } - } - this._handleGap(w, item, i); - if (o.verticalAlign === BI.VerticalAlign.Stretch && BI.isNull(item.height)) { - var top = o.innerVgap + o.vgap + o.tgap + this._optimiseItemTgap(item) + this._optimiseItemVgap(item), - bottom = o.innerVgap + o.vgap + o.bgap + this._optimiseItemBgap(item) + this._optimiseItemVgap(item); - var gap = (top + bottom) > 0 && (top + bottom) < 1 ? ((top + bottom) * 100).toFixed(1) + "%" : BI.pixFormat(top + bottom); - w.element.css("height", "calc(100% - " + gap + ")"); - } - return w; - }, - - populate: function (items) { - BI.InlineLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.inline", BI.InlineLayout); diff --git a/src/core/wrapper/layout/layout.lattice.js b/src/core/wrapper/layout/layout.lattice.js deleted file mode 100644 index 34845aa7b..000000000 --- a/src/core/wrapper/layout/layout.lattice.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 靠左对齐的自由浮动布局 - * @class BI.LatticeLayout - * @extends BI.Layout - * - * @cfg {JSON} options 配置属性 - * @cfg {Number} [hgap=0] 水平间隙 - * @cfg {Number} [vgap=0] 垂直间隙 - */ -BI.LatticeLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.LatticeLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-lattice clearfix" - // columnSize: [0.2, 0.2, 0.6], - }); - }, - render: function () { - BI.LatticeLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.LatticeLayout.superclass._addElement.apply(this, arguments); - if (o.columnSize && o.columnSize[i]) { - var width = o.columnSize[i] / BI.sum(o.columnSize) * 100 + "%"; - } else { - var width = 1 / this.options.items.length * 100 + "%"; - } - w.element.css({position: "relative", float: "left", width: width}); - return w; - }, - - populate: function (items) { - BI.LatticeLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.lattice", BI.LatticeLayout); diff --git a/src/core/wrapper/layout/layout.table.js b/src/core/wrapper/layout/layout.table.js deleted file mode 100644 index 51d6eeb14..000000000 --- a/src/core/wrapper/layout/layout.table.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * 上下的高度固定/左右的宽度固定,中间的高度/宽度自适应 - * - * @class BI.TableLayout - * @extends BI.Layout - */ -BI.TableLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.TableLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-t", - // scrolly: true, - columnSize: [], - rowSize: [], - horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch, - // rowSize: 30, // or [30,30,30] - hgap: 0, - vgap: 0, - items: [], - }); - }, - render: function () { - BI.TableLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - - var columnSize = o.columnSize.length > 0 ? o.columnSize : BI.range(items[0].length).fill(""); - - if (columnSize.length > 0) { - var template = []; - for (var i = 0; i < columnSize.length; i++) { - if (columnSize[i] === "") { - template.push("auto"); - } else if (columnSize[i] === "fill") { - template.push("1fr"); - } else { - template.push(this._optimiseGap(columnSize[i])); - } - } - this.element.css({ - "grid-template-columns": template.join(" "), - "grid-template-rows": BI.isArray(o.rowSize) ? BI.map(o.rowSize, function (i, size) { - return self._optimiseGap(size); - }).join(" ") : BI.range(o.items.length).fill(this._optimiseGap(o.rowSize)).join(" "), - "grid-row-gap": this._optimiseGap(o.vgap), - "grid-column-gap": this._optimiseGap(o.hgap), - }); - } - - return { - type: "bi.default", - ref: function (_ref) { - self.layout = _ref; - }, - items: this._formatItems(items), - }; - }, - - _formatItems: function (items) { - var o = this.options, self = this; - - function firstElement (item, cls) { - item.addClass(cls); - - return item; - } - - function firstObject (item, cls) { - item.cls = (item.cls || "") + cls; - - return item; - } - - function first (item, cls) { - if (item instanceof BI.Widget) { - return firstElement(item.element, cls); - } else if (item.el instanceof BI.Widget) { - return firstElement(item.el.element, cls); - } else if (item.el) { - return firstObject(item.el, cls); - } else { - return firstObject(item, cls); - } - } - - function wrapLayout (item) { - return { - type: "bi.horizontal_fill", - columnSize: ["fill"], - horizontalAlign: o.horizontalAlign, - verticalAlign: o.verticalAlign, - items: [BI.formatEL(item)], - }; - } - - return BI.reduce(items, function (rowItems, result, rowIndex) { - return result.concat(BI.map(rowItems, function (colIndex, item) { - var cls = self.getRowColumnCls(rowIndex, colIndex, items.length - 1, rowItems.length - 1); - if (BI.isEmpty(item)) { - return first(wrapLayout({ - type: "bi.layout", - }), cls); - } - - return first(wrapLayout(item), cls); - })); - }, []); - }, - - resize: function () { - // console.log("table布局不需要resize"); - }, - - populate: function (items) { - this.layout.populate(this._formatItems(items)); - }, -}); -BI.shortcut("bi.table", BI.TableLayout); diff --git a/src/core/wrapper/layout/layout.tape.js b/src/core/wrapper/layout/layout.tape.js deleted file mode 100644 index 39f852461..000000000 --- a/src/core/wrapper/layout/layout.tape.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * 水平tape布局 - * @class BI.HTapeLayout - * @extends BI.Layout - */ -BI.HTapeLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.HTapeLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-h-tape", - verticalAlign: BI.VerticalAlign.Top, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - columnSize: [], - items: [] - }); - }, - render: function () { - BI.HTapeLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var self = this, o = this.options; - items = BI.compact(items); - BI.each(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return; - } - if (!self.hasWidget(self._getChildName(i))) { - var w = BI._lazyCreateWidget(item); - self.addWidget(self._getChildName(i), w); - } else { - w = self.getWidgetByName(self._getChildName(i)); - } - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = item.width; - } - } - w.element.css({ - position: "absolute", - top: self._optimiseGap(self._optimiseItemTgap(item) + self._optimiseItemVgap(item) + o.innerVgap + o.vgap + o.tgap), - bottom: self._optimiseGap(self._optimiseItemBgap(item) + self._optimiseItemVgap(item) + o.innerVgap + o.vgap + o.bgap), - width: BI.isNumber(columnSize) ? self._optimiseGap(columnSize) : "" - }); - if (o.verticalAlign === BI.VerticalAlign.Middle) { - w.element.css({ - marginTop: "auto", - marginBottom: "auto" - }); - } else if (o.verticalAlign === BI.VerticalAlign.Bottom) { - w.element.css({ - marginTop: "auto" - }); - } - }); - - var left = {}, right = {}; - left[0] = o.innerHgap; - right[items.length - 1] = o.innerHgap; - - BI.any(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.getWidgetByName(self._getChildName(i)); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = item.width; - } - } - if (BI.isNull(left[i])) { - var preColumnSize = o.columnSize.length > 0 ? o.columnSize[i - 1] : items[i - 1].width; - left[i] = left[i - 1] + preColumnSize + self._optimiseItemLgap(items[i - 1]) + self._optimiseItemRgap(items[i - 1]) + 2 * self._optimiseItemHgap(items[i - 1]) + o.hgap + o.lgap + o.rgap; - } - w.element.css({ - left: self._optimiseGap(left[i] + self._optimiseItemLgap(item) + self._optimiseItemHgap(item) + o.hgap + o.lgap) - }); - - if (BI.isNull(columnSize) || columnSize === "" || columnSize === "fill") { - return true; - } - }); - BI.backAny(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.getWidgetByName(self._getChildName(i)); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (BI.isNull(right[i])) { - var nextColumnSize = o.columnSize.length > 0 ? o.columnSize[i + 1] : items[i + 1].width; - right[i] = right[i + 1] + nextColumnSize + self._optimiseItemLgap(items[i + 1]) + self._optimiseItemRgap(items[i + 1]) + 2 * self._optimiseItemHgap(items[i + 1]) + o.hgap + o.lgap + o.rgap; - } - w.element.css({ - right: self._optimiseGap(right[i] + self._optimiseItemRgap(item) + self._optimiseItemHgap(item) + o.hgap + o.rgap) - }); - - if (BI.isNull(columnSize) || columnSize === "" || columnSize === "fill") { - return true; - } - }); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.HTapeLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.htape", BI.HTapeLayout); - -/** - * 垂直tape布局 - * @class BI.VTapeLayout - * @extends BI.Layout - */ -BI.VTapeLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.VTapeLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-v-tape", - horizontalAlign: BI.HorizontalAlign.Left, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - rowSize: [], - items: [] - }); - }, - render: function () { - BI.VTapeLayout.superclass.render.apply(this, arguments); - this.populate(this.options.items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var self = this, o = this.options; - items = BI.compact(items); - BI.each(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return; - } - if (!self.hasWidget(self._getChildName(i))) { - var w = BI._lazyCreateWidget(item); - self.addWidget(self._getChildName(i), w); - } else { - w = self.getWidgetByName(self._getChildName(i)); - } - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = item.height; - } - } - w.element.css({ - position: "absolute", - left: self._optimiseGap(self._optimiseItemLgap(item) + self._optimiseItemHgap(item) + o.innerHgap + o.hgap + o.lgap), - right: self._optimiseGap(self._optimiseItemRgap(item) + self._optimiseItemHgap(item) + o.innerHgap + o.hgap + o.rgap), - height: BI.isNumber(rowSize) ? self._optimiseGap(rowSize) : "" - }); - if (o.horizontalAlign === BI.HorizontalAlign.Center) { - w.element.css({ - marginLeft: "auto", - marginRight: "auto" - }); - } else if (o.horizontalAlign === BI.HorizontalAlign.Right) { - w.element.css({ - marginLeft: "auto" - }); - } - }); - - var top = {}, bottom = {}; - top[0] = o.innerVgap; - bottom[items.length - 1] = o.innerVgap; - - BI.any(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.getWidgetByName(self._getChildName(i)); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = item.height; - } - } - if (BI.isNull(top[i])) { - var preRowSize = o.rowSize.length > 0 ? o.rowSize[i - 1] : items[i - 1].height; - top[i] = top[i - 1] + preRowSize + self._optimiseItemTgap(items[i - 1]) + self._optimiseItemBgap(items[i - 1]) + 2 * self._optimiseItemVgap(items[i - 1]) + o.vgap + o.tgap + o.bgap; - } - w.element.css({ - top: self._optimiseGap(top[i] + self._optimiseItemTgap(item) + self._optimiseItemVgap(item) + o.vgap + o.tgap) - }); - - if (BI.isNull(rowSize) || rowSize === "" || rowSize === "fill") { - return true; - } - }); - BI.backAny(items, function (i, item) { - if (BI.isEmptyObject(item)) { - return true; - } - var w = self.getWidgetByName(self._getChildName(i)); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (BI.isNull(bottom[i])) { - var nextRowSize = o.rowSize.length > 0 ? o.rowSize[i + 1] : items[i + 1].height; - bottom[i] = bottom[i + 1] + nextRowSize + self._optimiseItemTgap(items[i + 1]) + self._optimiseItemBgap(items[i + 1]) + 2 * self._optimiseItemVgap(items[i + 1]) + o.vgap + o.tgap + o.bgap; - } - w.element.css({ - bottom: self._optimiseGap(bottom[i] + self._optimiseItemBgap(item) + self._optimiseItemVgap(item) + o.vgap + o.bgap) - }); - - if (BI.isNull(rowSize) || rowSize === "" || rowSize === "fill") { - return true; - } - }); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.VTapeLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.vtape", BI.VTapeLayout); diff --git a/src/core/wrapper/layout/layout.td.js b/src/core/wrapper/layout/layout.td.js deleted file mode 100644 index cb3221570..000000000 --- a/src/core/wrapper/layout/layout.td.js +++ /dev/null @@ -1,168 +0,0 @@ -/** - * td布局 - * @class BI.TdLayout - * @extends BI.Layout - */ -BI.TdLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.TdLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-td", - columnSize: [], - rowSize: [], - verticalAlign: BI.VerticalAlign.Middle, - horizontalAlign: BI.HorizontalAlign.Stretch, - hgap: 0, - vgap: 0, - tgap: 0, - bgap: 0, - lgap: 0, - rgap: 0, - items: [] - }); - }, - render: function () { - BI.TdLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - this.$table = BI.Widget._renderEngine.createElement("
  • ").attr({cellspacing: 0, cellpadding: 0}).css({ - position: "relative", - width: (o.horizontalAlign === BI.HorizontalAlign.Center || o.horizontalAlign === BI.HorizontalAlign.Stretch) ? "100%" : "auto", - height: (o.verticalAlign !== BI.VerticalAlign.Top) ? "100%" : "auto", - "border-spacing": "0px", - border: "none", - "border-collapse": "separate" - }); - this.rows = 0; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (idx, arr) { - var o = this.options; - - function firstElement (item, row, col) { - if (row === 0) { - item.addClass("first-row"); - } - if (col === 0) { - item.addClass("first-col"); - } - item.addClass(BI.isOdd(row + 1) ? "odd-row" : "even-row"); - item.addClass(BI.isOdd(col + 1) ? "odd-col" : "even-col"); - item.addClass("center-element"); - } - - function firstObject (item, row, col) { - var cls = ""; - if (row === 0) { - cls += " first-row"; - } - if (col === 0) { - cls += " first-col"; - } - BI.isOdd(row + 1) ? (cls += " odd-row") : (cls += " even-row"); - BI.isOdd(col + 1) ? (cls += " odd-col") : (cls += " even-col"); - item.cls = (item.cls || "") + cls + " center-element"; - } - - function first (item, row, col) { - if (item instanceof BI.Widget) { - firstElement(item.element, row, col); - } else if (item.el instanceof BI.Widget) { - firstElement(item.el.element, row, col); - } else if (item.el) { - firstObject(item.el, row, col); - } else { - firstObject(item, row, col); - } - } - - var height = BI.isNumber(o.rowSize) ? this._optimiseGap(o.rowSize) : (o.rowSize[idx] === "" ? this._optimiseGap(1) : this._optimiseGap(o.rowSize[idx])); - var tr = BI._lazyCreateWidget({ - type: "bi.default", - tagName: "tr", - height: height, - css: { - "max-height": height, - "min-height": height - } - }); - - for (var i = 0; i < arr.length; i++) { - var w = BI._lazyCreateWidget(arr[i]); - if (o.verticalAlign === BI.VerticalAlign.Stretch) { - var top = o.vgap + o.tgap + this._optimiseItemTgap(arr[i]) + this._optimiseItemVgap(arr[i]), - bottom = o.vgap + o.bgap + this._optimiseItemBgap(arr[i]) + this._optimiseItemVgap(arr[i]); - w.element.css("height", "calc(100% - " + this._optimiseGap(top + bottom) + ")"); - } - w.element.css({position: "relative", top: "0", left: "0", margin: "0px auto"}); - var item = arr[i]; - this._handleGap(w, item, i); - first(w, this.rows++, i); - var width = ""; - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (columnSize > 0) { - width = this._optimiseGap(columnSize + (i === 0 ? o.hgap : 0) + o.hgap + o.lgap + o.rgap); - } - function hasFill() { - if (o.columnSize.length > 0) { - return o.columnSize.indexOf("fill") >= 0; - } - return BI.some(arr, function (i, item) { - if (item.width === "fill") { - return true; - } - }); - } - if ((BI.isNull(columnSize) || columnSize === "") && hasFill()) { - width = 2; - } - var td = BI._lazyCreateWidget({ - type: "bi.default", - width: width, - tagName: "td", - items: [w] - }); - // 对于表现为td的元素设置最大宽度,有几点需要注意 - // 1、由于直接对td设置最大宽度是在规范中未定义的, 所以要使用类似td:firstChild来迂回实现 - // 2、不能给多个td设置最大宽度,这样只会平分宽度 - // 3、多百分比宽度就算了 - if (columnSize > 0) { - td.element.css({ - "max-width": width, - "min-width": width - }); - } - td.element.css({ - position: "relative", - "vertical-align": o.verticalAlign, - margin: "0", - padding: "0", - border: "none" - }); - tr.addItem(td); - } - this.addWidget(this._getChildName(idx), tr); - return tr; - }, - - appendFragment: function (frag) { - this.$table.append(frag); - this.element.append(this.$table); - }, - - resize: function () { - // console.log("td布局不需要resize"); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.TdLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.td", BI.TdLayout); diff --git a/src/core/wrapper/layout/layout.vertical.js b/src/core/wrapper/layout/layout.vertical.js deleted file mode 100644 index b181b1d41..000000000 --- a/src/core/wrapper/layout/layout.vertical.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * 垂直布局 - * @class BI.VerticalLayout - * @extends BI.Layout - */ -BI.VerticalLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.VerticalLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-v", - horizontalAlign: BI.HorizontalAlign.Stretch, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - scrolly: true - }); - }, - render: function () { - BI.VerticalLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.VerticalLayout.superclass._addElement.apply(this, arguments); - w.element.css({ - position: "relative" - }); - this._handleGap(w, item, null, i); - if (o.horizontalAlign === BI.HorizontalAlign.Center) { - w.element.css({ - marginLeft: "auto", - marginRight: "auto" - }); - } else if (o.horizontalAlign === BI.HorizontalAlign.Right) { - w.element.css({ - marginLeft: "auto" - }); - } - return w; - }, - - populate: function (items) { - BI.VerticalLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.vertical", BI.VerticalLayout); diff --git a/src/core/wrapper/layout/layout.window.js b/src/core/wrapper/layout/layout.window.js deleted file mode 100644 index 281fa5e2a..000000000 --- a/src/core/wrapper/layout/layout.window.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * - * @class BI.WindowLayout - * @extends BI.Layout - */ -BI.WindowLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.WindowLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-window", - columns: 3, - rows: 2, - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - columnSize: [], - rowSize: [], - items: [] - }); - }, - render: function () { - BI.WindowLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { - self.populate(newValue); - }) : o.items; - this.populate(items); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - stroke: function (items) { - var o = this.options, self = this; - if (BI.isNumber(o.rowSize)) { - o.rowSize = BI.makeArray(o.items.length, 1 / o.items.length); - } - if (BI.isNumber(o.columnSize)) { - o.columnSize = BI.makeArray(o.items[0].length, 1 / o.items[0].length); - } - - function firstElement(item, cls) { - item.addClass(cls); - - return item; - } - - function firstObject(item, cls) { - item.cls = (item.cls || "") + cls; - - return item; - } - - function first(item, row, col) { - if (item instanceof BI.Widget) { - firstElement(item.element, row, col); - } else if (item.el instanceof BI.Widget) { - firstElement(item.el.element, row, col); - } else if (item.el) { - firstObject(item.el, row, col); - } else { - firstObject(item, row, col); - } - } - - for (var i = 0; i < o.rows; i++) { - for (var j = 0; j < o.columns; j++) { - if (!o.items[i][j]) { - throw new Error("create items error", o.items); - } - if (!this.hasWidget(this._getChildName(i + "_" + j))) { - var w = BI._lazyCreateWidget(o.items[i][j]); - w.element.css({ position: "absolute" }); - this.addWidget(this._getChildName(i + "_" + j), w); - } - } - } - var left = {}, right = {}, top = {}, bottom = {}; - left[0] = 0; - top[0] = 0; - right[o.columns - 1] = 0; - bottom[o.rows - 1] = 0; - // 从上到下 - for (var i = 0; i < o.rows; i++) { - for (var j = 0; j < o.columns; j++) { - var wi = this.getWidgetByName(this._getChildName(i + "_" + j)); - if (BI.isNull(top[i])) { - top[i] = top[i - 1] + (o.rowSize[i - 1] < 1 ? o.rowSize[i - 1] : o.rowSize[i - 1] + o.vgap + o.bgap); - } - var t = this._optimiseGap(top[i] + o.vgap + o.tgap), h = ""; - if (BI.isNumber(o.rowSize[i])) { - h = this._optimiseGap(o.rowSize[i]); - } - wi.element.css({ top: t, height: h }); - first(wi, self.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); - } - if (!BI.isNumber(o.rowSize[i])) { - break; - } - } - // 从下到上 - for (var i = o.rows - 1; i >= 0; i--) { - for (var j = 0; j < o.columns; j++) { - var wi = this.getWidgetByName(this._getChildName(i + "_" + j)); - if (BI.isNull(bottom[i])) { - bottom[i] = bottom[i + 1] + (o.rowSize[i + 1] < 1 ? o.rowSize[i + 1] : o.rowSize[i + 1] + o.vgap + o.tgap); - } - var b = this._optimiseGap(bottom[i] + o.vgap + o.bgap), h = ""; - if (BI.isNumber(o.rowSize[i])) { - h = this._optimiseGap(o.rowSize[i]); - } - wi.element.css({ bottom: b, height: h }); - first(wi, self.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); - } - if (!BI.isNumber(o.rowSize[i])) { - break; - } - } - // 从左到右 - for (var j = 0; j < o.columns; j++) { - for (var i = 0; i < o.rows; i++) { - var wi = this.getWidgetByName(this._getChildName(i + "_" + j)); - if (BI.isNull(left[j])) { - left[j] = left[j - 1] + (o.columnSize[j - 1] < 1 ? o.columnSize[j - 1] : o.columnSize[j - 1] + o.hgap + o.rgap); - } - var l = this._optimiseGap(left[j] + o.hgap + o.lgap), w = ""; - if (BI.isNumber(o.columnSize[j])) { - w = this._optimiseGap(o.columnSize[j]); - } - wi.element.css({ left: l, width: w }); - first(wi, self.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); - } - if (!BI.isNumber(o.columnSize[j])) { - break; - } - } - // 从右到左 - for (var j = o.columns - 1; j >= 0; j--) { - for (var i = 0; i < o.rows; i++) { - var wi = this.getWidgetByName(this._getChildName(i + "_" + j)); - if (BI.isNull(right[j])) { - right[j] = right[j + 1] + (o.columnSize[j + 1] < 1 ? o.columnSize[j + 1] : o.columnSize[j + 1] + o.hgap + o.lgap); - } - var r = this._optimiseGap(right[j] + o.hgap + o.rgap), w = ""; - if (BI.isNumber(o.columnSize[j])) { - w = this._optimiseGap(o.columnSize[j]); - } - wi.element.css({ right: r, width: w }); - first(wi, self.getRowColumnCls(i, j, o.rows - 1, o.columns - 1)); - } - if (!BI.isNumber(o.columnSize[j])) { - break; - } - } - }, - - resize: function () { - // console.log("window布局不需要resize"); - }, - - update: function (opt) { - return this.forceUpdate(opt); - }, - - populate: function (items) { - BI.WindowLayout.superclass.populate.apply(this, arguments); - this._mount(); - } -}); -BI.shortcut("bi.window", BI.WindowLayout); diff --git a/src/core/wrapper/layout/middle/middle.center.js b/src/core/wrapper/layout/middle/middle.center.js deleted file mode 100644 index bd13d360c..000000000 --- a/src/core/wrapper/layout/middle/middle.center.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * 水平和垂直方向都居中容器, 非自适应,用于宽度高度固定的面板 - * @class BI.CenterLayout - * @extends BI.Layout - */ -BI.CenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.CenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-center", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - BI.CenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options; - var list = [], items = o.items; - BI.each(items, function (i) { - list.push({ - column: i, - row: 0, - el: BI._lazyCreateWidget({ - type: "bi.default", - cls: "center-element " + (i === 0 ? "first-element " : "") + (i === items.length - 1 ? "last-element" : "") - }) - }); - }); - BI.each(items, function (i, item) { - if (item) { - var w = BI._lazyCreateWidget(item); - w.element.css({ - position: "absolute", - left: self._optimiseGap(o.hgap + o.lgap), - right: self._optimiseGap(o.hgap + o.rgap), - top: self._optimiseGap(o.vgap + o.tgap), - bottom: self._optimiseGap(o.vgap + o.bgap), - width: "auto", - height: "auto" - }); - list[i].el.addItem(w); - } - }); - return { - type: "bi.grid", - ref: function (_ref) { - self.layout = _ref; - }, - columns: list.length, - rows: 1, - items: list - }; - }, - - resize: function () { - // console.log("center布局不需要resize"); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.center", BI.CenterLayout); diff --git a/src/core/wrapper/layout/middle/middle.float.center.js b/src/core/wrapper/layout/middle/middle.float.center.js deleted file mode 100644 index 90c130cb2..000000000 --- a/src/core/wrapper/layout/middle/middle.float.center.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 浮动布局实现的居中容器 - * @class BI.FloatCenterLayout - * @extends BI.Layout - */ -BI.FloatCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.FloatCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-float-center", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.FloatCenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options, items = o.items; - var list = [], width = 100 / items.length; - BI.each(items, function (i) { - var widget = BI._lazyCreateWidget({ - type: "bi.default" - }); - widget.element.addClass("center-element " + (i === 0 ? "first-element " : "") + (i === items.length - 1 ? "last-element" : "")).css({ - width: width + "%", - height: "100%" - }); - list.push({ - el: widget - }); - }); - BI.each(items, function (i, item) { - if (item) { - var w = BI._lazyCreateWidget(item); - w.element.css({ - position: "absolute", - left: self._optimiseGap(o.hgap + o.lgap), - right: self._optimiseGap(o.hgap + o.rgap), - top: self._optimiseGap(o.vgap + o.tgap), - bottom: self._optimiseGap(o.vgap + o.bgap), - width: "auto", - height: "auto" - }); - list[i].el.addItem(w); - } - }); - return { - type: "bi.left", - ref: function (_ref) { - self.layout = _ref; - }, - items: list - }; - }, - - resize: function () { - // console.log("floatcenter布局不需要resize"); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.float_center", BI.FloatCenterLayout); diff --git a/src/core/wrapper/layout/middle/middle.horizontal.js b/src/core/wrapper/layout/middle/middle.horizontal.js deleted file mode 100644 index 81c12e7ae..000000000 --- a/src/core/wrapper/layout/middle/middle.horizontal.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 水平和垂直方向都居中容器, 非自适应,用于宽度高度固定的面板 - * @class BI.HorizontalCenterLayout - * @extends BI.Layout - */ -BI.HorizontalCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.HorizontalCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-h-center", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - render: function () { - BI.HorizontalCenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options, items = o.items; - var list = []; - BI.each(items, function (i) { - list.push({ - column: i, - row: 0, - el: BI._lazyCreateWidget({ - type: "bi.default", - cls: "center-element " + (i === 0 ? "first-element " : "") + (i === items.length - 1 ? "last-element" : "") - }) - }); - }); - BI.each(items, function (i, item) { - if (item) { - var w = BI._lazyCreateWidget(item); - w.element.css({ - position: "absolute", - left: self._optimiseGap(o.hgap + o.lgap), - right: self._optimiseGap(o.hgap + o.rgap), - top: self._optimiseGap(o.vgap + o.tgap), - bottom: self._optimiseGap(o.vgap + o.bgap), - width: "auto" - }); - list[i].el.addItem(w); - } - }); - return { - type: "bi.grid", - ref: function (_ref) { - self.layout = _ref; - }, - columns: list.length, - rows: 1, - items: list - }; - }, - - resize: function () { - // console.log("horizontal_center布局不需要resize"); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.horizontal_center", BI.HorizontalCenterLayout); diff --git a/src/core/wrapper/layout/middle/middle.vertical.js b/src/core/wrapper/layout/middle/middle.vertical.js deleted file mode 100644 index 6cc161716..000000000 --- a/src/core/wrapper/layout/middle/middle.vertical.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 垂直方向都居中容器, 非自适应,用于高度不固定的面板 - * @class BI.VerticalCenterLayout - * @extends BI.Layout - */ -BI.VerticalCenterLayout = BI.inherit(BI.Layout, { - props: function () { - return BI.extend(BI.VerticalCenterLayout.superclass.props.apply(this, arguments), { - baseCls: "bi-v-center", - hgap: 0, - vgap: 0, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0 - }); - }, - - render: function () { - BI.VerticalCenterLayout.superclass.render.apply(this, arguments); - var self = this, o = this.options, items = o.items; - var list = []; - BI.each(items, function (i) { - list.push({ - column: 0, - row: i, - el: BI._lazyCreateWidget({ - type: "bi.default", - cls: "center-element " + (i === 0 ? "first-element " : "") + (i === items.length - 1 ? "last-element" : "") - }) - }); - }); - BI.each(items, function (i, item) { - if (item) { - var w = BI._lazyCreateWidget(item); - w.element.css({ - position: "absolute", - left: self._optimiseGap(o.hgap + o.lgap), - right: self._optimiseGap(o.hgap + o.rgap), - top: self._optimiseGap(o.vgap + o.tgap), - bottom: self._optimiseGap(o.vgap + o.bgap), - height: "auto" - }); - list[i].el.addItem(w); - } - }); - return { - type: "bi.grid", - ref: function (_ref) { - self.layout = _ref; - }, - columns: 1, - rows: list.length, - items: list - }; - }, - - resize: function () { - // console.log("vertical_center布局不需要resize"); - }, - - addItem: function (item) { - // do nothing - throw new Error("Cannot add subwidget"); - }, - - populate: function (items) { - this.layout.populate.apply(this.layout, arguments); - } -}); -BI.shortcut("bi.vertical_center", BI.VerticalCenterLayout); diff --git a/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js b/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js deleted file mode 100644 index 592d50641..000000000 --- a/src/core/wrapper/layout/responsive/responsive.flex.horizontal.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 横向响应式布局 - * Created by GUY on 2016/12/2. - * - * @class BI.ResponsiveFlexHorizontalLayout - * @extends BI.FlexHorizontalLayout - */ -BI.ResponsiveFlexHorizontalLayout = BI.inherit(BI.FlexHorizontalLayout, { - // props: function () { - // return BI.extend(BI.ResponsiveFlexHorizontalLayout.superclass.props.apply(this, arguments), { - // // extraCls: "bi-responsive-f-h" - // }); - // }, - - mounted: function () { - var self = this, o = this.options; - if (o.horizontalAlign !== BI.HorizontalAlign.Center){ - return; - } - var defaultResize = function () { - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth <= 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - self._handleReverseGap(child, o.items[i], i | 0); - }); - self.element.css("flex-direction", "column"); - } - } - } - } - var resize = function () { - defaultResize(); - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth > 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - }) - self.resize(); - self.element.css("flex-direction", "row"); - } - } - } - } - this.unResize = BI.Resizers.add(this.getName(), resize); - defaultResize(); - }, - - destroyed: function () { - this.unResize?.(); - } -}); -BI.shortcut("bi.responsive_flex_horizontal", BI.ResponsiveFlexHorizontalLayout); diff --git a/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js b/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js deleted file mode 100644 index 5e8fcfd95..000000000 --- a/src/core/wrapper/layout/responsive/responsive.flex.wrapper.horizontal.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 横向响应式布局 - * Created by GUY on 2016/12/2. - * - * @class BI.ResponsiveFlexWrapperHorizontalLayout - * @extends BI.FlexWrapperHorizontalLayout - */ -BI.ResponsiveFlexWrapperHorizontalLayout = BI.inherit(BI.FlexWrapperHorizontalLayout, { - // props: function () { - // return BI.extend(BI.ResponsiveFlexWrapperHorizontalLayout.superclass.props.apply(this, arguments), { - // extraCls: "bi-responsive-f-h" - // }); - // }, - - mounted: function () { - var self = this, o = this.options; - if (o.horizontalAlign !== BI.HorizontalAlign.Center){ - return; - } - var defaultResize = function () { - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth <= 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - self._handleReverseGap(child, o.items[i], i | 0); - }); - self.element.css("flex-direction", "column"); - self.$wrapper.element.css("flex-direction", "column"); - } - } - } - } - var resize = function () { - defaultResize(); - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth > 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - }) - self.resize(); - self.element.css("flex-direction", "row"); - self.$wrapper.element.css("flex-direction", "row"); - } - } - } - } - this.unResize = BI.Resizers.add(this.getName(), resize); - defaultResize(); - }, - - destroyed: function () { - this.unResize(); - } -}); -BI.shortcut("bi.responsive_flex_scrollable_horizontal", BI.ResponsiveFlexWrapperHorizontalLayout); diff --git a/src/core/wrapper/layout/responsive/responsive.inline..js b/src/core/wrapper/layout/responsive/responsive.inline..js deleted file mode 100644 index 08f27fcfc..000000000 --- a/src/core/wrapper/layout/responsive/responsive.inline..js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 横向响应式布局 - * Created by GUY on 2016/12/2. - * - * @class BI.ResponsiveInlineLayout - * @extends BI.InlineLayout - */ -BI.ResponsiveInlineLayout = BI.inherit(BI.InlineLayout, { - mounted: function () { - var self = this, o = this.options; - if (o.horizontalAlign !== BI.HorizontalAlign.Center){ - return; - } - var defaultResize = function () { - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth <= 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - self._handleReverseGap(child, o.items[i], i | 0); - child.elemenet.css("display", ""); - }); - } - } - } - } - var resize = function () { - defaultResize(); - if (o.scrollable !== true && o.scrollx !== true) { - var clientWidth = document.body.clientWidth; - if(self.element.width() > 2/3 * clientWidth){ - if (clientWidth > 768) { - BI.each(self._children, function (i, child) { - self._clearGap(child); - }) - self.resize(); - } - } - } - } - this.unResize = BI.Resizers.add(this.getName(), resize); - defaultResize(); - }, - - destroyed: function () { - this.unResize(); - } -}); -BI.shortcut("bi.responsive_inline", BI.ResponsiveInlineLayout); diff --git a/src/core/wrapper/layout/sticky/sticky.horizontal.js b/src/core/wrapper/layout/sticky/sticky.horizontal.js deleted file mode 100644 index d88f28b6d..000000000 --- a/src/core/wrapper/layout/sticky/sticky.horizontal.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 横向黏性布局 - */ -BI.HorizontalStickyLayout = BI.inherit(BI.FlexHorizontalLayout, { - props: function () { - return BI.extend(BI.HorizontalStickyLayout.superclass.props.apply(this, arguments), { - extraCls: "bi-h-sticky", - scrollx: true, - // horizontalAlign: BI.HorizontalAlign.Stretch, - verticalAlign: BI.VerticalAlign.Stretch - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.HorizontalStickyLayout.superclass._addElement.apply(this, arguments); - var columnSize = o.columnSize.length > 0 ? o.columnSize[i] : item.width; - if (o.columnSize.length > 0) { - if (item.width >= 1 && o.columnSize[i] >= 1 && o.columnSize[i] !== item.width) { - columnSize = null; - } - } - if (columnSize !== "fill") { - var fillIndex; - BI.count(0, o.items.length, index => { - if (BI.isNotNull(fillIndex)) { - return; - } - if ((o.columnSize[index] === "fill" || o.items[index].width === "fill")) { - fillIndex = index; - } - }); - - if (fillIndex > i) { - w.element.css({ - position: "sticky", - zIndex: 1, - left: 0, - }); - } else { - w.element.css({ - position: "sticky", - zIndex: 1, - right: 0 - }); - } - } else { - w.element.css({ - overflow: "" - }); - } - return w; - } -}); -BI.shortcut("bi.horizontal_sticky", BI.HorizontalStickyLayout); diff --git a/src/core/wrapper/layout/sticky/sticky.vertical.js b/src/core/wrapper/layout/sticky/sticky.vertical.js deleted file mode 100644 index 71dc3ed8c..000000000 --- a/src/core/wrapper/layout/sticky/sticky.vertical.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 纵向黏性布局 - */ -BI.VerticalStickyLayout = BI.inherit(BI.FlexVerticalLayout, { - props: function () { - return BI.extend(BI.VerticalStickyLayout.superclass.props.apply(this, arguments), { - extraCls: "bi-v-sticky", - scrolly: true, - horizontalAlign: BI.HorizontalAlign.Stretch, - // verticalAlign: BI.VerticalAlign.Stretch - }); - }, - - _addElement: function (i, item) { - var o = this.options; - var w = BI.VerticalStickyLayout.superclass._addElement.apply(this, arguments); - var rowSize = o.rowSize.length > 0 ? o.rowSize[i] : item.height; - if (o.rowSize.length > 0) { - if (item.height >= 1 && o.rowSize[i] >= 1 && o.rowSize[i] !== item.height) { - rowSize = null; - } - } - if (rowSize !== "fill") { - var fillIndex; - BI.count(0, o.items.length, index => { - if (BI.isNotNull(fillIndex)) { - return; - } - if ((o.rowSize[index] === "fill" || o.items[index].height === "fill")) { - fillIndex = index; - } - }); - - if (fillIndex > i) { - w.element.css({ - position: "sticky", - zIndex: 1, - top: 0, - }); - } else { - w.element.css({ - position: "sticky", - zIndex: 1, - bottom: 0 - }); - } - } else { - w.element.css({ - overflow: "" - }); - } - return w; - } -}); -BI.shortcut("bi.vertical_sticky", BI.VerticalStickyLayout); diff --git a/src/less/base/dom.less b/src/less/base/dom.less deleted file mode 100644 index ffac75ef8..000000000 --- a/src/less/base/dom.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../index.less"; -@import "../lib/colors.less"; diff --git a/src/less/base/single/text.less b/src/less/base/single/text.less deleted file mode 100644 index 14f567d72..000000000 --- a/src/less/base/single/text.less +++ /dev/null @@ -1,10 +0,0 @@ -@import "../../index.less"; - -.bi-text { - .overflow-hidden(); - .box-sizing(border-box); - - // https://developer.mozilla.org/en-US/docs/Web/CSS/word-break 参考mdn最标准的规范. 不再接受任何质疑 - word-break: normal; - overflow-wrap: anywhere; -} diff --git a/src/less/core/utils/list-item.less b/src/less/core/utils/list-item.less deleted file mode 100644 index c084ac275..000000000 --- a/src/less/core/utils/list-item.less +++ /dev/null @@ -1,752 +0,0 @@ -@import "../../index.less"; - -// hover的时候背景变化,文字变黑 -.bi-list-item { - &:hover, &.hover { - color: @color-bi-text-black; - & .bi-input { - color: @color-bi-text-black; - } - & .bi-textarea { - color: @color-bi-text-black; - } - .background-color(@color-bi-background-highlight, 10%); - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item { - &:hover, &.hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - .background-color(@color-bi-background-highlight, 10%); - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - } - } -} - -// active的时候边框高亮 -.bi-list-item-border { - &:active, &.active { - border: 1px solid @color-bi-border-highlight; - } -} - -// 极简,hover的时候文字高亮 -.bi-list-item-simple { - &:hover, &.hover { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - } - &.disabled { - &, &:hover, &:active { - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -// hover的时候文字变黑 -// active的时候文字高亮 -.bi-list-item-effect { - &:hover { - color: @color-bi-text-black; - & .bi-input { - color: @color-bi-text-black; - } - & .bi-textarea { - color: @color-bi-text-black; - } - } - &.active, &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - } - &.disabled { - &, &:hover, &:active { - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item-effect { - &:hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - } - &.active, &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - } - } -} - -// hover的时候背景变化,文字变黑 -// :active的时候文字高亮,背景变化 -.bi-list-item-active { - &:hover, &.hover { - color: @color-bi-text-black; - & .bi-input { - color: @color-bi-text-black; - } - & .bi-textarea { - color: @color-bi-text-black; - } - .background-color(@color-bi-background-highlight, 10%); - } - &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - .background-color(@color-bi-background-highlight, 15%); - } - &.active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item-active { - &:hover, &.hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - .background-color(@color-bi-background-default, 5%); - } - &.active, &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - .background-color(@color-bi-background-default, 5%); - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - } - } -} - -// hover的时候背景变化,文字变黑 -// active的时候文字高亮,背景变化 -.bi-list-item-active2 { - &:hover, &.hover { - color: @color-bi-text-black; - & .bi-input { - color: @color-bi-text-black; - } - & .bi-textarea { - color: @color-bi-text-black; - } - .background-color(@color-bi-background-highlight, 10%); - } - &:active, &.active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - .background-color(@color-bi-background-highlight, 15%); - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item-active2 { - &:hover, &.hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - .background-color(@color-bi-background-highlight, 10%); - } - &:active, &.active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - .background-color(@color-bi-background-highlight, 15%); - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - } - } -} - -// hover的时候背景变化 -- 变灰 -// active的时候文字高亮背景变化 -- 变灰 -.bi-list-item-active3, .bi-list-item-select3 { - &:hover, &.hover { - background-color: @color-bi-background-normal; - } - &:active, &.active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - background-color: @color-bi-background-normal; - } - &.disabled { - &:hover, &.hover, &:active, &.active { - background-color: @color-bi-background-default !important; - } - } -} - -.bi-theme-dark { - .bi-list-item-active3, .bi-list-item-select3 { - &:hover, &.hover { - background-color: @color-bi-background-normal-theme-dark; - } - &:active, &.active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - background-color: @color-bi-background-normal-theme-dark; - } - &.disabled { - &:hover, &.hover, &:active, &.active { - background-color: @color-bi-background-default-theme-dark !important; - } - } - } -} - -// hover的时候背景变化 -// active的时候背景高亮 -.bi-list-item-select { - &:hover, &.hover { - .background-color(@color-bi-background-highlight, 10%); - } - &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - .background-color(@color-bi-background-highlight, 15%); - } - &.active { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - background-color: @color-bi-background-highlight; - & .bi-high-light { - color: @color-bi-text; - } - } - &.button-success { - &:active, &.active { - color: @color-bi-text; - background-color: @color-bi-background-success; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - & .bi-high-light { - color: @color-bi-text; - } - &.bi-high-light-border { - border-color: @color-bi-border-success; - } - } - } - &.button-warning { - & { - color: @color-bi-text-failure; - & .bi-input { - color: @color-bi-text-failure; - } - & .bi-textarea { - color: @color-bi-text-failure; - } - & .bi-high-light { - color: @color-bi-text-failure; - } - &.bi-high-light-border { - border-color: @color-bi-border-failure; - } - } - &:hover, &.hover { - color: @color-bi-text-failure; - & .bi-input { - color: @color-bi-text-failure; - } - & .bi-textarea { - color: @color-bi-text-failure; - } - background-color: @color-bi-background-light-failure; - & .bi-high-light { - color: @color-bi-text-failure; - } - &.bi-high-light-border { - border-color: @color-bi-border-failure; - } - } - &:active, &.active { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - background-color: @color-bi-background-failure; - & .bi-high-light { - color: @color-bi-text; - } - &.bi-high-light-border { - border-color: @color-bi-border-failure; - } - } - } - &.disabled { - &, &:hover, &:active { - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - background-color: transparent !important; - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - &.bi-high-light-border { - border-color: @color-bi-border-disabled; - } - &.hover, &.active { - color: @color-bi-text !important; - & .bi-input { - color: @color-bi-text !important; - } - & .bi-textarea { - color: @color-bi-text !important; - } - background-color: @color-bi-background-dark-gray !important; - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - &.bi-high-light-border { - border-color: @color-bi-border-disabled; - } - } - } - } -} - -.bi-theme-dark { - .bi-list-item-select { - &:hover, &.hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - .background-color(@color-bi-background-default, 5%); - } - &:active { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - .background-color(@color-bi-background-default, 5%); - } - &.active { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - background-color: @color-bi-background-highlight; - & .bi-high-light { - color: @color-bi-text; - } - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - &.hover, &.active { - background-color: @background-color-black-theme-dark !important; - } - } - } -} - -// hover的时候边框高亮,文字变黑 -// :active的时候文字高亮,边框高亮 -// .active的时候背景高亮,边框高亮 -.bi-list-item-select2 { - &:hover, &.hover { - color: @color-bi-text-black; - & .bi-input { - color: @color-bi-text-black; - } - & .bi-textarea { - color: @color-bi-text-black; - } - &.bi-border { - border-color: @color-bi-border-highlight; - } - } - &:active { - color: @color-bi-text-highlight; - & .bi-input { - color: @color-bi-text-highlight; - } - & .bi-textarea { - color: @color-bi-text-highlight; - } - &.bi-border { - border-color: @color-bi-border-highlight; - } - } - &.active { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - &.bi-border { - border-color: @color-bi-border-highlight; - } - background-color: @color-bi-background-highlight; - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item-select2 { - &:hover, &.hover { - color: @color-bi-text; - & .bi-input { - color: @color-bi-text; - } - & .bi-textarea { - color: @color-bi-text; - } - } - - &.active { - background-color: @color-bi-background-default-theme-dark; - } - - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - &.active { - background-color: @background-color-black-theme-dark !important; - } - } - } -} - -// 去掉list-item效果 -.bi-list-item-none { - &:hover, &.hover { - color: inherit; - & .bi-input { - color: inherit; - } - & .bi-textarea { - color: inherit; - } - background-color: transparent; - } - &:active, &.active { - color: inherit; - & .bi-input { - color: inherit; - } - & .bi-textarea { - color: inherit; - } - background-color: transparent; - & .bi-high-light { - color: inherit; - } - } - &.disabled { - &, &:hover, &:active { - color: @color-bi-text-disabled !important; - & .bi-input { - color: @color-bi-text-disabled !important; - } - & .bi-textarea { - color: @color-bi-text-disabled !important; - } - background-color: transparent !important; - & .bi-high-light { - color: @color-bi-text-disabled !important; - } - } - } -} - -.bi-theme-dark { - .bi-list-item-none { - &:hover, &.hover { - color: inherit; - & .bi-input { - color: inherit; - } - & .bi-textarea { - color: inherit; - } - background-color: transparent; - } - &:active, &.active { - color: inherit; - & .bi-input { - color: inherit; - } - & .bi-textarea { - color: inherit; - } - background-color: transparent; - & .bi-high-light { - color: inherit; - } - } - &.disabled { - &, &:hover, &:active { - background-color: transparent !important; - color: @color-bi-text-disabled-theme-dark !important; - & .bi-input { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-textarea { - color: @color-bi-text-disabled-theme-dark !important; - } - & .bi-high-light { - color: @color-bi-text-disabled-theme-dark !important; - } - } - } - } -} diff --git a/src/polyfill/console.js b/src/polyfill/console.js deleted file mode 100644 index 8687d9b9e..000000000 --- a/src/polyfill/console.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * 特殊情况 - * Created by wang on 15/6/23. - */ -// 解决console未定义问题 guy -_global.console = _global.console || (function () { - var c = {}; - c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile - = c.clear = c.exception = c.trace = c.assert = function () { - }; - return c; -})(); diff --git a/src/polyfill/event.js b/src/polyfill/event.js deleted file mode 100644 index 346ec16c8..000000000 --- a/src/polyfill/event.js +++ /dev/null @@ -1,15 +0,0 @@ -(function () { - if (typeof window.CustomEvent === "function") return false; // If not IE - - function CustomEvent (event, params) { - params = params || { bubbles: false, cancelable: false, detail: undefined }; - var evt = document.createEvent("CustomEvent"); - evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); - - return evt; - } - - CustomEvent.prototype = window.Event.prototype; - - window.CustomEvent = CustomEvent; -}()); diff --git a/src/polyfill/sort.js b/src/polyfill/sort.js deleted file mode 100644 index 5d6f7fb92..000000000 --- a/src/polyfill/sort.js +++ /dev/null @@ -1,34 +0,0 @@ -// 修复ie9下sort方法的bug -// IE的sort 需要显示声明返回-1, 0, 1三种比较结果才可正常工作,而Chrome, Firefox中可以直接返回true, false等 -// BI-36544 sort提供的参数就可以自定义返回值,不需要特别控制。这边使用冒泡相较于快排可能慢了点。 -// 这边先将webkit的限制去掉 -!function (window) { - var ua = window.navigator.userAgent.toLowerCase(), - reg = /msie/; - if (reg.test(ua)) { - var _sort = Array.prototype.sort; - Array.prototype.sort = function (fn) { - if (!!fn && typeof fn === "function") { - if (this.length < 2) { - return this; - } - var i = 0, j = i + 1, l = this.length, tmp, r = false, t = 0; - for (; i < l; i++) { - for (j = i + 1; j < l; j++) { - t = fn.call(this, this[i], this[j]); - r = (typeof t === "number" ? t : - t ? 1 : 0) > 0; - if (r === true) { - tmp = this[i]; - this[i] = this[j]; - this[j] = tmp; - } - } - } - return this; - } - return _sort.call(this); - - }; - } -}(window); \ No newline at end of file diff --git a/src/router/0.router.js b/src/router/0.router.js deleted file mode 100644 index adf48b1bc..000000000 --- a/src/router/0.router.js +++ /dev/null @@ -1,627 +0,0 @@ -(function () { - var Events = { - - // Bind an event to a `callback` function. Passing `"all"` will bind - // the callback to all events fired. - on: function (name, callback, context) { - if (!eventsApi(this, "on", name, [callback, context]) || !callback) return this; - this._events || (this._events = {}); - var events = this._events[name] || (this._events[name] = []); - events.push({callback: callback, context: context, ctx: context || this}); - return this; - }, - - // Bind an event to only be triggered a single time. After the first time - // the callback is invoked, it will be removed. - once: function (name, callback, context) { - if (!eventsApi(this, "once", name, [callback, context]) || !callback) return this; - var self = this; - var once = BI._.once(function () { - self.off(name, once); - callback.apply(this, arguments); - }); - once._callback = callback; - return this.on(name, once, context); - }, - - // Remove one or many callbacks. If `context` is null, removes all - // callbacks with that function. If `callback` is null, removes all - // callbacks for the event. If `name` is null, removes all bound - // callbacks for all events. - off: function (name, callback, context) { - if (!this._events || !eventsApi(this, "off", name, [callback, context])) return this; - - // Remove all callbacks for all events. - if (!name && !callback && !context) { - this._events = void 0; - return this; - } - - var names = name ? [name] : BI._.keys(this._events); - for (var i = 0, length = names.length; i < length; i++) { - name = names[i]; - - // Bail out if there are no events stored. - var events = this._events[name]; - if (!events) continue; - - // Remove all callbacks for this event. - if (!callback && !context) { - delete this._events[name]; - continue; - } - - // Find any remaining events. - var remaining = []; - for (var j = 0, k = events.length; j < k; j++) { - var event = events[j]; - if ( - callback && callback !== event.callback && - callback !== event.callback._callback || - context && context !== event.context - ) { - remaining.push(event); - } - } - - // Replace events if there are any remaining. Otherwise, clean up. - if (remaining.length) { - this._events[name] = remaining; - } else { - delete this._events[name]; - } - } - - return this; - }, - - un: function () { - this.off.apply(this, arguments); - }, - - // Trigger one or many events, firing all bound callbacks. Callbacks are - // passed the same arguments as `trigger` is, apart from the event name - // (unless you're listening on `"all"`, which will cause your callback to - // receive the true name of the event as the first argument). - trigger: function (name) { - if (!this._events) return this; - var args = slice.call(arguments, 1); - if (!eventsApi(this, "trigger", name, args)) return this; - var events = this._events[name]; - var allEvents = this._events.all; - if (events) triggerEvents(events, args); - if (allEvents) triggerEvents(allEvents, arguments); - return this; - }, - - fireEvent: function () { - this.trigger.apply(this, arguments); - }, - - // Inversion-of-control versions of `on` and `once`. Tell *this* object to - // listen to an event in another object ... keeping track of what it's - // listening to. - listenTo: function (obj, name, callback) { - var listeningTo = this._listeningTo || (this._listeningTo = {}); - var id = obj._listenId || (obj._listenId = BI._.uniqueId("l")); - listeningTo[id] = obj; - if (!callback && typeof name === "object") callback = this; - obj.on(name, callback, this); - return this; - }, - - listenToOnce: function (obj, name, callback) { - if (typeof name === "object") { - for (var event in name) this.listenToOnce(obj, event, name[event]); - return this; - } - if (eventSplitter.test(name)) { - var names = name.split(eventSplitter); - for (var i = 0, length = names.length; i < length; i++) { - this.listenToOnce(obj, names[i], callback); - } - return this; - } - if (!callback) return this; - var once = BI._.once(function () { - this.stopListening(obj, name, once); - callback.apply(this, arguments); - }); - once._callback = callback; - return this.listenTo(obj, name, once); - }, - - // Tell this object to stop listening to either specific events ... or - // to every object it's currently listening to. - stopListening: function (obj, name, callback) { - var listeningTo = this._listeningTo; - if (!listeningTo) return this; - var remove = !name && !callback; - if (!callback && typeof name === "object") callback = this; - if (obj) (listeningTo = {})[obj._listenId] = obj; - for (var id in listeningTo) { - obj = listeningTo[id]; - obj.off(name, callback, this); - if (remove || BI._.isEmpty(obj._events)) delete this._listeningTo[id]; - } - return this; - } - - }; - - // Regular expression used to split event strings. - var eventSplitter = /\s+/; - - // Implement fancy features of the Events API such as multiple event - // names `"change blur"` and jQuery-style event maps `{change: action}` - // in terms of the existing API. - var eventsApi = function (obj, action, name, rest) { - if (!name) return true; - - // Handle event maps. - if (typeof name === "object") { - for (var key in name) { - obj[action].apply(obj, [key, name[key]].concat(rest)); - } - return false; - } - - // Handle space separated event names. - if (eventSplitter.test(name)) { - var names = name.split(eventSplitter); - for (var i = 0, length = names.length; i < length; i++) { - obj[action].apply(obj, [names[i]].concat(rest)); - } - return false; - } - - return true; - }; - - // A difficult-to-believe, but optimized internal dispatch function for - // triggering events. Tries to keep the usual cases speedy (most internal - // BI events have 3 arguments). - var triggerEvents = function (events, args) { - var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; - switch (args.length) { - case 0: - while (++i < l) (ev = events[i]).callback.call(ev.ctx); - return; - case 1: - while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); - return; - case 2: - while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); - return; - case 3: - while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); - return; - default: - while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); - return; - } - }; - - // BI.Router - // --------------- - - // Routers map faux-URLs to actions, and fire events when routes are - // matched. Creating a new one sets its `routes` hash, if not set statically. - var Router = BI.Router = function (options) { - options || (options = {}); - if (options.routes) this.routes = options.routes; - this._bindRoutes(); - this._init.apply(this, arguments); - }; - - // Cached regular expressions for matching named param parts and splatted - // parts of route strings. - var optionalParam = /\((.*?)\)/g; - var namedParam = /(\(\?)?:\w+/g; - var splatParam = /\*\w+/g; - var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; - - // Set up all inheritable **BI.Router** properties and methods. - BI._.extend(Router.prototype, Events, { - - // _init is an empty function by default. Override it with your own - // initialization logic. - _init: function () { - }, - - // Manually bind a single named route to a callback. For example: - // - // this.route('search/:query/p:num', 'search', function(query, num) { - // ... - // }); - // - route: function (route, name, callback) { - if (!BI._.isRegExp(route)) route = this._routeToRegExp(route); - if (BI._.isFunction(name)) { - callback = name; - name = ""; - } - if (!callback) callback = this[name]; - var router = this; - BI.history.route(route, function (fragment) { - var args = router._extractParameters(route, fragment); - if (router.execute(callback, args, name) !== false) { - router.trigger.apply(router, ["route:" + name].concat(args)); - router.trigger("route", name, args); - BI.history.trigger("route", router, name, args); - } - }); - return this; - }, - - // Execute a route handler with the provided parameters. This is an - // excellent place to do pre-route setup or post-route cleanup. - execute: function (callback, args, name) { - if (callback) callback.apply(this, args); - }, - - // Simple proxy to `BI.history` to save a fragment into the history. - navigate: function (fragment, options) { - BI.history.navigate(fragment, options); - return this; - }, - - // Bind all defined routes to `BI.history`. We have to reverse the - // order of the routes here to support behavior where the most general - // routes can be defined at the bottom of the route map. - _bindRoutes: function () { - if (!this.routes) return; - this.routes = BI._.result(this, "routes"); - var route, routes = BI._.keys(this.routes); - while ((route = routes.pop()) != null) { - this.route(route, this.routes[route]); - } - }, - - // Convert a route string into a regular expression, suitable for matching - // against the current location hash. - _routeToRegExp: function (route) { - route = route.replace(escapeRegExp, "\\$&") - .replace(optionalParam, "(?:$1)?") - .replace(namedParam, function (match, optional) { - return optional ? match : "([^/?]+)"; - }) - .replace(splatParam, "([^?]*?)"); - return new RegExp("^" + route + "(?:\\?([\\s\\S]*))?$"); - }, - - // Given a route, and a URL fragment that it matches, return the array of - // extracted decoded parameters. Empty or unmatched parameters will be - // treated as `null` to normalize cross-browser behavior. - _extractParameters: function (route, fragment) { - var params = route.exec(fragment).slice(1); - return BI._.map(params, function (param, i) { - // Don't decode the search params. - if (i === params.length - 1) return param || null; - var resultParam = null; - if (param) { - try { - resultParam = decodeURIComponent(param); - } catch (e) { - resultParam = param; - } - } - return resultParam; - }); - } - - }); - - // History - // ---------------- - - // Handles cross-browser history management, based on either - // [pushState](http://diveintohtml5.info/history.html) and real URLs, or - // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) - // and URL fragments. If the browser supports neither (old IE, natch), - // falls back to polling. - var History = function () { - this.handlers = []; - this.checkUrl = BI._.bind(this.checkUrl, this); - - // Ensure that `History` can be used outside of the browser. - if (typeof window !== "undefined") { - this.location = _global.location; - this.history = _global.history; - } - }; - - // Cached regex for stripping a leading hash/slash and trailing space. - var routeStripper = /^[#\/]|\s+$/g; - - // Cached regex for stripping leading and trailing slashes. - var rootStripper = /^\/+|\/+$/g; - - // Cached regex for stripping urls of hash. - var pathStripper = /#.*$/; - - // Has the history handling already been started? - History.started = false; - - // Set up all inheritable **BI.History** properties and methods. - BI._.extend(History.prototype, Events, { - - // The default interval to poll for hash changes, if necessary, is - // twenty times a second. - interval: 50, - - // Are we at the app root? - atRoot: function () { - var path = this.location.pathname.replace(/[^\/]$/, "$&/"); - return path === this.root && !this.getSearch(); - }, - - // In IE6, the hash fragment and search params are incorrect if the - // fragment contains `?`. - getSearch: function () { - var match = this.location.href.replace(/#.*/, "").match(/\?.+/); - return match ? match[0] : ""; - }, - - // Gets the true hash value. Cannot use location.hash directly due to bug - // in Firefox where location.hash will always be decoded. - getHash: function (window) { - var match = (window || this).location.href.match(/#(.*)$/); - return match ? match[1] : ""; - }, - - // Get the pathname and search params, without the root. - getPath: function () { - var path = this.location.pathname + this.getSearch(); - try { - path = decodeURI(path); - } catch(e) { - } - var root = this.root.slice(0, -1); - if (!path.indexOf(root)) path = path.slice(root.length); - return path.charAt(0) === "/" ? path.slice(1) : path; - }, - - // Get the cross-browser normalized URL fragment from the path or hash. - getFragment: function (fragment) { - if (fragment == null) { - if (this._hasPushState || !this._wantsHashChange) { - fragment = this.getPath(); - } else { - fragment = this.getHash(); - } - } - return fragment.replace(routeStripper, ""); - }, - - // Start the hash change handling, returning `true` if the current URL matches - // an existing route, and `false` otherwise. - start: function (options) { - if (History.started) throw new Error("BI.history has already been started"); - History.started = true; - - // Figure out the initial configuration. Do we need an iframe? - // Is pushState desired ... is it available? - this.options = BI._.extend({root: "/"}, this.options, options); - this.root = this.options.root; - this._wantsHashChange = this.options.hashChange !== false; - this._hasHashChange = "onhashchange" in window; - this._wantsPushState = !!this.options.pushState; - this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); - this.fragment = this.getFragment(); - - // Normalize root to always include a leading and trailing slash. - this.root = ("/" + this.root + "/").replace(rootStripper, "/"); - - // Transition from hashChange to pushState or vice versa if both are - // requested. - if (this._wantsHashChange && this._wantsPushState) { - - // If we've started off with a route from a `pushState`-enabled - // browser, but we're currently in a browser that doesn't support it... - if (!this._hasPushState && !this.atRoot()) { - var root = this.root.slice(0, -1) || "/"; - this.location.replace(root + "#" + this.getPath()); - // Return immediately as browser will do redirect to new url - return true; - - // Or if we've started out with a hash-based route, but we're currently - // in a browser where it could be `pushState`-based instead... - } else if (this._hasPushState && this.atRoot()) { - this.navigate(this.getHash(), {replace: true}); - } - - } - - // Proxy an iframe to handle location events if the browser doesn't - // support the `hashchange` event, HTML5 history, or the user wants - // `hashChange` but not `pushState`. - if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) { - var iframe = document.createElement("iframe"); - iframe.src = "javascript:0"; - iframe.style.display = "none"; - iframe.tabIndex = -1; - var body = document.body; - // Using `appendChild` will throw on IE < 9 if the document is not ready. - this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; - this.iframe.document.open().close(); - this.iframe.location.hash = "#" + this.fragment; - } - - // Add a cross-platform `addEventListener` shim for older browsers. - var addEventListener = _global.addEventListener || function (eventName, listener) { - return attachEvent("on" + eventName, listener); - }; - - // Depending on whether we're using pushState or hashes, and whether - // 'onhashchange' is supported, determine how we check the URL state. - if (this._hasPushState) { - addEventListener("popstate", this.checkUrl, false); - } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { - addEventListener("hashchange", this.checkUrl, false); - } else if (this._wantsHashChange) { - this._checkUrlInterval = setInterval(this.checkUrl, this.interval); - } - - if (!this.options.silent) return this.loadUrl(); - }, - - // Disable BI.history, perhaps temporarily. Not useful in a real app, - // but possibly useful for unit testing Routers. - stop: function () { - // Add a cross-platform `removeEventListener` shim for older browsers. - var removeEventListener = _global.removeEventListener || function (eventName, listener) { - return detachEvent("on" + eventName, listener); - }; - - // Remove window listeners. - if (this._hasPushState) { - removeEventListener("popstate", this.checkUrl, false); - } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { - removeEventListener("hashchange", this.checkUrl, false); - } - - // Clean up the iframe if necessary. - if (this.iframe) { - document.body.removeChild(this.iframe.frameElement); - this.iframe = null; - } - - // Some environments will throw when clearing an undefined interval. - if (this._checkUrlInterval) clearInterval(this._checkUrlInterval); - History.started = false; - }, - - // Add a route to be tested when the fragment changes. Routes added later - // may override previous routes. - route: function (route, callback) { - this.handlers.unshift({route: route, callback: callback}); - }, - - // check route is Exist. if exist, return the route - checkRoute: function (route) { - for (var i = 0; i < this.handlers.length; i++) { - if (this.handlers[i].route.toString() === Router.prototype._routeToRegExp(route).toString()) { - return this.handlers[i]; - } - } - - return null; - }, - - // remove a route match in routes - unRoute: function (route) { - var index = BI._.findIndex(this.handlers, function (handler) { - return handler.route.test(route); - }); - if (index > -1) { - this.handlers.splice(index, 1); - } - }, - - // Checks the current URL to see if it has changed, and if it has, - // calls `loadUrl`, normalizing across the hidden iframe. - checkUrl: function (e) { - var current = this.getFragment(); - try { - // getFragment 得到的值是编码过的,而this.fragment是没有编码过的 - // 英文路径没有问题,遇上中文和空格有问题了 - current = decodeURIComponent(current); - } catch(e) { - } - // If the user pressed the back button, the iframe's hash will have - // changed and we should use that for comparison. - if (current === this.fragment && this.iframe) { - current = this.getHash(this.iframe); - } - - if (current === this.fragment) return false; - if (this.iframe) this.navigate(current); - this.loadUrl(); - }, - - // Attempt to load the current URL fragment. If a route succeeds with a - // match, returns `true`. If no defined routes matches the fragment, - // returns `false`. - loadUrl: function (fragment) { - fragment = this.fragment = this.getFragment(fragment); - return BI._.some(this.handlers, function (handler) { - if (handler.route.test(fragment)) { - handler.callback(fragment); - return true; - } - }); - }, - - // Save a fragment into the hash history, or replace the URL state if the - // 'replace' option is passed. You are responsible for properly URL-encoding - // the fragment in advance. - // - // The options object can contain `trigger: true` if you wish to have the - // route callback be fired (not usually desirable), or `replace: true`, if - // you wish to modify the current URL without adding an entry to the history. - navigate: function (fragment, options) { - if (!History.started) return false; - if (!options || options === true) options = {trigger: !!options}; - - // Normalize the fragment. - fragment = this.getFragment(fragment || ""); - - // Don't include a trailing slash on the root. - var root = this.root; - if (fragment === "" || fragment.charAt(0) === "?") { - root = root.slice(0, -1) || "/"; - } - var url = root + fragment; - - // Strip the hash and decode for matching. - fragment = fragment.replace(pathStripper, "") - try { - fragment = decodeURI(fragment); - } catch(e) { - } - - if (this.fragment === fragment) return; - this.fragment = fragment; - - // If pushState is available, we use it to set the fragment as a real URL. - if (this._hasPushState) { - this.history[options.replace ? "replaceState" : "pushState"]({}, document.title, url); - - // If hash changes haven't been explicitly disabled, update the hash - // fragment to store history. - } else if (this._wantsHashChange) { - this._updateHash(this.location, fragment, options.replace); - if (this.iframe && (fragment !== this.getHash(this.iframe))) { - // Opening and closing the iframe tricks IE7 and earlier to push a - // history entry on hash-tag change. When replace is true, we don't - // want this. - if (!options.replace) this.iframe.document.open().close(); - this._updateHash(this.iframe.location, fragment, options.replace); - } - - // If you've told us that you explicitly don't want fallback hashchange- - // based history, then `navigate` becomes a page refresh. - } else { - return this.location.assign(url); - } - if (options.trigger) return this.loadUrl(fragment); - }, - - // Update the hash location, either replacing the current entry, or adding - // a new one to the browser history. - _updateHash: function (location, fragment, replace) { - if (replace) { - var href = location.href.replace(/(javascript:|#).*$/, ""); - location.replace(href + "#" + fragment); - } else { - // Some browsers require that `hash` contains a leading #. - location.hash = "#" + fragment; - } - } - - }); - - // Create the default BI.history. - BI.history = new History; -}()); \ No newline at end of file diff --git a/src/router/router.js b/src/router/router.js deleted file mode 100644 index 4a2cf0c2f..000000000 --- a/src/router/router.js +++ /dev/null @@ -1,3208 +0,0 @@ -/*! - * vue-router v3.5.2 - * (c) 2021 Evan You - * @license MIT - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory()); - }(this, (function () { 'use strict'; - - /* */ - - function assert (condition, message) { - if (!condition) { - throw new Error(("[vue-router] " + message)) - } - } - - function warn (condition, message) { - if (!condition) { - typeof console !== 'undefined' && console.warn(("[vue-router] " + message)); - } - } - - function extend (a, b) { - for (var key in b) { - a[key] = b[key]; - } - return a - } - - /* */ - - var encodeReserveRE = /[!'()*]/g; - var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); }; - var commaRE = /%2C/g; - - // fixed encodeURIComponent which is more conformant to RFC3986: - // - escapes [!'()*] - // - preserve commas - var encode = function (str) { return encodeURIComponent(str) - .replace(encodeReserveRE, encodeReserveReplacer) - .replace(commaRE, ','); }; - - function decode (str) { - try { - return decodeURIComponent(str) - } catch (err) { - { - warn(false, ("Error decoding \"" + str + "\". Leaving it intact.")); - } - } - return str - } - - function resolveQuery ( - query, - extraQuery, - _parseQuery - ) { - if ( extraQuery === void 0 ) extraQuery = {}; - - var parse = _parseQuery || parseQuery; - var parsedQuery; - try { - parsedQuery = parse(query || ''); - } catch (e) { - warn(false, e.message); - parsedQuery = {}; - } - for (var key in extraQuery) { - var value = extraQuery[key]; - parsedQuery[key] = Array.isArray(value) - ? value.map(castQueryParamValue) - : castQueryParamValue(value); - } - return parsedQuery - } - - var castQueryParamValue = function (value) { return (value == null || typeof value === 'object' ? value : String(value)); }; - - function parseQuery (query) { - var res = {}; - - query = query.trim().replace(/^(\?|#|&)/, ''); - - if (!query) { - return res - } - - query.split('&').forEach(function (param) { - var parts = param.replace(/\+/g, ' ').split('='); - var key = decode(parts.shift()); - var val = parts.length > 0 ? decode(parts.join('=')) : null; - - if (res[key] === undefined) { - res[key] = val; - } else if (Array.isArray(res[key])) { - res[key].push(val); - } else { - res[key] = [res[key], val]; - } - }); - - return res - } - - function stringifyQuery (obj) { - var res = obj - ? Object.keys(obj) - .map(function (key) { - var val = obj[key]; - - if (val === undefined) { - return '' - } - - if (val === null) { - return encode(key) - } - - if (Array.isArray(val)) { - var result = []; - val.forEach(function (val2) { - if (val2 === undefined) { - return - } - if (val2 === null) { - result.push(encode(key)); - } else { - result.push(encode(key) + '=' + encode(val2)); - } - }); - return result.join('&') - } - - return encode(key) + '=' + encode(val) - }) - .filter(function (x) { return x.length > 0; }) - .join('&') - : null; - return res ? ("?" + res) : '' - } - - /* */ - - var trailingSlashRE = /\/?$/; - - function createRoute ( - record, - location, - redirectedFrom, - router - ) { - var stringifyQuery = router && router.options.stringifyQuery; - - var query = location.query || {}; - try { - query = clone(query); - } catch (e) {} - - var route = { - name: location.name || (record && record.name), - meta: (record && record.meta) || {}, - path: location.path || '/', - hash: location.hash || '', - query: query, - params: location.params || {}, - fullPath: getFullPath(location, stringifyQuery), - matched: record ? formatMatch(record) : [] - }; - if (redirectedFrom) { - route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery); - } - return Object.freeze(route) - } - - function clone (value) { - if (Array.isArray(value)) { - return value.map(clone) - } else if (value && typeof value === 'object') { - var res = {}; - for (var key in value) { - res[key] = clone(value[key]); - } - return res - } else { - return value - } - } - - // the starting route that represents the initial state - var START = createRoute(null, { - path: '/' - }); - - function formatMatch (record) { - var res = []; - while (record) { - res.unshift(record); - record = record.parent; - } - return res - } - - function getFullPath ( - ref, - _stringifyQuery - ) { - var path = ref.path; - var query = ref.query; if ( query === void 0 ) query = {}; - var hash = ref.hash; if ( hash === void 0 ) hash = ''; - - var stringify = _stringifyQuery || stringifyQuery; - return (path || '/') + stringify(query) + hash - } - - function isSameRoute (a, b, onlyPath) { - if (b === START) { - return a === b - } else if (!b) { - return false - } else if (a.path && b.path) { - return a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && (onlyPath || - a.hash === b.hash && - isObjectEqual(a.query, b.query)) - } else if (a.name && b.name) { - return ( - a.name === b.name && - (onlyPath || ( - a.hash === b.hash && - isObjectEqual(a.query, b.query) && - isObjectEqual(a.params, b.params)) - ) - ) - } else { - return false - } - } - - function isObjectEqual (a, b) { - if ( a === void 0 ) a = {}; - if ( b === void 0 ) b = {}; - - // handle null value #1566 - if (!a || !b) { return a === b } - var aKeys = Object.keys(a).sort(); - var bKeys = Object.keys(b).sort(); - if (aKeys.length !== bKeys.length) { - return false - } - return aKeys.every(function (key, i) { - var aVal = a[key]; - var bKey = bKeys[i]; - if (bKey !== key) { return false } - var bVal = b[key]; - // query values can be null and undefined - if (aVal == null || bVal == null) { return aVal === bVal } - // check nested equality - if (typeof aVal === 'object' && typeof bVal === 'object') { - return isObjectEqual(aVal, bVal) - } - return String(aVal) === String(bVal) - }) - } - - function isIncludedRoute (current, target) { - return ( - current.path.replace(trailingSlashRE, '/').indexOf( - target.path.replace(trailingSlashRE, '/') - ) === 0 && - (!target.hash || current.hash === target.hash) && - queryIncludes(current.query, target.query) - ) - } - - function queryIncludes (current, target) { - for (var key in target) { - if (!(key in current)) { - return false - } - } - return true - } - - function handleRouteEntered (route) { - for (var i = 0; i < route.matched.length; i++) { - var record = route.matched[i]; - for (var name in record.instances) { - var instance = record.instances[name]; - var cbs = record.enteredCbs[name]; - if (!instance || !cbs) { continue } - delete record.enteredCbs[name]; - for (var i$1 = 0; i$1 < cbs.length; i$1++) { - if (!instance._isBeingDestroyed) { cbs[i$1](instance); } - } - } - } - } - - // var View = { - // name: 'RouterView', - // functional: true, - // props: { - // name: { - // type: String, - // default: 'default' - // } - // }, - // render: function render (_, ref) { - // var props = ref.props; - // var children = ref.children; - // var parent = ref.parent; - // var data = ref.data; - - // // used by devtools to display a router-view badge - // data.routerView = true; - - // // directly use parent context's createElement() function - // // so that components rendered by router-view can resolve named slots - // var h = parent.$createElement; - // var name = props.name; - // var route = parent.$route; - // var cache = parent._routerViewCache || (parent._routerViewCache = {}); - - // // determine current view depth, also check to see if the tree - // // has been toggled inactive but kept-alive. - // var depth = 0; - // var inactive = false; - // while (parent && parent._routerRoot !== parent) { - // var vnodeData = parent.$vnode ? parent.$vnode.data : {}; - // if (vnodeData.routerView) { - // depth++; - // } - // if (vnodeData.keepAlive && parent._directInactive && parent._inactive) { - // inactive = true; - // } - // parent = parent.$parent; - // } - // data.routerViewDepth = depth; - - // // render previous view if the tree is inactive and kept-alive - // if (inactive) { - // var cachedData = cache[name]; - // var cachedComponent = cachedData && cachedData.component; - // if (cachedComponent) { - // // #2301 - // // pass props - // if (cachedData.configProps) { - // fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps); - // } - // return h(cachedComponent, data, children) - // } else { - // // render previous empty view - // return h() - // } - // } - - // var matched = route.matched[depth]; - // var component = matched && matched.components[name]; - - // // render empty node if no matched route or no config component - // if (!matched || !component) { - // cache[name] = null; - // return h() - // } - - // // cache component - // cache[name] = { component: component }; - - // // attach instance registration hook - // // this will be called in the instance's injected lifecycle hooks - // data.registerRouteInstance = function (vm, val) { - // // val could be undefined for unregistration - // var current = matched.instances[name]; - // if ( - // (val && current !== vm) || - // (!val && current === vm) - // ) { - // matched.instances[name] = val; - // } - // } - - // // also register instance in prepatch hook - // // in case the same component instance is reused across different routes - // ;(data.hook || (data.hook = {})).prepatch = function (_, vnode) { - // matched.instances[name] = vnode.componentInstance; - // }; - - // // register instance in init hook - // // in case kept-alive component be actived when routes changed - // data.hook.init = function (vnode) { - // if (vnode.data.keepAlive && - // vnode.componentInstance && - // vnode.componentInstance !== matched.instances[name] - // ) { - // matched.instances[name] = vnode.componentInstance; - // } - - // // if the route transition has already been confirmed then we weren't - // // able to call the cbs during confirmation as the component was not - // // registered yet, so we call it here. - // handleRouteEntered(route); - // }; - - // var configProps = matched.props && matched.props[name]; - // // save route and configProps in cache - // if (configProps) { - // extend(cache[name], { - // route: route, - // configProps: configProps - // }); - // fillPropsinData(component, data, route, configProps); - // } - - // return h(component, data, children) - // } - // }; - - // function fillPropsinData (component, data, route, configProps) { - // // resolve props - // var propsToPass = data.props = resolveProps(route, configProps); - // if (propsToPass) { - // // clone to prevent mutation - // propsToPass = data.props = extend({}, propsToPass); - // // pass non-declared props as attrs - // var attrs = data.attrs = data.attrs || {}; - // for (var key in propsToPass) { - // if (!component.props || !(key in component.props)) { - // attrs[key] = propsToPass[key]; - // delete propsToPass[key]; - // } - // } - // } - // } - - // function resolveProps (route, config) { - // switch (typeof config) { - // case 'undefined': - // return - // case 'object': - // return config - // case 'function': - // return config(route) - // case 'boolean': - // return config ? route.params : undefined - // default: - // { - // warn( - // false, - // "props in \"" + (route.path) + "\" is a " + (typeof config) + ", " + - // "expecting an object, function or boolean." - // ); - // } - // } - // } - - /* */ - - function resolvePath ( - relative, - base, - append - ) { - var firstChar = relative.charAt(0); - if (firstChar === '/') { - return relative - } - - if (firstChar === '?' || firstChar === '#') { - return base + relative - } - - var stack = base.split('/'); - - // remove trailing segment if: - // - not appending - // - appending to trailing slash (last segment is empty) - if (!append || !stack[stack.length - 1]) { - stack.pop(); - } - - // resolve relative path - var segments = relative.replace(/^\//, '').split('/'); - for (var i = 0; i < segments.length; i++) { - var segment = segments[i]; - if (segment === '..') { - stack.pop(); - } else if (segment !== '.') { - stack.push(segment); - } - } - - // ensure leading slash - if (stack[0] !== '') { - stack.unshift(''); - } - - return stack.join('/') - } - - function parsePath (path) { - var hash = ''; - var query = ''; - - var hashIndex = path.indexOf('#'); - if (hashIndex >= 0) { - hash = path.slice(hashIndex); - path = path.slice(0, hashIndex); - } - - var queryIndex = path.indexOf('?'); - if (queryIndex >= 0) { - query = path.slice(queryIndex + 1); - path = path.slice(0, queryIndex); - } - - return { - path: path, - query: query, - hash: hash - } - } - - function cleanPath (path) { - return path.replace(/\/\//g, '/') - } - - var isarray = Array.isArray || function (arr) { - return Object.prototype.toString.call(arr) == '[object Array]'; - }; - - /** - * Expose `pathToRegexp`. - */ - var pathToRegexp_1 = pathToRegexp; - var parse_1 = parse; - var compile_1 = compile; - var tokensToFunction_1 = tokensToFunction; - var tokensToRegExp_1 = tokensToRegExp; - - /** - * The main path matching regexp utility. - * - * @type {RegExp} - */ - var PATH_REGEXP = new RegExp([ - // Match escaped characters that would otherwise appear in future matches. - // This allows the user to escape special characters that won't transform. - '(\\\\.)', - // Match Express-style parameters and un-named parameters with a prefix - // and optional suffixes. Matches appear as: - // - // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] - // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] - // "/*" => ["/", undefined, undefined, undefined, undefined, "*"] - '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' - ].join('|'), 'g'); - - /** - * Parse a string for the raw tokens. - * - * @param {string} str - * @param {Object=} options - * @return {!Array} - */ - function parse (str, options) { - var tokens = []; - var key = 0; - var index = 0; - var path = ''; - var defaultDelimiter = options && options.delimiter || '/'; - var res; - - while ((res = PATH_REGEXP.exec(str)) != null) { - var m = res[0]; - var escaped = res[1]; - var offset = res.index; - path += str.slice(index, offset); - index = offset + m.length; - - // Ignore already escaped sequences. - if (escaped) { - path += escaped[1]; - continue - } - - var next = str[index]; - var prefix = res[2]; - var name = res[3]; - var capture = res[4]; - var group = res[5]; - var modifier = res[6]; - var asterisk = res[7]; - - // Push the current path onto the tokens. - if (path) { - tokens.push(path); - path = ''; - } - - var partial = prefix != null && next != null && next !== prefix; - var repeat = modifier === '+' || modifier === '*'; - var optional = modifier === '?' || modifier === '*'; - var delimiter = res[2] || defaultDelimiter; - var pattern = capture || group; - - tokens.push({ - name: name || key++, - prefix: prefix || '', - delimiter: delimiter, - optional: optional, - repeat: repeat, - partial: partial, - asterisk: !!asterisk, - pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?') - }); - } - - // Match any characters still remaining. - if (index < str.length) { - path += str.substr(index); - } - - // If the path exists, push it onto the end. - if (path) { - tokens.push(path); - } - - return tokens - } - - /** - * Compile a string to a template function for the path. - * - * @param {string} str - * @param {Object=} options - * @return {!function(Object=, Object=)} - */ - function compile (str, options) { - return tokensToFunction(parse(str, options), options) - } - - /** - * Prettier encoding of URI path segments. - * - * @param {string} - * @return {string} - */ - function encodeURIComponentPretty (str) { - return encodeURI(str).replace(/[\/?#]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) - } - - /** - * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. - * - * @param {string} - * @return {string} - */ - function encodeAsterisk (str) { - return encodeURI(str).replace(/[?#]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) - } - - /** - * Expose a method for transforming tokens into the path function. - */ - function tokensToFunction (tokens, options) { - // Compile all the tokens into regexps. - var matches = new Array(tokens.length); - - // Compile all the patterns before compilation. - for (var i = 0; i < tokens.length; i++) { - if (typeof tokens[i] === 'object') { - matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options)); - } - } - - return function (obj, opts) { - var path = ''; - var data = obj || {}; - var options = opts || {}; - var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent; - - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - - if (typeof token === 'string') { - path += token; - - continue - } - - var value = data[token.name]; - var segment; - - if (value == null) { - if (token.optional) { - // Prepend partial segment prefixes. - if (token.partial) { - path += token.prefix; - } - - continue - } else { - throw new TypeError('Expected "' + token.name + '" to be defined') - } - } - - if (isarray(value)) { - if (!token.repeat) { - throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') - } - - if (value.length === 0) { - if (token.optional) { - continue - } else { - throw new TypeError('Expected "' + token.name + '" to not be empty') - } - } - - for (var j = 0; j < value.length; j++) { - segment = encode(value[j]); - - if (!matches[i].test(segment)) { - throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') - } - - path += (j === 0 ? token.prefix : token.delimiter) + segment; - } - - continue - } - - segment = token.asterisk ? encodeAsterisk(value) : encode(value); - - if (!matches[i].test(segment)) { - throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') - } - - path += token.prefix + segment; - } - - return path - } - } - - /** - * Escape a regular expression string. - * - * @param {string} str - * @return {string} - */ - function escapeString (str) { - return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1') - } - - /** - * Escape the capturing group by escaping special characters and meaning. - * - * @param {string} group - * @return {string} - */ - function escapeGroup (group) { - return group.replace(/([=!:$\/()])/g, '\\$1') - } - - /** - * Attach the keys as a property of the regexp. - * - * @param {!RegExp} re - * @param {Array} keys - * @return {!RegExp} - */ - function attachKeys (re, keys) { - re.keys = keys; - return re - } - - /** - * Get the flags for a regexp from the options. - * - * @param {Object} options - * @return {string} - */ - function flags (options) { - return options && options.sensitive ? '' : 'i' - } - - /** - * Pull out keys from a regexp. - * - * @param {!RegExp} path - * @param {!Array} keys - * @return {!RegExp} - */ - function regexpToRegexp (path, keys) { - // Use a negative lookahead to match only capturing groups. - var groups = path.source.match(/\((?!\?)/g); - - if (groups) { - for (var i = 0; i < groups.length; i++) { - keys.push({ - name: i, - prefix: null, - delimiter: null, - optional: false, - repeat: false, - partial: false, - asterisk: false, - pattern: null - }); - } - } - - return attachKeys(path, keys) - } - - /** - * Transform an array into a regexp. - * - * @param {!Array} path - * @param {Array} keys - * @param {!Object} options - * @return {!RegExp} - */ - function arrayToRegexp (path, keys, options) { - var parts = []; - - for (var i = 0; i < path.length; i++) { - parts.push(pathToRegexp(path[i], keys, options).source); - } - - var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options)); - - return attachKeys(regexp, keys) - } - - /** - * Create a path regexp from string input. - * - * @param {string} path - * @param {!Array} keys - * @param {!Object} options - * @return {!RegExp} - */ - function stringToRegexp (path, keys, options) { - return tokensToRegExp(parse(path, options), keys, options) - } - - /** - * Expose a function for taking tokens and returning a RegExp. - * - * @param {!Array} tokens - * @param {(Array|Object)=} keys - * @param {Object=} options - * @return {!RegExp} - */ - function tokensToRegExp (tokens, keys, options) { - if (!isarray(keys)) { - options = /** @type {!Object} */ (keys || options); - keys = []; - } - - options = options || {}; - - var strict = options.strict; - var end = options.end !== false; - var route = ''; - - // Iterate over the tokens and create our regexp string. - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - - if (typeof token === 'string') { - route += escapeString(token); - } else { - var prefix = escapeString(token.prefix); - var capture = '(?:' + token.pattern + ')'; - - keys.push(token); - - if (token.repeat) { - capture += '(?:' + prefix + capture + ')*'; - } - - if (token.optional) { - if (!token.partial) { - capture = '(?:' + prefix + '(' + capture + '))?'; - } else { - capture = prefix + '(' + capture + ')?'; - } - } else { - capture = prefix + '(' + capture + ')'; - } - - route += capture; - } - } - - var delimiter = escapeString(options.delimiter || '/'); - var endsWithDelimiter = route.slice(-delimiter.length) === delimiter; - - // In non-strict mode we allow a slash at the end of match. If the path to - // match already ends with a slash, we remove it for consistency. The slash - // is valid at the end of a path match, not in the middle. This is important - // in non-ending mode, where "/test/" shouldn't match "/test//route". - if (!strict) { - route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'; - } - - if (end) { - route += '$'; - } else { - // In non-ending mode, we need the capturing groups to match as much as - // possible by using a positive lookahead to the end or next path segment. - route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'; - } - - return attachKeys(new RegExp('^' + route, flags(options)), keys) - } - - /** - * Normalize the given path string, returning a regular expression. - * - * An empty array can be passed in for the keys, which will hold the - * placeholder key descriptions. For example, using `/user/:id`, `keys` will - * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. - * - * @param {(string|RegExp|Array)} path - * @param {(Array|Object)=} keys - * @param {Object=} options - * @return {!RegExp} - */ - function pathToRegexp (path, keys, options) { - if (!isarray(keys)) { - options = /** @type {!Object} */ (keys || options); - keys = []; - } - - options = options || {}; - - if (path instanceof RegExp) { - return regexpToRegexp(path, /** @type {!Array} */ (keys)) - } - - if (isarray(path)) { - return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options) - } - - return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options) - } - pathToRegexp_1.parse = parse_1; - pathToRegexp_1.compile = compile_1; - pathToRegexp_1.tokensToFunction = tokensToFunction_1; - pathToRegexp_1.tokensToRegExp = tokensToRegExp_1; - - /* */ - - // $flow-disable-line - var regexpCompileCache = Object.create(null); - - function fillParams ( - path, - params, - routeMsg - ) { - params = params || {}; - try { - var filler = - regexpCompileCache[path] || - (regexpCompileCache[path] = pathToRegexp_1.compile(path)); - - // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }} - // and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string - if (typeof params.pathMatch === 'string') { params[0] = params.pathMatch; } - - return filler(params, { pretty: true }) - } catch (e) { - { - // Fix #3072 no warn if `pathMatch` is string - warn(typeof params.pathMatch === 'string', ("missing param for " + routeMsg + ": " + (e.message))); - } - return '' - } finally { - // delete the 0 if it was added - delete params[0]; - } - } - - /* */ - - function normalizeLocation ( - raw, - current, - append, - router - ) { - var next = typeof raw === 'string' ? { path: raw } : raw; - // named target - if (next._normalized) { - return next - } else if (next.name) { - next = extend({}, raw); - var params = next.params; - if (params && typeof params === 'object') { - next.params = extend({}, params); - } - return next - } - - // relative params - if (!next.path && next.params && current) { - next = extend({}, next); - next._normalized = true; - var params$1 = extend(extend({}, current.params), next.params); - if (current.name) { - next.name = current.name; - next.params = params$1; - } else if (current.matched.length) { - var rawPath = current.matched[current.matched.length - 1].path; - next.path = fillParams(rawPath, params$1, ("path " + (current.path))); - } else { - warn(false, "relative params navigation requires a current route."); - } - return next - } - - var parsedPath = parsePath(next.path || ''); - var basePath = (current && current.path) || '/'; - var path = parsedPath.path - ? resolvePath(parsedPath.path, basePath, append || next.append) - : basePath; - - var query = resolveQuery( - parsedPath.query, - next.query, - router && router.options.parseQuery - ); - - var hash = next.hash || parsedPath.hash; - if (hash && hash.charAt(0) !== '#') { - hash = "#" + hash; - } - - return { - _normalized: true, - path: path, - query: query, - hash: hash - } - } - - // var toTypes = [String, Object]; - // var eventTypes = [String, Array]; - - // var noop = function () {}; - - // var warnedCustomSlot; - // var warnedTagProp; - // var warnedEventProp; - - // var Link = { - // name: 'RouterLink', - // props: { - // to: { - // type: toTypes, - // required: true - // }, - // tag: { - // type: String, - // default: 'a' - // }, - // custom: Boolean, - // exact: Boolean, - // exactPath: Boolean, - // append: Boolean, - // replace: Boolean, - // activeClass: String, - // exactActiveClass: String, - // ariaCurrentValue: { - // type: String, - // default: 'page' - // }, - // event: { - // type: eventTypes, - // default: 'click' - // } - // }, - // render: function render (h) { - // var this$1 = this; - - // var router = this.$router; - // var current = this.$route; - // var ref = router.resolve( - // this.to, - // current, - // this.append - // ); - // var location = ref.location; - // var route = ref.route; - // var href = ref.href; - - // var classes = {}; - // var globalActiveClass = router.options.linkActiveClass; - // var globalExactActiveClass = router.options.linkExactActiveClass; - // // Support global empty active class - // var activeClassFallback = - // globalActiveClass == null ? 'router-link-active' : globalActiveClass; - // var exactActiveClassFallback = - // globalExactActiveClass == null - // ? 'router-link-exact-active' - // : globalExactActiveClass; - // var activeClass = - // this.activeClass == null ? activeClassFallback : this.activeClass; - // var exactActiveClass = - // this.exactActiveClass == null - // ? exactActiveClassFallback - // : this.exactActiveClass; - - // var compareTarget = route.redirectedFrom - // ? createRoute(null, normalizeLocation(route.redirectedFrom), null, router) - // : route; - - // classes[exactActiveClass] = isSameRoute(current, compareTarget, this.exactPath); - // classes[activeClass] = this.exact || this.exactPath - // ? classes[exactActiveClass] - // : isIncludedRoute(current, compareTarget); - - // var ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null; - - // var handler = function (e) { - // if (guardEvent(e)) { - // if (this$1.replace) { - // router.replace(location, noop); - // } else { - // router.push(location, noop); - // } - // } - // }; - - // var on = { click: guardEvent }; - // if (Array.isArray(this.event)) { - // this.event.forEach(function (e) { - // on[e] = handler; - // }); - // } else { - // on[this.event] = handler; - // } - - // var data = { class: classes }; - - // var scopedSlot = - // !this.$scopedSlots.$hasNormal && - // this.$scopedSlots.default && - // this.$scopedSlots.default({ - // href: href, - // route: route, - // navigate: handler, - // isActive: classes[activeClass], - // isExactActive: classes[exactActiveClass] - // }); - - // if (scopedSlot) { - // if (!this.custom) { - // !warnedCustomSlot && warn(false, 'In Vue Router 4, the v-slot API will by default wrap its content with an element. Use the custom prop to remove this warning:\n\n'); - // warnedCustomSlot = true; - // } - // if (scopedSlot.length === 1) { - // return scopedSlot[0] - // } else if (scopedSlot.length > 1 || !scopedSlot.length) { - // { - // warn( - // false, - // (" with to=\"" + (this.to) + "\" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.") - // ); - // } - // return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot) - // } - // } - - // { - // if ('tag' in this.$options.propsData && !warnedTagProp) { - // warn( - // false, - // "'s tag prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link." - // ); - // warnedTagProp = true; - // } - // if ('event' in this.$options.propsData && !warnedEventProp) { - // warn( - // false, - // "'s event prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link." - // ); - // warnedEventProp = true; - // } - // } - - // if (this.tag === 'a') { - // data.on = on; - // data.attrs = { href: href, 'aria-current': ariaCurrentValue }; - // } else { - // // find the first child and apply listener and href - // var a = findAnchor(this.$slots.default); - // if (a) { - // // in case the is a static node - // a.isStatic = false; - // var aData = (a.data = extend({}, a.data)); - // aData.on = aData.on || {}; - // // transform existing events in both objects into arrays so we can push later - // for (var event in aData.on) { - // var handler$1 = aData.on[event]; - // if (event in on) { - // aData.on[event] = Array.isArray(handler$1) ? handler$1 : [handler$1]; - // } - // } - // // append new listeners for router-link - // for (var event$1 in on) { - // if (event$1 in aData.on) { - // // on[event] is always a function - // aData.on[event$1].push(on[event$1]); - // } else { - // aData.on[event$1] = handler; - // } - // } - - // var aAttrs = (a.data.attrs = extend({}, a.data.attrs)); - // aAttrs.href = href; - // aAttrs['aria-current'] = ariaCurrentValue; - // } else { - // // doesn't have child, apply listener to self - // data.on = on; - // } - // } - - // return h(this.tag, data, this.$slots.default) - // } - // }; - - function guardEvent (e) { - // don't redirect with control keys - if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return } - // don't redirect when preventDefault called - if (e.defaultPrevented) { return } - // don't redirect on right click - if (e.button !== undefined && e.button !== 0) { return } - // don't redirect if `target="_blank"` - if (e.currentTarget && e.currentTarget.getAttribute) { - var target = e.currentTarget.getAttribute('target'); - if (/\b_blank\b/i.test(target)) { return } - } - // this may be a Weex event which doesn't have this method - if (e.preventDefault) { - e.preventDefault(); - } - return true - } - - function findAnchor (children) { - if (children) { - var child; - for (var i = 0; i < children.length; i++) { - child = children[i]; - if (child.tag === 'a') { - return child - } - if (child.children && (child = findAnchor(child.children))) { - return child - } - } - } - } - - // var _Vue; - - // function install (Vue) { - // if (install.installed && _Vue === Vue) { return } - // install.installed = true; - - // _Vue = Vue; - - // var isDef = function (v) { return v !== undefined; }; - - // var registerInstance = function (vm, callVal) { - // var i = vm.$options._parentVnode; - // if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) { - // i(vm, callVal); - // } - // }; - - // Vue.mixin({ - // beforeCreate: function beforeCreate () { - // if (isDef(this.$options.router)) { - // this._routerRoot = this; - // this._router = this.$options.router; - // this._router.init(this); - // Vue.util.defineReactive(this, '_route', this._router.history.current); - // } else { - // this._routerRoot = (this.$parent && this.$parent._routerRoot) || this; - // } - // registerInstance(this, this); - // }, - // destroyed: function destroyed () { - // registerInstance(this); - // } - // }); - - // Object.defineProperty(Vue.prototype, '$router', { - // get: function get () { return this._routerRoot._router } - // }); - - // Object.defineProperty(Vue.prototype, '$route', { - // get: function get () { return this._routerRoot._route } - // }); - - // Vue.component('RouterView', View); - // Vue.component('RouterLink', Link); - - // var strats = Vue.config.optionMergeStrategies; - // // use the same hook merging strategy for route hooks - // strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created; - // } - - /* */ - - var inBrowser = typeof window !== 'undefined'; - - /* */ - - function createRouteMap ( - routes, - oldPathList, - oldPathMap, - oldNameMap, - parentRoute - ) { - // the path list is used to control path matching priority - var pathList = oldPathList || []; - // $flow-disable-line - var pathMap = oldPathMap || Object.create(null); - // $flow-disable-line - var nameMap = oldNameMap || Object.create(null); - - routes.forEach(function (route) { - addRouteRecord(pathList, pathMap, nameMap, route, parentRoute); - }); - - // ensure wildcard routes are always at the end - for (var i = 0, l = pathList.length; i < l; i++) { - if (pathList[i] === '*') { - pathList.push(pathList.splice(i, 1)[0]); - l--; - i--; - } - } - - { - // warn if routes do not include leading slashes - var found = pathList - // check for missing leading slash - .filter(function (path) { return path && path.charAt(0) !== '*' && path.charAt(0) !== '/'; }); - - if (found.length > 0) { - var pathNames = found.map(function (path) { return ("- " + path); }).join('\n'); - warn(false, ("Non-nested routes must include a leading slash character. Fix the following routes: \n" + pathNames)); - } - } - - return { - pathList: pathList, - pathMap: pathMap, - nameMap: nameMap - } - } - - function addRouteRecord ( - pathList, - pathMap, - nameMap, - route, - parent, - matchAs - ) { - var path = route.path; - var name = route.name; - { - assert(path != null, "\"path\" is required in a route configuration."); - assert( - typeof route.component !== 'string', - "route config \"component\" for path: " + (String( - path || name - )) + " cannot be a " + "string id. Use an actual component instead." - ); - - warn( - // eslint-disable-next-line no-control-regex - !/[^\u0000-\u007F]+/.test(path), - "Route with path \"" + path + "\" contains unencoded characters, make sure " + - "your path is correctly encoded before passing it to the router. Use " + - "encodeURI to encode static segments of your path." - ); - } - - var pathToRegexpOptions = - route.pathToRegexpOptions || {}; - var normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict); - - if (typeof route.caseSensitive === 'boolean') { - pathToRegexpOptions.sensitive = route.caseSensitive; - } - - var record = { - path: normalizedPath, - regex: compileRouteRegex(normalizedPath, pathToRegexpOptions), - components: route.components || { default: route.component }, - alias: route.alias - ? typeof route.alias === 'string' - ? [route.alias] - : route.alias - : [], - instances: {}, - enteredCbs: {}, - name: name, - parent: parent, - matchAs: matchAs, - redirect: route.redirect, - beforeEnter: route.beforeEnter, - meta: route.meta || {}, - props: - route.props == null - ? {} - : route.components - ? route.props - : { default: route.props } - }; - - if (route.children) { - // Warn if route is named, does not redirect and has a default child route. - // If users navigate to this route by name, the default child will - // not be rendered (GH Issue #629) - { - if ( - route.name && - !route.redirect && - route.children.some(function (child) { return /^\/?$/.test(child.path); }) - ) { - warn( - false, - "Named Route '" + (route.name) + "' has a default child route. " + - "When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " + - "the default child route will not be rendered. Remove the name from " + - "this route and use the name of the default child route for named " + - "links instead." - ); - } - } - route.children.forEach(function (child) { - var childMatchAs = matchAs - ? cleanPath((matchAs + "/" + (child.path))) - : undefined; - addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs); - }); - } - - if (!pathMap[record.path]) { - pathList.push(record.path); - pathMap[record.path] = record; - } - - if (route.alias !== undefined) { - var aliases = Array.isArray(route.alias) ? route.alias : [route.alias]; - for (var i = 0; i < aliases.length; ++i) { - var alias = aliases[i]; - if (alias === path) { - warn( - false, - ("Found an alias with the same value as the path: \"" + path + "\". You have to remove that alias. It will be ignored in development.") - ); - // skip in dev to make it work - continue - } - - var aliasRoute = { - path: alias, - children: route.children - }; - addRouteRecord( - pathList, - pathMap, - nameMap, - aliasRoute, - parent, - record.path || '/' // matchAs - ); - } - } - - if (name) { - if (!nameMap[name]) { - nameMap[name] = record; - } else if (!matchAs) { - warn( - false, - "Duplicate named routes definition: " + - "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }" - ); - } - } - } - - function compileRouteRegex ( - path, - pathToRegexpOptions - ) { - var regex = pathToRegexp_1(path, [], pathToRegexpOptions); - { - var keys = Object.create(null); - regex.keys.forEach(function (key) { - warn( - !keys[key.name], - ("Duplicate param keys in route with path: \"" + path + "\"") - ); - keys[key.name] = true; - }); - } - return regex - } - - function normalizePath ( - path, - parent, - strict - ) { - if (!strict) { path = path.replace(/\/$/, ''); } - if (path[0] === '/') { return path } - if (parent == null) { return path } - return cleanPath(((parent.path) + "/" + path)) - } - - /* */ - - - - function createMatcher ( - routes, - router - ) { - var ref = createRouteMap(routes); - var pathList = ref.pathList; - var pathMap = ref.pathMap; - var nameMap = ref.nameMap; - - function addRoutes (routes) { - createRouteMap(routes, pathList, pathMap, nameMap); - } - - function addRoute (parentOrRoute, route) { - var parent = (typeof parentOrRoute !== 'object') ? nameMap[parentOrRoute] : undefined; - // $flow-disable-line - createRouteMap([route || parentOrRoute], pathList, pathMap, nameMap, parent); - - // add aliases of parent - if (parent && parent.alias.length) { - createRouteMap( - // $flow-disable-line route is defined if parent is - parent.alias.map(function (alias) { return ({ path: alias, children: [route] }); }), - pathList, - pathMap, - nameMap, - parent - ); - } - } - - function getRoutes () { - return pathList.map(function (path) { return pathMap[path]; }) - } - - function match ( - raw, - currentRoute, - redirectedFrom - ) { - var location = normalizeLocation(raw, currentRoute, false, router); - var name = location.name; - - if (name) { - var record = nameMap[name]; - { - warn(record, ("Route with name '" + name + "' does not exist")); - } - if (!record) { return _createRoute(null, location) } - var paramNames = record.regex.keys - .filter(function (key) { return !key.optional; }) - .map(function (key) { return key.name; }); - - if (typeof location.params !== 'object') { - location.params = {}; - } - - if (currentRoute && typeof currentRoute.params === 'object') { - for (var key in currentRoute.params) { - if (!(key in location.params) && paramNames.indexOf(key) > -1) { - location.params[key] = currentRoute.params[key]; - } - } - } - - location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")); - return _createRoute(record, location, redirectedFrom) - } else if (location.path) { - location.params = {}; - for (var i = 0; i < pathList.length; i++) { - var path = pathList[i]; - var record$1 = pathMap[path]; - if (matchRoute(record$1.regex, location.path, location.params)) { - return _createRoute(record$1, location, redirectedFrom) - } - } - } - // no match - return _createRoute(null, location) - } - - function redirect ( - record, - location - ) { - var originalRedirect = record.redirect; - var redirect = typeof originalRedirect === 'function' - ? originalRedirect(createRoute(record, location, null, router)) - : originalRedirect; - - if (typeof redirect === 'string') { - redirect = { path: redirect }; - } - - if (!redirect || typeof redirect !== 'object') { - { - warn( - false, ("invalid redirect option: " + (JSON.stringify(redirect))) - ); - } - return _createRoute(null, location) - } - - var re = redirect; - var name = re.name; - var path = re.path; - var query = location.query; - var hash = location.hash; - var params = location.params; - query = re.hasOwnProperty('query') ? re.query : query; - hash = re.hasOwnProperty('hash') ? re.hash : hash; - params = re.hasOwnProperty('params') ? re.params : params; - - if (name) { - // resolved named direct - var targetRecord = nameMap[name]; - { - assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found.")); - } - return match({ - _normalized: true, - name: name, - query: query, - hash: hash, - params: params - }, undefined, location) - } else if (path) { - // 1. resolve relative redirect - var rawPath = resolveRecordPath(path, record); - // 2. resolve params - var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\"")); - // 3. rematch with existing query and hash - return match({ - _normalized: true, - path: resolvedPath, - query: query, - hash: hash - }, undefined, location) - } else { - { - warn(false, ("invalid redirect option: " + (JSON.stringify(redirect)))); - } - return _createRoute(null, location) - } - } - - function alias ( - record, - location, - matchAs - ) { - var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\"")); - var aliasedMatch = match({ - _normalized: true, - path: aliasedPath - }); - if (aliasedMatch) { - var matched = aliasedMatch.matched; - var aliasedRecord = matched[matched.length - 1]; - location.params = aliasedMatch.params; - return _createRoute(aliasedRecord, location) - } - return _createRoute(null, location) - } - - function _createRoute ( - record, - location, - redirectedFrom - ) { - if (record && record.redirect) { - return redirect(record, redirectedFrom || location) - } - if (record && record.matchAs) { - return alias(record, location, record.matchAs) - } - return createRoute(record, location, redirectedFrom, router) - } - - return { - match: match, - addRoute: addRoute, - getRoutes: getRoutes, - addRoutes: addRoutes - } - } - - function matchRoute ( - regex, - path, - params - ) { - var m = path.match(regex); - - if (!m) { - return false - } else if (!params) { - return true - } - - for (var i = 1, len = m.length; i < len; ++i) { - var key = regex.keys[i - 1]; - if (key) { - // Fix #1994: using * with props: true generates a param named 0 - params[key.name || 'pathMatch'] = typeof m[i] === 'string' ? decode(m[i]) : m[i]; - } - } - - return true - } - - function resolveRecordPath (path, record) { - return resolvePath(path, record.parent ? record.parent.path : '/', true) - } - - /* */ - - // use User Timing api (if present) for more accurate key precision - var Time = - inBrowser && window.performance && window.performance.now - ? window.performance - : Date; - - function genStateKey () { - return Time.now().toFixed(3) - } - - var _key = genStateKey(); - - function getStateKey () { - return _key - } - - function setStateKey (key) { - return (_key = key) - } - - /* */ - - var positionStore = Object.create(null); - - function setupScroll () { - // Prevent browser scroll behavior on History popstate - if ('scrollRestoration' in window.history) { - window.history.scrollRestoration = 'manual'; - } - // Fix for #1585 for Firefox - // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678 - // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with - // window.location.protocol + '//' + window.location.host - // location.host contains the port and location.hostname doesn't - var protocolAndPath = window.location.protocol + '//' + window.location.host; - var absolutePath = window.location.href.replace(protocolAndPath, ''); - // preserve existing history state as it could be overriden by the user - var stateCopy = extend({}, window.history.state); - stateCopy.key = getStateKey(); - window.history.replaceState(stateCopy, '', absolutePath); - window.addEventListener('popstate', handlePopState); - return function () { - window.removeEventListener('popstate', handlePopState); - } - } - - function handleScroll ( - router, - to, - from, - isPop - ) { - if (!router.app) { - return - } - - var behavior = router.options.scrollBehavior; - if (!behavior) { - return - } - - { - assert(typeof behavior === 'function', "scrollBehavior must be a function"); - } - - // wait until re-render finishes before scrolling - BI.nextTick(function () { - var position = getScrollPosition(); - var shouldScroll = behavior.call( - router, - to, - from, - isPop ? position : null - ); - - if (!shouldScroll) { - return - } - - if (typeof shouldScroll.then === 'function') { - shouldScroll - .then(function (shouldScroll) { - scrollToPosition((shouldScroll), position); - }) - .catch(function (err) { - { - assert(false, err.toString()); - } - }); - } else { - scrollToPosition(shouldScroll, position); - } - }); - } - - function saveScrollPosition () { - var key = getStateKey(); - if (key) { - positionStore[key] = { - x: window.pageXOffset, - y: window.pageYOffset - }; - } - } - - function handlePopState (e) { - saveScrollPosition(); - if (e.state && e.state.key) { - setStateKey(e.state.key); - } - } - - function getScrollPosition () { - var key = getStateKey(); - if (key) { - return positionStore[key] - } - } - - function getElementPosition (el, offset) { - var docEl = document.documentElement; - var docRect = docEl.getBoundingClientRect(); - var elRect = el.getBoundingClientRect(); - return { - x: elRect.left - docRect.left - offset.x, - y: elRect.top - docRect.top - offset.y - } - } - - function isValidPosition (obj) { - return isNumber(obj.x) || isNumber(obj.y) - } - - function normalizePosition (obj) { - return { - x: isNumber(obj.x) ? obj.x : window.pageXOffset, - y: isNumber(obj.y) ? obj.y : window.pageYOffset - } - } - - function normalizeOffset (obj) { - return { - x: isNumber(obj.x) ? obj.x : 0, - y: isNumber(obj.y) ? obj.y : 0 - } - } - - function isNumber (v) { - return typeof v === 'number' - } - - var hashStartsWithNumberRE = /^#\d/; - - function scrollToPosition (shouldScroll, position) { - var isObject = typeof shouldScroll === 'object'; - if (isObject && typeof shouldScroll.selector === 'string') { - // getElementById would still fail if the selector contains a more complicated query like #main[data-attr] - // but at the same time, it doesn't make much sense to select an element with an id and an extra selector - var el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line - ? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line - : document.querySelector(shouldScroll.selector); - - if (el) { - var offset = - shouldScroll.offset && typeof shouldScroll.offset === 'object' - ? shouldScroll.offset - : {}; - offset = normalizeOffset(offset); - position = getElementPosition(el, offset); - } else if (isValidPosition(shouldScroll)) { - position = normalizePosition(shouldScroll); - } - } else if (isObject && isValidPosition(shouldScroll)) { - position = normalizePosition(shouldScroll); - } - - if (position) { - // $flow-disable-line - if ('scrollBehavior' in document.documentElement.style) { - window.scrollTo({ - left: position.x, - top: position.y, - // $flow-disable-line - behavior: shouldScroll.behavior - }); - } else { - window.scrollTo(position.x, position.y); - } - } - } - - /* */ - - var supportsPushState = - inBrowser && - (function () { - var ua = window.navigator.userAgent; - - if ( - (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && - ua.indexOf('Mobile Safari') !== -1 && - ua.indexOf('Chrome') === -1 && - ua.indexOf('Windows Phone') === -1 - ) { - return false - } - - return window.history && typeof window.history.pushState === 'function' - })(); - - function pushState (url, replace) { - saveScrollPosition(); - // try...catch the pushState call to get around Safari - // DOM Exception 18 where it limits to 100 pushState calls - var history = window.history; - try { - if (replace) { - // preserve existing history state as it could be overriden by the user - var stateCopy = extend({}, history.state); - stateCopy.key = getStateKey(); - history.replaceState(stateCopy, '', url); - } else { - history.pushState({ key: setStateKey(genStateKey()) }, '', url); - } - } catch (e) { - window.location[replace ? 'replace' : 'assign'](url); - } - } - - function replaceState (url) { - pushState(url, true); - } - - /* */ - - function runQueue (queue, fn, cb) { - var step = function (index) { - if (index >= queue.length) { - cb(); - } else { - if (queue[index]) { - fn(queue[index], function () { - step(index + 1); - }); - } else { - step(index + 1); - } - } - }; - step(0); - } - - // When changing thing, also edit router.d.ts - var NavigationFailureType = { - redirected: 2, - aborted: 4, - cancelled: 8, - duplicated: 16 - }; - - function createNavigationRedirectedError (from, to) { - return createRouterError( - from, - to, - NavigationFailureType.redirected, - ("Redirected when going from \"" + (from.fullPath) + "\" to \"" + (stringifyRoute( - to - )) + "\" via a navigation guard.") - ) - } - - function createNavigationDuplicatedError (from, to) { - var error = createRouterError( - from, - to, - NavigationFailureType.duplicated, - ("Avoided redundant navigation to current location: \"" + (from.fullPath) + "\".") - ); - // backwards compatible with the first introduction of Errors - error.name = 'NavigationDuplicated'; - return error - } - - function createNavigationCancelledError (from, to) { - return createRouterError( - from, - to, - NavigationFailureType.cancelled, - ("Navigation cancelled from \"" + (from.fullPath) + "\" to \"" + (to.fullPath) + "\" with a new navigation.") - ) - } - - function createNavigationAbortedError (from, to) { - return createRouterError( - from, - to, - NavigationFailureType.aborted, - ("Navigation aborted from \"" + (from.fullPath) + "\" to \"" + (to.fullPath) + "\" via a navigation guard.") - ) - } - - function createRouterError (from, to, type, message) { - var error = new Error(message); - error._isRouter = true; - error.from = from; - error.to = to; - error.type = type; - - return error - } - - var propertiesToLog = ['params', 'query', 'hash']; - - function stringifyRoute (to) { - if (typeof to === 'string') { return to } - if ('path' in to) { return to.path } - var location = {}; - propertiesToLog.forEach(function (key) { - if (key in to) { location[key] = to[key]; } - }); - return JSON.stringify(location, null, 2) - } - - function isError (err) { - return Object.prototype.toString.call(err).indexOf('Error') > -1 - } - - function isNavigationFailure (err, errorType) { - return ( - isError(err) && - err._isRouter && - (errorType == null || err.type === errorType) - ) - } - - /* */ - - function resolveAsyncComponents (matched) { - return function (to, from, next) { - var hasAsync = false; - var pending = 0; - var error = null; - - flatMapComponents(matched, function (def, _, match, key) { - // if it's a function and doesn't have cid attached, - // assume it's an async component resolve function. - // we are not using Vue's default async resolving mechanism because - // we want to halt the navigation until the incoming component has been - // resolved. - if (typeof def === 'function' && def.cid === undefined) { - hasAsync = true; - pending++; - - var resolve = once(function (resolvedDef) { - if (isESModule(resolvedDef)) { - resolvedDef = resolvedDef.default; - } - // save resolved on async factory in case it's used elsewhere - def.resolved = resolvedDef; - match.components[key] = resolvedDef; - pending--; - if (pending <= 0) { - next(); - } - }); - - var reject = once(function (reason) { - var msg = "Failed to resolve async component " + key + ": " + reason; - warn(false, msg); - if (!error) { - error = isError(reason) - ? reason - : new Error(msg); - next(error); - } - }); - - var res; - try { - res = def(resolve, reject); - } catch (e) { - reject(e); - } - if (res) { - if (typeof res.then === 'function') { - res.then(resolve, reject); - } else { - // new syntax in Vue 2.3 - var comp = res.component; - if (comp && typeof comp.then === 'function') { - comp.then(resolve, reject); - } - } - } - } - }); - - if (!hasAsync) { next(); } - } - } - - function flatMapComponents ( - matched, - fn - ) { - return flatten(matched.map(function (m) { - return Object.keys(m.components).map(function (key) { return fn( - m.components[key], - m.instances[key], - m, key - ); }) - })) - } - - function flatten (arr) { - return Array.prototype.concat.apply([], arr) - } - - var hasSymbol = - typeof Symbol === 'function' && - typeof Symbol.toStringTag === 'symbol'; - - function isESModule (obj) { - return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module') - } - - // in Webpack 2, require.ensure now also returns a Promise - // so the resolve/reject functions may get called an extra time - // if the user uses an arrow function shorthand that happens to - // return that Promise. - function once (fn) { - var called = false; - return function () { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - if (called) { return } - called = true; - return fn.apply(this, args) - } - } - - /* */ - - var History = function History (router, base) { - this.router = router; - this.base = normalizeBase(base); - // start with a route object that stands for "nowhere" - this.current = START; - this.pending = null; - this.ready = false; - this.readyCbs = []; - this.readyErrorCbs = []; - this.errorCbs = []; - this.listeners = []; - }; - - History.prototype.listen = function listen (cb) { - this.cb = cb; - }; - - History.prototype.onReady = function onReady (cb, errorCb) { - if (this.ready) { - cb(); - } else { - this.readyCbs.push(cb); - if (errorCb) { - this.readyErrorCbs.push(errorCb); - } - } - }; - - History.prototype.onError = function onError (errorCb) { - this.errorCbs.push(errorCb); - }; - - History.prototype.transitionTo = function transitionTo ( - location, - onComplete, - onAbort - ) { - var this$1 = this; - - var route; - // catch redirect option https://github.com/vuejs/vue-router/issues/3201 - try { - route = this.router.match(location, this.current); - } catch (e) { - this.errorCbs.forEach(function (cb) { - cb(e); - }); - // Exception should still be thrown - throw e - } - var prev = this.current; - this.confirmTransition( - route, - function () { - this$1.updateRoute(route); - onComplete && onComplete(route); - this$1.ensureURL(); - this$1.router.afterHooks.forEach(function (hook) { - hook && hook(route, prev); - }); - - // fire ready cbs once - if (!this$1.ready) { - this$1.ready = true; - this$1.readyCbs.forEach(function (cb) { - cb(route); - }); - } - }, - function (err) { - if (onAbort) { - onAbort(err); - } - if (err && !this$1.ready) { - // Initial redirection should not mark the history as ready yet - // because it's triggered by the redirection instead - // https://github.com/vuejs/vue-router/issues/3225 - // https://github.com/vuejs/vue-router/issues/3331 - if (!isNavigationFailure(err, NavigationFailureType.redirected) || prev !== START) { - this$1.ready = true; - this$1.readyErrorCbs.forEach(function (cb) { - cb(err); - }); - } - } - } - ); - }; - - History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) { - var this$1 = this; - - var current = this.current; - this.pending = route; - var abort = function (err) { - // changed after adding errors with - // https://github.com/vuejs/vue-router/pull/3047 before that change, - // redirect and aborted navigation would produce an err == null - if (!isNavigationFailure(err) && isError(err)) { - if (this$1.errorCbs.length) { - this$1.errorCbs.forEach(function (cb) { - cb(err); - }); - } else { - warn(false, 'uncaught error during route navigation:'); - console.error(err); - } - } - onAbort && onAbort(err); - }; - var lastRouteIndex = route.matched.length - 1; - var lastCurrentIndex = current.matched.length - 1; - if ( - isSameRoute(route, current) && - // in the case the route map has been dynamically appended to - lastRouteIndex === lastCurrentIndex && - route.matched[lastRouteIndex] === current.matched[lastCurrentIndex] - ) { - this.ensureURL(); - return; - } - - var ref = resolveQueue( - this.current.matched, - route.matched - ); - var updated = ref.updated; - var deactivated = ref.deactivated; - var activated = ref.activated; - - var queue = [].concat( - // in-component leave guards - extractLeaveGuards(deactivated), - // global before hooks - this.router.beforeHooks, - // in-component update hooks - extractUpdateHooks(updated), - // in-config enter guards - activated.map(function (m) { return m.beforeEnter; }), - // async components - resolveAsyncComponents(activated) - ); - - var iterator = function (hook, next) { - if (this$1.pending !== route) { - return abort(createNavigationCancelledError(current, route)) - } - try { - hook(route, current, function (to) { - if (to === false) { - // next(false) -> abort navigation, ensure current URL - this$1.ensureURL(true); - abort(createNavigationAbortedError(current, route)); - } else if (isError(to)) { - this$1.ensureURL(true); - abort(to); - } else if ( - typeof to === 'string' || - (typeof to === 'object' && - (typeof to.path === 'string' || typeof to.name === 'string')) - ) { - // next('/') or next({ path: '/' }) -> redirect - abort(createNavigationRedirectedError(current, route)); - if (typeof to === 'object' && to.replace) { - this$1.replace(to); - } else { - this$1.push(to); - } - } else { - // confirm transition and pass on the value - next(to); - } - }); - } catch (e) { - abort(e); - } - }; - - runQueue(queue, iterator, function () { - // wait until async components are resolved before - // extracting in-component enter guards - var enterGuards = extractEnterGuards(activated); - var queue = enterGuards.concat(this$1.router.resolveHooks); - runQueue(queue, iterator, function () { - if (this$1.pending !== route) { - return abort(createNavigationCancelledError(current, route)) - } - this$1.pending = null; - onComplete(route); - if (this$1.router.app) { - BI.nextTick(function () { - handleRouteEntered(route); - }); - } - }); - }); - }; - - History.prototype.updateRoute = function updateRoute (route) { - this.current = route; - this.cb && this.cb(route); - }; - - History.prototype.setupListeners = function setupListeners () { - // Default implementation is empty - }; - - History.prototype.teardown = function teardown () { - // clean up event listeners - // https://github.com/vuejs/vue-router/issues/2341 - this.listeners.forEach(function (cleanupListener) { - cleanupListener(); - }); - this.listeners = []; - - // reset current history route - // https://github.com/vuejs/vue-router/issues/3294 - this.current = START; - this.pending = null; - }; - - function normalizeBase (base) { - if (!base) { - if (inBrowser) { - // respect tag - var baseEl = document.querySelector('base'); - base = (baseEl && baseEl.getAttribute('href')) || '/'; - // strip full URL origin - base = base.replace(/^https?:\/\/[^\/]+/, ''); - } else { - base = '/'; - } - } - // make sure there's the starting slash - if (base.charAt(0) !== '/') { - base = '/' + base; - } - // remove trailing slash - return base.replace(/\/$/, '') - } - - function resolveQueue ( - current, - next - ) { - var i; - var max = Math.max(current.length, next.length); - for (i = 0; i < max; i++) { - if (current[i] !== next[i]) { - break - } - } - return { - updated: next.slice(0, i), - activated: next.slice(i), - deactivated: current.slice(i) - } - } - - function extractGuards ( - records, - name, - bind, - reverse - ) { - var guards = flatMapComponents(records, function (def, instance, match, key) { - var guard = extractGuard(def, name); - if (guard) { - return Array.isArray(guard) - ? guard.map(function (guard) { return bind(guard, instance, match, key); }) - : bind(guard, instance, match, key) - } - }); - return flatten(reverse ? guards.reverse() : guards) - } - - function extractGuard ( - def, - key - ) { - if (typeof def !== 'function') { - // extend now so that global mixins are applied. - // def = _Vue.extend(def); - } - return def[key] - } - - function extractLeaveGuards (deactivated) { - return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true) - } - - function extractUpdateHooks (updated) { - return extractGuards(updated, 'beforeRouteUpdate', bindGuard) - } - - function bindGuard (guard, instance) { - if (instance) { - return function boundRouteGuard () { - return guard.apply(instance, arguments) - } - } - } - - function extractEnterGuards ( - activated - ) { - return extractGuards( - activated, - 'beforeRouteEnter', - function (guard, _, match, key) { - return bindEnterGuard(guard, match, key) - } - ) - } - - function bindEnterGuard ( - guard, - match, - key - ) { - return function routeEnterGuard (to, from, next) { - return guard(to, from, function (cb) { - if (typeof cb === 'function') { - if (!match.enteredCbs[key]) { - match.enteredCbs[key] = []; - } - match.enteredCbs[key].push(cb); - } - next(cb); - }) - } - } - - /* */ - - var HTML5History = /*@__PURE__*/(function (History) { - function HTML5History (router, base) { - History.call(this, router, base); - - this._startLocation = getLocation(this.base); - } - - if ( History ) HTML5History.__proto__ = History; - HTML5History.prototype = Object.create( History && History.prototype ); - HTML5History.prototype.constructor = HTML5History; - - HTML5History.prototype.setupListeners = function setupListeners () { - var this$1 = this; - - if (this.listeners.length > 0) { - return - } - - var router = this.router; - var expectScroll = router.options.scrollBehavior; - var supportsScroll = supportsPushState && expectScroll; - - if (supportsScroll) { - this.listeners.push(setupScroll()); - } - - var handleRoutingEvent = function () { - var current = this$1.current; - - // Avoiding first `popstate` event dispatched in some browsers but first - // history route not updated since async guard at the same time. - var location = getLocation(this$1.base); - if (this$1.current === START && location === this$1._startLocation) { - return - } - - this$1.transitionTo(location, function (route) { - if (supportsScroll) { - handleScroll(router, route, current, true); - } - }); - }; - window.addEventListener('popstate', handleRoutingEvent); - this.listeners.push(function () { - window.removeEventListener('popstate', handleRoutingEvent); - }); - }; - - HTML5History.prototype.go = function go (n) { - window.history.go(n); - }; - - HTML5History.prototype.push = function push (location, onComplete, onAbort) { - var this$1 = this; - - var ref = this; - var fromRoute = ref.current; - this.transitionTo(location, function (route) { - pushState(cleanPath(this$1.base + route.fullPath)); - handleScroll(this$1.router, route, fromRoute, false); - onComplete && onComplete(route); - }, onAbort); - }; - - HTML5History.prototype.replace = function replace (location, onComplete, onAbort) { - var this$1 = this; - - var ref = this; - var fromRoute = ref.current; - this.transitionTo(location, function (route) { - replaceState(cleanPath(this$1.base + route.fullPath)); - handleScroll(this$1.router, route, fromRoute, false); - onComplete && onComplete(route); - }, onAbort); - }; - - HTML5History.prototype.ensureURL = function ensureURL (push) { - if (getLocation(this.base) !== this.current.fullPath) { - var current = cleanPath(this.base + this.current.fullPath); - push ? pushState(current) : replaceState(current); - } - }; - - HTML5History.prototype.getCurrentLocation = function getCurrentLocation () { - return getLocation(this.base) - }; - - return HTML5History; - }(History)); - - function getLocation (base) { - var path = window.location.pathname; - var pathLowerCase = path.toLowerCase(); - var baseLowerCase = base.toLowerCase(); - // base="/a" shouldn't turn path="/app" into "/a/pp" - // https://github.com/vuejs/vue-router/issues/3555 - // so we ensure the trailing slash in the base - if (base && ((pathLowerCase === baseLowerCase) || - (pathLowerCase.indexOf(cleanPath(baseLowerCase + '/')) === 0))) { - path = path.slice(base.length); - } - return (path || '/') + window.location.search + window.location.hash - } - - /* */ - - var HashHistory = /*@__PURE__*/(function (History) { - function HashHistory (router, base, fallback) { - History.call(this, router, base); - // check history fallback deeplinking - if (fallback && checkFallback(this.base)) { - return - } - ensureSlash(); - } - - if ( History ) HashHistory.__proto__ = History; - HashHistory.prototype = Object.create( History && History.prototype ); - HashHistory.prototype.constructor = HashHistory; - - // this is delayed until the app mounts - // to avoid the hashchange listener being fired too early - HashHistory.prototype.setupListeners = function setupListeners () { - var this$1 = this; - - if (this.listeners.length > 0) { - return - } - - var router = this.router; - var expectScroll = router.options.scrollBehavior; - var supportsScroll = supportsPushState && expectScroll; - - if (supportsScroll) { - this.listeners.push(setupScroll()); - } - - var handleRoutingEvent = function () { - var current = this$1.current; - if (!ensureSlash()) { - return - } - this$1.transitionTo(getHash(), function (route) { - if (supportsScroll) { - handleScroll(this$1.router, route, current, true); - } - if (!supportsPushState) { - replaceHash(route.fullPath); - } - }); - }; - var eventType = supportsPushState ? 'popstate' : 'hashchange'; - window.addEventListener( - eventType, - handleRoutingEvent - ); - this.listeners.push(function () { - window.removeEventListener(eventType, handleRoutingEvent); - }); - }; - - HashHistory.prototype.push = function push (location, onComplete, onAbort) { - var this$1 = this; - - var ref = this; - var fromRoute = ref.current; - this.transitionTo( - location, - function (route) { - pushHash(route.fullPath); - handleScroll(this$1.router, route, fromRoute, false); - onComplete && onComplete(route); - }, - onAbort - ); - }; - - HashHistory.prototype.replace = function replace (location, onComplete, onAbort) { - var this$1 = this; - - var ref = this; - var fromRoute = ref.current; - this.transitionTo( - location, - function (route) { - replaceHash(route.fullPath); - handleScroll(this$1.router, route, fromRoute, false); - onComplete && onComplete(route); - }, - onAbort - ); - }; - - HashHistory.prototype.go = function go (n) { - window.history.go(n); - }; - - HashHistory.prototype.ensureURL = function ensureURL (push) { - var current = this.current.fullPath; - if (getHash() !== current) { - push ? pushHash(current) : replaceHash(current); - } - }; - - HashHistory.prototype.getCurrentLocation = function getCurrentLocation () { - return getHash() - }; - - return HashHistory; - }(History)); - - function checkFallback (base) { - var location = getLocation(base); - if (!/^\/#/.test(location)) { - window.location.replace(cleanPath(base + '/#' + location)); - return true - } - } - - function ensureSlash () { - var path = getHash(); - if (path.charAt(0) === '/') { - return true - } - replaceHash('/' + path); - return false - } - - function getHash () { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - var href = window.location.href; - var index = href.indexOf('#'); - // empty path - if (index < 0) { return '' } - - href = href.slice(index + 1); - - return href - } - - function getUrl (path) { - var href = window.location.href; - var i = href.indexOf('#'); - var base = i >= 0 ? href.slice(0, i) : href; - return (base + "#" + path) - } - - function pushHash (path) { - if (supportsPushState) { - pushState(getUrl(path)); - } else { - window.location.hash = path; - } - } - - function replaceHash (path) { - if (supportsPushState) { - replaceState(getUrl(path)); - } else { - window.location.replace(getUrl(path)); - } - } - - /* */ - - var AbstractHistory = /*@__PURE__*/(function (History) { - function AbstractHistory (router, base) { - History.call(this, router, base); - this.stack = []; - this.index = -1; - } - - if ( History ) AbstractHistory.__proto__ = History; - AbstractHistory.prototype = Object.create( History && History.prototype ); - AbstractHistory.prototype.constructor = AbstractHistory; - - AbstractHistory.prototype.push = function push (location, onComplete, onAbort) { - var this$1 = this; - - this.transitionTo( - location, - function (route) { - this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route); - this$1.index++; - onComplete && onComplete(route); - }, - onAbort - ); - }; - - AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) { - var this$1 = this; - - this.transitionTo( - location, - function (route) { - this$1.stack = this$1.stack.slice(0, this$1.index).concat(route); - onComplete && onComplete(route); - }, - onAbort - ); - }; - - AbstractHistory.prototype.go = function go (n) { - var this$1 = this; - - var targetIndex = this.index + n; - if (targetIndex < 0 || targetIndex >= this.stack.length) { - return - } - var route = this.stack[targetIndex]; - this.confirmTransition( - route, - function () { - var prev = this$1.current; - this$1.index = targetIndex; - this$1.updateRoute(route); - this$1.router.afterHooks.forEach(function (hook) { - hook && hook(route, prev); - }); - }, - function (err) { - if (isNavigationFailure(err, NavigationFailureType.duplicated)) { - this$1.index = targetIndex; - } - } - ); - }; - - AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () { - var current = this.stack[this.stack.length - 1]; - return current ? current.fullPath : '/' - }; - - AbstractHistory.prototype.ensureURL = function ensureURL () { - // noop - }; - - return AbstractHistory; - }(History)); - - /* */ - - var VueRouter = function VueRouter (options) { - if ( options === void 0 ) options = {}; - - this.app = null; - this.apps = []; - this.options = options; - this.beforeHooks = []; - this.resolveHooks = []; - this.afterHooks = []; - this.matcher = createMatcher(options.routes || [], this); - - var mode = options.mode || 'hash'; - this.fallback = - mode === 'history' && !supportsPushState && options.fallback !== false; - if (this.fallback) { - mode = 'hash'; - } - if (!inBrowser) { - mode = 'abstract'; - } - this.mode = mode; - - switch (mode) { - case 'history': - this.history = new HTML5History(this, options.base); - break - case 'hash': - this.history = new HashHistory(this, options.base, this.fallback); - break - case 'abstract': - this.history = new AbstractHistory(this, options.base); - break - default: - { - assert(false, ("invalid mode: " + mode)); - } - } - }; - - var prototypeAccessors = { currentRoute: { configurable: true } }; - - VueRouter.prototype.match = function match (raw, current, redirectedFrom) { - return this.matcher.match(raw, current, redirectedFrom) - }; - - prototypeAccessors.currentRoute.get = function () { - return this.history && this.history.current - }; - - VueRouter.prototype.init = function init (app /* Vue component instance */) { - var this$1 = this; - - this.apps.push(app); - - // set up app destroyed handler - // https://github.com/vuejs/vue-router/issues/2639 - app.once('hook:destroyed', function () { - // clean out app from this.apps array once destroyed - var index = this$1.apps.indexOf(app); - if (index > -1) { this$1.apps.splice(index, 1); } - // ensure we still have a main app or null if no apps - // we do not release the router so it can be reused - if (this$1.app === app) { this$1.app = this$1.apps[0] || null; } - - if (!this$1.app) { this$1.history.teardown(); } - }); - - // main app previously initialized - // return as we don't need to set up new history listener - if (this.app) { - return - } - - this.app = app; - - var history = this.history; - - if (history instanceof HTML5History || history instanceof HashHistory) { - var handleInitialScroll = function (routeOrError) { - var from = history.current; - var expectScroll = this$1.options.scrollBehavior; - var supportsScroll = supportsPushState && expectScroll; - - if (supportsScroll && 'fullPath' in routeOrError) { - handleScroll(this$1, routeOrError, from, false); - } - }; - var setupListeners = function (routeOrError) { - history.setupListeners(); - handleInitialScroll(routeOrError); - }; - history.transitionTo( - history.getCurrentLocation(), - setupListeners, - setupListeners - ); - } - - history.listen(function (route) { - this$1.apps.forEach(function (app) { - app._router.history.current = route; - }); - }); - }; - - VueRouter.prototype.beforeEach = function beforeEach (fn) { - return registerHook(this.beforeHooks, fn) - }; - - VueRouter.prototype.beforeResolve = function beforeResolve (fn) { - return registerHook(this.resolveHooks, fn) - }; - - VueRouter.prototype.afterEach = function afterEach (fn) { - return registerHook(this.afterHooks, fn) - }; - - VueRouter.prototype.onReady = function onReady (cb, errorCb) { - this.history.onReady(cb, errorCb); - }; - - VueRouter.prototype.onError = function onError (errorCb) { - this.history.onError(errorCb); - }; - - VueRouter.prototype.push = function push (location, onComplete, onAbort) { - var this$1 = this; - - // $flow-disable-line - if (!onComplete && !onAbort && typeof Promise !== 'undefined') { - return new Promise(function (resolve, reject) { - this$1.history.push(location, resolve, reject); - }) - } else { - this.history.push(location, onComplete, onAbort); - } - }; - - VueRouter.prototype.replace = function replace (location, onComplete, onAbort) { - var this$1 = this; - - // $flow-disable-line - if (!onComplete && !onAbort && typeof Promise !== 'undefined') { - return new Promise(function (resolve, reject) { - this$1.history.replace(location, resolve, reject); - }) - } else { - this.history.replace(location, onComplete, onAbort); - } - }; - - VueRouter.prototype.go = function go (n) { - this.history.go(n); - }; - - VueRouter.prototype.back = function back () { - this.go(-1); - }; - - VueRouter.prototype.forward = function forward () { - this.go(1); - }; - - VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) { - var route = to - ? to.matched - ? to - : this.resolve(to).route - : this.currentRoute; - if (!route) { - return [] - } - return [].concat.apply( - [], - route.matched.map(function (m) { - return Object.keys(m.components).map(function (key) { - return m.components[key] - }) - }) - ) - }; - - VueRouter.prototype.resolve = function resolve ( - to, - current, - append - ) { - current = current || this.history.current; - var location = normalizeLocation(to, current, append, this); - var route = this.match(location, current); - var fullPath = route.redirectedFrom || route.fullPath; - var base = this.history.base; - var href = createHref(base, fullPath, this.mode); - return { - location: location, - route: route, - href: href, - // for backwards compat - normalizedTo: location, - resolved: route - } - }; - - VueRouter.prototype.getRoutes = function getRoutes () { - return this.matcher.getRoutes() - }; - - VueRouter.prototype.addRoute = function addRoute (parentOrRoute, route) { - this.matcher.addRoute(parentOrRoute, route); - if (this.history.current !== START) { - this.history.transitionTo(this.history.getCurrentLocation()); - } - }; - - Object.defineProperties( VueRouter.prototype, prototypeAccessors ); - - function registerHook (list, fn) { - list.push(fn); - return function () { - var i = list.indexOf(fn); - if (i > -1) { list.splice(i, 1); } - } - } - - function createHref (base, fullPath, mode) { - var path = mode === 'hash' ? '#' + fullPath : fullPath; - return base ? cleanPath(base + '/' + path) : path - } - - // VueRouter.install = install; - VueRouter.version = '3.5.2'; - VueRouter.isNavigationFailure = isNavigationFailure; - VueRouter.NavigationFailureType = NavigationFailureType; - VueRouter.START_LOCATION = START; - - - var $router, cbs = []; - BI.RouterWidget = BI.inherit(BI.Widget, { - init: function () { - this.$router = this._router = BI.Router.$router = $router = new VueRouter({ - mode: this.options.mode, - routes: this.options.routes, - base: this.options.base, - }); - Fix.defineReactiveProperty(BI.Router.$router.history, "current"); - this.$router.beforeEach(function (to, from, next) { - if (to.matched.length === 0) { - //如果上级也未匹配到路由则跳转主页面,如果上级能匹配到则转上级路由 - from.path ? next({ path: from.path }) : next('/'); - } else { - //如果匹配到正确跳转 - next(); - } - }); - this.$router.afterEach(function () { - cbs.forEach(function (cb) {cb();}); - }); - this.$router.init(this); - } - }); - BI.shortcut("bi.router", BI.RouterWidget); - - BI.RouterView = BI.inherit(BI.Widget, { - props: { - baseCls: 'bi-router-view', - deps: 0, - name: 'default' - }, - created: function () { - var self = this, o = this.options; - cbs.push(this._callbackListener = function () { - var current = $router.history.current; - // 匹配的路径名(/component/:id) - var matchedPath = current.matched[o.deps] && current.matched[o.deps].path; - var component = current.matched[o.deps] && current.matched[o.deps].components[o.name]; - - if (BI.isNotNull(component)) { - if (matchedPath) { - BI.each(current.params, function (key, value) { - // 把 :id 替换成具体的值(/component/demo.td) - matchedPath = matchedPath.replace(`:${key}`, value); - }); - } - self.tab.setSelect(matchedPath || "/"); - } - }); - // "bi.router_view"是由"bi.tab"实现的,cardCreator是一个异步过程,在"bi.router_view"创建之前,cbs里不会有创建子组件的方法,在初始化路由时,没法直接渲染到子组件,所以这里手动加了一次调用 - this._callbackListener(); - }, - render: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - ref: function (_ref) { - self.tab = _ref; - }, - single: o.single, // 是不是单页面 - keepAlives: o.keepAlives, - logic: { - dynamic: false - }, - showIndex: false, - cardCreator: function (v) { - return $router.history.current.matched[o.deps].components[o.name]; - } - }; - }, - destroyed: function () { - // BI.remove方法会把第二个参数当迭代器执行导致方法多执行一遍 - cbs.splice(cbs.indexOf(this._callbackListener), 1); - } - }); - BI.shortcut("bi.router_view", BI.RouterView); - - BI.Router = BI.Router || VueRouter; - BI.Router.isSameRoute = isSameRoute; - return VueRouter; - - }))); - \ No newline at end of file diff --git a/src/third/sort.gb2312.js b/src/third/sort.gb2312.js deleted file mode 100644 index be8277301..000000000 --- a/src/third/sort.gb2312.js +++ /dev/null @@ -1,7 +0,0 @@ -!(function () { - var codes = " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺚⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠⻡⻢⻣⻤⻥⻦⻧⻨⻩⻪⻫⻬⻭⻮⻯⻰⻱⻲⻳⻴⻵⻶⻷⻸⻹⻺⻻⻼⻽⻾⻿⼀⼁⼂⼃⼄⼅⼆⼇⼈⼉⼊⼋⼌⼍⼎⼏⼐⼑⼒⼓⼔⼕⼖⼗⼘⼙⼚⼛⼜⼝⼞⼟⼠⼡⼢⼣⼤⼥⼦⼧⼨⼩⼪⼫⼬⼭⼮⼯⼰⼱⼲⼳⼴⼵⼶⼷⼸⼹⼺⼻⼼⼽⼾⼿⽀⽁⽂⽃⽄⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿⾀⾁⾂⾃⾄⾅⾆⾇⾈⾉⾊⾋⾌⾍⾎⾏⾐⾑⾒⾓⾔⾕⾖⾗⾘⾙⾚⾛⾜⾝⾞⾟⾠⾡⾢⾣⾤⾥⾦⾧⾨⾩⾪⾫⾬⾭⾮⾯⾰⾱⾲⾳⾴⾵⾶⾷⾸⾹⾺⾻⾼⾽⾾⾿⿀⿁⿂⿃⿄⿅⿆⿇⿈⿉⿊⿋⿌⿍⿎⿏⿐⿑⿒⿓⿔⿕⿖⿗⿘⿙⿚⿛⿜⿝⿞⿟⿠⿡⿢⿣⿤⿥⿦⿧⿨⿩⿪⿫⿬⿭⿮⿯⿰⿱⿲⿳⿴⿵⿶⿷⿸⿹⿺⿻⿼⿽⿾⿿ 、。〃〄々〆〇〈〉《》「」『』【】〒〓〔〕〖〗〘〙〚〛〜〝〞〟〠〡〢〣〤〥〦〧〨〩〪〭〮〯〫〬〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾〿぀ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ゗゘゙゚゛゜ゝゞゟ゠ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ㄀㄁㄂㄃㄄ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩㄪㄫㄬㄭㄮㄯ㄰ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ㆏㆐㆑㆒㆓㆔㆕㆖㆗㆘㆙㆚㆛㆜㆝㆞㆟ㆠㆡㆢㆣㆤㆥㆦㆧㆨㆩㆪㆫㆬㆭㆮㆯㆰㆱㆲㆳㆴㆵㆶㆷㆸㆹㆺㆻㆼㆽㆾㆿ㇀㇁㇂㇃㇄㇅㇆㇇㇈㇉㇊㇋㇌㇍㇎㇏㇐㇑㇒㇓㇔㇕㇖㇗㇘㇙㇚㇛㇜㇝㇞㇟㇠㇡㇢㇣㇤㇥㇦㇧㇨㇩㇪㇫㇬㇭㇮㇯ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㈝㈞㈟㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈪㈫㈬㈭㈮㈯㈰㈱㈲㈳㈴㈵㈶㈷㈸㈹㈺㈻㈼㈽㈾㈿㉀㉁㉂㉃㉄㉅㉆㉇㉈㉉㉊㉋㉌㉍㉎㉏㉐㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉼㉽㉾㉿㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㊊㊋㊌㊍㊎㊏㊐㊑㊒㊓㊔㊕㊖㊗㊘㊙㊚㊛㊜㊝㊞㊟㊠㊡㊢㊣㊤㊥㊦㊧㊨㊩㊪㊫㊬㊭㊮㊯㊰㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㋌㋍㋎㋏㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝㋞㋟㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽㋾㋿㌀㌁㌂㌃㌄㌅㌆㌇㌈㌉㌊㌋㌌㌍㌎㌏㌐㌑㌒㌓㌔㌕㌖㌗㌘㌙㌚㌛㌜㌝㌞㌟㌠㌡㌢㌣㌤㌥㌦㌧㌨㌩㌪㌫㌬㌭㌮㌯㌰㌱㌲㌳㌴㌵㌶㌷㌸㌹㌺㌻㌼㌽㌾㌿㍀㍁㍂㍃㍄㍅㍆㍇㍈㍉㍊㍋㍌㍍㍎㍏㍐㍑㍒㍓㍔㍕㍖㍗㍘㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍱㍲㍳㍴㍵㍶㍷㍸㍹㍺㍻㍼㍽㍾㍿㎀㎁㎂㎃㎄㎅㎆㎇㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏋㏌㏍㏎㏏㏐㏑㏒㏓㏔㏕㏖㏗㏘㏙㏚㏛㏜㏝㏞㏟㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㏿㐀㐁㐂㐃㐄㐅㐆㐇㐈㐉㐊㐋㐌㐍㐎㐏㐐㐑㐒㐓㐔㐕㐖㐗㐘㐙㐚㐛㐜㐝㐞㐟㐠㐡㐢㐣㐤㐥㐦㐧㐨㐩㐪㐫㐬㐭㐮㐯㐰㐱㐲㐳㐴㐵㐶㐷㐸㐹㐺㐻㐼㐽㐾㐿㑀㑁㑂㑃㑄㑅㑆㑇㑈㑉㑊㑋㑌㑍㑎㑏㑐㑑㑒㑓㑔㑕㑖㑗㑘㑙㑚㑛㑜㑝㑞㑟㑠㑡㑢㑣㑤㑥㑦㑧㑨㑩㑪㑫㑬㑭㑮㑯㑰㑱㑲㑳㑴㑵㑶㑷㑸㑹㑺㑻㑼㑽㑾㑿㒀㒁㒂㒃㒄㒅㒆㒇㒈㒉㒊㒋㒌㒍㒎㒏㒐㒑㒒㒓㒔㒕㒖㒗㒘㒙㒚㒛㒜㒝㒞㒟㒠㒡㒢㒣㒤㒥㒦㒧㒨㒩㒪㒫㒬㒭㒮㒯㒰㒱㒲㒳㒴㒵㒶㒷㒸㒹㒺㒻㒼㒽㒾㒿㓀㓁㓂㓃㓄㓅㓆㓇㓈㓉㓊㓋㓌㓍㓎㓏㓐㓑㓒㓓㓔㓕㓖㓗㓘㓙㓚㓛㓜㓝㓞㓟㓠㓡㓢㓣㓤㓥㓦㓧㓨㓩㓪㓫㓬㓭㓮㓯㓰㓱㓲㓳㓴㓵㓶㓷㓸㓹㓺㓻㓼㓽㓾㓿㔀㔁㔂㔃㔄㔅㔆㔇㔈㔉㔊㔋㔌㔍㔎㔏㔐㔑㔒㔓㔔㔕㔖㔗㔘㔙㔚㔛㔜㔝㔞㔟㔠㔡㔢㔣㔤㔥㔦㔧㔨㔩㔪㔫㔬㔭㔮㔯㔰㔱㔲㔳㔴㔵㔶㔷㔸㔹㔺㔻㔼㔽㔾㔿㕀㕁㕂㕃㕄㕅㕆㕇㕈㕉㕊㕋㕌㕍㕎㕏㕐㕑㕒㕓㕔㕕㕖㕗㕘㕙㕚㕛㕜㕝㕞㕟㕠㕡㕢㕣㕤㕥㕦㕧㕨㕩㕪㕫㕬㕭㕮㕯㕰㕱㕲㕳㕴㕵㕶㕷㕸㕹㕺㕻㕼㕽㕾㕿㖀㖁㖂㖃㖄㖅㖆㖇㖈㖉㖊㖋㖌㖍㖎㖏㖐㖑㖒㖓㖔㖕㖖㖗㖘㖙㖚㖛㖜㖝㖞㖟㖠㖡㖢㖣㖤㖥㖦㖧㖨㖩㖪㖫㖬㖭㖮㖯㖰㖱㖲㖳㖴㖵㖶㖷㖸㖹㖺㖻㖼㖽㖾㖿㗀㗁㗂㗃㗄㗅㗆㗇㗈㗉㗊㗋㗌㗍㗎㗏㗐㗑㗒㗓㗔㗕㗖㗗㗘㗙㗚㗛㗜㗝㗞㗟㗠㗡㗢㗣㗤㗥㗦㗧㗨㗩㗪㗫㗬㗭㗮㗯㗰㗱㗲㗳㗴㗵㗶㗷㗸㗹㗺㗻㗼㗽㗾㗿㘀㘁㘂㘃㘄㘅㘆㘇㘈㘉㘊㘋㘌㘍㘎㘏㘐㘑㘒㘓㘔㘕㘖㘗㘘㘙㘚㘛㘜㘝㘞㘟㘠㘡㘢㘣㘤㘥㘦㘧㘨㘩㘪㘫㘬㘭㘮㘯㘰㘱㘲㘳㘴㘵㘶㘷㘸㘹㘺㘻㘼㘽㘾㘿㙀㙁㙂㙃㙄㙅㙆㙇㙈㙉㙊㙋㙌㙍㙎㙏㙐㙑㙒㙓㙔㙕㙖㙗㙘㙙㙚㙛㙜㙝㙞㙟㙠㙡㙢㙣㙤㙥㙦㙧㙨㙩㙪㙫㙬㙭㙮㙯㙰㙱㙲㙳㙴㙵㙶㙷㙸㙹㙺㙻㙼㙽㙾㙿㚀㚁㚂㚃㚄㚅㚆㚇㚈㚉㚊㚋㚌㚍㚎㚏㚐㚑㚒㚓㚔㚕㚖㚗㚘㚙㚚㚛㚜㚝㚞㚟㚠㚡㚢㚣㚤㚥㚦㚧㚨㚩㚪㚫㚬㚭㚮㚯㚰㚱㚲㚳㚴㚵㚶㚷㚸㚹㚺㚻㚼㚽㚾㚿㛀㛁㛂㛃㛄㛅㛆㛇㛈㛉㛊㛋㛌㛍㛎㛏㛐㛑㛒㛓㛔㛕㛖㛗㛘㛙㛚㛛㛜㛝㛞㛟㛠㛡㛢㛣㛤㛥㛦㛧㛨㛩㛪㛫㛬㛭㛮㛯㛰㛱㛲㛳㛴㛵㛶㛷㛸㛹㛺㛻㛼㛽㛾㛿㜀㜁㜂㜃㜄㜅㜆㜇㜈㜉㜊㜋㜌㜍㜎㜏㜐㜑㜒㜓㜔㜕㜖㜗㜘㜙㜚㜛㜜㜝㜞㜟㜠㜡㜢㜣㜤㜥㜦㜧㜨㜩㜪㜫㜬㜭㜮㜯㜰㜱㜲㜳㜴㜵㜶㜷㜸㜹㜺㜻㜼㜽㜾㜿㝀㝁㝂㝃㝄㝅㝆㝇㝈㝉㝊㝋㝌㝍㝎㝏㝐㝑㝒㝓㝔㝕㝖㝗㝘㝙㝚㝛㝜㝝㝞㝟㝠㝡㝢㝣㝤㝥㝦㝧㝨㝩㝪㝫㝬㝭㝮㝯㝰㝱㝲㝳㝴㝵㝶㝷㝸㝹㝺㝻㝼㝽㝾㝿㞀㞁㞂㞃㞄㞅㞆㞇㞈㞉㞊㞋㞌㞍㞎㞏㞐㞑㞒㞓㞔㞕㞖㞗㞘㞙㞚㞛㞜㞝㞞㞟㞠㞡㞢㞣㞤㞥㞦㞧㞨㞩㞪㞫㞬㞭㞮㞯㞰㞱㞲㞳㞴㞵㞶㞷㞸㞹㞺㞻㞼㞽㞾㞿㟀㟁㟂㟃㟄㟅㟆㟇㟈㟉㟊㟋㟌㟍㟎㟏㟐㟑㟒㟓㟔㟕㟖㟗㟘㟙㟚㟛㟜㟝㟞㟟㟠㟡㟢㟣㟤㟥㟦㟧㟨㟩㟪㟫㟬㟭㟮㟯㟰㟱㟲㟳㟴㟵㟶㟷㟸㟹㟺㟻㟼㟽㟾㟿㠀㠁㠂㠃㠄㠅㠆㠇㠈㠉㠊㠋㠌㠍㠎㠏㠐㠑㠒㠓㠔㠕㠖㠗㠘㠙㠚㠛㠜㠝㠞㠟㠠㠡㠢㠣㠤㠥㠦㠧㠨㠩㠪㠫㠬㠭㠮㠯㠰㠱㠲㠳㠴㠵㠶㠷㠸㠹㠺㠻㠼㠽㠾㠿㡀㡁㡂㡃㡄㡅㡆㡇㡈㡉㡊㡋㡌㡍㡎㡏㡐㡑㡒㡓㡔㡕㡖㡗㡘㡙㡚㡛㡜㡝㡞㡟㡠㡡㡢㡣㡤㡥㡦㡧㡨㡩㡪㡫㡬㡭㡮㡯㡰㡱㡲㡳㡴㡵㡶㡷㡸㡹㡺㡻㡼㡽㡾㡿㢀㢁㢂㢃㢄㢅㢆㢇㢈㢉㢊㢋㢌㢍㢎㢏㢐㢑㢒㢓㢔㢕㢖㢗㢘㢙㢚㢛㢜㢝㢞㢟㢠㢡㢢㢣㢤㢥㢦㢧㢨㢩㢪㢫㢬㢭㢮㢯㢰㢱㢲㢳㢴㢵㢶㢷㢸㢹㢺㢻㢼㢽㢾㢿㣀㣁㣂㣃㣄㣅㣆㣇㣈㣉㣊㣋㣌㣍㣎㣏㣐㣑㣒㣓㣔㣕㣖㣗㣘㣙㣚㣛㣜㣝㣞㣟㣠㣡㣢㣣㣤㣥㣦㣧㣨㣩㣪㣫㣬㣭㣮㣯㣰㣱㣲㣳㣴㣵㣶㣷㣸㣹㣺㣻㣼㣽㣾㣿㤀㤁㤂㤃㤄㤅㤆㤇㤈㤉㤊㤋㤌㤍㤎㤏㤐㤑㤒㤓㤔㤕㤖㤗㤘㤙㤚㤛㤜㤝㤞㤟㤠㤡㤢㤣㤤㤥㤦㤧㤨㤩㤪㤫㤬㤭㤮㤯㤰㤱㤲㤳㤴㤵㤶㤷㤸㤹㤺㤻㤼㤽㤾㤿㥀㥁㥂㥃㥄㥅㥆㥇㥈㥉㥊㥋㥌㥍㥎㥏㥐㥑㥒㥓㥔㥕㥖㥗㥘㥙㥚㥛㥜㥝㥞㥟㥠㥡㥢㥣㥤㥥㥦㥧㥨㥩㥪㥫㥬㥭㥮㥯㥰㥱㥲㥳㥴㥵㥶㥷㥸㥹㥺㥻㥼㥽㥾㥿㦀㦁㦂㦃㦄㦅㦆㦇㦈㦉㦊㦋㦌㦍㦎㦏㦐㦑㦒㦓㦔㦕㦖㦗㦘㦙㦚㦛㦜㦝㦞㦟㦠㦡㦢㦣㦤㦥㦦㦧㦨㦩㦪㦫㦬㦭㦮㦯㦰㦱㦲㦳㦴㦵㦶㦷㦸㦹㦺㦻㦼㦽㦾㦿㧀㧁㧂㧃㧄㧅㧆㧇㧈㧉㧊㧋㧌㧍㧎㧏㧐㧑㧒㧓㧔㧕㧖㧗㧘㧙㧚㧛㧜㧝㧞㧟㧠㧡㧢㧣㧤㧥㧦㧧㧨㧩㧪㧫㧬㧭㧮㧯㧰㧱㧲㧳㧴㧵㧶㧷㧸㧹㧺㧻㧼㧽㧾㧿㨀㨁㨂㨃㨄㨅㨆㨇㨈㨉㨊㨋㨌㨍㨎㨏㨐㨑㨒㨓㨔㨕㨖㨗㨘㨙㨚㨛㨜㨝㨞㨟㨠㨡㨢㨣㨤㨥㨦㨧㨨㨩㨪㨫㨬㨭㨮㨯㨰㨱㨲㨳㨴㨵㨶㨷㨸㨹㨺㨻㨼㨽㨾㨿㩀㩁㩂㩃㩄㩅㩆㩇㩈㩉㩊㩋㩌㩍㩎㩏㩐㩑㩒㩓㩔㩕㩖㩗㩘㩙㩚㩛㩜㩝㩞㩟㩠㩡㩢㩣㩤㩥㩦㩧㩨㩩㩪㩫㩬㩭㩮㩯㩰㩱㩲㩳㩴㩵㩶㩷㩸㩹㩺㩻㩼㩽㩾㩿㪀㪁㪂㪃㪄㪅㪆㪇㪈㪉㪊㪋㪌㪍㪎㪏㪐㪑㪒㪓㪔㪕㪖㪗㪘㪙㪚㪛㪜㪝㪞㪟㪠㪡㪢㪣㪤㪥㪦㪧㪨㪩㪪㪫㪬㪭㪮㪯㪰㪱㪲㪳㪴㪵㪶㪷㪸㪹㪺㪻㪼㪽㪾㪿㫀㫁㫂㫃㫄㫅㫆㫇㫈㫉㫊㫋㫌㫍㫎㫏㫐㫑㫒㫓㫔㫕㫖㫗㫘㫙㫚㫛㫜㫝㫞㫟㫠㫡㫢㫣㫤㫥㫦㫧㫨㫩㫪㫫㫬㫭㫮㫯㫰㫱㫲㫳㫴㫵㫶㫷㫸㫹㫺㫻㫼㫽㫾㫿㬀㬁㬂㬃㬄㬅㬆㬇㬈㬉㬊㬋㬌㬍㬎㬏㬐㬑㬒㬓㬔㬕㬖㬗㬘㬙㬚㬛㬜㬝㬞㬟㬠㬡㬢㬣㬤㬥㬦㬧㬨㬩㬪㬫㬬㬭㬮㬯㬰㬱㬲㬳㬴㬵㬶㬷㬸㬹㬺㬻㬼㬽㬾㬿㭀㭁㭂㭃㭄㭅㭆㭇㭈㭉㭊㭋㭌㭍㭎㭏㭐㭑㭒㭓㭔㭕㭖㭗㭘㭙㭚㭛㭜㭝㭞㭟㭠㭡㭢㭣㭤㭥㭦㭧㭨㭩㭪㭫㭬㭭㭮㭯㭰㭱㭲㭳㭴㭵㭶㭷㭸㭹㭺㭻㭼㭽㭾㭿㮀㮁㮂㮃㮄㮅㮆㮇㮈㮉㮊㮋㮌㮍㮎㮏㮐㮑㮒㮓㮔㮕㮖㮗㮘㮙㮚㮛㮜㮝㮞㮟㮠㮡㮢㮣㮤㮥㮦㮧㮨㮩㮪㮫㮬㮭㮮㮯㮰㮱㮲㮳㮴㮵㮶㮷㮸㮹㮺㮻㮼㮽㮾㮿㯀㯁㯂㯃㯄㯅㯆㯇㯈㯉㯊㯋㯌㯍㯎㯏㯐㯑㯒㯓㯔㯕㯖㯗㯘㯙㯚㯛㯜㯝㯞㯟㯠㯡㯢㯣㯤㯥㯦㯧㯨㯩㯪㯫㯬㯭㯮㯯㯰㯱㯲㯳㯴㯵㯶㯷㯸㯹㯺㯻㯼㯽㯾㯿㰀㰁㰂㰃㰄㰅㰆㰇㰈㰉㰊㰋㰌㰍㰎㰏㰐㰑㰒㰓㰔㰕㰖㰗㰘㰙㰚㰛㰜㰝㰞㰟㰠㰡㰢㰣㰤㰥㰦㰧㰨㰩㰪㰫㰬㰭㰮㰯㰰㰱㰲㰳㰴㰵㰶㰷㰸㰹㰺㰻㰼㰽㰾㰿㱀㱁㱂㱃㱄㱅㱆㱇㱈㱉㱊㱋㱌㱍㱎㱏㱐㱑㱒㱓㱔㱕㱖㱗㱘㱙㱚㱛㱜㱝㱞㱟㱠㱡㱢㱣㱤㱥㱦㱧㱨㱩㱪㱫㱬㱭㱮㱯㱰㱱㱲㱳㱴㱵㱶㱷㱸㱹㱺㱻㱼㱽㱾㱿㲀㲁㲂㲃㲄㲅㲆㲇㲈㲉㲊㲋㲌㲍㲎㲏㲐㲑㲒㲓㲔㲕㲖㲗㲘㲙㲚㲛㲜㲝㲞㲟㲠㲡㲢㲣㲤㲥㲦㲧㲨㲩㲪㲫㲬㲭㲮㲯㲰㲱㲲㲳㲴㲵㲶㲷㲸㲹㲺㲻㲼㲽㲾㲿㳀㳁㳂㳃㳄㳅㳆㳇㳈㳉㳊㳋㳌㳍㳎㳏㳐㳑㳒㳓㳔㳕㳖㳗㳘㳙㳚㳛㳜㳝㳞㳟㳠㳡㳢㳣㳤㳥㳦㳧㳨㳩㳪㳫㳬㳭㳮㳯㳰㳱㳲㳳㳴㳵㳶㳷㳸㳹㳺㳻㳼㳽㳾㳿㴀㴁㴂㴃㴄㴅㴆㴇㴈㴉㴊㴋㴌㴍㴎㴏㴐㴑㴒㴓㴔㴕㴖㴗㴘㴙㴚㴛㴜㴝㴞㴟㴠㴡㴢㴣㴤㴥㴦㴧㴨㴩㴪㴫㴬㴭㴮㴯㴰㴱㴲㴳㴴㴵㴶㴷㴸㴹㴺㴻㴼㴽㴾㴿㵀㵁㵂㵃㵄㵅㵆㵇㵈㵉㵊㵋㵌㵍㵎㵏㵐㵑㵒㵓㵔㵕㵖㵗㵘㵙㵚㵛㵜㵝㵞㵟㵠㵡㵢㵣㵤㵥㵦㵧㵨㵩㵪㵫㵬㵭㵮㵯㵰㵱㵲㵳㵴㵵㵶㵷㵸㵹㵺㵻㵼㵽㵾㵿㶀㶁㶂㶃㶄㶅㶆㶇㶈㶉㶊㶋㶌㶍㶎㶏㶐㶑㶒㶓㶔㶕㶖㶗㶘㶙㶚㶛㶜㶝㶞㶟㶠㶡㶢㶣㶤㶥㶦㶧㶨㶩㶪㶫㶬㶭㶮㶯㶰㶱㶲㶳㶴㶵㶶㶷㶸㶹㶺㶻㶼㶽㶾㶿㷀㷁㷂㷃㷄㷅㷆㷇㷈㷉㷊㷋㷌㷍㷎㷏㷐㷑㷒㷓㷔㷕㷖㷗㷘㷙㷚㷛㷜㷝㷞㷟㷠㷡㷢㷣㷤㷥㷦㷧㷨㷩㷪㷫㷬㷭㷮㷯㷰㷱㷲㷳㷴㷵㷶㷷㷸㷹㷺㷻㷼㷽㷾㷿㸀㸁㸂㸃㸄㸅㸆㸇㸈㸉㸊㸋㸌㸍㸎㸏㸐㸑㸒㸓㸔㸕㸖㸗㸘㸙㸚㸛㸜㸝㸞㸟㸠㸡㸢㸣㸤㸥㸦㸧㸨㸩㸪㸫㸬㸭㸮㸯㸰㸱㸲㸳㸴㸵㸶㸷㸸㸹㸺㸻㸼㸽㸾㸿㹀㹁㹂㹃㹄㹅㹆㹇㹈㹉㹊㹋㹌㹍㹎㹏㹐㹑㹒㹓㹔㹕㹖㹗㹘㹙㹚㹛㹜㹝㹞㹟㹠㹡㹢㹣㹤㹥㹦㹧㹨㹩㹪㹫㹬㹭㹮㹯㹰㹱㹲㹳㹴㹵㹶㹷㹸㹹㹺㹻㹼㹽㹾㹿㺀㺁㺂㺃㺄㺅㺆㺇㺈㺉㺊㺋㺌㺍㺎㺏㺐㺑㺒㺓㺔㺕㺖㺗㺘㺙㺚㺛㺜㺝㺞㺟㺠㺡㺢㺣㺤㺥㺦㺧㺨㺩㺪㺫㺬㺭㺮㺯㺰㺱㺲㺳㺴㺵㺶㺷㺸㺹㺺㺻㺼㺽㺾㺿㻀㻁㻂㻃㻄㻅㻆㻇㻈㻉㻊㻋㻌㻍㻎㻏㻐㻑㻒㻓㻔㻕㻖㻗㻘㻙㻚㻛㻜㻝㻞㻟㻠㻡㻢㻣㻤㻥㻦㻧㻨㻩㻪㻫㻬㻭㻮㻯㻰㻱㻲㻳㻴㻵㻶㻷㻸㻹㻺㻻㻼㻽㻾㻿㼀㼁㼂㼃㼄㼅㼆㼇㼈㼉㼊㼋㼌㼍㼎㼏㼐㼑㼒㼓㼔㼕㼖㼗㼘㼙㼚㼛㼜㼝㼞㼟㼠㼡㼢㼣㼤㼥㼦㼧㼨㼩㼪㼫㼬㼭㼮㼯㼰㼱㼲㼳㼴㼵㼶㼷㼸㼹㼺㼻㼼㼽㼾㼿㽀㽁㽂㽃㽄㽅㽆㽇㽈㽉㽊㽋㽌㽍㽎㽏㽐㽑㽒㽓㽔㽕㽖㽗㽘㽙㽚㽛㽜㽝㽞㽟㽠㽡㽢㽣㽤㽥㽦㽧㽨㽩㽪㽫㽬㽭㽮㽯㽰㽱㽲㽳㽴㽵㽶㽷㽸㽹㽺㽻㽼㽽㽾㽿㾀㾁㾂㾃㾄㾅㾆㾇㾈㾉㾊㾋㾌㾍㾎㾏㾐㾑㾒㾓㾔㾕㾖㾗㾘㾙㾚㾛㾜㾝㾞㾟㾠㾡㾢㾣㾤㾥㾦㾧㾨㾩㾪㾫㾬㾭㾮㾯㾰㾱㾲㾳㾴㾵㾶㾷㾸㾹㾺㾻㾼㾽㾾㾿㿀㿁㿂㿃㿄㿅㿆㿇㿈㿉㿊㿋㿌㿍㿎㿏㿐㿑㿒㿓㿔㿕㿖㿗㿘㿙㿚㿛㿜㿝㿞㿟㿠㿡㿢㿣㿤㿥㿦㿧㿨㿩㿪㿫㿬㿭㿮㿯㿰㿱㿲㿳㿴㿵㿶㿷㿸㿹㿺㿻㿼㿽㿾㿿䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿䁀䁁䁂䁃䁄䁅䁆䁇䁈䁉䁊䁋䁌䁍䁎䁏䁐䁑䁒䁓䁔䁕䁖䁗䁘䁙䁚䁛䁜䁝䁞䁟䁠䁡䁢䁣䁤䁥䁦䁧䁨䁩䁪䁫䁬䁭䁮䁯䁰䁱䁲䁳䁴䁵䁶䁷䁸䁹䁺䁻䁼䁽䁾䁿䂀䂁䂂䂃䂄䂅䂆䂇䂈䂉䂊䂋䂌䂍䂎䂏䂐䂑䂒䂓䂔䂕䂖䂗䂘䂙䂚䂛䂜䂝䂞䂟䂠䂡䂢䂣䂤䂥䂦䂧䂨䂩䂪䂫䂬䂭䂮䂯䂰䂱䂲䂳䂴䂵䂶䂷䂸䂹䂺䂻䂼䂽䂾䂿䃀䃁䃂䃃䃄䃅䃆䃇䃈䃉䃊䃋䃌䃍䃎䃏䃐䃑䃒䃓䃔䃕䃖䃗䃘䃙䃚䃛䃜䃝䃞䃟䃠䃡䃢䃣䃤䃥䃦䃧䃨䃩䃪䃫䃬䃭䃮䃯䃰䃱䃲䃳䃴䃵䃶䃷䃸䃹䃺䃻䃼䃽䃾䃿䄀䄁䄂䄃䄄䄅䄆䄇䄈䄉䄊䄋䄌䄍䄎䄏䄐䄑䄒䄓䄔䄕䄖䄗䄘䄙䄚䄛䄜䄝䄞䄟䄠䄡䄢䄣䄤䄥䄦䄧䄨䄩䄪䄫䄬䄭䄮䄯䄰䄱䄲䄳䄴䄵䄶䄷䄸䄹䄺䄻䄼䄽䄾䄿䅀䅁䅂䅃䅄䅅䅆䅇䅈䅉䅊䅋䅌䅍䅎䅏䅐䅑䅒䅓䅔䅕䅖䅗䅘䅙䅚䅛䅜䅝䅞䅟䅠䅡䅢䅣䅤䅥䅦䅧䅨䅩䅪䅫䅬䅭䅮䅯䅰䅱䅲䅳䅴䅵䅶䅷䅸䅹䅺䅻䅼䅽䅾䅿䆀䆁䆂䆃䆄䆅䆆䆇䆈䆉䆊䆋䆌䆍䆎䆏䆐䆑䆒䆓䆔䆕䆖䆗䆘䆙䆚䆛䆜䆝䆞䆟䆠䆡䆢䆣䆤䆥䆦䆧䆨䆩䆪䆫䆬䆭䆮䆯䆰䆱䆲䆳䆴䆵䆶䆷䆸䆹䆺䆻䆼䆽䆾䆿䇀䇁䇂䇃䇄䇅䇆䇇䇈䇉䇊䇋䇌䇍䇎䇏䇐䇑䇒䇓䇔䇕䇖䇗䇘䇙䇚䇛䇜䇝䇞䇟䇠䇡䇢䇣䇤䇥䇦䇧䇨䇩䇪䇫䇬䇭䇮䇯䇰䇱䇲䇳䇴䇵䇶䇷䇸䇹䇺䇻䇼䇽䇾䇿䈀䈁䈂䈃䈄䈅䈆䈇䈈䈉䈊䈋䈌䈍䈎䈏䈐䈑䈒䈓䈔䈕䈖䈗䈘䈙䈚䈛䈜䈝䈞䈟䈠䈡䈢䈣䈤䈥䈦䈧䈨䈩䈪䈫䈬䈭䈮䈯䈰䈱䈲䈳䈴䈵䈶䈷䈸䈹䈺䈻䈼䈽䈾䈿䉀䉁䉂䉃䉄䉅䉆䉇䉈䉉䉊䉋䉌䉍䉎䉏䉐䉑䉒䉓䉔䉕䉖䉗䉘䉙䉚䉛䉜䉝䉞䉟䉠䉡䉢䉣䉤䉥䉦䉧䉨䉩䉪䉫䉬䉭䉮䉯䉰䉱䉲䉳䉴䉵䉶䉷䉸䉹䉺䉻䉼䉽䉾䉿䊀䊁䊂䊃䊄䊅䊆䊇䊈䊉䊊䊋䊌䊍䊎䊏䊐䊑䊒䊓䊔䊕䊖䊗䊘䊙䊚䊛䊜䊝䊞䊟䊠䊡䊢䊣䊤䊥䊦䊧䊨䊩䊪䊫䊬䊭䊮䊯䊰䊱䊲䊳䊴䊵䊶䊷䊸䊹䊺䊻䊼䊽䊾䊿䋀䋁䋂䋃䋄䋅䋆䋇䋈䋉䋊䋋䋌䋍䋎䋏䋐䋑䋒䋓䋔䋕䋖䋗䋘䋙䋚䋛䋜䋝䋞䋟䋠䋡䋢䋣䋤䋥䋦䋧䋨䋩䋪䋫䋬䋭䋮䋯䋰䋱䋲䋳䋴䋵䋶䋷䋸䋹䋺䋻䋼䋽䋾䋿䌀䌁䌂䌃䌄䌅䌆䌇䌈䌉䌊䌋䌌䌍䌎䌏䌐䌑䌒䌓䌔䌕䌖䌗䌘䌙䌚䌛䌜䌝䌞䌟䌠䌡䌢䌣䌤䌥䌦䌧䌨䌩䌪䌫䌬䌭䌮䌯䌰䌱䌲䌳䌴䌵䌶䌷䌸䌹䌺䌻䌼䌽䌾䌿䍀䍁䍂䍃䍄䍅䍆䍇䍈䍉䍊䍋䍌䍍䍎䍏䍐䍑䍒䍓䍔䍕䍖䍗䍘䍙䍚䍛䍜䍝䍞䍟䍠䍡䍢䍣䍤䍥䍦䍧䍨䍩䍪䍫䍬䍭䍮䍯䍰䍱䍲䍳䍴䍵䍶䍷䍸䍹䍺䍻䍼䍽䍾䍿䎀䎁䎂䎃䎄䎅䎆䎇䎈䎉䎊䎋䎌䎍䎎䎏䎐䎑䎒䎓䎔䎕䎖䎗䎘䎙䎚䎛䎜䎝䎞䎟䎠䎡䎢䎣䎤䎥䎦䎧䎨䎩䎪䎫䎬䎭䎮䎯䎰䎱䎲䎳䎴䎵䎶䎷䎸䎹䎺䎻䎼䎽䎾䎿䏀䏁䏂䏃䏄䏅䏆䏇䏈䏉䏊䏋䏌䏍䏎䏏䏐䏑䏒䏓䏔䏕䏖䏗䏘䏙䏚䏛䏜䏝䏞䏟䏠䏡䏢䏣䏤䏥䏦䏧䏨䏩䏪䏫䏬䏭䏮䏯䏰䏱䏲䏳䏴䏵䏶䏷䏸䏹䏺䏻䏼䏽䏾䏿䐀䐁䐂䐃䐄䐅䐆䐇䐈䐉䐊䐋䐌䐍䐎䐏䐐䐑䐒䐓䐔䐕䐖䐗䐘䐙䐚䐛䐜䐝䐞䐟䐠䐡䐢䐣䐤䐥䐦䐧䐨䐩䐪䐫䐬䐭䐮䐯䐰䐱䐲䐳䐴䐵䐶䐷䐸䐹䐺䐻䐼䐽䐾䐿䑀䑁䑂䑃䑄䑅䑆䑇䑈䑉䑊䑋䑌䑍䑎䑏䑐䑑䑒䑓䑔䑕䑖䑗䑘䑙䑚䑛䑜䑝䑞䑟䑠䑡䑢䑣䑤䑥䑦䑧䑨䑩䑪䑫䑬䑭䑮䑯䑰䑱䑲䑳䑴䑵䑶䑷䑸䑹䑺䑻䑼䑽䑾䑿䒀䒁䒂䒃䒄䒅䒆䒇䒈䒉䒊䒋䒌䒍䒎䒏䒐䒑䒒䒓䒔䒕䒖䒗䒘䒙䒚䒛䒜䒝䒞䒟䒠䒡䒢䒣䒤䒥䒦䒧䒨䒩䒪䒫䒬䒭䒮䒯䒰䒱䒲䒳䒴䒵䒶䒷䒸䒹䒺䒻䒼䒽䒾䒿䓀䓁䓂䓃䓄䓅䓆䓇䓈䓉䓊䓋䓌䓍䓎䓏䓐䓑䓒䓓䓔䓕䓖䓗䓘䓙䓚䓛䓜䓝䓞䓟䓠䓡䓢䓣䓤䓥䓦䓧䓨䓩䓪䓫䓬䓭䓮䓯䓰䓱䓲䓳䓴䓵䓶䓷䓸䓹䓺䓻䓼䓽䓾䓿䔀䔁䔂䔃䔄䔅䔆䔇䔈䔉䔊䔋䔌䔍䔎䔏䔐䔑䔒䔓䔔䔕䔖䔗䔘䔙䔚䔛䔜䔝䔞䔟䔠䔡䔢䔣䔤䔥䔦䔧䔨䔩䔪䔫䔬䔭䔮䔯䔰䔱䔲䔳䔴䔵䔶䔷䔸䔹䔺䔻䔼䔽䔾䔿䕀䕁䕂䕃䕄䕅䕆䕇䕈䕉䕊䕋䕌䕍䕎䕏䕐䕑䕒䕓䕔䕕䕖䕗䕘䕙䕚䕛䕜䕝䕞䕟䕠䕡䕢䕣䕤䕥䕦䕧䕨䕩䕪䕫䕬䕭䕮䕯䕰䕱䕲䕳䕴䕵䕶䕷䕸䕹䕺䕻䕼䕽䕾䕿䖀䖁䖂䖃䖄䖅䖆䖇䖈䖉䖊䖋䖌䖍䖎䖏䖐䖑䖒䖓䖔䖕䖖䖗䖘䖙䖚䖛䖜䖝䖞䖟䖠䖡䖢䖣䖤䖥䖦䖧䖨䖩䖪䖫䖬䖭䖮䖯䖰䖱䖲䖳䖴䖵䖶䖷䖸䖹䖺䖻䖼䖽䖾䖿䗀䗁䗂䗃䗄䗅䗆䗇䗈䗉䗊䗋䗌䗍䗎䗏䗐䗑䗒䗓䗔䗕䗖䗗䗘䗙䗚䗛䗜䗝䗞䗟䗠䗡䗢䗣䗤䗥䗦䗧䗨䗩䗪䗫䗬䗭䗮䗯䗰䗱䗲䗳䗴䗵䗶䗷䗸䗹䗺䗻䗼䗽䗾䗿䘀䘁䘂䘃䘄䘅䘆䘇䘈䘉䘊䘋䘌䘍䘎䘏䘐䘑䘒䘓䘔䘕䘖䘗䘘䘙䘚䘛䘜䘝䘞䘟䘠䘡䘢䘣䘤䘥䘦䘧䘨䘩䘪䘫䘬䘭䘮䘯䘰䘱䘲䘳䘴䘵䘶䘷䘸䘹䘺䘻䘼䘽䘾䘿䙀䙁䙂䙃䙄䙅䙆䙇䙈䙉䙊䙋䙌䙍䙎䙏䙐䙑䙒䙓䙔䙕䙖䙗䙘䙙䙚䙛䙜䙝䙞䙟䙠䙡䙢䙣䙤䙥䙦䙧䙨䙩䙪䙫䙬䙭䙮䙯䙰䙱䙲䙳䙴䙵䙶䙷䙸䙹䙺䙻䙼䙽䙾䙿䚀䚁䚂䚃䚄䚅䚆䚇䚈䚉䚊䚋䚌䚍䚎䚏䚐䚑䚒䚓䚔䚕䚖䚗䚘䚙䚚䚛䚜䚝䚞䚟䚠䚡䚢䚣䚤䚥䚦䚧䚨䚩䚪䚫䚬䚭䚮䚯䚰䚱䚲䚳䚴䚵䚶䚷䚸䚹䚺䚻䚼䚽䚾䚿䛀䛁䛂䛃䛄䛅䛆䛇䛈䛉䛊䛋䛌䛍䛎䛏䛐䛑䛒䛓䛔䛕䛖䛗䛘䛙䛚䛛䛜䛝䛞䛟䛠䛡䛢䛣䛤䛥䛦䛧䛨䛩䛪䛫䛬䛭䛮䛯䛰䛱䛲䛳䛴䛵䛶䛷䛸䛹䛺䛻䛼䛽䛾䛿䜀䜁䜂䜃䜄䜅䜆䜇䜈䜉䜊䜋䜌䜍䜎䜏䜐䜑䜒䜓䜔䜕䜖䜗䜘䜙䜚䜛䜜䜝䜞䜟䜠䜡䜢䜣䜤䜥䜦䜧䜨䜩䜪䜫䜬䜭䜮䜯䜰䜱䜲䜳䜴䜵䜶䜷䜸䜹䜺䜻䜼䜽䜾䜿䝀䝁䝂䝃䝄䝅䝆䝇䝈䝉䝊䝋䝌䝍䝎䝏䝐䝑䝒䝓䝔䝕䝖䝗䝘䝙䝚䝛䝜䝝䝞䝟䝠䝡䝢䝣䝤䝥䝦䝧䝨䝩䝪䝫䝬䝭䝮䝯䝰䝱䝲䝳䝴䝵䝶䝷䝸䝹䝺䝻䝼䝽䝾䝿䞀䞁䞂䞃䞄䞅䞆䞇䞈䞉䞊䞋䞌䞍䞎䞏䞐䞑䞒䞓䞔䞕䞖䞗䞘䞙䞚䞛䞜䞝䞞䞟䞠䞡䞢䞣䞤䞥䞦䞧䞨䞩䞪䞫䞬䞭䞮䞯䞰䞱䞲䞳䞴䞵䞶䞷䞸䞹䞺䞻䞼䞽䞾䞿䟀䟁䟂䟃䟄䟅䟆䟇䟈䟉䟊䟋䟌䟍䟎䟏䟐䟑䟒䟓䟔䟕䟖䟗䟘䟙䟚䟛䟜䟝䟞䟟䟠䟡䟢䟣䟤䟥䟦䟧䟨䟩䟪䟫䟬䟭䟮䟯䟰䟱䟲䟳䟴䟵䟶䟷䟸䟹䟺䟻䟼䟽䟾䟿䠀䠁䠂䠃䠄䠅䠆䠇䠈䠉䠊䠋䠌䠍䠎䠏䠐䠑䠒䠓䠔䠕䠖䠗䠘䠙䠚䠛䠜䠝䠞䠟䠠䠡䠢䠣䠤䠥䠦䠧䠨䠩䠪䠫䠬䠭䠮䠯䠰䠱䠲䠳䠴䠵䠶䠷䠸䠹䠺䠻䠼䠽䠾䠿䡀䡁䡂䡃䡄䡅䡆䡇䡈䡉䡊䡋䡌䡍䡎䡏䡐䡑䡒䡓䡔䡕䡖䡗䡘䡙䡚䡛䡜䡝䡞䡟䡠䡡䡢䡣䡤䡥䡦䡧䡨䡩䡪䡫䡬䡭䡮䡯䡰䡱䡲䡳䡴䡵䡶䡷䡸䡹䡺䡻䡼䡽䡾䡿䢀䢁䢂䢃䢄䢅䢆䢇䢈䢉䢊䢋䢌䢍䢎䢏䢐䢑䢒䢓䢔䢕䢖䢗䢘䢙䢚䢛䢜䢝䢞䢟䢠䢡䢢䢣䢤䢥䢦䢧䢨䢩䢪䢫䢬䢭䢮䢯䢰䢱䢲䢳䢴䢵䢶䢷䢸䢹䢺䢻䢼䢽䢾䢿䣀䣁䣂䣃䣄䣅䣆䣇䣈䣉䣊䣋䣌䣍䣎䣏䣐䣑䣒䣓䣔䣕䣖䣗䣘䣙䣚䣛䣜䣝䣞䣟䣠䣡䣢䣣䣤䣥䣦䣧䣨䣩䣪䣫䣬䣭䣮䣯䣰䣱䣲䣳䣴䣵䣶䣷䣸䣹䣺䣻䣼䣽䣾䣿䤀䤁䤂䤃䤄䤅䤆䤇䤈䤉䤊䤋䤌䤍䤎䤏䤐䤑䤒䤓䤔䤕䤖䤗䤘䤙䤚䤛䤜䤝䤞䤟䤠䤡䤢䤣䤤䤥䤦䤧䤨䤩䤪䤫䤬䤭䤮䤯䤰䤱䤲䤳䤴䤵䤶䤷䤸䤹䤺䤻䤼䤽䤾䤿䥀䥁䥂䥃䥄䥅䥆䥇䥈䥉䥊䥋䥌䥍䥎䥏䥐䥑䥒䥓䥔䥕䥖䥗䥘䥙䥚䥛䥜䥝䥞䥟䥠䥡䥢䥣䥤䥥䥦䥧䥨䥩䥪䥫䥬䥭䥮䥯䥰䥱䥲䥳䥴䥵䥶䥷䥸䥹䥺䥻䥼䥽䥾䥿䦀䦁䦂䦃䦄䦅䦆䦇䦈䦉䦊䦋䦌䦍䦎䦏䦐䦑䦒䦓䦔䦕䦖䦗䦘䦙䦚䦛䦜䦝䦞䦟䦠䦡䦢䦣䦤䦥䦦䦧䦨䦩䦪䦫䦬䦭䦮䦯䦰䦱䦲䦳䦴䦵䦶䦷䦸䦹䦺䦻䦼䦽䦾䦿䧀䧁䧂䧃䧄䧅䧆䧇䧈䧉䧊䧋䧌䧍䧎䧏䧐䧑䧒䧓䧔䧕䧖䧗䧘䧙䧚䧛䧜䧝䧞䧟䧠䧡䧢䧣䧤䧥䧦䧧䧨䧩䧪䧫䧬䧭䧮䧯䧰䧱䧲䧳䧴䧵䧶䧷䧸䧹䧺䧻䧼䧽䧾䧿䨀䨁䨂䨃䨄䨅䨆䨇䨈䨉䨊䨋䨌䨍䨎䨏䨐䨑䨒䨓䨔䨕䨖䨗䨘䨙䨚䨛䨜䨝䨞䨟䨠䨡䨢䨣䨤䨥䨦䨧䨨䨩䨪䨫䨬䨭䨮䨯䨰䨱䨲䨳䨴䨵䨶䨷䨸䨹䨺䨻䨼䨽䨾䨿䩀䩁䩂䩃䩄䩅䩆䩇䩈䩉䩊䩋䩌䩍䩎䩏䩐䩑䩒䩓䩔䩕䩖䩗䩘䩙䩚䩛䩜䩝䩞䩟䩠䩡䩢䩣䩤䩥䩦䩧䩨䩩䩪䩫䩬䩭䩮䩯䩰䩱䩲䩳䩴䩵䩶䩷䩸䩹䩺䩻䩼䩽䩾䩿䪀䪁䪂䪃䪄䪅䪆䪇䪈䪉䪊䪋䪌䪍䪎䪏䪐䪑䪒䪓䪔䪕䪖䪗䪘䪙䪚䪛䪜䪝䪞䪟䪠䪡䪢䪣䪤䪥䪦䪧䪨䪩䪪䪫䪬䪭䪮䪯䪰䪱䪲䪳䪴䪵䪶䪷䪸䪹䪺䪻䪼䪽䪾䪿䫀䫁䫂䫃䫄䫅䫆䫇䫈䫉䫊䫋䫌䫍䫎䫏䫐䫑䫒䫓䫔䫕䫖䫗䫘䫙䫚䫛䫜䫝䫞䫟䫠䫡䫢䫣䫤䫥䫦䫧䫨䫩䫪䫫䫬䫭䫮䫯䫰䫱䫲䫳䫴䫵䫶䫷䫸䫹䫺䫻䫼䫽䫾䫿䬀䬁䬂䬃䬄䬅䬆䬇䬈䬉䬊䬋䬌䬍䬎䬏䬐䬑䬒䬓䬔䬕䬖䬗䬘䬙䬚䬛䬜䬝䬞䬟䬠䬡䬢䬣䬤䬥䬦䬧䬨䬩䬪䬫䬬䬭䬮䬯䬰䬱䬲䬳䬴䬵䬶䬷䬸䬹䬺䬻䬼䬽䬾䬿䭀䭁䭂䭃䭄䭅䭆䭇䭈䭉䭊䭋䭌䭍䭎䭏䭐䭑䭒䭓䭔䭕䭖䭗䭘䭙䭚䭛䭜䭝䭞䭟䭠䭡䭢䭣䭤䭥䭦䭧䭨䭩䭪䭫䭬䭭䭮䭯䭰䭱䭲䭳䭴䭵䭶䭷䭸䭹䭺䭻䭼䭽䭾䭿䮀䮁䮂䮃䮄䮅䮆䮇䮈䮉䮊䮋䮌䮍䮎䮏䮐䮑䮒䮓䮔䮕䮖䮗䮘䮙䮚䮛䮜䮝䮞䮟䮠䮡䮢䮣䮤䮥䮦䮧䮨䮩䮪䮫䮬䮭䮮䮯䮰䮱䮲䮳䮴䮵䮶䮷䮸䮹䮺䮻䮼䮽䮾䮿䯀䯁䯂䯃䯄䯅䯆䯇䯈䯉䯊䯋䯌䯍䯎䯏䯐䯑䯒䯓䯔䯕䯖䯗䯘䯙䯚䯛䯜䯝䯞䯟䯠䯡䯢䯣䯤䯥䯦䯧䯨䯩䯪䯫䯬䯭䯮䯯䯰䯱䯲䯳䯴䯵䯶䯷䯸䯹䯺䯻䯼䯽䯾䯿䰀䰁䰂䰃䰄䰅䰆䰇䰈䰉䰊䰋䰌䰍䰎䰏䰐䰑䰒䰓䰔䰕䰖䰗䰘䰙䰚䰛䰜䰝䰞䰟䰠䰡䰢䰣䰤䰥䰦䰧䰨䰩䰪䰫䰬䰭䰮䰯䰰䰱䰲䰳䰴䰵䰶䰷䰸䰹䰺䰻䰼䰽䰾䰿䱀䱁䱂䱃䱄䱅䱆䱇䱈䱉䱊䱋䱌䱍䱎䱏䱐䱑䱒䱓䱔䱕䱖䱗䱘䱙䱚䱛䱜䱝䱞䱟䱠䱡䱢䱣䱤䱥䱦䱧䱨䱩䱪䱫䱬䱭䱮䱯䱰䱱䱲䱳䱴䱵䱶䱷䱸䱹䱺䱻䱼䱽䱾䱿䲀䲁䲂䲃䲄䲅䲆䲇䲈䲉䲊䲋䲌䲍䲎䲏䲐䲑䲒䲓䲔䲕䲖䲗䲘䲙䲚䲛䲜䲝䲞䲟䲠䲡䲢䲣䲤䲥䲦䲧䲨䲩䲪䲫䲬䲭䲮䲯䲰䲱䲲䲳䲴䲵䲶䲷䲸䲹䲺䲻䲼䲽䲾䲿䳀䳁䳂䳃䳄䳅䳆䳇䳈䳉䳊䳋䳌䳍䳎䳏䳐䳑䳒䳓䳔䳕䳖䳗䳘䳙䳚䳛䳜䳝䳞䳟䳠䳡䳢䳣䳤䳥䳦䳧䳨䳩䳪䳫䳬䳭䳮䳯䳰䳱䳲䳳䳴䳵䳶䳷䳸䳹䳺䳻䳼䳽䳾䳿䴀䴁䴂䴃䴄䴅䴆䴇䴈䴉䴊䴋䴌䴍䴎䴏䴐䴑䴒䴓䴔䴕䴖䴗䴘䴙䴚䴛䴜䴝䴞䴟䴠䴡䴢䴣䴤䴥䴦䴧䴨䴩䴪䴫䴬䴭䴮䴯䴰䴱䴲䴳䴴䴵䴶䴷䴸䴹䴺䴻䴼䴽䴾䴿䵀䵁䵂䵃䵄䵅䵆䵇䵈䵉䵊䵋䵌䵍䵎䵏䵐䵑䵒䵓䵔䵕䵖䵗䵘䵙䵚䵛䵜䵝䵞䵟䵠䵡䵢䵣䵤䵥䵦䵧䵨䵩䵪䵫䵬䵭䵮䵯䵰䵱䵲䵳䵴䵵䵶䵷䵸䵹䵺䵻䵼䵽䵾䵿䶀䶁䶂䶃䶄䶅䶆䶇䶈䶉䶊䶋䶌䶍䶎䶏䶐䶑䶒䶓䶔䶕䶖䶗䶘䶙䶚䶛䶜䶝䶞䶟䶠䶡䶢䶣䶤䶥䶦䶧䶨䶩䶪䶫䶬䶭䶮䶯䶰䶱䶲䶳䶴䶵䶶䶷䶸䶹䶺䶻䶼䶽䶾䶿䷀䷁䷂䷃䷄䷅䷆䷇䷈䷉䷊䷋䷌䷍䷎䷏䷐䷑䷒䷓䷔䷕䷖䷗䷘䷙䷚䷛䷜䷝䷞䷟䷠䷡䷢䷣䷤䷥䷦䷧䷨䷩䷪䷫䷬䷭䷮䷯䷰䷱䷲䷳䷴䷵䷶䷷䷸䷹䷺䷻䷼䷽䷾䷿乥乲兙兛兝兞兡兣兺匁厼叾哛唜唟喸嗧囕夞巼怾旕朩朰栍桛椧烪猠瓧瓩瓰瓱瓲瓼甅硛硳穒縇莻虄襨迲闏鞥啊腌錒锕阿哀哎唉埃挨溾銰鎄锿凒啀嘊捱敱敳溰癌皑皚磑娾昹毐濭矮蔼藹譪躷霭靄伌僾叆嗳噯塧壒嫒嬡愛懓懝暧曖爱瑷璦皧瞹砹硋碍礙艾薆譺賹鑀隘靉餲馤鱫鴱侒偣啽媕安峖庵桉氨痷盦盫腤菴萻葊蓭誝諳谙鞌鞍韽馣鮟鵪鶕鹌儑玵雸俺唵垵埯揞罯銨铵堓屵岸按晻暗案洝胺荌豻貋錌闇隌黯肮骯岇昂昻枊盎醠凹柪梎熬爊軪厫嗷嗸嶅廒慠摮敖滶獒獓璈磝翱翶翺聱蔜螯謷謸遨鏖隞骜鰲鳌鷔鼇媪媼抝艹芺袄襖镺傲坳垇墺奡奥奧嫯岙岰嶴懊拗擙澚澳鏊隩驁丷仈八叭吧哵夿岜巴扒扷捌朳柭玐疤笆粑羓芭蚆豝釟魞鲃叐妭抜拔炦癹胈茇菝詙跋軷颰魃鼥把鈀钯靶坝垻壩弝欛灞爸矲罢罷耙覇跁霸鮁鲅挀掰白佰捭摆擺柏栢瓸百竡粨絔襬庍拜拝敗猈稗粺薭贁败韛扳搬攽斑斒班瘢癍肦般螌褩辬頒颁鳻坂岅昄板版瓪粄舨蝂鈑钣闆阪魬伴办半坢姅怑扮拌湴瓣秚絆绊辦鉡靽垹帮幇幚幫捠梆浜縍邦邫鞤榜牓綁绑膀髈傍塝挷搒棒棓玤磅稖艕蒡蚌蜯謗谤鎊镑佨剝勹包孢枹煲笣胞苞蕔裦褒襃闁齙龅窇薄雹保堡堢媬宝宲寚寳寶怉珤緥葆藵褓賲靌飹飽饱駂鳵鴇鸨儤勽嚗報忁报抱暴曓爆犦菢虣蚫袌豹趵鉋鑤铇骲髱鮑鲍卑庳悲揹杯柸桮椑盃碑背藣陂鵯鹎北鉳俻倍偝偹備僃备孛悖惫愂憊昁梖焙牬犕狈狽珼琲碚禙糒苝蓓蛽被褙誖貝贝軰輩辈邶郥鄁鋇鐾钡鞁鞴骳呗唄喯奔栟泍漰犇錛锛奙本楍畚翉苯倴坋坌捹撪桳渀笨逩伻嗙嘣奟崩嵭痭祊絣綳繃绷閍甭甮埄埲琣琫菶鞛塴揼泵甏蹦迸逬鏰镚偪屄楅榌毴螕豍逼鎞鰏鲾鵖嬶荸鼻佊俾匕啚夶妣彼朼柀比毞沘疕秕笔筆粃聛舭貏鄙佖咇哔嗶坒堛壁奰妼婢嬖币幣幤庇廦弊弻弼彃必怭怶愊愎敝斃朇柲梐毕毖毙湢滗滭潷濞煏熚狴獘獙珌璧畀畁畢疪痹痺皕睤睥碧禆筚箅箆篦篳粊綼縪繴罼腷臂芘苾荜萆萞蓖蓽蔽薜蜌袐襅襞襣觱詖诐貱賁贔贲赑跸蹕躃躄避邲鄨鄪鉍鏎鐴铋閇閉閟闭陛鞸韠飶饆馝駜驆髀髲魓鮅鷝鷩鼊炞煸牑猵獱甂砭笾箯籩糄編编萹蝙边邉邊鍽鞕鞭鯾鯿鳊匾惼扁揙碥稨窆藊褊貶贬鴘便卞变変峅弁徧忭抃昪汳汴玣緶缏艑苄覍諚變辡辧辨辩辫辮辯遍釆閞儦墂幖彪标標檦淲滮瀌熛爂猋瘭磦穮脿膘臕蔈藨謤贆鏢鑣镖镳颩颮颷飆飇飈飊飑飙飚驫骉骠髟嫑婊表裱褾諘錶俵摽鳔憋瘪癟虌蟞鱉鳖鼈龞別别徶莂蛂襒蹩彆傧儐宾彬斌梹椕槟檳汃滨濒濱濵瀕玢瑸璸繽缤虨豩豳賓賔邠鑌镔霦頻顮摈擯殡殯膑臏髌髕髩鬂鬓鬢仌仒兵冫冰掤氷蛃鋲丙偋寎怲抦昞昺柄棅炳眪禀秉稟苪邴鈵鉼陃鞆鞞餅餠饼並併倂傡垪并幷庰摒栤病窉竝誁靐鮩僠剥嶓拨撥播波溊玻癶癷盋砵碆礡紴缽菠袰蹳鉢钵餑饽驋鱍亳仢伯侼僰勃博帛愽懪挬搏桲欂泊浡淿渤煿牔狛猼瓝瓟礴秡箔簙糪肑胉脖膊舶艊萡葧袯袹襏襮謈踣郣鈸鉑鋍鎛鑮钹铂镈餺馎馛馞駁駮驳髆髉鮊鲌鵓鹁跛孹擘檗簸蘗譒啵蔔峬庯晡誧逋鈽錻钸餔鵏轐醭鳪卜卟哺捕补補鸔不佈勏吥咘埗埠布廍怖悑抪捗柨步歨歩瓿篰簿荹蔀踄部郶鈈钚餢嚓擦攃礤礸遪偲猜才材纔裁財财倸啋埰婇寀彩採棌毝睬綵跴踩采縩菜蔡傪参參叄叅喰嬠湌爘飡餐驂骖惭慙慚残殘蚕蝅蠶蠺惨慘憯朁穇黪黲儏澯灿燦璨粲薒謲仓仺伧倉傖凔嵢沧滄濸獊舱艙苍蒼螥鶬鸧欌藏鑶賶撡操糙嘈嶆慒曹曺槽漕艚蓸螬褿鏪愺懆艸草騲肏襙鄵鼜侧側冊册厕厠夨廁恻惻憡拺敇测測畟笧策筞筴箣簎粣荝萗萴蓛嵾篸埁岑涔笒噌层層嶒曽曾竲驓蹭偛叉嗏扠挿插揷杈疀臿艖銟鍤锸餷馇垞察嵖搽查査槎檫猹碴秅茬茶詧靫蹅鑔镲侘刹剎奼姹岔差汊紁衩詫诧拆肞芆釵钗侪儕喍柴犲祡豺茝囆瘥虿蠆袃訍幨掺搀摻攙梴裧襜覘觇辿鋓儃儳劖嚵壥婵嬋孱巉廛棎欃毚湹潹潺澶瀍瀺煘獑磛禅緾纏纒缠艬苂蝉螹蟐蟬蟾誗讒谗躔鄽酁鋋鑱镵饞馋丳产冁刬剗剷囅嵼幝摌斺旵浐滻灛燀產産簅繟蒇蕆諂譂讇谄醦鏟铲閳闡阐骣忏懴懺摲硟羼韂顫颤伥倀娼昌椙淐猖琩菖裮錩锠閶阊鯧鲳鼚仧仩偿償兏嘗嚐塲嫦尝常徜瑺瓺甞肠腸膓苌萇裳長镸长鱨鲿僘厂厰场場廠惝敞昶氅鋹倡唱怅悵暢焻玚瑒畅畼誯韔鬯弨怊抄欩窼訬超鈔钞嘲巢巣晁朝樔漅潮牊窲罺謿轈鄛鼂鼌吵巐炒焣煼眧麨仦仯耖觘伡俥唓砗硨莗蛼車车偖扯撦勶坼屮彻徹掣撤澈烢爡瞮硩聅迠頙嗔抻捵棽琛瞋諃謓賝郴塵宸尘忱愖敐敶晨曟栕桭梣樄沉煁瘎臣茞莀莐蔯薼螴訦諶谌軙辰迧鈂陈陳霃鷐麎墋夦硶碜磣贂趻踸鍖儭嚫榇櫬疢衬襯讖谶趁趂齓齔龀偁僜憆摚撐撑晿柽棦橕檉泟浾爯牚琤瞠碀称稱穪竀緽罉蛏蟶赪赬鏿鐣阷靗頳饓丞乗乘呈城埕堘塍塖娍宬峸惩憕懲成承挰掁揨朾枨棖椉橙檙洆溗澂澄瀓珵珹畻程窚筬絾脭荿裎誠诚郕酲鋮铖騬鯎侱庱徎悜睈逞騁骋秤吃哧喫嗤噄妛媸彨彲摛攡殦瓻痴癡眵瞝笞粚絺胵蚩螭訵誺魑鴟鵄鸱黐齝匙墀弛持池漦竾筂箎篪茌荎蚳謘貾赿踟迟迡遅遟遲鍉馳驰伬侈卶叺呎垑尺恥欼歯耻肔胣蚇袲袳裭褫豉鉹齒齿侙傺勅勑叱啻彳恜慗憏懘抶敕斥杘湁灻炽烾熾痸瘛翄翅翤翨腟赤趩遫鉓銐雴飭饬鶒鷘麶充冲嘃忡憃憧摏沖浺珫罿翀舂艟茺衝蹖崇崈漴爞緟虫蝩蟲褈隀埫宠寵揰銃铳抽搊犨犫瘳篘紬仇俦儔嬦帱幬惆愁懤栦梼椆檮燽畴疇皗稠筹籌絒綢绸菗薵裯詶讎讐踌躊酧酬醻雔雠雦丑丒偢吜杽瞅矁醜魗殠臭臰遚鮘出初岀摴榋樗貙齣刍厨媰幮廚橱櫉櫥滁犓篨耡芻蒢蒭蜍蟵豠趎蹰躇躕鉏鋤锄除雏雛鶵储儲杵椘楚楮檚濋璴础礎禇處齭齼亍俶傗儊処埱处怵憷搐敊斶欪歜泏滀珿畜矗竌竐絀绌臅触觸諔豖鄐閦黜搋膗揣膪踹巛川氚瑏穿传傳剶圌暷椽篅舡舩船輲遄僢喘堾歂舛荈踳串汌猭玔賗釧钏鶨刅摐牎牕疮瘡窓窗窻噇幢床牀傸磢闖闯创刱剏剙創怆愴吹炊龡倕垂埀捶搥桘棰槌箠腄菙錘鎚锤陲顀媋旾春暙杶椿槆橁櫄瑃箺萅蝽輴鰆鶞唇浱淳湻滣漘犉純纯脣莼蒓蓴醇醕錞陙鯙鶉鹑偆惷睶萶蠢賰戳繛趠踔逴哾啜嚽娕娖婥惙擉歠涰磭綽绰踀輟辍辵辶酫鑡餟齪龊偨玼疵縒蠀趀跐骴髊齹垐嬨慈柌濨珁瓷甆磁礠祠糍茨薋詞词辝辞辤辭雌飺餈鴜鶿鷀鹚佌此泚皉鮆伺佽刺刾庛朿栨次絘茦莿蛓螆賜赐匆囪囱忩怱悤暰枞棇樅樬漗潨熜瑽璁瞛篵繱聡聦聪聰苁茐葱蓯蔥蟌鍯鏓鏦騘驄骢丛从叢婃孮従徔徖從悰樷欉淙漎潀潈灇爜琮藂誴賨賩錝愡憁謥凑楱湊腠輳辏怚橻粗觕麁麄麤徂殂促噈媨憱猝瘄瘯簇縬脨蔟誎趗踧踿蹙蹴蹵醋顣鼀撺攛汆蹿躥鑹镩巑櫕欑穳殩熶爨窜竄篡簒催凗墔崔嵟慛摧榱槯磪縗缞脺鏙漼璀皠趡伜倅啐啛忰悴毳淬濢焠琗疩瘁竁粋粹紣綷翆翠脃脆膬膵臎萃襊顇村澊皴竴膥邨侟壿存拵刌忖寸籿搓撮瑳磋蹉遳醝鎈嵯嵳痤睉矬蒫蔖虘酂酇鹺鹾脞剉剒厝夎庴挫措莝莡蓌逪銼錯锉错咑哒嗒噠墶搭撘笚耷褡鎉鎝剳匒呾垯妲怛溚炟燵畗畣瘩笪答羍荅荙薘蟽詚跶达迏迖迚逹達鐽靼鞑韃龖龘打亣大眔繨呆呔懛獃傣歹代侢叇垈埭岱帒带帯帶廗待怠戴曃柋殆瀻玳瑇甙簤紿緿绐艜蚮蝳袋襶貣貸贷跢蹛軑軚軩轪迨逮霴靆鴏黛黱丹儋勯匰单単單妉媅担擔殚殫甔眈砃箪簞耼耽聃聸褝襌躭郸鄲酖頕亶伔刐抌掸撢撣玬瓭疸紞胆膽衴賧赕馾黕黵但僤唌啖啗啿嘾噉嚪帎惮憚憺旦柦氮沊泹淡澹狚疍瘅癉癚禫窞繵腅萏蓞蛋蜑觛訑誕诞贉霮餤饏駳髧鴠黮儅噹当澢珰璫當筜簹艡蟷裆襠鐺铛闣党挡擋攩欓灙譡讜谠黨凼圵垱壋婸宕愓档檔氹潒璗瓽盪瞊砀碭礑簜荡菪蕩蘯趤逿雼刀刂叨忉朷氘舠螩釖魛鱽捯倒壔导導岛島嶋嶌嶹捣搗擣槝祷禂禱蹈陦隝隯到噵悼椡檤焘燾瓙盗盜稲稻纛翢翿艔菿衜衟軇辺道嘚得徳德恴悳惪棏淂鍀锝的扥扽噔嬁灯燈璒登竳簦艠豋蹬戥等凳墱嶝櫈瞪磴覴邓鄧鐙镫隥仾低啲埞堤奃岻彽樀氐滴磾秪羝袛趆隄鞮唙啇嘀嚁嫡廸敌敵梑涤滌狄笛籴糴翟苖荻蔋蔐藡覿觌豴蹢迪鏑镝靮頔馰髢鸐厎呧坘坻底弤抵拞掋柢牴砥聜菧觝詆诋軧邸阺骶鯳俤偙僀地坔埅埊墑墬娣媂嶳帝弟怟慸摕旳杕枤梊棣楴焍玓珶甋眱睇碲祶禘第締缔腣苐菂蒂蔕蝃蝭螮諦谛踶递逓遆遞遰釱鉪嗲傎厧嵮巅巓巔掂攧敁槇槙滇瘨癫癲蹎顚顛颠齻典嚸奌婰敟椣点碘蒧蕇跕踮點佃坫垫墊壂奠婝店惦扂橂殿淀澱玷琔电甸癜磹簟蜔鈿钿阽電靛驔凋刁刟叼奝弴彫汈琱瞗碉簓虭蛁貂錭雕鮉鯛鲷鳭鵰鼦屌扚伄吊弔掉瘹盄窎窵竨蓧藋訋調釣鈟銚銱鋽鑃钓铞铫雿魡爹褺跌叠咥喋垤堞峌嵽幉恎惵戜挕昳曡楪殜氎牃牒瓞畳疂疉疊眣眰碟絰绖耊耋胅臷艓苵蜨蝶螲褋詄諜谍趃跮蹀迭镻鰈鲽鴩哋丁仃叮帄玎疔盯耵虰酊釘钉靪奵嵿濎艼薡鐤頂顶鼎鼑啶定忊椗矴碇碠磸聢腚萣蝊訂订錠锭顁飣饤丟丢銩铥东倲冬咚埬娻岽崠崬徚昸東氡氭涷笗苳菄蝀鮗鯟鶇鶫鸫鼕嬞懂箽董蕫諌侗働冻凍动動垌姛恫戙挏栋棟洞湩硐胨胴腖迵霘駧兜兠吺唗枓橷篼蔸都唞乧抖蚪鈄钭阧陡吋斗斣梪毭浢痘窦竇脰荳豆逗郖酘閗闘餖饾鬥鬦鬪鬬鬭剢厾嘟督醏闍阇凟匵嬻椟櫝殰毒涜渎瀆牍牘犊犢独獨瓄皾裻読讀讟读豄贕錖鑟韇韣韥騳髑黩黷堵琽睹笃篤覩賭赌妒妬度杜殬渡秺肚芏荰螙蠧蠹鍍镀靯偳媏端耑褍鍴短塅断斷椴段毈煅瑖碫簖籪緞缎腶葮躖鍛锻垖堆塠痽磓鐓鐜镦鴭頧兊兌兑对対對怼憝憞懟濧瀩碓祋綐薱譈譵轛队陮隊吨噸墩墪惇撉撴敦犜獤礅蜳蹲蹾驐盹趸躉伅庉沌潡炖燉盾砘碷踲逇遁遯鈍钝頓顿剟咄哆嚉多夛掇敠敪毲畓裰凙剫喥夺奪敓敚痥踱鈬鐸铎亸哚嚲垛垜埵奲崜挆朵朶椯綞缍趓躱躲軃鬌刴剁堕墮墯尮惰憜挅柮桗舵跥跺陊陏飿饳鵽妸妿娿婀屙俄吪囮娥峉峨峩涐珴皒睋磀莪蛾訛誐譌讹迗鈋鋨锇頟額额魤鵝鵞鹅噁枙砨頋騀鵈偔僫匎卾厄呃呝咢咹噩垩堊堨堮姶岋崿廅恶悪惡愕戹扼搤搹擜櫮歞歺湂琧砈砐硆礘腭苊萼蕚蚅蝁覨諤讍谔豟軛軶轭遌遏遻鄂鈪鍔鑩锷閼阏阨阸頞顎颚餓餩饿鰐鰪鱷鳄鶚鹗齃齶誒诶欸奀恩煾蒽峎嗯摁侕儿児兒唲峏栭洏粫而耏聏胹荋袻輀轜陑隭髵鮞鲕鴯鸸尒尓尔栮毦洱爾珥耳薾衈趰迩邇鉺铒餌饵駬二佴刵咡弍弐樲誀貮貳贰髶冹发彂沷発發乏伐傠坺垡墢姂栰橃浌疺瞂笩筏罚罰罸茷藅閥阀佱峜法灋砝鍅珐琺蕟髪髮勫噃嬏帆幡忛憣旙旛畨番籓繙翻藩轓颿飜鱕凡凢凣匥墦杋柉棥樊瀿烦煩燔璠矾礬笲籵緐繁羳膰舤舧蕃薠蘩蠜襎蹯釩鐇鐢钒鷭仮反払橎返奿嬎梵氾汎泛滼瀪犯畈盕笵範范訉販贩軓軬輽飯飰饭匚坊堏方枋汸淓牥芳蚄趽邡鈁錺钫鴋妨房肪防魴鲂仿倣旊昉昘瓬眆紡纺舫訪访髣鶭放啡妃婓婔扉暃渄猆緋绯菲蜚裶霏非靟飛飝飞餥馡騑騛鯡鲱淝肥腓蜰匪奜悱斐朏棐榧篚翡胐蕜誹诽俷剕厞吠屝废廃廢昲曊杮櫠沸濷狒疿痱癈肺胇芾萉蟦費费鐨镄陫靅鼣分吩帉昐朆梤棻氛竕紛纷翂芬衯訜躮酚鈖雰餴饙馚坟墳妢岎幩朌枌棼橨汾濆炃焚燌燓獖羒羵蒶蕡蚠蚡豮豶轒鐼隫馩魵黂鼖鼢粉黺份偾僨奋奮弅忿愤憤瀵瞓秎粪糞膹鱝鲼丰仹偑僼凨凬凮堼妦寷封峯峰崶枫桻楓檒沣沨渢灃烽犎猦琒疯瘋盽砜碸篈葑蘴蜂蠭豐鄷酆鋒鎽鏠锋霻靊風飌风麷冯堸夆摓浲溄漨綘縫缝艂逢馮唪覂諷讽俸凤奉湗焨煈賵赗鳯鳳鴌覅仏佛坲梻紑否妚殕缶缹缻雬鴀伕呋夫妋姇娐孵尃怤懯敷旉柎玞砆稃筟粰糐紨綒肤胕膚荂荴衭趺跗邞鄜酜鈇鳺麩麬麱麸乀伏俘凫刜匐咈哹垘孚岪巿帗幅幞弗怫扶拂服枎柫栿桴棴榑氟泭洑浮涪澓炥烰玸琈甶畉畐癁砩祓福稪符笰箙紱紼絥綍绂绋罘罦翇艀艴芙芣苻茀茯莩菔葍虙蚨蜉蝠袚袱襆襥諨豧踾輻辐郛鉘鉜韍韨颫髴鮄鮲鳧鳬鴔鵩鶝黻乶俌俛俯呒嘸府弣抚拊捬撫斧椨滏焤甫盙簠脯腐腑蜅輔辅郙釜釡阝頫鬴黼付偩傅冨副咐坿复妇婏婦媍嬔富峊彿復椱父祔禣秿竎緮縛缚腹萯蕧蚥蚹蛗蝜蝮袝複褔覄覆訃詂讣負賦賻负赋赙赴輹鍑鍢阜附馥駙驸鮒鰒鲋鳆嘎嘠旮噶尜釓錷钆尕玍尬魀侅垓姟峐晐畡祴絯荄該该豥賅賌赅郂陔忋改絠丐乢匃匄戤摡概槩槪溉漑瓂盖葢蓋鈣钙凲坩尲尴尶尷干忓攼杆柑泔漧玕甘疳矸竿筸粓肝苷迀酐魐鳱仠感擀敢桿橄澉澸皯秆稈簳芉衦赶趕鱤鳡倝凎幹旰榦檊汵淦灨盰紺绀詌贑贛赣骭冈冮刚剛堈堽岡掆摃棡牨犅疘矼綱纲缸罁罡肛釭鋼鎠钢岗崗港戅戆戇杠槓焵焹筻槔槹橰櫜皋皐睾篙糕羔膏臯韟餻高髙鷎鷱鼛夰搞杲槀槁檺稁稾稿縞缟菒藁藳鎬镐勂吿告峼祮祰禞筶誥诰郜鋯锆割哥圪彁戈戓戨搁擱歌滒牫犵疙肐胳袼謌鎶饹鴚鴿鸽佫佮匌呄嗝塥愅挌搿敋格槅櫊滆獦膈臵葛蛒蛤裓觡諽輵轕鎘镉閣阁隔革鞈鞷韐韚騔骼鬲鮯哿嗰笴舸个亇個各箇茖虼鉻铬給给根跟哏亘亙揯搄艮茛刯庚椩浭焿畊絚緪縆羮羹耕菮賡赓鶊鹒哽埂峺挭梗綆绠耿莄郠骾鯁鲠堩更侊公功匑匔厷塨宫宮工幊弓恭愩慐攻杛碽篢糼糿肱蚣觥觵躬躳髸龏龔龚巩廾拱拲栱汞珙輁鞏供共唝嗊熕貢贡佝勾沟溝痀篝簼緱缑芶袧褠鈎鉤钩鞲韝岣枸狗玽笱耇耈耉苟蚼豿冓啂坸垢够夠姤媾彀搆撀构構煹覯觏訽詬诟購购遘雊估咕唂唃姑嫴孤巬巭杚柧橭沽泒稒笟箍箛篐罛苽菇菰蓇蛄觚軱軲轱辜酤鈲鮕鴣鸪傦古啒嘏夃尳愲扢榖毂汩淈濲瀔牯皷皼盬瞽穀糓縎罟羖股脵臌薣蛊蠱詁诂谷轂逧鈷钴餶馉骨鶻鹘鼓鼔僱凅固堌崓崮故梏棝榾牿痼祻錮锢雇顧顾鯝鲴刮劀呱栝桰歄煱瓜緺胍趏踻颪颳騧鴰鸹冎剐剮叧寡卦啩坬挂掛絓罣褂詿诖乖叏拐枴柺箉罫夬怪恠倌关官棺涫瘝癏窤蒄覌観觀观関闗關鰥鱞鳏琯璭痯筦管舘輨錧館馆鳤丱冠卝悹悺惯慣掼摜樌欟毌泴潅灌爟瓘盥矔礶祼罆罐貫贯躀遦鏆鑵雚鱹鸛鹳僙光咣垙姯桄洸灮炗炚炛烡珖胱茪輄銧黆广広廣犷獷臩俇臦逛亀圭妫媯嫢嬀嶲巂帰廆归摫椝槻槼櫷歸珪瑰璝瓌皈瞡硅胿茥蘬袿規规邽郌閨闺雟騩鬶鬹鮭鲑龜龟佹匦匭厬垝姽宄庋庪恑攱晷氿湀癸祪簋蛫蟡觤詭诡軌轨陒鬼刽刿劊劌撌攰昋柜桂桧椢槶樻檜櫃猤癐眭瞆瞶禬筀蓕螝襘貴贵跪鐀鑎鞼鱖鱥鳜丨惃滚滾磙緄緷绲蓘蔉衮袞輥辊鮌鯀鲧棍睔謴啯嘓埚堝墎崞彉彍懖楇濄猓瘑聒蝈蟈郭鈛鍋锅囯囶囻国圀國帼幗慖掴摑漍簂聝腘膕蔮虢馘惈果椁槨淉粿綶菓蜾裹褁輠餜馃腂过過鐹哈紦鉿铪咍嗨孩还骸塰海烸胲酼醢亥嗐妎害氦餀饚駭駴骇佄哻嫨憨犴蚶谽酣頇顸馠魽鼾函凾含唅圅娢寒崡嵅晗梒浛涵澏焓琀甝筨虷蜬邗邯鋡韓韩丆喊浫罕豃傼厈垾屽悍憾扞捍撖撼旱晘暵汉汗涆漢瀚焊熯猂皔睅翰莟菡蔊蛿蜭螒譀輚釬銲鋎閈闬雗頷顄颔馯駻鶾兯爳夯吭垳斻杭笐筕絎绗航苀蚢裄貥迒頏颃魧沆嚆茠蒿薅薧乚儫嗥嘷噑嚎壕椃毜毫濠獆獋獔竓籇蚝蠔譹豪好郝侴傐号哠恏悎昊昦晧暠暤暭曍浩淏滈澔灏灝皓皜皞皡皥秏耗聕薃號鄗顥颢鰝呵喝嗬抲欱蠚訶诃何劾合咊和啝姀峆惒敆曷朅柇核楁毼河涸渮澕熆狢皬盇盉盍盒礉禾篕籺粭紇纥翮荷菏萂螛覈訸詥貈貉郃釛鉌鑉閡閤闔阂阖鞨頜颌餄饸魺鲄鶡鹖麧齕龁龢哬嗃嚇垎壑寉焃煂熇燺爀癋碋翯袔褐謞賀贺赫靍靎靏鶮鶴鸖鹤嘿潶黑黒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒撗桁横橫烆珩胻蘅衡鑅鴴鵆鸻啈叿呍哄嚝揈渹灴烘焢硡薨訇谾軣輷轟轰鍧仜吰垬妅娂宏宖屸弘彋汯沗泓洪浤渱潂玒玜硔竑竤篊粠紅紘紭綋红纮羾翃翝耾苰荭葒葓虹谹谼鈜鉷鋐閎闳霐霟鞃魟鴻鸿黉黌晎撔澒蕻訌讧銾閧闀闂鬨齁侯喉帿猴瘊睺矦篌糇翭翵葔鄇銗鍭餱骺鯸吼吽犼候厚后垕堠後洉茩豞逅郈鮜鱟鲎鲘乎乯匢匫呼唿嘑垀寣幠忽恗惚昒曶歑泘淴滹烀糊膴苸虍虖謼軤轷雐雽喖嘝囫壶壷壺媩弧抇搰斛楜槲湖瀫焀煳狐猢瑚瓳箶絗縠胡葫蔛蝴螜衚觳醐鍸隺頶餬鬍魱鰗鵠鶘鶦鹄鹕乕俿唬汻浒滸琥萀虎虝錿鯱互冱嗀嚛婟嫭嫮岵帍弖怘怙戶户戸戽扈护摢昈枑槴沍沪滬熩瓠祜笏簄粐綔芐蔰護豰鄠鍙頀鱯鳠鳸鸌鹱埖婲椛硴糀花蒊蘤誮錵划劃华呚哗嘩姡搳撶滑猾磆華蕐螖譁釪釫鋘鏵铧驊骅鷨化夻婳嫿嬅崋摦杹枠桦槬樺澅画畫畵繣舙觟話諙諣譮话黊徊怀懐懷槐櫰淮瀤耲蘹褢褱踝咶坏壊壞蘾孉懽欢歓歡犿獾讙貛酄驩鴅鵍圜堚嬛寏寰峘桓洹澴狟獂环環瓛糫絙綄繯缳羦荁萈萑豲貆還鍰鐶锾镮闤阛雈鬟鹮睆緩缓唤喚喛嚾奂奐宦嵈幻患愌换換擐攌梙槵浣涣渙漶澣烉焕煥瑍痪瘓肒藧豢轘逭鯇鯶鰀鲩塃宺巟慌朚肓荒衁偟凰喤堭墴媓崲徨惶揘楻湟潢煌熿獚瑝璜癀皇磺穔篁簧艎葟蝗蟥諻趪遑鍠鐄锽隍韹餭騜鰉鱑鳇鷬黃黄兤奛幌怳恍晃晄櫎炾熀縨詤謊谎愰曂榥滉皝皩鎤咴噅噕婎媈幑徽恢拻挥揮撝晖暉楎洃瀈灰灳烣煇睢睳禈翚翬蘳袆褘詼诙豗輝辉隓隳鰴麾佪囘回囬廻廽恛洄烠痐茴蚘蛔蛕蜖迴逥鮰悔檓毀毁毇燬虺譭会僡儶匯卉喙嘒嚖圚嬒寭屶屷彗彙彚徻恚恵惠慧憓懳晦暳會槥橞檅櫘汇泋湏滙潓濊烩燴獩璤璯瘣瞺秽穢篲絵繢繪绘缋翙翽芔荟蔧蕙薈薉藱蟪詯誨諱譓譿讳诲賄贿鏸鐬闠阓靧頮顪颒餯婚惛昏昬棔殙涽睧睯荤葷蔒轋閽阍忶浑渾珲琿餛馄魂鼲俒倱圂婫尡慁掍混溷焝睴觨諢诨劐吙攉秴耠豁騞佸活秮秳伙夥漷火灬煷邩鈥钬俰剨咟喐嚄嚯嚿奯彟彠惑或捇掝擭旤曤檴沎湱濩瀖獲癨眓矆矐祸禍穫窢耯臛艧获蒦藿蠖謋貨货鍃鑊锪镬閄雘霍靃韄乩僟击刉刏剞叽咭唧喞嗘嘰圾基墼姬屐嵆嵇撃擊朞机枅槣樭機櫅毄激犄玑璣畸畿癪矶磯禨积稘稽積笄筓箕簊綨緁緝缉羁羇羈耭肌芨虀覉覊觭譏譤讥賫賷赍跻踑躋躸銈錤鐖鑇鑙隮雞鞿韲飢饑饥魕鳮鶏鶺鷄鸄鸡鹡齏齑亟亼亽伋佶偮卙即卽及叝吉堲塉姞嫉岌嶯彶忣急愱戢揤极棘楖楫極槉檝殛汲湒潗濈焏疾瘠皀皍磼笈箿籍級级耤膌艥蒺蕀蕺蝍螏襋觙谻趌踖蹐躤輯轚辑郆銡鍓鏶集雧霵齎丮几妀嵴己幾戟挤掎撠擠橶泲犱穖脊虮蟣魢鱾麂伎偈兾冀剂剤劑勣哜嚌坖垍塈妓季寂寄廭彐彑徛忌悸惎懻技旡既旣暨暩曁梞檕檵洎济済漃漈濟瀱璾痵癠祭禝稩稷穄穊穧紀紒継績繋繼纪继绩罽臮芰茍茤荠葪蓟蔇薊薺蘎蘮蘻裚襀覬觊計記誋諅计记跡跽蹟迹际際霁霽驥骥髻鬾魝魥鯚鯽鰶鰿鱀鱭鲚鲫鵋鷑齌乫伽佳傢加嘉家徍抸拁枷梜毠泇浃浹犌猳珈痂笳糘耞腵葭袈豭貑跏迦鉫鎵镓鴐麚唊圿夹夾忦恝戛戞扴脥荚莢蛱蛺袷裌郏郟鋏铗頬頰颊鴶鵊假叚婽岬徦斚斝椵榎槚檟玾甲瘕胛賈贾鉀钾价價嫁幏架榢稼駕驾兼冿囏坚堅奸姦姧尖幵惤戋戔搛椷椾樫櫼歼殱殲湔瀐瀸煎熞熸牋犍猏玪瑊监監睷碊礛礷笺箋緘縑缄缣肩艰艱菅菺葌蒹蔪蕑蕳虃譼豜豣鋻鑯間间雃靬鞯韀韉餰馢鰔鰜鰹鲣鳒鳽鵑鵳鶼鹣麉俭倹儉减剪囝堿帴弿彅戩戬拣挸捡揀揃撿暕枧柬梘检検檢減湕瀽瑐睑瞼硷碱礆笕筧简篯簡籛絸繭翦茧藆蠒裥襇襉襺詃謇謭譾谫趼蹇鐗鐧锏鬋鰎鹸鹻鹼件俴健僭剑剣剱劍劎劒劔墹寋建徤擶旔栫楗榗槛檻毽洊涧渐溅漸澗濺瀳牮珔瞷磵礀箭糋繝腱臶舰艦荐薦袸見覵覸见諓諫譛谏賎賤贱趝跈践踐踺轞鉴鍳鍵鏩鐱鑑鑒鑬鑳键鞬餞饯僵壃姜将將摪橿殭江浆漿畕畺疅疆礓繮缰翞茳葁薑螀螿豇韁鱂鳉傋塂奖奨奬桨槳獎耩膙蒋蔣講讲顜勥匞匠夅嵹弜弶摾櫤洚滰犟糡糨絳绛謽酱醤醬降交僬姣娇嬌峧嶕嶣憍椒浇澆焦燋礁穚簥胶膠膲艽茭茮蕉虠蛟蟭跤轇郊鐎驕骄鮫鲛鵁鷦鷮鹪嚼佼侥僥儌剿劋勦孂徺徼憿挢捁搅摷撟撹攪敫敽敿晈暞曒灚烄煍燞狡璬皎皦矫矯笅筊絞繳纐绞缴脚腳臫蟜角譑賋踋鉸铰餃饺鱎龣叫呌嘂嘄嘦噍噭嬓嶠挍敎教斠滘漖潐獥珓皭窌窖藠訆譥趭較轎轿较酵醮釂喈喼嗟堦媘嫅接掲揭擑椄楬湝煯疖痎癤皆秸稭脻菨蝔街謯阶階鞂鶛倢偼傑刦刧刼劫劼卩卪婕媫孑尐岊崨嵥嶻巀幯截拮捷掶搩擮昅杢杰桀桔桝楶榤洁滐潔狤疌睫碣礍竭節結结羯节莭蓵蛣蜐蠘蠞蠽衱袺訐詰誱讦诘跲踕迼鉣鍻镼鞊頡颉鮚鲒姐媎檞毑解觧飷丯介借吤唶堺屆届岕庎徣悈戒楐犗玠琾界畍疥砎芥藉蚧蛶衸褯誡诫鎅骱魪今仐堇堻巾惍斤津珒琎琻璡矜矝砛禁筋紟荕衿襟觔金釒釿钅鹶黅仅侭僅儘卺厪嫤巹廑慬槿漌瑾紧緊菫蓳謹谨錦锦饉馑伒僸凚劤劲勁唫噤嚍墐壗妗嬧尽搢晉晋枃歏殣浕浸溍濅濜烬煡燼瑨璶盡祲縉缙荩藎覲觐賮贐赆近进進靳齽京亰兢坕坙婛巠惊旌旍晶橸泾涇猄睛秔稉粳精経經綡经聙腈茎荆荊菁葏驚鯨鲸鶁鶄麖麠鼱丼井儆刭剄坓宑幜憬憼景暻殌汫汬澋璄璟璥穽肼蟼警阱頚頸颈俓傹净凈境妌婙婧弪弳径徑敬曔桱梷浄淨瀞獍痉痙竞竟竧竫競竸胫脛莖誩踁迳逕鏡镜靓靖静靚靜鵛冂冋坰埛扃絅蘏蘔駉駫侰僒冏囧泂浻澃炅炯烱煚煛熲燛窘綗褧迥逈顈颎丩勼啾揂揪揫摎朻樛牞究糺糾纠萛赳阄鬏鬮鳩鸠久乆九乣奺杦汣灸玖紤舏酒镹韭韮倃僦匓匛匶厩咎就廄廏廐慦捄救旧柩柾桕欍殧疚臼舅舊鯦鷲鹫麔齨凥匊娵婮居岨崌抅拘掬梮椐檋毩毱泃涺狙琚疽眗砠罝腒艍苴蜛裾諊跔跙踘躹鋦锔陱雎鞠鞫駒驹鮈鴡鶋侷啹婅局巈挶椈橘泦淗湨焗犑狊粷繘菊蘜趜跼蹫輂郹閰駶驧鵙鵴鶪鼰鼳举咀弆挙擧椇榉榘櫸欅沮矩筥聥舉莒蒟襷踽齟龃乬俱倨倶具剧劇勮句埧埾壉姖寠屦屨岠巨巪怇惧愳懅懼拒拠据據昛歫洰澽炬烥犋秬窭窶簴粔耟聚苣虡蚷袓詎讵豦貗距踞躆遽邭醵鉅鋸鐻钜锯颶飓駏鮔勬姢娟捐朘涓焆脧蠲裐鋑鎸鐫镌鹃卷呟埍巻捲臇菤錈锩倦劵勌奆婘帣弮惓慻桊淃狷獧瓹眷睊睠絭絹绢罥羂腃蔨讂鄄餋噘屩屫撅撧亅决刔劂匷厥噊噱孒孓崛崫嶡嶥弡彏憠憰戄抉挗捔掘攫斍桷橛橜櫭欮氒決泬灍焳熦爑爝爴爵獗玃玦玨珏瑴疦瘚矍矡砄絕絶绝臄芵蕝蕨虳蚗蟨蟩覐覚覺觉觖觮觼訣譎诀谲貜赽趉趹蹶蹷躩鈌鐍鐝钁镢駃鴂鴃鷢倔军君均桾汮皲皸皹碅莙菌蚐袀覠軍鈞銁銞鍕钧頵鮶鲪麇麏麕俊儁呁埈寯峻懏捃攈攟晙棞浚濬燇珺畯竣箘箟葰蜠賐郡陖隽雋餕馂駿骏鵔鵕鵘咖喀佧卡咔咯垰胩裃鉲奒开揩鐦锎開凯凱剀剴嘅垲塏嵦恺愷慨暟楷蒈輆鍇鎧铠锴闓闿颽勓忾愾欬炌烗鎎刊勘堪嵁戡栞龕龛侃偘冚凵坎惂欿歁砍竷莰輡轗顑墈崁看瞰矙磡衎闞阚鬫嫝嵻康忼慷槺漮砊穅粇糠躿鏮閌鱇扛亢伉匟囥抗炕犺邟鈧钪闶尻嵪髛丂拷攷栲洘烤考犒銬铐靠鮳鯌鲓匼嗑嵙搕柯棵榼樖牁牱犐珂疴痾瞌砢磕礚科稞窠苛萪薖蚵蝌趷軻轲醘鈳钶頦顆颏颗髁咳壳揢殻殼翗可坷岢嵑嶱敤渇渴炣克刻勀勊堁娔客尅峇恪愘愙氪溘碦礊緙缂艐衉課课錁锞騍骒剋啃垦墾恳懇肎肯肻豤貇錹掯硍裉褃劥坑妔挳摼牼硁硜硻誙銵鍞鏗铿阬倥埪崆悾涳硿空箜躻錓鵼孔恐控鞚剾彄抠摳眍瞘芤劶口冦叩宼寇怐扣敂滱瞉窛筘簆蔲蔻釦鷇刳哭圐堀枯桍矻窟跍郀骷鮬楛狜苦俈喾嚳库庫廤焅瘔秙絝绔袴裤褲酷咵夸姱舿誇侉垮銙挎胯趶跨骻擓蒯侩儈凷哙噲圦块塊墤巜廥快旝欳浍澮狯獪筷糩脍膾郐鄶鱠鲙宽寛寬臗鑧髋髖梡欵款歀窽窾劻匡匩哐恇洭硄筐筺誆诓軭邼忹抂狂狅誑诳軖軠鵟儣夼懭况圹壙岲懬旷昿曠框況爌眖眶矌矿砿礦穬絋絖纊纩貺贶軦邝鄺鉱鋛鑛黋亏刲岿巋悝盔窥窺聧虧闚顝喹夔奎巙戣揆晆暌楏楑櫆犪睽葵藈蘷虁蝰躨逵鄈鍨鍷頯馗騤骙魁傀煃磈跬蹞頍匮匱喟嘳媿嬇尯愦愧憒殨溃潰篑簣籄聩聭聵膭蒉蕢謉餽饋馈坤堃堒崐崑昆晜潉焜熴猑琨瑻菎蜫裈裩褌醌錕锟騉髠髡髨鯤鲲鵾鶤鹍壸壼悃捆梱硱祵稇稛綑裍閫閸阃困涃睏廓扩拡括挄擴濶筈萿葀蛞闊阔霩鞟鞹韕頢髺鬠啦垃拉搚柆菈邋嚹旯磖喇藞剌揦揧攋楋櫴溂爉瓎瘌翋腊臈臘蜡蝋蝲蠟辢辣鑞镴鬎鯻鞡來俫倈婡崃崍庲徕徠来梾棶涞淶猍琜筙箂莱萊逨郲錸铼騋鯠鶆麳襰唻濑瀨瀬癞癩睐睞籁籟藾賚賴赉赖頼顂鵣儖兰啉囒婪岚嵐幱惏懢拦攔斓斕栏欄欗澜瀾灆灡燣燷璼篮籃籣繿葻蓝藍蘫蘭褴襕襤襴襽譋讕谰躝鑭镧闌阑韊壈嬾孄孏懒懶揽擥攬榄欖浨漤灠爦纜缆罱覧覽览醂顲嚂滥濫烂燗爁爛爤瓓糷钄啷勆嫏廊斏桹榔樃欴狼琅瑯硠稂筤艆蓈蜋螂躴郎郒郞鋃鎯锒塱崀朖朗朤烺蓢誏埌浪莨蒗閬阆捞撈粩僗劳労勞哰崂嶗憥朥浶牢痨癆磱窂簩蟧醪鐒铹顟髝佬咾姥恅栳潦狫珯硓老耂荖蛯轑銠铑鮱唠嗠嘮嫪憦橯涝澇烙耢耮躼軂酪乐仂勒叻忇扐楽樂氻泐玏砳竻簕艻阞韷餎鰳鱳鳓了儽嫘擂攂樏檑櫑欙瓃畾礌礧累縲纍纝缧罍羸蔂蘲虆轠鐳鑘镭雷靁鱩鼺傫儡厽垒塁壘壨櫐洡灅癗矋磊磥礨絫耒蕌蕾藟蘽蠝誄讄诔鑸鸓泪涙淚禷类纇肋蘱酹銇錑頛頪類颣嘞唥塄棱楞碐稜薐冷倰堎愣睖踜刕剓剺劙厘喱嚟囄嫠孷廲悡斄梨梸棃樆漓灕犁犂狸琍璃瓈盠睝离穲竰筣篱籬糎縭纚缡罹艃荲菞蓠蔾藜蘺蟍蟸蠫褵謧貍邌醨釐鋫錅鏫鑗離驪骊鯏鯬鱺鲡鵹鸝鹂黎黧俚娌峛峢峲李欚浬澧理礼禮粴蠡裏裡豊逦邐醴里鋰锂鯉鱧鱱鲤鳢丽例俐俪傈儮儷凓利力励勵历厉厤厯厲叓吏呖唎唳嚦囇坜塛壢娳婯孋屴岦巁悧悷慄戾搮擽攊攦攭暦曆曞朸枥栃栎栗栛棙檪櫔櫟櫪欐歴歷沥沴浰涖溧濿瀝爄爏犡猁珕瑮瓅瓑瓥疠疬痢癘癧皪盭睙砅砬砺砾磿礪礫礰禲秝立笠篥粒粝糲綟脷苈苙茘荔莅莉蒚蒞藶蚸蛎蛠蜊蜧蝷蠇蠣觻詈讈赲跞躒轢轣轹郦酈鉝隶隷隸雳靂靋鬁鳨鴗鷅麗麜哩亷劆匲匳嗹噒奁奩嫾帘廉怜慩憐梿槤櫣涟溓漣濂濓瀮熑燫磏簾籢籨縺翴联聨聫聮聯臁莲蓮薕螊蠊裢褳覝謰蹥连連鎌鐮镰鬑鰱鲢嬚摙敛斂歛琏璉羷脸臉蔹蘝蘞裣襝鄻僆堜媡恋戀楝殓殮湅潋澰瀲炼煉瑓練纞练萰錬鍊鏈链鰊俍凉墚梁椋樑涼粮粱糧良踉輬辌駺両两俩倆兩唡啢掚緉脼蜽裲魉魎亮倞哴喨悢晾湸諒谅輌輛辆量鍄撩蹽僚嘹嫽寥寮尞屪嵺嶚嶛廫憀敹暸橑漻燎爎爒獠璙疗療竂簝繚缭聊膋膫藔蟟豂賿蹘辽遼飉髎鷯鹩憭曢瞭蓼鄝釕钌镽尥尦廖撂料炓窷鐐镣咧挘毟儠冽列劣劽哷埒埓姴巤挒捩擸栵洌浖烈烮煭犣猎猟獵聗脟茢蛚裂趔躐迾颲鬛鬣鮤鱲鴷拎临冧厸壣崊嶙斴晽暽林淋潾瀶燐獜琳璘疄瞵碄磷箖粦粼綝繗翷臨轔辚遴邻鄰鏻阾隣霖驎鱗鳞麐麟亃僯凛凜廩廪懍懔撛檁檩澟癛癝菻吝恡悋橉焛甐膦蔺藺賃赁蹸躏躙躪轥閵〇伶凌刢呤囹坽夌姈婈孁崚彾掕昤朎柃棂櫺欞泠淩澪灵燯爧狑玲琌瓴皊砱祾秢竛笭紷綾绫羐羚翎聆舲苓菱蓤蔆蕶蛉衑裬詅跉軨輘酃醽鈴錂铃閝陵零霊霗霛霝駖魿鯪鲮鴒鸰鹷麢齡齢龄龗岭岺嶺袊領领令另炩蘦靈溜澑熘蹓刘劉嚠媹嵧懰斿旈旒榴橊流浏瀏琉瑠瑬璢畄留畱疁瘤癅硫磂蒥蓅藰蟉裗鎏鎦鏐鐂镏镠飀飅飗駠駵騮驑骝鰡鶹鹠麍嬼柳栁桞桺橮熮珋綹绺罶羀鋶锍六塯廇磟翏遛雡霤飂餾馏鬸鷚鹨咙嚨尨嶐巃巄昽曨朧栊槞櫳泷湰滝漋瀧爖珑瓏癃眬矓砻礱礲窿竜笼篭籠聋聾胧茏蘢蠪蠬襱豅躘鏧鑨隆霳靇驡鸗龍龒龓龙儱垄垅壟壠拢攏竉陇隴哢徿梇贚剅喽嘍娄婁廔楼樓溇漊熡瞜耧耬艛蒌蔞蝼螻謱軁遱鞻髅髏鷜塿嵝嶁搂摟甊篓簍屚漏瘘瘺瘻鏤镂陋露噜嚕撸擼謢卢嚧垆壚庐廬攎曥枦栌櫨泸瀘炉爐獹玈璷瓐盧矑籚纑罏胪臚舮舻艫芦蘆蠦轤轳鈩鑪顱颅馿髗魲鱸鲈鸕鸬黸卤塷掳擄樐橹櫓氇氌滷澛瀂硵磠穞艣艪蓾虏虜鏀鐪鑥镥魯鲁鹵侓僇剹勎勠圥坴塶娽峍廘彔录戮摝椂樚淕淥渌漉潞熝琭璐甪盝睩硉碌祿禄稑穋箓簏簬簵簶籙粶膔菉蔍蕗虂螰賂赂趢路踛蹗輅轆辂辘逯醁錄録錴鏕鏴陆陸騄騼鯥鴼鵦鵱鷺鹭鹿麓圝圞奱娈孌孪孿峦巒挛攣曫栾欒滦灓灤癴癵羉脔臠虊銮鑾鵉鸞鸾卵乱亂釠抡掄仑伦侖倫囵圇婨崘崙棆沦淪碖磮綸纶耣腀芲菕蜦踚輪轮錀陯鯩埨惀稐溣論论啰囉捋頱儸囖攞椤欏猡玀箩籮罗羅脶腡萝蘿螺覶覼逻邏鏍鑼锣镙饠騾驘骡鸁倮剆曪瘰癳臝蓏蠃裸躶峈摞泺洛洜漯濼犖珞硌硦笿絡纙络荦落詻雒駱骆鮥鵅榈櫚氀膢藘閭闾驢驴侣侶偻僂儢吕呂屡屢履慺挔捛旅梠焒祣稆穭絽縷缕膂膐褛褸郘鋁铝勴垏嵂律慮櫖氯滤濾爈率箻綠緑繂绿膟葎虑鑢圙寽掠略畧稤鋝鋢锊妈媽嫲嘛犘痲痳蔴蟆蟇麻杩溤犸獁玛瑪码碼蚂螞遤鎷馬马鰢鷌傌嘜榪睰祃禡罵閁駡骂鬕吗嗎埋薶霾买嘪荬蕒買鷶佅劢勱卖唛売脈脉衇賣迈邁霡霢麥麦顢颟姏悗慲摱樠瞒瞞蛮蠻謾谩鞔饅馒鬗鬘鰻鳗娨屘満满滿矕螨蟎襔鏋僈墁嫚幔慢曼槾漫澷熳獌縵缦蔄蔓蘰鄤鏝镘牤厖吂哤娏忙恾杗杧汒浝牻狵痝盲盳硭笀芒茫蘉蛖邙釯鋩铓駹壾漭硥茻莽莾蟒蠎猫貓堥旄枆楙毛氂渵牦犛矛罞芼茅茆蝥蟊軞酕鉾錨锚髦髳鶜乮冇卯夘峁戼昴泖笷蓩鉚铆冃冐冒媢帽愗懋暓柕毷瑁皃眊瞀耄茂萺蝐袤覒貌貿贸鄚鄮嚒嚰濹么麼麽坆堳塺媒嵋徾攗枚栂梅楣楳槑沒没湄湈煤猸玫珻瑂眉睂禖脄脢腜苺莓葿郿酶鋂鎇镅霉鶥鹛黴凂媄媺嬍嵄挴毎每浼渼燘美羙躾鎂镁黣嚜妹媚寐抺旀昧沬煝痗眛睸祙篃蝞袂跊韎鬽魅椚们們扪捫玧璊穈菛虋鍆钔門閅门悶懑懣暪焖燜闷掹擝矇蒙儚幪懞曚朦橗檬氋氓溕濛獴甍甿盟瞢矒礞艨莔萌蕄虻蝱鄳鄸霿靀顭饛鯍鸏鹲冡勐懵猛艋蜢蠓錳锰鯭鼆夢夣孟懜梦癦霥咪眯瞇冞弥彌戂擟攠瀰爢猕獼瓕祢禰糜縻蒾藌蘪蘼袮詸謎谜迷醚醾醿釄镾靡鸍麊麋麛麿侎孊弭敉沵洣渳濔灖米粎羋脒芈葞蔝銤冖冪嘧塓宓宻密峚幂幎幦怽榓樒櫁汨沕泌淧滵漞濗熐祕秘簚糸羃蔤蜜覓覔覛觅謐谧鼏婂媔嬵宀杣棉檰櫋眠矈矊矏綿緜绵臱芇蝒丏偭免冕勉勔喕娩愐汅沔渑湎澠眄睌絻緬缅腼葂靦鮸糆面靣麪麫麵麺喵媌嫹描瞄緢苗鶓鹋劰杪淼渺眇秒篎緲缈藐邈妙庙庿廟玅竗乜吀咩哶孭幭懱搣櫗滅瀎灭烕礣篾蔑薎蠛衊鑖鱴鴓垊姄岷崏怋慜捪旻旼民玟珉琘琝瑉痻盿砇碈緍緡缗罠苠鈱錉鍲鴖僶冺刡勄忞忟悯惽愍憫抿敃敏敯暋泯湣潣皿笢笽簢蠠閔閩闵闽鰵鳘黽黾冥名嫇明暝朙榠洺溟猽眀眳瞑茗蓂螟覭詺鄍銘铭鳴鸣佲凕姳慏酩命掵謬谬嚤摸劘嫫嬤嬷尛庅摩摹擵模橅磨糢膜蘑謨謩谟饃饝馍髍魔魹懡抹嗼圽塻墨妺嫼寞帓帞昩末枺歾歿殁沫漠爅獏瘼皌眜眽眿瞐瞙砞礳秣絈纆耱茉莈莫蓦藦蛨蟔貃貊貘銆鏌镆陌靺驀魩默黙哞侔劺呣恈牟眸繆缪蛑謀谋踎鍪鴾麰某毪氁亩姆峔拇母牡牳畂畆畒畝畞畮砪胟踇鉧仫凩募坶墓幕幙慔慕暮暯木楘毣沐炑牧狇目睦穆縸艒苜莯蚞鉬钼雮霂鞪嗱拏拿搻鎿镎乸哪雫吶呐妠捺笝納纳肭蒳衲袦豽貀軜那郍鈉钠靹魶孻腉乃倷奶嬭廼氖疓艿迺釢奈柰渿耐萘螚褦錼鼐囡侽南喃娚抩暔枏柟楠男畘莮諵遖难難戁揇湳煵腩萳蝻赧婻囔乪嚢囊欜蠰饢馕擃攮曩灢儾齉孬呶夒峱嶩巎怓憹挠撓猱獶獿硇碙蛲蟯詉譊鐃铙匘垴堖嫐恼悩惱瑙碯脑脳腦淖臑閙闹鬧抐疒眲訥讷呢娞脮腇餒馁鮾鯘內内氝氞錗嫩嫰恁能妮倪坭埿婗尼屔怩棿泥淣猊秜籾聣臡蚭蜺觬貎跜輗郳鈮铌霓馜鯢鲵麑齯伱伲你儗儞妳孴抳拟掜擬旎晲柅檷狔聻苨薿隬匿堄嫟嬺屰惄愵昵暱氼溺眤睨縌胒腻膩誽逆拈蔫哖姩年秊秥粘鮎鯰鲇鲶鵇黏捻撚撵攆涊淰焾碾簐蹍蹨躎輦辇卄唸埝廿念惗艌娘嬢孃酿醸釀嫋嬝嬲樢茑蔦袅裊褭鳥鸟尿脲捏揑苶啮嗫噛嚙囁囓圼孼孽嵲嶭巕帇摰敜枿槷櫱涅湼痆篞籋糱糵聂聶臬臲菍蘖蠥讘踂踗踙蹑躡錜鎳鑈鑷钀镊镍闑陧隉顳颞齧囜您脌拰儜凝咛嚀嬣宁寍寕寗寜寧擰柠橣檸狞獰甯聍聹薴鑏鬡鸋拧矃佞侫倿泞澝濘妞汼牛牜忸扭杻炄狃紐纽莥鈕钮靵侬儂农哝噥檂欁浓濃燶禯秾穠脓膿蕽襛譨農辳醲鬞繷弄挊挵癑齈羺槈檽獳耨鎒鐞伮奴孥帑笯駑驽努弩砮胬傉怒搙奻暖渜煖煗餪黁傩儺娜挪梛橠喏愞懦懧掿搦榒稬穤糑糥糯諾诺蹃逽鍩锘女籹釹钕恧朒沑衂衄婩疟瘧硸虐喔噢哦筽塸櫙欧歐殴毆熰瓯甌膒藲謳讴鏂鴎鷗鸥偶吘呕嘔耦腢蕅藕怄慪沤漚啪妑皅舥苩葩趴掱杷潖爬琶筢帊帕怕袙拍俳徘排棑牌犤猅箄簰簲輫哌沠派渒湃蒎鎃攀潘眅萠丬媻幋搫柈槃洀瀊爿盘盤磐磻縏蒰蟠跘蹒蹣鎜鞶冸判叛沜泮溿炍牉畔盼聁袢襻詊鋬鑻頖鵥乓滂胮膖雱霶厐嫎庞庬彷徬旁舽螃逄鰟鳑龎龐耪覫炐眫肨胖抛拋脬萢刨匏咆垉庖炰爮狍袍褜軳鞄麃麅跑奅泡炮疱皰砲礟礮靤麭呸怌肧胚衃醅培婄毰裴裵賠赔錇锫阫陪俖伂佩姵帔斾旆沛浿犻珮蓜轡辔配霈馷喷噴歕湓瓫盆葐呠翸剻匉嘭怦恲抨梈泙烹砰硑磞軯閛駍倗傰堋塜塳弸彭憉捀朋棚椖樥澎熢硼稝竼篣篷纄膨芃莑蓬蘕蟚蟛袶輣錋鑝韸韼騯髼鬅鬔鵬鹏捧淎皏掽椪槰碰踫丕伓伾劈噼坯岯悂憵批披抷旇枈炋狉狓砒磇礔礕秛秠紕纰翍耚豾邳釽鈚鉟銔錃錍陴霹駓髬魾啤埤壀崥枇毗毘焷琵疲皮笓篺罴羆肶脾腗膍蚍蚽蚾蜱螷蠯裨豼貔郫鈹铍阰隦魮鮍鲏鵧鼙仳匹吡噽嚭圮嶏庀擗疋痞癖脴苉諀銢鴄僻媲嫓屁揊淠潎澼甓疈稫譬辟闢鷿鸊偏囨媥楄犏篇翩鍂鶣楩胼腁賆跰蹁駢騈骈骿覑諞谝貵片騗騙骗魸剽勡嘌彯慓旚漂犥翲螵飃飄飘魒嫖瓢薸闝殍皫瞟篻縹缥醥顠僄徱票驃鰾撆撇暼氕瞥覕丿苤鐅嫳姘拚拼砏礗穦馪驞嚬娦嫔嬪玭琕矉薲蘋蠙貧贫顰频颦品榀汖牝聘乒俜娉涄甹砯聠艵頩凭凴呯坪塀屏岼帡帲幈平慿憑枰檘洴淜焩玶瓶甁竮箳簈缾胓苹荓萍蓱蚲蛢評评軿輧郱鮃鲆屛坡岥泼溌潑酦醗醱釙鏺钋頗颇嘙嚩婆櫇皤蔢鄱叵尀笸箥鉕钷駊哱奤岶廹敀昢洦湐烞珀破砶粕蒪迫魄剖娝垺抔抙捊箁裒咅哣掊犃仆噗扑撲攴攵潽炇痡鋪铺陠鯆僕匍圤墣濮獛璞瞨穙纀莆菐菩葡蒱蒲贌酺鏷镤圃圑埔擈普暜朴樸檏氆浦溥烳諩譜谱蹼鐠镨曝瀑舖舗七倛傶僛凄嘁墄妻娸悽慼慽戚捿攲敧期柒栖桤桼棲榿欹欺沏淒漆紪緀萋褄諆踦蹊迉郪鏚霋魌鶈丌亓亝其剘圻埼奇岐岓崎嵜帺忯愭懠掑斉斊旂旗棊棋檱櫀歧淇濝猉玂琦琪璂畦疧碁碕祁祈祺禥竒簯簱籏粸綥綦耆肵脐臍艩芪萁萕蕲藄蘄蚑蚔蚚蛴蜝蜞螧蠐褀跂軝鄿釮錡锜陭隑頎颀騎騏騹骐骑鬐鬿鯕鰭鲯鳍鵸鶀麒麡齊齐乞企启呇唘啓啔啟婍屺岂晵杞棨玘盀綺绮芑諬豈起邔闙呮咠唭噐器夡契弃愒憇憩摖暣栔棄槭欫气気氣汔汽泣湆湇滊炁甈盵矵砌碛碶磜磧磩罊芞葺藒蟿訖讫迄鐑掐擖葜峠拤跒酠鞐冾圶帢恰殎洽硈胢髂仟佥僉千厱圱圲奷婜孯岍悭愆慳扦拪掔搴撁攐攑攓杄檶櫏欦汘汧牵牽竏签簽籖籤粁臤芊茾蚈褰諐謙谦谸迁遷釺鈆鉛鏲钎铅阡韆顅騫骞鬜鬝鵮鹐乹乾亁仱偂前墘媊岒忴扲拑掮揵榩橬歬潛潜濳灊箝羬荨葥蕁虔軡鈐鉗銭錢鎆钤钱钳騚騝鰬黔黚槏浅淺繾缱肷膁蜸譴谴遣鑓伣俔倩傔儙刋堑塹壍嬱嵌悓慊棈椠槧欠歉皘篏篟綪縴芡茜蒨蔳輤呛啌嗆嗴嶈戕戗戧搶摤斨枪椌槍溬牄猐獇玱瑲篬羌羗羫腔蜣謒跄蹌蹡鎗鏘锖锵墙墻嫱嬙廧強强彊樯檣漒牆艢蔃蔷薔蘠墏抢繈繦羟羥襁鏹镪唴炝熗羻劁勪墝墽帩幧悄敲橇毃燆硗磽繑繰缲趬跷踍蹺蹻郻鄡鄥鍫鍬鐰锹頝骹乔侨僑喬嘺墧嫶峤憔桥槗樵橋櫵犞癄睄瞧硚礄翘翹荍荞菬蕎藮譙谯趫鐈鞒鞽顦巧愀釥髜俏僺峭撬撽窍竅誚诮躈陗鞘鞩韒髚切苆癿聺茄且匧厒妾怯悏惬愜挈洯淁穕窃竊笡箧篋籡蛪趄踥郄鍥锲鯜亲侵兓媇寴嵚嵰嶔欽綅衾親誛钦顉駸骎鮼勤嗪噙埐嫀嶜庈懃懄捦擒斳檎澿珡琴琹瘽禽秦耹肣芩芹菦菳蚙螓蠄鈙鈫雂靲鳹鵭坅寑寖寝寢昑梫笉螼赾鋟锓吢吣唚抋揿搇撳沁瀙菣藽倾傾卿圊埥寈氢氫淸清蜻軽輕轻郬錆鑋靑青鯖鲭剠勍啨夝情擎擏晴暒棾樈檠殑氰甠硘葝黥庼廎檾漀苘請謦请頃顷儬凊庆慶掅櫦殸濪碃磬箐綮罄靘儝卭宆惸憌桏橩焪焭煢熍琼璚瓊瓗睘瞏穷穹窮竆笻筇舼茕藑藭蛩蛬赹跫邛銎丘丠坵媝恘恷楸湫湬秋秌穐篍緧萩蓲蘒蚯蝵蟗蠤趥邱鞦鞧鰌鰍鳅鶖鹙龝俅叴唒囚崷巯巰扏朹梂殏毬求汓泅浗渞湭煪犰玌球璆皳盚紌絿肍芁莍虬虯蛷蝤裘觓觩訄訅賕赇逎逑遒酋醔釚釻銶頄鮂鯄鰽鼽搝糗伹佉匤区區呿坥屈岖岴嶇憈抾敺浀焌煀祛筁粬紶胠蛆蛐袪覰詘誳诎趋趍趨躯軀阹駆駈驅驱髷魼鰸鱋鶌麯麴麹黢佢劬忂戵斪朐欋欔氍淭渠灈爠璖璩癯瞿磲籧絇翑胊臞菃葋蕖蘧螶蟝蠷蠼衐衢躣軥鑺鴝鸜鸲鼩取娶曲竘竬蝺詓齲龋刞厺去耝覷覻觑趣閴闃阒麮鼁圈圏奍悛棬椦箞鐉佺全啳埢姾峑巏恮拳搼权楾権權泉洤湶牷犈瑔痊硂筌絟縓荃葲蜷蠸觠詮诠跧踡輇辁醛銓铨闎顴颧駩騡鬈鰁鳈齤烇犬犭犮畎綣绻虇券劝勧勸牶韏炔缺缼蒛阙瘸傕却卻埆塙崅悫愨慤搉棤榷燩琷皵硞确碏確碻礐礭趞闋闕阕雀鵲鹊囷夋踆逡宭峮帬羣群裙裠呥嘫然燃繎肰蚦蚺衻袇袡髥髯冄冉姌媣染橪珃苒蒅儴勷瀼獽瓤禳穣穰蘘躟鬤嚷壌壤攘爙懹譲讓让娆嬈桡橈荛蕘襓饒饶扰擾隢繞绕遶惹热熱人亻仁壬忈忎朲秂芢銋魜鵀忍栠栣棯秹稔綛荏荵躵仞仭任刃刄妊姙屻岃扨杒梕牣祍紉紝絍纫纴肕腍衽袵訒認认讱軔轫鈓靭靱韌韧飪餁饪扔仍礽芿辸陾囸日衵釰釼鈤馹驲傛媶嫆嬫容峵嵘嵤嶸戎搈搑曧栄榕榮榵槦毧溶瀜烿熔爃狨瑢穁絨縙绒羢肜茙茸荣蓉蝾融螎蠑褣鎔镕駥傇冗坈宂氄軵穃厹媃揉柔楺渘煣瑈瓇禸粈糅脜腬葇蝚蹂輮鍒鞣騥鰇鶔韖宍肉譳嶿侞儒嚅如嬬孺帤挐曘桇渪濡筎繻茹蒘蕠薷蝡蠕袽襦邚醹銣铷顬颥鱬鴑鴽乳擩汝肗辱鄏入嗕媷扖杁洳溽縟缛蓐褥鳰堧壖撋偄媆朊瑌瓀碝礝緛耎腝軟輭软阮桵甤緌蕤壡惢橤繠蕊蕋蘂蘃叡枘汭瑞睿芮蚋蜹銳鋭锐瞤橍润潤膶閏閠闰挼捼偌叒婼嵶弱楉渃焫爇箬篛若蒻鄀鰙鰯鶸仨撒洒灑訯躠靸卅摋櫒脎萨蕯薩鈒钑隡颯飒馺嘥噻塞愢揌毢毸腮顋鰓鳃嗮僿簺賽赛三厁叁弎毵毶毿犙鬖伞傘糁糝糣糤繖鏒鏾饊馓俕散潵閐壭桑桒槡嗓搡磉褬鎟顙颡丧喪慅掻搔溞繅缫臊螦颾騒騷骚鰠鱢鳋嫂扫掃埽氉瘙矂髞閪啬嗇懎摵擌栜歮歰洓涩渋澀澁濇濏瀒瑟璱瘷穑穡穯繬色譅轖銫鏼铯雭飋森椮槮襂僧鬙乷唦杀桬榝樧殺毮沙煞猀痧砂硰粆紗繺纱蔱裟鎩铩閷髿魦鯊鯋鲨啥傻儍倽厦唼啑喢嗄帹廈歃箑翜翣萐閯霎筛篩簁簛籭晒曬傓删刪剼嘇圸姍姗山幓彡挻搧杉柵檆潸澘煽狦珊痁笘縿羴羶脠膻舢芟苫衫跚軕邖釤钐閊鯅晱炶煔熌睒覢閃闪陕陝僐善墠墡嬗扇掞擅敾椫樿歚汕灗疝磰禪繕缮膳蟮蟺訕謆譱讪贍赡赸鄯銏鐥饍騸骟鱓鱔鳝伤傷商墒慯殇殤滳漡熵禓蔏螪觞觴謪鬺垧扄晌樉賞贘赏鋿鏛鑜丄上尙尚恦緔绱鞝弰捎旓梢烧焼燒稍筲艄莦萷蕱輎髾鮹勺杓柖玿芍韶少劭卲哨娋潲紹綤绍袑邵奓奢檨猞畬畭畲賒賖赊輋佘揲舌虵蛇蛥捨舍厍厙射弽慑慴懾摂摄攝欇涉涻渉滠灄社舎蔎蠂設设赦韘騇麝伸侁兟呻堔妽姺娠屾峷扟敒曑柛氠深燊珅甡甧申眒砷穼籶籸糂紳绅罙罧莘葠蓡蔘薓裑訷詵诜身駪鯓鯵鰺鲹鵢什榊神鉮鰰哂婶嬸审宷審弞曋沈渖瀋瞫矤矧覾訠諗讅谂谉邥頣魫侺愼慎昚涁渗滲甚瘆瘮眘祳肾胂脤腎葚蜃蜄鋠升呏声斘昇曻枡殅泩湦焺牲狌珄生甥竔笙聲苼鉎鍟阩陞陹鵿鼪憴縄繉繩绳譝偗渻省眚剩剰勝圣墭嵊晟晠榺橳琞盛聖胜蕂貹賸呞失尸屍师師施浉湤湿溮溼濕狮獅瑡箷絁葹蒒蓍虱蝨褷襹詩诗邿酾釃釶鉇鍦鯴鰤鲺鳲鳾鶳鸤乭十埘塒姼实実寔實峕嵵拾时旹時榯湜溡炻石祏竍蚀蝕識识遈鉐食飠饣鮖鰣鲥鼫鼭乨使兘史始宩屎榁矢笶豕鉂駛驶世丗亊事仕侍冟势勢卋呩嗜噬士奭嬕室崼市式弑弒徥忕恀恃戺拭揓是昰枾柹柿栻氏澨烒煶眂眎眡睗示礻秲筮簭舐舓莳蒔螫襫視视觢試誓諟諡謚试谥貰贳軾轼适逝適遾釈释釋鈰鉃鉽銴铈飾餙餝饰鰘籂辻収收垨守手扌艏首兽受售嘼壽夀寿授涭狩獣獸痩瘦綬绶膄鏉书倏倐儵叔姝婌抒掓摅攄書杸枢梳樞橾殊殳毹毺淑瀭焂琡疎疏紓綀纾舒菽蔬跾踈軗輸输鄃陎鮛鵨塾孰尗熟璹秫贖赎属屬数數暏暑曙潻癙糬署薥薯藷蜀蠴襡襩鱪鱰黍鼠鼡侸咰墅尌庶庻怷恕戍捒朮术束树樹沭漱潄澍濖竖竪絉腧荗蒁虪術裋豎述鉥錰鏣霔鶐刷唰耍誜摔衰甩卛帅帥蟀拴栓閂闩涮腨双孀孇欆礵艭雙霜騻驦骦鷞鸘鹴塽慡漺爽縔鏯灀脽誰谁水氵氺閖帨涗涚睡祱稅税裞吮楯橓瞚瞬舜蕣順顺鬊說説说妁搠朔槊欶烁爍獡矟硕碩箾蒴鎙鑠铄丝俬凘厮厶司咝嘶噝媤廝思恖撕斯楒泀澌燍磃禗禠私糹絲緦纟缌罳蕬虒蛳蜤螄蟖蟴鉰銯鋖鍶鐁锶颸飔騦鷥鸶鼶死亖似佀価俟儩兕嗣四姒娰孠寺巳杫枱柶梩榹汜泗泤洍洠涘瀃牭祀禩竢笥耛耜肂肆蕼覗貄釲鈶鈻飤飼饲駟騃驷倯凇娀崧嵩庺忪憽松枀枩柗梥檧淞濍硹菘鬆傱嵷怂悚愯慫楤竦耸聳駷宋訟誦讼诵送鎹頌颂餸凁嗖廀廋捜搜摉摗溲獀艘蒐蓃螋鄋醙鎪锼颼飕餿馊騪傁叜叟嗾擻櫢瞍籔薮藪嗽擞瘶囌櫯甦稣穌窣苏蘇蘓酥鯂俗傃僳嗉塐塑夙嫊宿愫愬憟梀榡樎樕橚殐泝洬涑溯溸潚潥玊珟璛碿簌粛粟素縤肃肅膆莤蔌藗觫訴謖诉谡趚蹜速遡遬鋉餗驌骕鱐鷫鹔狻痠酸匴祘笇筭算蒜倠哸夊浽滖濉熣芕荽荾虽雖鞖瓍綏绥遀隋随隨髄瀡膸髓亗埣嬘岁嵗旞檖歲歳澻煫燧璲睟砕碎祟禭穂穗穟繀繐繸襚誶譢谇賥遂邃鐆鐩隧韢孙孫搎槂狲猻荪蓀蕵薞飧飱损損榫笋筍箰簨鎨隼鶽傞唆嗍嗦娑挱挲摍桫梭睃簑簔縮缩羧莎莏蓑趖鮻乺唢嗩所暛溑獕琐琑瑣索褨鎍鎖鎻鏁锁溹蜶逤他塌她它榙溻牠祂褟趿鉈铊闧塔墖獭獺鮙鰨鳎傝嚃嚺崉挞搨撻榻橽毾沓涾澾濌狧禢粏誻譶踏蹋蹹躂躢遝遢錔闒闥闼阘鞜鞳侤囼孡胎儓台坮嬯抬擡旲檯炱炲箈籉臺苔菭薹跆邰颱駘骀鮐鲐冭太夳忲态態汏汰汱泰溙燤肽舦酞鈦钛啴嘽坍怹摊擹攤滩潬灘痑瘫癱舑貪贪倓坛埮墰墵壇壜婒弹弾彈惔憛昙曇榃橝檀潭燂痰罈罎藫覃談譚譠谈谭貚郯醈醰錟锬顃僋嗿坦忐憳憻暺毯璮菼袒襢醓鉭钽叹嘆探歎湠炭碳舕劏嘡汤湯羰薚蝪蹚鏜镗鞺鼞傏唐啺坣堂塘嵣搪棠榶樘橖溏漟煻瑭磄禟篖糃糖糛膅膛蓎螗螳赯踼鄌醣鎕闛隚餹饄鶶伖倘偒傥儻戃曭淌爣矘耥躺鎲钂镋摥烫燙趟鐋铴夲嫍幍弢慆掏搯槄涛滔濤瑫絛縚縧绦詜謟轁鞱韜韬飸饕匋咷啕桃洮淘祹綯绹萄蜪裪迯逃醄鋾陶鞀鞉饀駣騊鼗討讨套忑忒慝特脦蟘鋱铽熥膯鼟儯幐滕漛疼痋籐籘縢腾藤虅螣誊謄邆駦騰驣鰧霯剔擿梯踢銻锑鷈鷉偍厗啼嗁媞崹徲惿提渧漽瑅睼碮禔禵稊綈緹绨缇罤蕛褆謕趧蹄蹏醍鍗題题騠鮷鯷鳀鵜鶗鶙鷤鹈体挮躰軆骵體倜剃嚏嚔屉屜悌悐惕惖戻掦揥替朑歒殢涕瓋笹籊薙褅趯逖逷髰鬀鬄兲天婖添酟靔靝黇塡填屇恬搷沺湉璳甛甜田畋畑碵磌窴緂胋菾闐阗鴫鷆鷏倎唺忝悿晪殄淟琠痶睓腆舔覥觍賟錪餂掭瑱舚佻庣恌挑旫祧聎岧岹条條樤祒笤芀苕萔蓚蓨蜩调迢鋚鎥鞗髫鯈鰷鲦齠龆嬥宨晀朓窕窱脁誂眺粜糶絩覜趒跳怗聑萜貼贴僣帖蛈鉄銕鐡鐵铁驖呫飻餮厅厛听庁廰廳桯汀烃烴綎耓聴聼聽鞓亭停婷嵉庭廷楟榳渟筳聤莛葶蜓蝏諪邒閮霆鼮侹圢娗挺梃涏烶珽町甼脡艇誔鋌铤頲颋嗵樋炵痌絧蓪通仝佟僮勭同哃峂峒峝庝彤晍曈朣桐橦氃浵潼烔燑犝狪獞眮瞳砼秱穜童粡膧茼蚒詷赨酮鉖鉵銅铜餇鮦鲖捅桶筒筩統綂统恸慟憅痛衕偷偸婾媮緰鋀鍮亠头投頭骰妵敨斢紏蘣黈透凸堗宊嶀怢捸涋湥痜禿秃突葖鋵鵚鼵凃図图圖圗塗屠峹嵞庩廜徒悇捈揬梌涂潳瑹瘏稌筡腯荼蒤跿途酴鈯鍎馟駼鵌鶟鷋鷵吐唋土圡釷钍兎兔堍莵菟迌鵵汢圕湍煓猯貒剸团団團慱抟摶槫檲漙篿糰鏄鷒鷻墥畽疃彖湪褖推蓷藬尵弚橔穨蘈蹪隤頹頺頽颓魋俀僓腿蹆骽娧煺蛻蜕螁褪退駾吞呑噋旽暾朜涒焞囤坉屯忳臀臋芚蛌豘豚軘霕飩饨魨鲀黗氽乇仛侂咃咜托扡拕拖挩捝杔汑沰涶脫脱莌袥託讬飥饦馲魠鮵佗侻坨堶媠岮柁槖橐沱沲狏砣砤碢紽袉詑跎酡阤陀陁馱駄駝駞騨驒驝驮驼鮀鴕鸵鼉鼍鼧妥嫷庹彵椭楕橢鰖鵎唾嶞拓柝毤毻箨籜萚蘀跅劸哇嗗娲媧屲挖搲攨洼溛漥瓾畖穵窊窐窪蛙韈鼃娃佤咓瓦砙邷嗢聉腽膃袜襪韤呙咼喎歪竵外顡剜塆壪婠帵弯彎湾潫灣睕蜿豌丸刓完岏忨抏捖汍烷玩琓笂紈纨翫芄貦頑顽倇唍埦婉宛惋挽晚晥晩晼梚椀涴琬畹皖盌碗箢綩綰绾脘莞菀萖踠輓鋔万卍卐妧捥杤澫瞣脕腕萬薍蟃贃贎輐鋄錽鎫尣尩尪尫汪亡亾仼兦王莣蚟彺往徃惘暀枉棢瀇網网罒罓罔罖菵蛧蝄誷輞辋魍妄忘旺望朢迋偎危厃喴威媙崴嵔嶶巍微愄揋揻椳楲溦烓煨燰癓縅葨葳薇蜲蝛覣詴逶隇隈霺鰃鰄鳂唯喡囗囲围圍壝媁峗峞嵬帏帷幃惟桅欈沩洈涠湋溈潍潙潿濰為爲犩琟矀硙維维蓶覹违違鄬醀鍏闈闱韋韦鮠亹伟伪偉偽僞儰委娓寪尾屗崣嶉徫愇捤撱斖暐梶椲洧浘渨濻瀢炜煒猥玮瑋痏痿硊碨緯纬腲艉芛苇荱萎葦蒍蔿諉诿踓鍡隗韑韙韡韪頠颹骩骪骫鮪鲔为位卫叞味喂墛媦尉慰懀未渭煟熭犚猬畏緭罻胃苿菋蔚藯蘶蜼蝟螱衛衞褽謂讆讏谓躗躛軎轊鏏霨餧餵饖魏鮇鳚塭昷榅榲殟温溫瑥瘟豱輼轀辒鎾鞰饂鰛鰮鳁彣文炆珳瘒紋繧纹聞芠蚉蚊螡蟁閺閿闅闦闻阌雯馼駇魰鳼鴍鼤伆刎吻呅呡抆桽稳穏穩紊肳脗問妏揾搵汶渂璺莬问顐嗡翁聬螉鎓鶲鹟勜塕奣嵡攚暡滃瞈蓊瓮甕罋蕹齆倭唩挝涡涹渦猧窝窩莴萵蜗蝸踒婐婑我捰仴偓卧媉幄捾握斡枂楃沃渥濣焥瓁瞃硪肟腛臒臥齷龌乌剭呜嗚圬屋巫弙杇歍汙汚污洿烏窏箼螐誈誣诬邬鄔鎢钨鰞鴮吳吴吾呉墲娪峿无梧橆毋洖浯無珸璑祦芜茣莁蕪蜈蟱譕郚鋙铻鯃鵐鷡鹀鼯乄五仵伍侮倵儛午啎妩娒娬嫵庑廡忤怃憮捂摀武潕熓牾玝珷瑦甒瞴碔舞躌迕逜陚鵡鹉俉兀务務勿卼唔坞塢奦婺寤屼岉嵍嵨忢悞悟悮戊扤敄旿晤杌溩焐熃物痦矹窹粅芴蘁誤误鋈阢隖雺雾霚霧靰騖骛鶩鹜鼿齀俙傒僖兮凞卥厀吸唏唽嘻噏嚱夕奚娭嬆嬉屖嵠巇希徆徯忚怸恓息悉悕惁惜扱扸昔晞晰晳暿曦析桸榽樨橀欷歙氥汐浠淅渓溪潝烯焁焈焟焬煕熄熈熙熹熺熻燨爔牺犀犠犧狶琋瘜皙睎瞦矽硒磎礂稀穸窸粞糦緆繥羲翕翖肸肹膝舾莃菥蒠蜥螅螇蟋蠵裼西覡觹觽觿譆谿豀豨豯貕赥邜郗鄎酅醯釸錫鏭鐊鑴锡隵餏饎饻鯑鵗鸂鼷习喺媳嶍席椺槢檄漝習蒵蓆薂袭襲觋謵趘郋鎴隰霫飁騱騽驨鰼鳛喜囍壐屣徙憘憙枲橲歖洗漇玺璽矖禧縰葈葸蓰蟢諰謑蹝躧鈢鉨鉩鱚係匸卌呬墍屃屓屭忥怬恄慀戏戯戱戲椞欯潟澙熂犔盻磶禊稧系細綌縘繫细绤舃舄蕮虩衋覤赩趇郤釳闟阋隙隟霼餼饩鬩黖傄呷煆瞎虲虾蝦谺閕颬鰕侠俠匣埉峡峽敮暇柙炠烚狎狭狹珨瑕硖硤碬磍祫筪縖翈舝舺蕸赮轄辖遐鍜鎋陜陿霞騢魻鶷黠閜丅下乤吓圷夏夓懗梺疜睱罅諕鎼鏬仙仚佡僊僲先嘕奾嬐孅屳廯忺憸掀攕暹杴枮氙珗祆秈籼繊纎纖纤苮莶薟褼襳跹蹮躚酰銛銽鍁铦锨韯韱馦鮮鱻鲜鶱伭咁咸啣嗛妶娴娹婱嫌嫺嫻弦憪挦撏涎湺澖甉痫癇癎盷瞯礥稴絃胘舷藖蚿蛝衔衘誸諴賢贒贤輱醎銜鑦閑閒闲鷳鷴鷼鹇鹹麙冼尟尠崄嶮幰搟攇显櫶毨灦烍燹狝猃獫獮玁禒筅箲藓蘚蚬蜆譣赻跣銑鍌铣险険險韅顕顯僩僴县咞哯垷埳塪壏姭娊宪岘峴憲撊晛橌橺涀瀗献獻现現県睍粯糮絤綫線縣线缐羡羨腺臔臽苋莧誢豏鋧錎限陥陷霰餡馅麲鼸乡厢廂忀楿欀湘瓖相稥箱緗纕缃膷芗萫葙薌襄郷鄉鄊鄕鑲镶香驤骧鱜麘佭庠栙瓨祥絴翔詳详跭享亯响想晑蚃蠁銄響飨餉饗饟饷鮝鯗鱶鲞像勨向嚮姠嶑巷曏橡珦缿蟓衖襐象鐌項项鱌侾削呺哓嘐嘵嚣嚻囂婋宯宵庨彇憢揱撨枭枵梟櫹歊毊消潇瀟灱灲烋焇猇獢痚痟硝硣穘窙箫簘簫綃绡翛肖膮萧蕭藃虈虓蛸蟂蟏蟰蠨踃逍銷销霄颵驍骁髇髐魈鴞鴵鷍鸮崤殽洨淆訤誵郩小晓暁曉皛皢筱筿篠謏俲傚効咲哮啸嘋嘨嘯孝恔效敩斅斆校歗涍熽笑詨誟些娎揳楔歇猲蝎蠍偕劦勰协協嗋嚡垥奊孈峫恊愶拹挟挾携撷擕擷攜斜旪熁燲瑎絜綊緳縀缬翓胁脅脇脋膎蝢衺襭諧讗谐邪鞋鞵龤写冩寫藛血亵伳偞偰僁卨卸噧塮夑媟屑屟屧嶰廨徢懈暬械榍榭泄泻洩渫澥瀉瀣灺炧炨烲焎燮爕獬祄禼糏紲絏絬緤繲纈绁缷薢薤蟹蠏褉褻謝谢躞邂靾鞢韰齂齘齛齥俽噷噺妡嬜廞心忄忻惞新昕杺欣歆盺芯薪訢辛邤鈊鋅鑫锌馨馫枔襑鐔镡伈伩信囟孞炘焮脪舋衅訫軐釁阠顖馸垶惺星曐煋猩瑆皨箵篂腥興觪觲謃騂骍鮏鯹侀刑哘型娙形洐滎硎荥蛵行邢郉鈃鉶銒鋞钘铏陉陘餳饧擤睲醒倖兴姓婞嬹幸性悻杏涬緈臖荇莕葕兄兇凶匂匈哅忷恟汹洶胷胸芎訩詾讻賯熊熋雄焸焽夐敻詗诇休俢修咻庥樇烌羞脙脩臹貅銝鎀鏅飍饈馐髤髹鮴鱃鵂鸺苬朽滫潃糔嗅嚊岫峀溴珛琇璓秀綉繍繡绣螑袖褎褏銹鏥鏽锈齅偦吁嘘噓圩墟媭嬃戌揟旴楈欨欻歔歘燸疞盱砉綇縃胥蕦虗虚虛蝑裇訏許諝譃谞鑐需須须顼驉鬚魆魖俆冔徐禑蒣呴喣姁暊栩湑珝盨稰糈詡諿许诩鄦醑伵侐勖勗卹叙垿壻婿序怴恤慉敍敘旭昫晇朂槒欰殈汿沀洫溆漵潊烅烼煦獝珬盢瞁稸絮続緒緖續绪续聓聟芧蓄蓿藇藚訹賉酗銊頊鱮儇吅喧塇媗宣弲愃愋懁揎昍晅暄梋煊瑄睻矎禤箮翧翾萱萲蓒蕿藼蘐蝖蠉諠諼譞谖軒轩鋗鍹鞙駽鰚嫙悬懸旋暶檈漩玄玹琁璇璿痃蜁咺暅烜癣癬选選怰昡楥楦泫渲炫琄眩眴碹絢縼繏绚蔙衒袨贙鉉鏇铉镟颴疶蒆薛辥辪靴鞾乴壆学學峃嶨斈泶澩燢穴茓袕觷踅鷽鸴樰膤艝轌雪鱈鳕吷坹岤桖瀥狘瞲謔谑趐勋勛勲勳嚑坃埙塤壎壦曛焄熏燻爋獯矄纁臐薫薰蘍醺偱噚姰寻尋峋巡廵循恂揗攳旬杊栒桪樳毥洵浔潯灥燅燖珣璕畃紃荀蟳詢询郇鄩駨鱏鱘鲟伨侚卂噀奞巺巽徇愻殉殾汛潠狥稄蕈訊訓訙训讯迅迿逊遜鑂顨馴驯丫压吖呀圧垭壓孲庘押枒桠椏錏鐚铔鴉鴨鵶鸦鸭伢厑厓堐岈崕崖涯漄牙猚琊睚笌芽蚜衙齖厊哑唖啞庌疨痖瘂蕥雅亚亜亞俹冴劜圔圠埡娅婭挜掗揠氩氬犽猰玡砑稏窫聐襾覀訝讶軋轧迓齾傿剦嫣嬮崦嶖恹懕懨樮歅淊淹渰湮漹烟焉焑煙珚硽篶胭臙菸鄢醃閹阉黫严厳啱喦嚴埏塩壛壧妍姸娫娮岩嵒嵓巌巖巗延揅昖楌檐櫩欕沿炎炏狿琂盐研硏碞礹筵簷綖莚蔅虤蜒言訁訮詽讠郔閆閻闫阎顏顔颜鹽麣乵俨偃儼兖兗剡匽厣厴噞夵奄孍嵃巘巚弇愝戭扊抁掩揜曮棪椼檿沇渷演琰甗眼縯罨萒蝘衍裺褗躽遃郾酓隒顩魇魘鰋鶠黡黤黬黭黶鼴鼹齴龑偐厌厭咽唁喭嚈嚥囐堰墕妟姲嬊嬿宴彥彦敥晏暥曕曣椻溎滟灎灔灧灩烻焔焰焱熖燄燕爓牪猒砚硯艳艶艷覎觃觾諺讌讞谚谳豓豔贋贗赝軅酀酽醶醼釅隁雁餍饜騐験騴驗驠验鬳鳫鴈鴳鷃鷰齞央姎抰殃泱眏秧胦鉠鍈雵鞅鴦鸯佯劷垟崵崸徉扬揚敭旸昜暘杨楊氜洋炀烊煬珜疡瘍眻羊羏蛘諹輰鍚钖阦阳陽霷颺飏鰑鴹鸉仰佒傟养卬咉坱岟慃懩攁柍楧氧氱瀁炴痒癢礢紻蝆軮飬養駚怏恙样様樣漾羕詇吆喓夭妖幺楆殀祅腰葽訞邀鴁鴢倄傜嗂垚堯姚媱尧尭峣嶢嶤徭愮揺搖摇摿暚榣滧烑爻猺珧瑤瑶磘窑窯窰繇肴蘨謠謡谣軺轺遙遥邎鎐顤颻飖餆餚鰩鱙鳐仸偠咬婹宎岆崾抭杳枖柼榚溔狕眑窅窈舀苭蓔闄騕鷕齩曜熎燿獟矅穾窔筄纅耀艞药葯薬藥袎要覞詏讑靿鷂鹞鼼倻吔噎擨暍椰歋潱蠮捓揶爷爺瑘耶釾鋣鎁铘也冶嘢埜壄漜野业亱僷叶墷夜嶪嶫抴捙掖擛擪擫晔曄曅曗曳曵枼枽業殗洂液澲烨煠燁爗璍皣瞱瞸礏腋葉謁谒邺鄴鍱鎑鐷靥靨頁页餣饁馌驜鵺鸈亪一乊伊依医吚咿噫壱壹夁嫛嬄弌悘揖撎檹毉洢渏漪猗瑿畩祎禕稦繄蛜衣衤譩辷郼醫銥铱鷖鹥黟黳乁仪侇儀冝匜咦圯夷姨媐宐宜宧寲峓嶬嶷巸彛彜彝彞怡恞扅拸暆杝柂栘桋椬椸沂沶洟熪狋珆瓵疑痍眙移簃籎羠胰荑萓蛦螔袘觺詒誃謻讉诒貽贻跠迻遗遺鏔頉頤頥顊颐飴饴鮧鴺乙乛以佁倚偯嬟崺已庡扆攺敼旑旖椅檥矣礒笖舣艤苡苢蚁螘蟻裿輢轙迆迤迱逘酏釔鈘鉯钇顗鳦齮乂义亄亦亿仡伇伿佚佾俋億兿刈劓劮勚勩匇呓呭呹唈嗌囈圛坄垼埶埸墿奕嫕嬑寱屹峄嶧帟帠幆廙异弈弋役忆忔怈怿悒悥意憶懌懿抑挹敡斁易晹曀曎杙枍枻栧棭榏槸檍欭歝殔殪殹毅泆浂浥浳湙溢潩澺瀷炈焲熠熤熼燚燡燱獈玴異疫痬瘗瘞瘱癔益睪瞖秇穓竩篒縊繶繹绎缢羛義羿翊翌翳翼耴肄肊膉臆艗艺芅苅萟蓺薏藙藝蘙虉蛡蜴螠衪袣裔裛褹襼訲訳詍詣誼譯議讛议译诣谊豙豛豷貖貤贀跇軼轶逸邑鄓醳醷釴鈠鎰鐿镒镱阣隿霬饐駅驛驿骮鮨鯣鶂鶃鶍鷁鷊鷧鷾鸃鹝鹢黓齸弬侌凐喑噾囙因垔堙姻婣愔慇栶殷氤洇溵濦瘖磤禋秵筃絪緸茵荫蒑蔭裀諲銦铟闉阥阴陰陻隂霒霠鞇音韾駰骃齗乑冘吟噖嚚圁垠夤婬寅峾崟崯斦檭殥泿淫滛烎犾狺珢璌碒荶蔩蟫訔訚訡誾鄞鈝銀银霪鷣齦龂龈吲尹嶾廴引朄檃檼櫽淾濥瘾癮粌蘟蚓螾讔赺趛輑鈏隐隠隱靷飮飲饮印垽堷廕慭憖憗懚洕湚猌癊窨胤茚酳鮣偀嘤噟嚶婴媖嫈嬰孆孾应応愥應撄攖朠桜樱櫻渶瀴煐珱瑛璎瓔甇甖碤礯緓纓绬缨罂罃罌膺英莺蘡蝧蠳褮譍譻賏軈鑍锳霙韺鴬鶑鶧鶯鷪鷹鸎鸚鹦鹰僌営塋嬴巆攍楹櫿溁溋滢潆濙濚濴瀅瀛瀠瀯灐灜熒營瑩盁盈禜籝籯縈茔荧莹萤营萦萾蓥藀蛍蝇蝿螢蠅覮謍贏赢迎鎣巊廮影摬梬浧潁瘿癭矨穎郢鐛頴颍颕颖媵映暎硬膡鱦哟唷喲佣傭嗈噰墉壅嫞庸廱慵拥擁滽澭灉牅痈癕癰臃邕郺鄘鏞镛雍雝饔鱅鳙鷛喁顒颙鰫俑勇勈咏埇塎嵱彮怺恿悀惥愑愹慂柡栐永泳涌湧甬硧蛹詠踊踴鯒鲬用砽苚蒏醟优優呦嚘峳幽忧怮悠憂懮攸櫌泑浟滺瀀纋羪耰逌鄾麀偤尢尤庮怞怣楢沋油游犹猶猷由甴疣秞肬莜莸蕕蚰蝣訧輏輶逰遊邮郵鈾铀駀魷鮋鱿鲉丣卣友有栯梄槱湵牖牗禉羑聈苃莠蜏酉銪铕黝亴佑佦侑又右哊唀囿姷孧宥峟幼柚櫾牰狖祐蚴誘诱貁迶酭釉鼬唹扜扝淤瘀盓穻箊紆纡込迂迃陓乻予于亐伃余俞兪堣堬妤娛娯娱媀嬩崳嵎嵛愉愚扵揄於旟杅桙楡楰榆欤歈歟歶渔渝湡漁澞牏狳玗玙瑜璵盂睮禺窬竽籅羭腴臾舁舆艅茰萮萸蕍蘛虞虶蝓螸衧褕覦觎諛謣谀踰輿轝逾邘酑鍝隃隅雓雩餘馀騟骬髃魚魣鮽鯲鰅鱼鷠鸆齵与伛俁俣偊傴匬噳圄圉宇寙屿嶼庾懙挧敔斔斞楀瑀瘐祤禹穥窳羽與萭語语貐鄅雨頨麌齬龉俼僪儥喅喩喻圫域堉妪嫗寓峪嶎庽彧御忬悆惐愈慾戫昱棛棜棫櫲欎欝欥欲毓浴淢淯滪潏澦灪焴煜燏燠爩狱獄玉琙瘉癒矞砡硢硲礇礖礜禦秗稢稶篽籞籲粖緎罭聿肀育艈芋芌茟蒮蓣蓹蕷薁蘌蜟蜮袬裕誉諭譽谕豫軉輍逳遇遹郁醧鈺銉鋊錥鐭钰閾阈雤霱預预飫饇饫馭驈驭鬰鬱鬻魊鱊鳿鴥鴧鴪鵒鷸鸒鹆鹬冤剈囦嬽寃悁惌棩淵渁渆渊渕灁眢肙葾蒬蜎蜵裷駌鳶鴛鵷鸢鸳鹓鼘鼝元円原厡厵员員园圆圎園圓垣塬媴嫄援杬榞榬橼櫞沅湲源溒爰猨猿笎緣縁缘羱芫茒蒝薗蚖蝝蝯螈袁褤謜貟贠轅辕邍邧酛鈨鎱騵魭鶢鶰黿鼋盶薳远逺遠鋺傆噮垸夗妴媛怨愿掾瑗禐苑衏裫褑院願啘曰曱矱箹約约哕噦刖妜嬳岄岳嶽恱悅悦戉抈捳月樾泧瀹爚玥礿禴篗籆籥籰粤粵蘥蚎蚏越跀跃躍軏鈅鉞鑰钥钺閱閲阅鸑鸙黦龠龥奫晕暈氲氳煴熅蒀蒕蝹贇赟馧云伝勻匀囩妘愪抣昀橒沄涢溳澐熉畇眃秐筠筼篔紜縜纭耘耺芸蒷蕓郧鄖鋆雲允喗夽抎殒殞狁磒荺賱鈗阭陨隕霣馻齫齳傊孕恽惲愠慍枟熨緼縕缊腪蕰蕴薀藴蘊褞运運郓鄆酝醖醞韗韞韫韵韻餫匝咂帀扎拶桚沞臜臢迊鉔魳囃杂沯砸襍雑雜雥韴咋哉栽渽溨災灾烖甾畠睵賳宰崽傤儎再在扗洅縡載载酨兂橵簪簮糌鐕鐟鵤偺咱喒儧儹噆寁揝撍攅攒攢昝趱趲囋暂暫濽灒瓉瓒瓚禶襸讃讚賛贊赞蹔鄼錾鏨饡匨牂羘臧賍賘贓贜赃髒駔驵塟奘弉脏臓臟葬蔵銺傮糟蹧遭醩凿鑿早枣栆棗澡璅璪薻藻蚤唕唣喿噪慥梍灶煰燥皁皂竃竈簉艁譟趮躁造则則啧啫嘖嫧帻幘択择擇樍歵沢泎泽溭滜澤皟瞔矠礋箦簀舴蔶蠌襗諎謮責賾责赜迮鸅齚齰仄崱庂捑昃昗汄戝蠈賊贼鰂鱡鲗怎譖谮増增憎橧璔矰磳繒缯罾譄鄫鱛囎熷甑贈赠鋥锃鬵偧劄哳喳抯挓揸摣柤楂樝渣皶皻紥紮觰譇齄齇札牐箚耫蚻譗鍘铡閘闸霅厏拃眨砟鮓鮺鲊鲝乍吒咤宱搾栅榨溠灹炸痄蚱詐诈醡夈捚摘斋斎榸粂齋宅檡窄鉙债債寨瘵砦噡岾嶦惉旃旜枬栴毡氈氊沾瞻薝蛅詀詹譫谵趈邅閚霑飦饘驙魙鱣鳣鸇鹯讝嫸展崭嶃嶄搌斩斬榐橏琖盏盞輾辗醆颭飐佔偡僝占嶘战戦戰栈桟棧湛站綻绽菚蘸虥虦覱譧轏驏傽嫜张張彰慞暲樟漳獐璋章粻蔁蟑遧鄣鏱餦騿鱆麞仉幥掌涨漲礃丈仗墇嶂帐帳幛扙杖涱痮瘬瘴瞕粀胀脹賬账障佋妱巶招昭皽釗鉊鍣钊駋找沼爪爫瑵兆召垗旐曌枛棹櫂炤照燳狣瞾笊箌罀罩羄肁肇肈詔诏赵趙鮡嗻嫬遮厇哲啠喆嚞埑悊折摺晢晣歽矺砓磔籷粍虴蛰蜇蟄袩詟謫謺讁讋谪輒輙轍辄辙銸鮿乽者褶襵赭踷鍺锗柘樜浙淛蔗蟅这這鷓鹧侦偵嫃寊帧帪幀搸斟桢椹楨榛樼殝浈湞溱潧澵獉珍珎瑧甄眞真砧碪祯禎禛箴籈胗臻葴蒖蓁薽貞贞轃遉酙針鉁錱鍼针鱵姫屒弫抮昣枕畛疹眕稹紾縝縥缜聄萙袗裖覙診诊軫轸辴駗鬒黰侲圳塦挋振揕朕栚甽眹紖絼纼誫賑赈鋴鎭鎮镇阵陣震鴆鸩争佂凧埩姃媜峥崝崢征徰徴徵怔掙揁炡烝爭狰猙癥眐睁睜筝箏篜糽聇脀蒸踭鉦錚鏳钲铮鬇愸抍拯掟撜整晸氶塣幁挣政正症証諍證证诤郑鄭靕鴊之倁卮吱巵憄搘支枝栀栺梔椥榰汁汥泜疷知祗祬秓稙綕織织肢胑胝脂臸芝蘵蜘衼隻馶鳷鴲鼅侄値值埴執妷姪嬂慹戠执摭植樴殖淔漐潪犆瓡直禃絷縶聀职職膱蟙跖踯蹠躑軄釞馽凪劧只咫址坁坧墌夂帋恉扺抧指旨枳止汦沚洔淽疻砋祇祉秖紙纸芷茋藢衹襧訨趾軹轵酯阯黹乿俧偫傂儨制剬劕厔垁墆娡寘峙崻帙帜幟庢庤廌彘徏徝志忮懥懫扻挃挚掷搱摨摯擲擳旘晊智柣栉桎梽櫍櫛歭治洷滍滞滯潌瀄炙熫狾猘璏瓆畤疐痓痔痣瘈礩祑秩秷稚稺穉窒筫紩緻置翐膣至致芖蛭袟袠製覟觗觯觶誌豑豒豸貭質贄质贽跱踬躓輊轾迣郅銍鋕鑕铚锧陟隲雉駤騭騺驇骘鯯鴙鷙鸷中伀刣妐幒彸忠柊汷泈炂盅籦終终舯蔠蜙螤螽衳衷蹱鈡銿鍾鐘钟锺鴤鼨冢喠塚尰徸歱煄瘇种種肿腫踵仲众偅堹妕媑狆眾祌筗茽蚛衆衶諥重侜周啁喌嚋婤州徟洲淍炿烐珘盩矪粥舟謅譸诌诪賙赒輈輖辀週郮銂霌駲騆鵃鸼妯碡軸轴帚晭疛睭箒肘菷鯞伷僽冑呪咒咮噣宙昼晝甃皱皺籀籒籕粙紂縐纣绉胄荮葤詋酎駎驟骤侏朱株槠橥櫧櫫洙潴瀦猪珠硃秼絑茱蕏藸蛛蝫蠩袾誅諸诛诸豬跦邾銖铢駯鮢鯺鴸鼄劚孎斸曯欘灟炢烛燭爥瘃窋竹竺笁笜篴舳茿蓫蠋蠾躅逐逫钃鱁丶主劯嘱囑宔帾拄渚濐煑煮燝瞩矚罜褚詝陼鸀麈乼伫佇住助坾墸壴嵀拀杼柱柷樦殶注炷疰眝砫祝祩竚筑筯箸築篫簗紵紸纻羜翥苎苧莇著蛀註貯贮跓軴迬鉒鋳鑄铸飳馵駐驻麆抓撾檛簻膼髽跩拽专叀塼嫥専專瑼甎砖磗磚膞蟤諯鄟顓颛鱄孨竱轉转僎啭囀堟撰灷瑑篆篹籑縳腞蒃襈譔賺赚転饌馔妆妝娤庄庒桩梉樁湷粧糚荘莊装裝壮壯壵撞焋状狀椎追錐锥隹騅骓鵻沝坠墜娷惴甀畷硾礈笍綴縋缀缒腏膇諈贅赘醊錣鑆啍宒窀肫衠諄谆迍准凖埻準綧稕訰倬拙捉桌梲棁棳槕涿炪焯穛穱窧鐯丵劅卓叕啄啅圴妰娺彴撯擆擢斀斫斮斱斲斵晫椓櫡汋浊浞濁濯灂灼烵犳琢琸着硺禚窡篧籗籱罬茁蠗蠿諁諑謶诼酌鋜鐲镯鵫鷟兹呲咨嗞姕姿孖孜孳孶崰嵫栥椔淄湽滋澬玆禌秶稵粢紎緇緕纃缁茊茲菑葘觜訾諮谘貲資赀资赼趑趦輜輺辎鄑鈭錙鍿鎡锱镃頾頿髭鯔鰦鲻鶅鼒齍齜龇蓻仔吇呰啙姉姊子杍梓榟橴滓矷秄秭笫籽紫耔胏茈虸訿釨倳剚字恣渍漬牸眥眦胔胾自芓茡荢嗭倧堫宗嵏嵕惾朡棕椶熧猣磫稯綜緃緵繌综翪腙葼蝬豵踨踪蹤鍐鑁騌騣骔鬃鬉鬷鯮鯼倊偬傯嵸总惣捴揔搃摠焧燪総緫縂總蓗昮猔疭瘲碂粽糉糭縦縱纵掫棷棸箃緅菆諏诹邹郰鄒鄹陬騶驺鯫鲰黀齱齺走赱鯐奏揍租菹葅蒩卆卒哫崒崪族椊箤足踤鏃镞俎唨爼珇祖組组詛诅鎺阻靻劗躜躦鉆鑚鑽钻籫繤纂纉纘缵攥厜嗺樶纗蟕嘴噿嶊璻冣嶵晬最栬槜檇檌祽稡絊罪蕞辠酔酻醉鋷錊噂墫尊嶟樽繜罇遵鐏鱒鳟鶎鷷僔撙譐捘銌嘬穝捽昨秨稓笮筰苲莋鈼佐左繓作侳做唑坐岝岞座怍柞祚糳胙葃葄蓙袏酢阼飵咗龦龧龨龩龪龫龬龭龮龯龰龱龲龳龴龵龶龷龸龹龺龻龼龽龾龿鿀鿁鿂鿃鿄鿅鿆鿇鿈鿉鿊鿋鿌鿍鿎鿏鿐"; - BI.CODE_INDEX = {}; - for(var i = 0; i < codes.length; i++) { - BI.CODE_INDEX[codes[i]] = i - } -})(); \ No newline at end of file diff --git a/src/widget/collapse/collapse.js b/src/widget/collapse/collapse.js deleted file mode 100644 index f899c3588..000000000 --- a/src/widget/collapse/collapse.js +++ /dev/null @@ -1,108 +0,0 @@ -BI.Collapse = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-collapse", - items: [], - value: [], - trigger: "click", - accordion: false, - bordered: true, - ghost: false, - isDefaultInit: false, - openMotion: { - animation: "bi-slide-up", - animationDuring: 200 - } - }, - - render: function () { - var o = this.options; - - var collapseCls = o.ghost ? "" : "bi-background " + (o.bordered ? "bi-border bi-border-radius" : ""); - - this.expanders = {}; - - return { - type: "bi.vertical", - cls: collapseCls, - items: this._getItems(this.options.items) - - }; - }, - - _getItems: function (items) { - var self = this, o = this.options; - - return BI.map(items, function (index, item) { - var isActive = BI.contains(self._getCurrentValue(o.value), item.value); - var cls = o.ghost || index === 0 ? "" : "bi-border-top"; - - var el = BI.extend({ - type: "bi.arrow_group_node", - height: 30, - text: item.text, - value: item.value, - open: isActive - }, item.el); - - var popup = BI.extend({ - animation: o.openMotion.animation, - animationDuring: o.openMotion.animationDuring - }, item.popup); - - return BI.extend({ - type: "bi.expander", - cls: cls, - isDefaultInit: o.isDefaultInit, - trigger: o.trigger, - listeners: [{ - eventName: BI.Expander.EVENT_EXPAND, - action: function () { - self._hideOtherExpander(item.value); - self.fireEvent(BI.Collapse.EVENT_EXPAND, item.value); - } - }] - }, item, { - el: el, - popup: popup, - ref: function (_ref) { - BI.isFunction(item.ref) && item.ref(_ref); - self.expanders[item.value] = _ref; - } - }); - }); - }, - - _hideOtherExpander: function (expandKey) { - if (this.options.accordion) { - BI.each(this.expanders, function (key, expander) { - key !== (expandKey + "") && expander.hideView(); - }); - } - }, - - _getCurrentValue: function (v) { - var values = BI.isNotEmptyArray(v) ? v : BI.isKey(v) ? [v] : []; - - return this.options.accordion ? values.slice(0, 1) : values; - }, - - getValue: function () { - var value = []; - BI.each(this.expanders, function (key, expander) { - expander.isExpanded() && value.push(key); - }); - - return value; - }, - - setValue: function (v) { - var values = BI.map(this._getCurrentValue(v), function (idx, value) {return value + "";}); - BI.each(this.expanders, function (key, expander) { - BI.contains(values, key) ? expander.showView() : expander.hideView(); - }); - } -}); - -BI.Collapse.EVENT_EXPAND = "EVENT_EXPAND"; -BI.shortcut("bi.collapse", BI.Collapse); diff --git a/src/widget/date/calendar/combo.month.date.js b/src/widget/date/calendar/combo.month.date.js deleted file mode 100644 index aac5a7fc0..000000000 --- a/src/widget/date/calendar/combo.month.date.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * 日期控件中的月份下拉框 - * - * Created by GUY on 2015/9/7. - * @class BI.MonthDateCombo - * @extends BI.Trigger - */ -BI.MonthDateCombo = BI.inherit(BI.Trigger, { - _defaultConfig: function () { - return BI.extend( BI.MonthDateCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-month-combo", - height: 24, - container: null - }); - }, - _init: function () { - BI.MonthDateCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.trigger = BI.createWidget({ - type: "bi.date_triangle_trigger" - }); - - this.popup = BI.createWidget({ - type: "bi.month_popup", - allowMonths: o.allowMonths, - behaviors: o.behaviors - }); - - this.popup.on(BI.MonthPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.MonthDateCombo.EVENT_CHANGE); - }); - - - this.combo = BI.createWidget({ - type: "bi.combo", - offsetStyle: "center", - container: o.container, - element: this, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - el: this.trigger, - popup: { - minWidth: 100, - stopPropagation: false, - el: { - type: "bi.vertical", - hgap: 6, - vgap: 5, - items: [this.popup] - } - } - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.doBehavior(); - }); - }, - - populate: function () { - this.popup.populate.apply(this.popup, arguments); - }, - - setValue: function (v) { - this.trigger.setValue(v); - this.popup.setValue(v); - }, - - getValue: function () { - return this.popup.getValue(); - } -}); -BI.MonthDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.month_date_combo", BI.MonthDateCombo); \ No newline at end of file diff --git a/src/widget/date/calendar/combo.year.date.js b/src/widget/date/calendar/combo.year.date.js deleted file mode 100644 index c8e72580b..000000000 --- a/src/widget/date/calendar/combo.year.date.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * 年份下拉框 - * - * Created by GUY on 2015/9/7. - * @class BI.YearDateCombo - * @extends BI.Trigger - */ -BI.YearDateCombo = BI.inherit(BI.Trigger, { - _defaultConfig: function () { - return BI.extend( BI.YearDateCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-year-combo", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - behaviors: {}, - height: 24, - container: null - }); - }, - _init: function () { - BI.YearDateCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.trigger = BI.createWidget({ - type: "bi.date_triangle_trigger" - }); - - this.popup = BI.createWidget({ - type: "bi.year_popup", - behaviors: o.behaviors, - min: o.min, - max: o.max, - width: 122 - }); - - this.popup.on(BI.YearPopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.YearDateCombo.EVENT_CHANGE); - }); - - - this.combo = BI.createWidget({ - type: "bi.combo", - offsetStyle: "center", - element: this, - container: o.container, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - el: this.trigger, - popup: { - minWidth: 100, - stopPropagation: false, - el: this.popup - } - }); - this.combo.on(BI.Combo.EVENT_CHANGE, function () { - self.fireEvent(BI.YearDateCombo.EVENT_CHANGE); - }); - // BI-22551 popup未初始化传入的behavior无效 - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.doBehavior(); - self.fireEvent(BI.YearDateCombo.EVENT_BEFORE_POPUPVIEW); - }); - }, - - setMinDate: function (minDate) { - this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - this.popup.setMaxDate(maxDate); - }, - - setValue: function (v) { - this.trigger.setValue(v); - this.popup.setValue(v); - }, - - getValue: function () { - return this.popup.getValue(); - } -}); -BI.YearDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.YearDateCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.year_date_combo", BI.YearDateCombo); diff --git a/src/widget/date/calendar/picker.date.js b/src/widget/date/calendar/picker.date.js deleted file mode 100644 index 369982dfa..000000000 --- a/src/widget/date/calendar/picker.date.js +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Created by GUY on 2015/9/7. - * @class BI.DatePicker - * @extends BI.Widget - */ -BI.DatePicker = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.DatePicker.superclass._defaultConfig.apply(this, arguments); - - return BI.extend(conf, { - baseCls: "bi-date-picker", - height: 40, - min: "1900-01-01", // 最小日期 - max: "2099-12-31" // 最大日期 - }); - }, - - _init: function () { - BI.DatePicker.superclass._init.apply(this, arguments); - var self = this; - var o = this.options; - this._year = BI.getDate().getFullYear(); - this._month = BI.getDate().getMonth() + 1; - this.left = BI.createWidget({ - type: "bi.icon_button", - cls: "pre-page-h-font", - width: 24, - height: 24 - }); - this.left.on(BI.IconButton.EVENT_CHANGE, function () { - if (self._month === 1) { - self.setValue({ - year: (self.year.getValue() - 1) || (BI.getDate().getFullYear() - 1), - month: 12 - }); - } else { - self.setValue({ - year: self.year.getValue() || BI.getDate().getFullYear(), - month: (self.month.getValue() - 1) || BI.getDate().getMonth() - }); - } - self.fireEvent(BI.DatePicker.EVENT_CHANGE); - // self._checkLeftValid(); - // self._checkRightValid(); - }); - - this.right = BI.createWidget({ - type: "bi.icon_button", - cls: "next-page-h-font", - width: 24, - height: 24 - }); - - this.right.on(BI.IconButton.EVENT_CHANGE, function () { - if (self._month === 12) { - self.setValue({ - year: (self.year.getValue() + 1) || (BI.getDate().getFullYear() + 1), - month: 1 - }); - } else { - self.setValue({ - year: self.year.getValue() || BI.getDate().getFullYear(), - month: (self.month.getValue() + 1) || (BI.getDate().getMonth() + 2) - }); - } - self.fireEvent(BI.DatePicker.EVENT_CHANGE); - // self._checkLeftValid(); - // self._checkRightValid(); - }); - - this.year = BI.createWidget({ - type: "bi.year_date_combo", - behaviors: o.behaviors, - min: o.min, - max: o.max - }); - this.year.on(BI.YearDateCombo.EVENT_CHANGE, function () { - self.setValue({ - year: self.year.getValue(), - month: self._refreshMonth() - }); - self.fireEvent(BI.DatePicker.EVENT_CHANGE); - }); - this.year.on(BI.YearDateCombo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - }); - this.month = BI.createWidget({ - type: "bi.month_date_combo", - behaviors: o.behaviors, - allowMonths: this._getAllowMonths() - }); - this.month.on(BI.MonthDateCombo.EVENT_CHANGE, function () { - self.setValue({ - year: self.year.getValue() || self._year, - month: self.month.getValue() - }); - self.fireEvent(BI.DatePicker.EVENT_CHANGE); - }); - this.month.on(BI.YearDateCombo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - }); - - BI.createWidget({ - type: "bi.htape", - element: this, - items: [{ - el: { - type: "bi.center_adapt", - items: [this.left] - }, - width: 24 - }, { - el: { - type: "bi.center_adapt", - hgap: 10, - items: [this.year, this.month] - } - }, { - el: { - type: "bi.center_adapt", - items: [this.right] - }, - width: 24 - }] - }); - this.setValue({ - year: this._year, - month: this._month - }); - }, - - _refreshMonth: function (defaultMonth) { - var month = this.month.getValue(); - this.month.populate(this._getAllowMonths()); - var allowMonth = this._getAllowMonths(); - if (!BI.contains(allowMonth, month)) { - month = defaultMonth || allowMonth[0]; - } - this.month.setValue(month); - return month; - }, - - _getAllowMonths: function () { - var obj = this._getCheckMinMaxDate(); - var year = this.year.getValue() || this._year; - - return BI.filter(BI.range(1, 13), function (idx, v) { - return !BI.checkDateVoid(year, v, 1, obj.min, obj.max)[0]; - }); - }, - - // 上一年月不合法则灰化 - _checkLeftValid: function () { - var obj = this._getCheckMinMaxDate(); - var year = this._month === 1 ? this._year - 1 : this._year; - var month = this._month === 1 ? 12 : this._month - 1; - var valid = BI.isNull(BI.checkDateVoid(year, month, 1, obj.min, obj.max)[0]); - this.left.setEnable(valid); - - return valid; - }, - - // 下一年月不合法则灰化 - _checkRightValid: function () { - var obj = this._getCheckMinMaxDate(); - var year = this._month === 12 ? this._year + 1 : this._year; - var month = this._month === 12 ? 1 : this._month + 1; - var valid = BI.isNull(BI.checkDateVoid(year, month, 1, obj.min, obj.max)[0]); - this.right.setEnable(valid); - - return valid; - }, - - _getCheckMinMaxDate: function () { - var o = this.options; - var minDate = BI.parseDateTime(o.min, "%Y-%X-%d"); - var maxDate = BI.parseDateTime(o.max, "%Y-%X-%d"); - minDate.setDate(1); - maxDate.setDate(1); - - return { - min: BI.print(minDate, "%Y-%X-%d"), - max: BI.print(maxDate, "%Y-%X-%d") - }; - }, - - setMinDate: function (minDate) { - this.options.min = minDate; - this.year.setMinDate(minDate); - this._refreshMonth(this._month); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - setMaxDate: function (maxDate) { - this.options.max = maxDate; - this.year.setMaxDate(maxDate); - this._refreshMonth(this._month); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - setValue: function (ob) { - this._year = BI.parseInt(ob.year); - this._month = BI.parseInt(ob.month); - this.year.setValue(ob.year); - this._refreshMonth(this._month); - this.month.setValue(ob.month); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - getValue: function () { - return { - year: this.year.getValue(), - month: this.month.getValue() - }; - } -}); -BI.DatePicker.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.date_picker", BI.DatePicker); diff --git a/src/widget/date/calendar/picker.year.js b/src/widget/date/calendar/picker.year.js deleted file mode 100644 index ac94ecd2b..000000000 --- a/src/widget/date/calendar/picker.year.js +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Created by GUY on 2015/9/7. - * @class BI.YearPicker - * @extends BI.Widget - */ -BI.YearPicker = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.YearPicker.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-year-picker", - behaviors: {}, - height: 40, - min: "1900-01-01", // 最小日期 - max: "2099-12-31" // 最大日期 - }); - }, - - _init: function () { - BI.YearPicker.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this._year = BI.getDate().getFullYear(); - this.left = BI.createWidget({ - type: "bi.icon_button", - cls: "pre-page-h-font", - width: 25, - height: 25 - }); - this.left.on(BI.IconButton.EVENT_CHANGE, function () { - self.setValue(self.year.getValue() - 1); - self.fireEvent(BI.YearPicker.EVENT_CHANGE); - // self._checkLeftValid(); - // self._checkRightValid(); - }); - - this.right = BI.createWidget({ - type: "bi.icon_button", - cls: "next-page-h-font", - width: 25, - height: 25 - }); - - this.right.on(BI.IconButton.EVENT_CHANGE, function () { - self.setValue(self.year.getValue() + 1); - self.fireEvent(BI.YearPicker.EVENT_CHANGE); - // self._checkLeftValid(); - // self._checkRightValid(); - }); - - this.year = BI.createWidget({ - type: "bi.year_date_combo", - min: o.min, - behaviors: o.behaviors, - max: o.max, - width: 50 - }); - this.year.on(BI.YearDateCombo.EVENT_CHANGE, function () { - self.setValue(self.year.getValue()); - self.fireEvent(BI.YearPicker.EVENT_CHANGE); - }); - this.year.on(BI.YearDateCombo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.YearPicker.EVENT_BEFORE_POPUPVIEW); - }); - - BI.createWidget({ - type: "bi.htape", - element: this, - items: [{ - el: { - type: "bi.center_adapt", - items: [this.left] - }, - width: 25 - }, { - type: "bi.center_adapt", - items: [{ - el: this.year - }] - }, { - el: { - type: "bi.center_adapt", - items: [this.right] - }, - width: 25 - }] - }); - this.setValue(this._year); - }, - - _checkLeftValid: function () { - var o = this.options; - var valid = this._year > BI.parseDateTime(o.min, "%Y-%X-%d").getFullYear(); - this.left.setEnable(valid); - return valid; - }, - - _checkRightValid: function () { - var o = this.options; - var valid = this._year < BI.parseDateTime(o.max, "%Y-%X-%d").getFullYear(); - this.right.setEnable(valid); - return valid; - }, - - setMinDate: function (minDate) { - this.options.min = minDate; - this.year.setMinDate(minDate); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - setMaxDate: function (maxDate) { - this.options.max = maxDate; - this.year.setMaxDate(maxDate); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - - setValue: function (v) { - this._year = v; - this.year.setValue(v); - // this._checkLeftValid(); - // this._checkRightValid(); - }, - - getValue: function () { - return this.year.getValue(); - } -}); -BI.YearPicker.EVENT_CHANGE = "EVENT_CHANGE"; -BI.YearPicker.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.year_picker", BI.YearPicker); diff --git a/src/widget/date/calendar/popup.calendar.date.js b/src/widget/date/calendar/popup.calendar.date.js deleted file mode 100644 index ce2892f55..000000000 --- a/src/widget/date/calendar/popup.calendar.date.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Created by GUY on 2015/9/7. - * @class BI.DateCalendarPopup - * @extends BI.Widget - */ -BI.DateCalendarPopup = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-date-calendar-popup", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - selectedTime: null - }, - - _createNav: function (v) { - var date = BI.Calendar.getDateJSONByPage(v); - var calendar = BI.createWidget({ - type: "bi.calendar", - logic: { - dynamic: true - }, - min: this.options.min, - max: this.options.max, - year: date.year, - month: date.month, - // BI-45616 此处为确定当前应该展示哪个年月对应的Calendar, day不是关键数据, 给1号就可 - day: 1 - }); - return calendar; - }, - - render: function () { - var self = this, - o = this.options; - this.today = BI.getDate(); - this._year = this.today.getFullYear(); - this._month = this.today.getMonth() + 1; - this._day = this.today.getDate(); - - this.selectedTime = o.selectedTime || { - year: this._year, - month: this._month, - day: this._day - }; - this.datePicker = BI.createWidget({ - type: "bi.date_picker", - behaviors: o.behaviors, - min: o.min, - max: o.max - }); - - this.calendar = BI.createWidget({ - direction: "top", - logic: { - dynamic: true - }, - type: "bi.navigation", - tab: this.datePicker, - cardCreator: BI.bind(this._createNav, this), - - afterCardCreated: function () { - - }, - - afterCardShow: function () { - this.setValue(self.selectedTime); - } - }); - - this.datePicker.on(BI.DatePicker.EVENT_CHANGE, function () { - self.selectedTime = self.datePicker.getValue(); - self.selectedTime.day = 1; - self.calendar.setSelect(BI.Calendar.getPageByDateJSON(self.selectedTime)); - }); - - this.datePicker.on(BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, function () { - self.fireEvent(BI.DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - }); - - this.calendar.on(BI.Navigation.EVENT_CHANGE, function () { - self.selectedTime = self.calendar.getValue(); - self.setValue(self.selectedTime); - self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); - }); - - return [{ - type: "bi.vertical", - items: [{ - el: this.calendar, - hgap: 12, - bgap: 7 - }] - }, { - type: "bi.absolute", - items: [{ - el: { - type: "bi.layout", - cls: "bi-split-top" - }, - height: 1, - top: 40, - left: 0, - right: 0 - }] - }] - }, - - _checkMin: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMinDate(o.min); - }); - }, - - _checkMax: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMaxDate(o.max); - }); - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - this.datePicker.setMinDate(minDate); - this._checkMin(); - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - this.datePicker.setMaxDate(maxDate); - this._checkMax(); - } - }, - - setValue: function (timeOb) { - this.datePicker.setValue(timeOb); - this.calendar.setSelect(BI.Calendar.getPageByDateJSON(timeOb)); - this.calendar.setValue(timeOb); - this.selectedTime = timeOb; - }, - - getValue: function () { - return this.selectedTime; - } -}); -BI.DateCalendarPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.date_calendar_popup", BI.DateCalendarPopup); diff --git a/src/widget/date/calendar/popup.month.js b/src/widget/date/calendar/popup.month.js deleted file mode 100644 index 402c6ffc2..000000000 --- a/src/widget/date/calendar/popup.month.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 月份展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.MonthPopup - * @extends BI.Trigger - */ -BI.MonthPopup = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MonthPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-month-popup", - behaviors: {} - }); - }, - - _init: function () { - BI.MonthPopup.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.selectedMonth = BI.getDate().getMonth() + 1; - - this.month = BI.createWidget({ - type: "bi.button_group", - element: this, - behaviors: o.behaviors, - items: BI.createItems(this._getItems(o.allowMonths), {}), - layouts: [BI.LogicFactory.createLogic("table", BI.extend({ - dynamic: true - }, { - columns: 2, - rows: 6, - columnSize: [1 / 2, 1 / 2], - rowSize: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - })), { - type: "bi.center_adapt", - vgap: 2, - }], - value: o.value - }); - - this.month.on(BI.Controller.EVENT_CHANGE, function (type, value) { - self.selectedMonth = value; - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.MonthPopup.EVENT_CHANGE); - } - }); - }, - - _getItems: function(m) { - BI.Widget.pushContext(this); - // 纵向排列月 - var month = [1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12]; - var items = []; - items.push(month.slice(0, 2)); - items.push(month.slice(2, 4)); - items.push(month.slice(4, 6)); - items.push(month.slice(6, 8)); - items.push(month.slice(8, 10)); - items.push(month.slice(10, 12)); - items = BI.map(items, function (i, item) { - return BI.map(item, function (j, td) { - return { - type: "bi.text_item", - cls: "bi-border-radius bi-list-item-select", - textAlign: "center", - whiteSpace: "nowrap", - once: false, - forceSelected: true, - height: BI.toPix(BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, 1), - width: 30, - value: td, - text: td, - disabled: !BI.contains(m, td) - }; - }); - }); - BI.Widget.popContext(); - - return items; - }, - - populate: function(months) { - this.month.populate(this._getItems(months)); - }, - - getValue: function () { - return this.selectedMonth; - }, - - setValue: function (v) { - v = BI.parseInt(v); - this.selectedMonth = v; - this.month.setValue([v]); - } -}); -BI.MonthPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.month_popup", BI.MonthPopup); diff --git a/src/widget/date/calendar/popup.year.js b/src/widget/date/calendar/popup.year.js deleted file mode 100644 index 8c6c4d614..000000000 --- a/src/widget/date/calendar/popup.year.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * 年份展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.YearPopup - * @extends BI.Trigger - */ -BI.YearPopup = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.YearPopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-year-popup", - behaviors: {}, - min: "1900-01-01", // 最小日期 - max: "2099-12-31" // 最大日期 - }); - }, - - _createYearCalendar: function (v) { - var o = this.options, y = this._year; - - var calendar = BI.createWidget({ - type: "bi.year_calendar", - behaviors: o.behaviors, - min: o.min, - max: o.max, - logic: { - dynamic: true - }, - year: y + v * 12 - }); - calendar.setValue(this._year); - return calendar; - }, - - _init: function () { - BI.YearPopup.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.selectedYear = this._year = BI.getDate().getFullYear(); - - this.backBtn = BI.createWidget({ - type: "bi.icon_button", - cls: "pre-page-h-font", - width: 24, - height: 24, - value: -1 - }); - - this.preBtn = BI.createWidget({ - type: "bi.icon_button", - cls: "next-page-h-font", - width: 24, - height: 24, - value: 1 - }); - - this.navigation = BI.createWidget({ - type: "bi.navigation", - element: this, - single: true, - logic: { - dynamic: true - }, - tab: { - cls: "year-popup-navigation bi-high-light bi-split-top", - height: 24, - items: [this.backBtn, this.preBtn] - }, - cardCreator: BI.bind(this._createYearCalendar, this), - afterCardCreated: function () { - this.setValue(self.selectedYear); - } - }); - - this.navigation.on(BI.Navigation.EVENT_CHANGE, function () { - self.selectedYear = this.getValue(); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.YearPopup.EVENT_CHANGE, self.selectedYear); - }); - - if(BI.isKey(o.value)){ - this.setValue(o.value); - } - }, - - _checkMin: function () { - var calendar = this.navigation.getSelectedCard(); - if (BI.isNotNull(calendar)) { - calendar.setMinDate(this.options.min); - } - }, - - _checkMax: function () { - var calendar = this.navigation.getSelectedCard(); - if (BI.isNotNull(calendar)) { - calendar.setMaxDate(this.options.max); - } - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - this._checkMin(); - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - this._checkMax(); - } - }, - - getValue: function () { - return this.selectedYear; - }, - - setValue: function (v) { - var o = this.options; - v = BI.parseInt(v); - // 切换年不受范围限制 - // 对于年控件来说,只要传入的minDate和maxDate的year区间包含v就是合法的 - // var startDate = BI.parseDateTime(o.min, "%Y-%X-%d"); - // var endDate = BI.parseDateTime(o.max, "%Y-%X-%d"); - // if (BI.checkDateVoid(v, 1, 1, BI.print(BI.getDate(startDate.getFullYear(), 0, 1), "%Y-%X-%d"), BI.print(BI.getDate(endDate.getFullYear(), 0, 1), "%Y-%X-%d"))[0]) { - // v = BI.getDate().getFullYear(); - // } - - this.selectedYear = v; - this.navigation.setSelect(BI.YearCalendar.getPageByYear(v)); - this.navigation.setValue(v); - } -}); -BI.YearPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.year_popup", BI.YearPopup); \ No newline at end of file diff --git a/src/widget/date/calendar/trigger.triangle.date.js b/src/widget/date/calendar/trigger.triangle.date.js deleted file mode 100644 index 32c61dc1f..000000000 --- a/src/widget/date/calendar/trigger.triangle.date.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 日期控件中的年份或月份trigger - * - * Created by GUY on 2015/9/7. - * @class BI.DateTriangleTrigger - * @extends BI.Trigger - */ -BI.DateTriangleTrigger = BI.inherit(BI.Trigger, { - _const: { - height: 24, - iconWidth: 12, - iconHeight: 12 - }, - - _defaultConfig: function () { - return BI.extend( BI.DateTriangleTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-date-triangle-trigger solid-triangle-bottom-font cursor-pointer", - height: 24 - }); - }, - _init: function () { - BI.DateTriangleTrigger.superclass._init.apply(this, arguments); - var o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "right", - text: o.text, - value: o.value, - height: c.height - }); - - BI.createWidget({ - type: "bi.vertical_adapt", - element: this, - items: [{ - el: this.text, - rgap: 5 - }, { - type: "bi.icon_label", - width: 16 - }] - }); - }, - - setValue: function (v) { - this.text.setValue(v); - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function (v) { - this.text.setText(v); - }, - - getText: function () { - return this.item.getText(); - }, - - getKey: function () { - - } -}); -BI.shortcut("bi.date_triangle_trigger", BI.DateTriangleTrigger); \ No newline at end of file diff --git a/src/widget/datepane/card.static.datepane.js b/src/widget/datepane/card.static.datepane.js deleted file mode 100644 index 34ed5ac14..000000000 --- a/src/widget/datepane/card.static.datepane.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Created by zcf on 2017/2/20. - */ -BI.StaticDatePaneCard = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.StaticDatePaneCard.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-date-pane", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - selectedTime: null - }); - }, - _init: function () { - BI.StaticDatePaneCard.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.today = BI.getDate(); - this._year = this.today.getFullYear(); - this._month = this.today.getMonth() + 1; - - this.selectedTime = o.selectedTime || { - year: this._year, - month: this._month - }; - - this.datePicker = BI.createWidget({ - type: "bi.date_picker", - behaviors: o.behaviors, - min: o.min, - max: o.max - }); - this.datePicker.on(BI.DatePicker.EVENT_CHANGE, function () { - var value = self.datePicker.getValue(); - var monthDay = BI.getMonthDays(BI.getDate(value.year, value.month - 1, 1)); - var day = self.selectedTime.day || 0; - if (day > monthDay) { - day = monthDay; - } - self.selectedTime = { - year: value.year, - month: value.month - }; - day !== 0 && (self.selectedTime.day = day); - self.calendar.setSelect(BI.Calendar.getPageByDateJSON(self.selectedTime)); - self.calendar.setValue(self.selectedTime); - day !== 0 && self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); - }); - this.datePicker.on(BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, function () { - self.fireEvent(BI.StaticDatePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - }); - - this.calendar = BI.createWidget({ - direction: "custom", - // logic: { - // dynamic: false - // }, - type: "bi.navigation", - tab: this.datePicker, - cardCreator: BI.bind(this._createNav, this) - }); - this.calendar.on(BI.Navigation.EVENT_CHANGE, function () { - self.selectedTime = self.calendar.getValue(); - self.calendar.empty(); - self.setValue(self.selectedTime); - self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); - }); - this.setValue(o.selectedTime); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - el: this.datePicker, - height: 40 - }, this.calendar], - hgap: 10 - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.layout", - cls: "bi-split-top" - }, - height: 1, - top: 40, - left: 0, - right: 0 - }] - }); - - }, - - _createNav: function (v) { - var date = BI.Calendar.getDateJSONByPage(v); - var calendar = BI.createWidget({ - type: "bi.calendar", - logic: { - dynamic: false - }, - min: this.options.min, - max: this.options.max, - year: date.year, - month: date.month, - day: this.selectedTime.day - }); - return calendar; - }, - - _getNewCurrentDate: function () { - var today = BI.getDate(); - return { - year: today.getFullYear(), - month: today.getMonth() + 1 - }; - }, - - _setCalenderValue: function (date) { - this.calendar.setSelect(BI.Calendar.getPageByDateJSON(date)); - this.calendar.setValue(date); - this.selectedTime = date; - }, - - _setDatePicker: function (timeOb) { - if (BI.isNull(timeOb) || BI.isNull(timeOb.year) || BI.isNull(timeOb.month)) { - this.datePicker.setValue(this._getNewCurrentDate()); - } else { - this.datePicker.setValue(timeOb); - } - }, - - _setCalendar: function (timeOb) { - if (BI.isNull(timeOb) || BI.isNull(timeOb.day)) { - this.calendar.empty(); - this._setCalenderValue(this._getNewCurrentDate()); - } else { - this._setCalenderValue(timeOb); - } - }, - - _checkMin: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMinDate(o.min); - }); - }, - - _checkMax: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMaxDate(o.max); - }); - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - this.datePicker.setMinDate(minDate); - this._checkMin(); - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - this.datePicker.setMaxDate(maxDate); - this._checkMax(); - } - }, - - setValue: function (timeOb) { - this._setDatePicker(timeOb); - this._setCalendar(timeOb); - }, - - getValue: function () { - return this.selectedTime; - } - -}); -BI.StaticDatePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW" -BI.shortcut("bi.static_date_pane_card", BI.StaticDatePaneCard); \ No newline at end of file diff --git a/src/widget/datepane/datepane.js b/src/widget/datepane/datepane.js deleted file mode 100644 index 3537797c3..000000000 --- a/src/widget/datepane/datepane.js +++ /dev/null @@ -1,217 +0,0 @@ -BI.DynamicDatePane = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-dynamic-date-pane", - minDate: "1900-01-01", - maxDate: "2099-12-31", - supportDynamic: true - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vtape", - items: [{ - el: { - type: "bi.linear_segment", - invisible: !o.supportDynamic, - cls: "bi-split-bottom", - height: 30, - items: BI.createItems([{ - text: BI.i18nText("BI-Multi_Date_YMD"), - value: BI.DynamicDatePane.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicDatePane.Dynamic - }], { - textAlign: "center" - }), - listeners: [{ - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - var value = this.getValue()[0]; - self.dateTab.setSelect(value); - switch (value) { - case BI.DynamicDatePane.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - break; - case BI.DynamicDatePane.Dynamic: - self.dynamicPane.setValue({ - year: 0 - }); - break; - default: - break; - } - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - }], - ref: function () { - self.switcher = this; - } - }, - height: o.supportDynamic ? 30 : 0 - }, { - type: "bi.tab", - ref: function () { - self.dateTab = this; - }, - showIndex: BI.DynamicDatePane.Static, - cardCreator: function (v) { - switch (v) { - case BI.DynamicDatePane.Static: - return { - type: "bi.static_date_pane_card", - min: o.minDate, - max: o.maxDate, - behaviors: o.behaviors, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - }, { - eventName: "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW", - action: function () { - self.fireEvent(BI.DynamicDatePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }], - ref: function () { - self.ymd = this; - } - }; - case BI.DynamicDatePane.Dynamic: - default: - return { - type: "bi.vtape", - items: [{ - type: "bi.dynamic_date_card", - min: o.minDate, - max: o.maxDate, - ref: function () { - self.dynamicPane = this; - } - }, { - el: { - type: "bi.center", - items: [{ - type: "bi.text_button", - cls: "bi-high-light bi-border-top", - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - textHeight: 23, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.setValue(); - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-border-left bi-high-light bi-border-top", - textHeight: 23, - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicDatePopup.EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - } - }] - }] - }, - height: 24 - }] - }; - } - } - }] - }; - }, - - created: function () { - this.setValue(this.options.value); - }, - - _checkValueValid: function (value) { - return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); - }, - - _checkValue: function (v) { - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - default: - return true; - } - }, - - setMinDate: function (minDate) { - if (this.options.minDate !== minDate) { - this.options.minDate = minDate; - this.ymd.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.maxDate !== maxDate) { - this.options.maxDate = maxDate; - this.ymd.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - v = v || {}; - var type = v.type || BI.DynamicDateCombo.Static; - var value = v.value || v; - this.switcher.setValue(type); - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - break; - case BI.DynamicDateCombo.Static: - default: - if (this._checkValueValid(value)) { - var date = BI.getDate(); - this.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1 - }); - } else { - this.ymd.setValue(value); - } - break; - } - }, - - getValue: function () { - var type = this.dateTab.getSelect(); - return { - type: type, - value: type === BI.DynamicDatePane.Static ? this.dateTab.getValue() : this.dynamicPane.getValue() - }; - } -}); - -BI.DynamicDatePane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDatePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; - -BI.shortcut("bi.dynamic_date_pane", BI.DynamicDatePane); - -BI.extend(BI.DynamicDatePane, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/datetime/datetime.combo.js b/src/widget/datetime/datetime.combo.js deleted file mode 100644 index 28037bb69..000000000 --- a/src/widget/datetime/datetime.combo.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Created by Urthur on 2017/7/14. - */ -BI.DateTimeCombo = BI.inherit(BI.Single, { - constants: { - popupHeight: 290, - popupWidth: 270, - comboAdjustHeight: 1, - border: 1, - iconWidth: 24 - }, - _defaultConfig: function (conf) { - return BI.extend(BI.DateTimeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-date-time-combo bi-focus-shadow " + (conf.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - width: 200, - height: 24, - minDate: "1900-01-01", - maxDate: "2099-12-31" - }); - }, - _init: function () { - BI.DateTimeCombo.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - var date = BI.getDate(); - this.storeValue = BI.isNotNull(opts.value) ? opts.value : { - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate(), - hour: date.getHours(), - minute: date.getMinutes(), - second: date.getSeconds() - }; - this.trigger = BI.createWidget({ - type: "bi.date_time_trigger", - height: opts.height, - min: opts.minDate, - max: opts.maxDate, - value: opts.value - }); - - this.popup = BI.createWidget({ - type: "bi.date_time_popup", - behaviors: opts.behaviors, - min: opts.minDate, - max: opts.maxDate, - value: opts.value - }); - self.setValue(this.storeValue); - - this.popup.on(BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE, function () { - self.setValue(self.storeValue); - self.hidePopupView(); - self.fireEvent(BI.DateTimeCombo.EVENT_CANCEL); - }); - this.popup.on(BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE, function () { - self.storeValue = self.popup.getValue(); - self.setValue(self.storeValue); - self.hidePopupView(); - self.fireEvent(BI.DateTimeCombo.EVENT_CONFIRM); - }); - this.combo = BI.createWidget({ - type: "bi.combo", - container: opts.container, - toggle: false, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - el: this.trigger, - adjustLength: this.constants.comboAdjustHeight, - popup: { - el: this.popup, - width: this.constants.popupWidth, - stopPropagation: false - }, - // DEC-4250 和复选下拉一样,点击不收起 - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0; - } - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DateTimeCombo.EVENT_BEFORE_POPUPVIEW); - }); - - var triggerBtn = BI.createWidget({ - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-font", - width: this.constants.iconWidth, - height: opts.height, - }); - triggerBtn.on(BI.IconButton.EVENT_CHANGE, function () { - if (self.combo.isViewVisible()) { - // self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - BI.createWidget({ - type: "bi.htape", - columnSize: ["", this.constants.iconWidth], - element: this, - items: [this.combo, triggerBtn] - }); - }, - - setValue: function (v) { - this.storeValue = v; - this.popup.setValue(v); - this.trigger.setValue(v); - }, - getValue: function () { - return this.storeValue; - }, - - hidePopupView: function () { - this.combo.hideView(); - } -}); - -BI.DateTimeCombo.EVENT_CANCEL = "EVENT_CANCEL"; -BI.DateTimeCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DateTimeCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DateTimeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.date_time_combo", BI.DateTimeCombo); diff --git a/src/widget/datetime/datetime.popup.js b/src/widget/datetime/datetime.popup.js deleted file mode 100644 index 7102fbc41..000000000 --- a/src/widget/datetime/datetime.popup.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Created by Urthur on 2017/7/14. - */ -BI.DateTimePopup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.DateTimePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-date-time-popup", - width: 268, - height: 374 - }); - }, - _init: function () { - BI.DateTimePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - this.cancelButton = BI.createWidget({ - type: "bi.text_button", - cls: "multidate-popup-button bi-border-top bi-border-right", - shadow: true, - text: BI.i18nText("BI-Basic_Cancel") - }); - this.cancelButton.on(BI.TextButton.EVENT_CHANGE, function () { - self.fireEvent(BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE); - }); - - this.okButton = BI.createWidget({ - type: "bi.text_button", - cls: "multidate-popup-button bi-border-top", - shadow: true, - text: BI.i18nText("BI-Basic_OK") - }); - this.okButton.on(BI.TextButton.EVENT_CHANGE, function () { - self.fireEvent(BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE); - }); - - this.dateCombo = BI.createWidget({ - type: "bi.date_calendar_popup", - behaviors: opts.behaviors, - min: self.options.min, - max: self.options.max - }); - self.dateCombo.on(BI.DateCalendarPopup.EVENT_CHANGE, function () { - self.fireEvent(BI.DateTimePopup.CALENDAR_EVENT_CHANGE); - }); - - this.dateButton = BI.createWidget({ - type: "bi.grid", - items: [[this.cancelButton, this.okButton]] - }); - BI.createWidget({ - element: this, - type: "bi.vtape", - items: [{ - el: this.dateCombo - }, { - el: { - type: "bi.center_adapt", - cls: "bi-split-top", - items: [{ - type: "bi.dynamic_date_time_select", - ref: function (_ref) { - self.timeSelect = _ref; - } - }] - }, - height: 50 - }, { - el: this.dateButton, - height: 30 - }] - }); - this.setValue(opts.value); - }, - - setValue: function (v) { - var value = v, date; - if (BI.isNull(value)) { - date = BI.getDate(); - this.dateCombo.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - this.timeSelect.setValue({ - hour: date.getHours(), - minute: date.getMinutes(), - second: date.getSeconds() - }); - } else { - this.dateCombo.setValue({ - year: value.year, - month: value.month, - day: value.day - }); - this.timeSelect.setValue({ - hour: value.hour, - minute: value.minute, - second: value.second - }); - } - }, - - getValue: function () { - return BI.extend({ - year: this.dateCombo.getValue().year, - month: this.dateCombo.getValue().month, - day: this.dateCombo.getValue().day - }, this.timeSelect.getValue()); - } -}); -BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE = "BUTTON_CANCEL_EVENT_CHANGE"; -BI.DateTimePopup.CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; -BI.shortcut("bi.date_time_popup", BI.DateTimePopup); diff --git a/src/widget/datetime/datetime.trigger.js b/src/widget/datetime/datetime.trigger.js deleted file mode 100644 index d161585e6..000000000 --- a/src/widget/datetime/datetime.trigger.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Created by Urthur on 2017/7/14. - */ -BI.DateTimeTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - iconWidth:24 - }, - - _defaultConfig: function () { - return BI.extend(BI.DateTimeTrigger.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-date-time-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - width: 200 - }); - }, - _init: function () { - BI.DateTimeTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - height: o.height, - width: o.width, - hgap: c.hgap - }); - - BI.createWidget({ - type: "bi.htape", - element: this, - items: [{ - el: this.text - },{ - el: BI.createWidget(), - width: this._const.iconWidth - }] - }); - this.setValue(o.value); - }, - - _printTime: function (v) { - return v < 10 ? "0" + v : v; - }, - - setValue: function (v) { - var self = this; - var value = v, dateStr; - if(BI.isNull(value)) { - value = BI.getDate(); - dateStr = BI.print(value, "%Y-%X-%d %H:%M:%S"); - } else { - var date = BI.getDate(value.year, value.month - 1, value.day, value.hour, value.minute, value.second); - dateStr = BI.print(date, "%Y-%X-%d %H:%M:%S"); - - } - this.text.setText(dateStr); - this.text.setTitle(dateStr); - } - -}); -BI.shortcut("bi.date_time_trigger", BI.DateTimeTrigger); diff --git a/src/widget/datetimepane/card.static.datetimepane.js b/src/widget/datetimepane/card.static.datetimepane.js deleted file mode 100644 index b63b83c9a..000000000 --- a/src/widget/datetimepane/card.static.datetimepane.js +++ /dev/null @@ -1,205 +0,0 @@ -BI.StaticDateTimePaneCard = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.StaticDateTimePaneCard.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-date-time-pane", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - selectedTime: null - }); - }, - _init: function () { - BI.StaticDateTimePaneCard.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.today = BI.getDate(); - this._year = this.today.getFullYear(); - this._month = this.today.getMonth() + 1; - - this.selectedTime = o.selectedTime || { - year: this._year, - month: this._month - }; - - this.datePicker = BI.createWidget({ - type: "bi.date_picker", - behaviors: o.behaviors, - min: o.min, - max: o.max - }); - this.datePicker.on(BI.DatePicker.EVENT_CHANGE, function () { - var value = self.datePicker.getValue(); - var monthDay = BI.getMonthDays(BI.getDate(value.year, value.month - 1, 1)); - var day = self.selectedTime.day || 0; - if (day > monthDay) { - day = monthDay; - } - self.selectedTime = BI.extend(self.selectedTime, { - year: value.year, - month: value.month - }); - day !== 0 && (self.selectedTime.day = day); - self.calendar.setSelect(BI.Calendar.getPageByDateJSON(self.selectedTime)); - self.calendar.setValue(self.selectedTime); - day !== 0 && self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); - }); - - this.datePicker.on(BI.DatePicker.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, function () { - self.fireEvent(BI.StaticDateTimePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - }); - - this.calendar = BI.createWidget({ - direction: "custom", - // logic: { - // dynamic: false - // }, - type: "bi.navigation", - tab: this.datePicker, - cardCreator: BI.bind(this._createNav, this) - }); - this.calendar.on(BI.Navigation.EVENT_CHANGE, function () { - self.selectedTime = BI.extend(self.calendar.getValue(), self.timeSelect.getValue()); - self.calendar.empty(); - self.setValue(self.selectedTime); - self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - hgap: 10, - items: [{ - el: this.datePicker, - height: 40 - }, this.calendar, { - el: { - type: "bi.dynamic_date_time_select", - cls: "bi-split-top", - ref: function () { - self.timeSelect = this; - }, - listeners: [{ - eventName: BI.DynamicDateTimeSelect.EVENT_CONFIRM, - action: function () { - self.selectedTime = BI.extend(self.calendar.getValue(), self.timeSelect.getValue()); - self.fireEvent("EVENT_CHANGE"); - } - }] - }, - height: 40 - }] - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.layout", - cls: "bi-split-top" - }, - height: 1, - top: 40, - left: 0, - right: 0 - }] - }); - this.setValue(o.selectedTime); - - }, - - _createNav: function (v) { - var date = BI.Calendar.getDateJSONByPage(v); - var calendar = BI.createWidget({ - type: "bi.calendar", - logic: { - dynamic: false - }, - min: this.options.min, - max: this.options.max, - year: date.year, - month: date.month, - day: this.selectedTime.day - }); - return calendar; - }, - - _getNewCurrentDate: function () { - var today = BI.getDate(); - return { - year: today.getFullYear(), - month: today.getMonth() + 1 - }; - }, - - _setCalenderValue: function (date) { - this.calendar.setSelect(BI.Calendar.getPageByDateJSON(date)); - this.calendar.setValue(date); - this.selectedTime = BI.extend({}, this.timeSelect.getValue(), date); - }, - - _setDatePicker: function (timeOb) { - if (BI.isNull(timeOb) || BI.isNull(timeOb.year) || BI.isNull(timeOb.month)) { - this.datePicker.setValue(this._getNewCurrentDate()); - } else { - this.datePicker.setValue(timeOb); - } - }, - - _setCalendar: function (timeOb) { - if (BI.isNull(timeOb) || BI.isNull(timeOb.day)) { - this.calendar.empty(); - this._setCalenderValue(this._getNewCurrentDate()); - } else { - this._setCalenderValue(timeOb); - } - }, - - _checkMin: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMinDate(o.min); - }); - }, - - _checkMax: function () { - var o = this.options; - BI.each(this.calendar.getAllCard(), function (idx, calendar) { - calendar.setMaxDate(o.max); - }); - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - this.datePicker.setMinDate(minDate); - this._checkMin(); - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - this.datePicker.setMaxDate(maxDate); - this._checkMax(); - } - }, - - setValue: function (timeOb) { - timeOb = timeOb || {}; - this._setDatePicker(timeOb); - this._setCalendar(timeOb); - this.timeSelect.setValue({ - hour: timeOb.hour, - minute: timeOb.minute, - second: timeOb.second - }); - }, - - getValue: function () { - return this.selectedTime; - } - -}); -BI.StaticDateTimePaneCard.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.static_date_time_pane_card", BI.StaticDateTimePaneCard); \ No newline at end of file diff --git a/src/widget/datetimepane/datetimepane.js b/src/widget/datetimepane/datetimepane.js deleted file mode 100644 index aaad8a0dd..000000000 --- a/src/widget/datetimepane/datetimepane.js +++ /dev/null @@ -1,214 +0,0 @@ -BI.DynamicDateTimePane = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-dynamic-date-pane", - minDate: "1900-01-01", - maxDate: "2099-12-31", - supportDynamic: true, - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vtape", - items: [{ - el: { - type: "bi.linear_segment", - invisible: !o.supportDynamic, - cls: "bi-split-bottom", - height: 30, - items: BI.createItems([{ - text: BI.i18nText("BI-Multi_Date_YMD"), - value: BI.DynamicDateTimePane.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicDateTimePane.Dynamic - }], { - textAlign: "center" - }), - listeners: [{ - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - var value = this.getValue()[0]; - self.dateTab.setSelect(value); - switch (value) { - case BI.DynamicDateTimePane.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - break; - case BI.DynamicDateTimePane.Dynamic: - self.dynamicPane.setValue({ - year: 0 - }); - break; - default: - break; - } - self.fireEvent(BI.DynamicDateTimePane.EVENT_CHANGE); - } - }], - ref: function () { - self.switcher = this; - } - }, - height: o.supportDynamic ? 30 : 0 - }, { - type: "bi.tab", - ref: function () { - self.dateTab = this; - }, - showIndex: BI.DynamicDateTimePane.Static, - cardCreator: function (v) { - switch (v) { - case BI.DynamicDateTimePane.Static: - return { - type: "bi.static_date_time_pane_card", - min: o.minDate, - max: o.maxDate, - behaviors: o.behaviors, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent(BI.DynamicDateTimePane.EVENT_CHANGE); - } - }, { - eventName: "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW", - action: function () { - self.fireEvent(BI.DynamicDateTimePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }], - ref: function () { - self.ymd = this; - } - }; - case BI.DynamicDateTimePane.Dynamic: - default: - return { - type: "bi.vtape", - items: [{ - type: "bi.dynamic_date_card", - min: o.minDate, - max: o.maxDate, - ref: function () { - self.dynamicPane = this; - } - }, { - el: { - type: "bi.center", - items: [{ - type: "bi.text_button", - cls: "bi-high-light bi-border-top", - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - textHeight: 23, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.setValue(); - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-border-left bi-high-light bi-border-top", - textHeight: 23, - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicDatePane.EVENT_CHANGE); - } - } - }] - }] - }, - height: 24 - }] - }; - } - } - }] - }; - }, - - created: function () { - this.setValue(this.options.value); - }, - - _checkValueValid: function (value) { - return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); - }, - - _checkValue: function (v) { - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - default: - return true; - } - }, - - setMinDate: function (minDate) { - if (this.options.minDate !== minDate) { - this.options.minDate = minDate; - this.ymd.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.maxDate !== maxDate) { - this.options.maxDate = maxDate; - this.ymd.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - v = v || {}; - var type = v.type || BI.DynamicDateTimePane.Static; - var value = v.value || v; - this.switcher.setValue(type); - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateTimePane.Dynamic: - this.dynamicPane.setValue(value); - break; - case BI.DynamicDateTimePane.Static: - default: - if (this._checkValueValid(value)) { - var date = BI.getDate(); - this.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1 - }); - } else { - this.ymd.setValue(value); - } - break; - } - }, - - getValue: function () { - return { - type: this.dateTab.getSelect(), - value: this.dateTab.getValue() - }; - } -}); -BI.DynamicDateTimePane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateTimePane.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.dynamic_date_time_pane", BI.DynamicDateTimePane); - -BI.extend(BI.DynamicDateTimePane, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/downlist/combo.downlist.js b/src/widget/downlist/combo.downlist.js deleted file mode 100644 index 10c39bfbf..000000000 --- a/src/widget/downlist/combo.downlist.js +++ /dev/null @@ -1,143 +0,0 @@ -(function() { - function transformItems(items) { - if (!items) return items; - var result = BI.cloneDeep(items); - var isComplexItmes = BI.some(items, function (_, item) { - return BI.isArray(item); - }); - // 传一维数组,帮转二维 - if (!isComplexItmes) { - result = [result]; - } - // 帮转 el - BI.each(result, function (_, arr) { - BI.each(arr, function (_, item) { - if (item.children && !item.el) { - item.el = { - text: item.text, - icon: item.icon, - cls: item.cls, - iconCls1: item.iconCls1, - value: item.value - }; - } - }); - }); - return result; - } - - /** - * Created by roy on 15/8/14. - */ - BI.DownListCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.DownListCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-down-list-combo", - height: 24, - items: [], - adjustLength: 0, - direction: "bottom", - trigger: "click", - container: null, - stopPropagation: false, - el: {}, - popup: {}, - minWidth: 140, - maxHeight: 1000, - destroyWhenHide: false, - isDefaultInit: true, - }); - }, - - _init: function () { - BI.DownListCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.downlistcombo = BI.createWidget({ - element: this, - type: "bi.combo", - trigger: o.trigger, - isNeedAdjustWidth: false, - isDefaultInit: o.isDefaultInit, - container: o.container, - adjustLength: o.adjustLength, - direction: o.direction, - belowMouse: o.belowMouse, - stopPropagation: o.stopPropagation, - destroyWhenHide: o.destroyWhenHide, - el: { - type: "bi.icon_trigger", - extraCls: o.iconCls, - width: o.width, - height: o.height, - ...o.el - }, - popup: { - el: { - type: "bi.down_list_popup", - ref: function (ref) { - self.popupView = ref; - }, - items: transformItems(o.items), - chooseType: o.chooseType, - value: o.value, - listeners: [{ - eventName: BI.DownListPopup.EVENT_CHANGE, - action: function (value) { - self.fireEvent(BI.DownListCombo.EVENT_CHANGE, value); - self.downlistcombo.hideView(); - } - }, { - eventName: BI.DownListPopup.EVENT_SON_VALUE_CHANGE, - action: function (value, fatherValue) { - self.fireEvent(BI.DownListCombo.EVENT_SON_VALUE_CHANGE, value, fatherValue); - self.downlistcombo.hideView(); - } - }] - }, - stopPropagation: o.stopPropagation, - maxHeight: o.maxHeight, - minWidth: o.minWidth, - ...o.popup - } - }); - - this.downlistcombo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.DownListCombo.EVENT_BEFORE_POPUPVIEW); - }); - }, - - hideView: function () { - this.downlistcombo.hideView(); - }, - - showView: function (e) { - this.downlistcombo.showView(e); - }, - - populate: function (items) { - this.popupView.populate(items); - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - adjustWidth: function () { - this.downlistcombo.adjustWidth(); - }, - - adjustHeight: function () { - this.downlistcombo.adjustHeight(); - } - }); - BI.DownListCombo.EVENT_CHANGE = "EVENT_CHANGE"; - BI.DownListCombo.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; - BI.DownListCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - - BI.shortcut("bi.down_list_combo", BI.DownListCombo); -}()); diff --git a/src/widget/downlist/group.downlist.js b/src/widget/downlist/group.downlist.js deleted file mode 100644 index c7cc2ce49..000000000 --- a/src/widget/downlist/group.downlist.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Created by roy on 15/9/6. - */ -BI.DownListGroup = BI.inherit(BI.Widget, { - constants: { - iconCls: "check-mark-ha-font" - }, - _defaultConfig: function () { - return BI.extend(BI.DownListGroup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-down-list-group", - items: [ - { - el: {} - } - ] - }); - }, - _init: function () { - BI.DownListGroup.superclass._init.apply(this, arguments); - var o = this.options, self = this; - - this.downlistgroup = BI.createWidget({ - element: this, - type: "bi.button_tree", - items: o.items, - chooseType: 0, // 0单选,1多选 - layouts: [{ - type: "bi.vertical", - hgap: 0, - vgap: 0 - }], - value: o.value - }); - this.downlistgroup.on(BI.Controller.EVENT_CHANGE, function (type) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if(type === BI.Events.CLICK) { - self.fireEvent(BI.DownListGroup.EVENT_CHANGE, arguments); - } - }); - }, - getValue: function () { - return this.downlistgroup.getValue(); - }, - setValue: function (v) { - this.downlistgroup.setValue(v); - } - - -}); -BI.DownListGroup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.down_list_group", BI.DownListGroup); \ No newline at end of file diff --git a/src/widget/downlist/item.downlist.js b/src/widget/downlist/item.downlist.js deleted file mode 100644 index 531806ca0..000000000 --- a/src/widget/downlist/item.downlist.js +++ /dev/null @@ -1,102 +0,0 @@ -BI.DownListItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.DownListItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-down-list-item bi-list-item-active", - cls: "", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - logic: { - dynamic: true - }, - selected: false, - iconHeight: null, - iconWidth: null, - textHgap: 0, - textVgap: 0, - textLgap: 0, - textRgap: 0 - }); - }, - _init: function () { - BI.DownListItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-item-text", - textAlign: "left", - hgap: o.textHgap, - vgap: o.textVgap, - lgap: o.textLgap, - rgap: o.textRgap, - text: o.text, - value: o.value, - keyword: o.keyword, - height: o.height - }); - - - var icon = BI.isPlainObject(o.icon) ? o.icon : { - type: "bi.icon", - width: o.iconWidth, - height: o.iconHeight, - } - - this.icon = BI.createWidget({ - type: "bi.center_adapt", - width: 36, - height: o.height, - items: [{ - el: icon, - }], - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left), BI.extend(o.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, this.icon, this.text) - })))); - }, - - setValue: function () { - if (!this.isReadOnly()) { - this.text.setValue.apply(this.text, arguments); - } - }, - - getValue: function () { - return this.text.getValue(); - }, - - setText: function () { - this.text.setText.apply(this.text, arguments); - }, - - getText: function () { - return this.text.getText(); - }, - - doClick: function () { - BI.DownListItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.DownListItem.EVENT_CHANGE, this.getValue(), this); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - } -}); -BI.DownListItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.down_list_item", BI.DownListItem); \ No newline at end of file diff --git a/src/widget/downlist/item.downlistgroup.js b/src/widget/downlist/item.downlistgroup.js deleted file mode 100644 index df4a09ac7..000000000 --- a/src/widget/downlist/item.downlistgroup.js +++ /dev/null @@ -1,118 +0,0 @@ -BI.DownListGroupItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - var conf = BI.DownListGroupItem.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-down-list-group-item", - logic: { - dynamic: false - }, - // invalid: true, - iconCls1: "dot-e-font", - icon: "", - iconCls2: "pull-right-e-font" - }); - }, - render: function () { - var o = this.options; - var self = this; - this.text = BI.createWidget({ - type: "bi.label", - cls: "list-group-item-text", - textAlign: "left", - text: o.text, - value: o.value, - height: o.height, - }); - - if (BI.isPlainObject(o.icon)) { - this.icon1 = BI.createWidget({ - width: 36, - height: o.height, - type: "bi.center_adapt", - items: [o.icon], - }); - } else { - this.icon1 = BI.createWidget({ - type: "bi.icon_button", - cls: o.iconCls1, - width: 36, - height: o.height, - iconHeight: o.iconHeight, - iconWidth: 36, - disableSelected: true, - selected: this._digest(o.value), - }); - } - - this.icon2 = BI.createWidget({ - type: "bi.icon_button", - cls: o.iconCls2, - width: 24, - forceNotSelected: true - }); - - this.element.hover(function () { - if (self.isEnabled()) { - self.hover(); - } - }, function () { - if (self.isEnabled()) { - self.dishover(); - } - }); - - return { - type: "bi.horizontal_fill", - columnSize: [36, "fill", 24], - items: [this.icon1, this.text, this.icon2] - } - }, - - _getLevel: function () { - var child = BI.first(this.options.childValues); - return BI.isNotNull(child) ? (child + "").split(BI.BlankSplitChar).length : 0; - }, - - _digest: function (v) { - var self = this, o = this.options; - v = BI.isArray(v) ? v : [v]; - var level = this._getLevel(); - return BI.any(v, function (idx, value) { - return BI.contains(o.childValues, (value + "").split(BI.BlankSplitChar).slice(0, level).join(BI.BlankSplitChar)); - }); - }, - - hover: function () { - BI.DownListGroupItem.superclass.hover.apply(this, arguments); - this.icon1.element.addClass("hover"); - this.icon2.element.addClass("hover"); - - }, - - dishover: function () { - BI.DownListGroupItem.superclass.dishover.apply(this, arguments); - this.icon1.element.removeClass("hover"); - this.icon2.element.removeClass("hover"); - }, - - doClick: function () { - BI.DownListGroupItem.superclass.doClick.apply(this, arguments); - if (this.isValid()) { - this.fireEvent(BI.DownListGroupItem.EVENT_CHANGE, this.getValue()); - } - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - setValue: function (v) { - this.icon1.setSelected && this.icon1.setSelected(this._digest(v)); - }, -}); -BI.DownListGroupItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.down_list_group_item", BI.DownListGroupItem); diff --git a/src/widget/downlist/popup.downlist.js b/src/widget/downlist/popup.downlist.js deleted file mode 100644 index 0e802a695..000000000 --- a/src/widget/downlist/popup.downlist.js +++ /dev/null @@ -1,301 +0,0 @@ -/** - * Created by roy on 15/9/8. - * 处理popup中的item分组样式 - * 一个item分组中的成员大于一时,该分组设置为单选,并且默认状态第一个成员设置为已选择项 - */ -BI.DownListPopup = BI.inherit(BI.Pane, { - constants: { - nextIcon: "pull-right-e-font", - height: 24, - iconHeight: 12, - iconWidth: 12, - hgap: 0, - vgap: 0, - border: 1 - }, - _defaultConfig: function () { - var conf = BI.DownListPopup.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-down-list-popup", - items: [], - chooseType: BI.Selection.Multi - }); - }, - _init: function () { - BI.DownListPopup.superclass._init.apply(this, arguments); - this.singleValues = []; - this.childValueMap = {}; - this.fatherValueMap = {}; - this.items = []; - var self = this, o = this.options, children = this._createPopupItems(o.items); - this.popup = BI.createWidget({ - type: "bi.button_tree", - items: BI.createItems(children, - {}, { - adjustLength: -2 - } - ), - layouts: [{ - type: "bi.vertical", - hgap: this.constants.hgap, - vgap: this.constants.vgap - }], - value: this._digest(o.value), - chooseType: o.chooseType - }); - - this.popup.on(BI.ButtonTree.EVENT_CHANGE, function (value, object) { - var changedValue = value; - if (BI.isNotNull(self.childValueMap[value])) { - changedValue = self.childValueMap[value]; - self.fireEvent(BI.DownListPopup.EVENT_SON_VALUE_CHANGE, changedValue, self.fatherValueMap[value]); - } else { - self.fireEvent(BI.DownListPopup.EVENT_CHANGE, changedValue, object); - } - - - if (!BI.contains(self.singleValues, changedValue)) { - var item = self.getValue(); - var result = []; - BI.each(item, function (i, valueObject) { - if (valueObject.value != changedValue) { - result.push(valueObject); - } - }); - self.setValue(result); - } - - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.popup], - vgap: 5 - }); - - }, - _createPopupItems: function (items) { - var self = this, result = []; - // 不能修改populate进来的item的引用 - BI.each(items, function (i, it) { - var item_done = { - type: "bi.down_list_group", - items: [] - }; - - var storeItem = []; - - BI.each(it, function (i, sourceItem) { - var item = BI.extend({}, sourceItem); - if (BI.isNotEmptyArray(sourceItem.children) && !BI.isEmpty(sourceItem.el)) { - item.type = "bi.combo_group"; - // popup未初始化返回的是options中的value, 在经过buttontree的getValue concat之后,无法区分值来自options - // 还是item自身, 这边控制defaultInit为true来避免这个问题 - item.isDefaultInit = true; - item.cls = "down-list-group"; - item.trigger = "hover"; - item.isNeedAdjustWidth = false; - item.el = sourceItem.el; - item.el.title = sourceItem.el.title || sourceItem.el.text; - item.el.type = "bi.down_list_group_item"; - item.el.logic = { - dynamic: true - }; - item.el.height = sourceItem.el.height || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT; - item.el.iconCls2 = self.constants.nextIcon; - item.popup = { - lgap: 1, - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical" - }] - - }, - innerVgap: 5, - maxHeight: 378 - }; - self._createChildren(item, sourceItem); - } else { - item.type = sourceItem.type || "bi.down_list_item"; - item.title = sourceItem.title || sourceItem.text; - item.textRgap = 10; - item.isNeedAdjustWidth = false; - item.logic = { - dynamic: true - }; - } - var el_done = {}; - el_done.el = item; - item_done.items.push(el_done); - storeItem.push(item); - }); - if (self._isGroup(item_done.items)) { - BI.each(item_done.items, function (i, item) { - self.singleValues.push(item.el.value); - }); - } - - result.push(item_done); - self.items.push(storeItem); - if (self._needSpliter(i, items.length)) { - var spliter_container = BI.createWidget({ - type: "bi.vertical", - items: [{ - el: { - type: "bi.layout", - cls: "bi-down-list-spliter bi-split-top cursor-pointer", - height: 0 - } - - }], - cls: "bi-down-list-spliter-container cursor-pointer", - vgap: 5, - hgap: 12 - }); - result.push(spliter_container); - } - }); - return result; - }, - - _createChildren: function (targetItem, sourceItem) { - var self = this; - targetItem.el.childValues = []; - targetItem.items = targetItem.children = []; - BI.each(sourceItem.children, function (i, child) { - var item = BI.extend({}, child); - var fatherValue = BI.deepClone(targetItem.el.value); - var childValue = BI.deepClone(item.value); - self.singleValues.push(item.value); - item.type = item.type || "bi.down_list_item"; - item.extraCls = " child-down-list-item"; - item.title = item.title || item.text; - item.textRgap = 10; - item.isNeedAdjustWidth = false; - item.logic = { - dynamic: true - }; - item.father = fatherValue; - item.childValue = item.value; - self.fatherValueMap[self._createChildValue(fatherValue, childValue)] = fatherValue; - self.childValueMap[self._createChildValue(fatherValue, childValue)] = childValue; - item.value = self._createChildValue(fatherValue, childValue); - targetItem.el.childValues.push(item.value); - targetItem.items.push(item); - }); - }, - - _isGroup: function (i) { - return i.length > 1; - }, - - _needSpliter: function (i, itemLength) { - return i < itemLength - 1; - }, - - _createChildValue: function (fatherValue, childValue) { - return fatherValue + BI.BlankSplitChar + childValue; - }, - - _digest: function (valueItem) { - var self = this; - var valueArray = []; - BI.each(valueItem, function (i, item) { - var value; - if (BI.isNotNull(item.childValue)) { - value = self._createChildValue(item.value, item.childValue); - } else { - value = item.value; - } - valueArray.push(value); - } - ); - return valueArray; - }, - - _checkValues: function (values) { - var value = []; - BI.each(this.items, function (idx, itemGroup) { - BI.each(itemGroup, function (id, item) { - if(BI.isNotNull(item.children)) { - var childValues = BI.map(item.children, "value"); - var v = joinValue(childValues, values[idx]); - if(BI.isNotEmptyString(v)) { - value.push(v); - } - }else{ - if(item.value === values[idx][0]) { - value.push(values[idx][0]); - } - } - }); - }); - return value; - - function joinValue (sources, targets) { - var value = ""; - BI.some(sources, function (idx, s) { - return BI.some(targets, function (id, t) { - if(s === t) { - value = s; - return true; - } - }); - }); - return value; - } - }, - - populate: function (items) { - BI.DownListPopup.superclass.populate.apply(this, arguments); - this.items = []; - this.childValueMap = {}; - this.fatherValueMap = {}; - this.singleValues = []; - var children = this._createPopupItems(items); - var popupItem = BI.createItems(children, - {}, { - adjustLength: -2 - } - ); - this.popup.populate(popupItem); - }, - - setValue: function (valueItem) { - this.popup.setValue(this._digest(valueItem)); - }, - - _getValue: function () { - var v = []; - BI.each(this.popup.getAllButtons(), function (i, item) { - i % 2 === 0 && v.push(item.getValue()); - }); - return v; - }, - - getValue: function () { - var self = this, result = []; - var values = this._checkValues(this._getValue()); - BI.each(values, function (i, value) { - var valueItem = {}; - if (BI.isNotNull(self.childValueMap[value])) { - var fartherValue = self.fatherValueMap[value]; - valueItem.childValue = self.childValueMap[value]; - valueItem.value = fartherValue; - } else { - valueItem.value = value; - } - result.push(valueItem); - }); - return result; - } - - -}); - -BI.DownListPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DownListPopup.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; -BI.shortcut("bi.down_list_popup", BI.DownListPopup); diff --git a/src/widget/dynamicdate/dynamicdate.caculate.js b/src/widget/dynamicdate/dynamicdate.caculate.js deleted file mode 100644 index 665661d9e..000000000 --- a/src/widget/dynamicdate/dynamicdate.caculate.js +++ /dev/null @@ -1,117 +0,0 @@ -!(function () { - BI.DynamicDateHelper = {}; - BI.extend(BI.DynamicDateHelper, { - getCalculation: function (obj) { - var date = BI.getDate(); - - return this.getCalculationByDate(date, obj); - }, - - getDescription: function (obj) { - var value = ""; - var endText = ""; - if(BI.isNotNull(obj.year)) { - if(BI.parseInt(obj.year) !== 0) { - value += Math.abs(obj.year) + BI.i18nText("BI-Basic_Year") + (obj.year < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Year"), obj.position); - } - if(BI.isNotNull(obj.quarter)) { - if(BI.parseInt(obj.quarter) !== 0) { - value += Math.abs(obj.quarter) + BI.i18nText("BI-Basic_Single_Quarter") + (obj.quarter < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Single_Quarter"), obj.position); - } - if(BI.isNotNull(obj.month)) { - if(BI.parseInt(obj.month) !== 0) { - value += Math.abs(obj.month) + BI.i18nText("BI-Basic_Month") + (obj.month < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Month"), obj.position); - } - if(BI.isNotNull(obj.week)) { - if(BI.parseInt(obj.week) !== 0) { - value += Math.abs(obj.week) + BI.i18nText("BI-Basic_Week") + (obj.week < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Week"), obj.position); - } - if(BI.isNotNull(obj.day)) { - if(BI.parseInt(obj.day) !== 0) { - value += Math.abs(obj.day) + BI.i18nText("BI-Basic_Day") + (obj.day < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = BI.size(obj) === 1 ? getPositionText(BI.i18nText("BI-Basic_Month"), obj.position) : ""; - } - if(BI.isNotNull(obj.workDay) && BI.parseInt(obj.workDay) !== 0) { - value += Math.abs(obj.workDay) + BI.i18nText("BI-Basic_Work_Day") + (obj.workDay < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - return value + endText; - - function getPositionText (baseText, position) { - switch (position) { - case BI.DynamicDateCard.OFFSET.BEGIN: - return baseText + BI.i18nText("BI-Basic_Begin_Start"); - case BI.DynamicDateCard.OFFSET.END: - return baseText + BI.i18nText("BI-Basic_End_Stop"); - case BI.DynamicDateCard.OFFSET.CURRENT: - default: - return BI.i18nText("BI-Basic_Current_Day"); - } - } - }, - - getCalculationByDate: function (date, obj) { - if (BI.isNotNull(obj.year)) { - date = BI.getDate((date.getFullYear() + BI.parseInt(obj.year)), date.getMonth(), date.getDate()); - } - if (BI.isNotNull(obj.quarter)) { - date = BI.getOffsetQuarter(date, BI.parseInt(obj.quarter)); - } - if (BI.isNotNull(obj.month)) { - date = BI.getOffsetMonth(date, BI.parseInt(obj.month)); - } - if (BI.isNotNull(obj.week)) { - date = BI.getOffsetDate(date, BI.parseInt(obj.week) * 7); - } - if (BI.isNotNull(obj.day)) { - date = BI.getOffsetDate(date, BI.parseInt(obj.day)); - } - if (BI.isNotNull(obj.workDay)) { - // 配置了节假日就按照节假日计算工作日偏移,否则按正常的天去算 - if(BI.isNotNull(BI.holidays)) { - var count = Math.abs(obj.workDay); - for (var i = 0; i < count; i++) { - date = BI.getOffsetDate(date, obj.workDay < 0 ? -1 : 1); - if(BI.isNotNull(BI.holidays[BI.print(date, "%Y-%X-%d")])) { - i--; - } - } - } else { - date = BI.getOffsetDate(date, BI.parseInt(obj.workDay)); - } - } - if (BI.isNotNull(obj.position) && obj.position !== BI.DynamicDateCard.OFFSET.CURRENT) { - date = this.getBeginDate(date, obj); - } - - return BI.getDate(date.getFullYear(), date.getMonth(), date.getDate()); - }, - - getBeginDate: function (date, obj) { - if (BI.isNotNull(obj.day)) { - return obj.position === BI.DynamicDateCard.OFFSET.BEGIN ? BI.getDate(date.getFullYear(), date.getMonth(), 1) : BI.getDate(date.getFullYear(), date.getMonth(), (BI.getLastDateOfMonth(date)).getDate()); - } - if (BI.isNotNull(obj.week)) { - return obj.position === BI.DynamicDateCard.OFFSET.BEGIN ? BI.getWeekStartDate(date) : BI.getWeekEndDate(date); - } - if (BI.isNotNull(obj.month)) { - return obj.position === BI.DynamicDateCard.OFFSET.BEGIN ? BI.getDate(date.getFullYear(), date.getMonth(), 1) : BI.getDate(date.getFullYear(), date.getMonth(), (BI.getLastDateOfMonth(date)).getDate()); - } - if (BI.isNotNull(obj.quarter)) { - return obj.position === BI.DynamicDateCard.OFFSET.BEGIN ? BI.getQuarterStartDate(date) : BI.getQuarterEndDate(date); - } - if (BI.isNotNull(obj.year)) { - return obj.position === BI.DynamicDateCard.OFFSET.BEGIN ? BI.getDate(date.getFullYear(), 0, 1) : BI.getDate(date.getFullYear(), 11, 31); - } - return date; - } - }); -})(); diff --git a/src/widget/dynamicdate/dynamicdate.card.js b/src/widget/dynamicdate/dynamicdate.card.js deleted file mode 100644 index ad347e97d..000000000 --- a/src/widget/dynamicdate/dynamicdate.card.js +++ /dev/null @@ -1,423 +0,0 @@ -BI.DynamicDateCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-dynamic-date-card" - }, - - render: function () { - var self = this; - this.position = BI.DynamicDateCard.OFFSET.CURRENT; - return { - type: "bi.vertical", - items: [{ - el: { - type: "bi.label", - text: BI.i18nText("BI-Multi_Date_Relative_Current_Time"), - textAlign: "left", - lgap: 10 - }, - tgap: 10, - bgap: 5 - }, { - type: "bi.button_group", - ref: function () { - self.checkgroup = this; - }, - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - lgap: 4, - value: [BI.DynamicDateCard.TYPE.YEAR], - items: BI.createItems([{ - text: BI.i18nText("BI-Basic_Year"), - value: BI.DynamicDateCard.TYPE.YEAR - }, { - text: BI.i18nText("BI-Basic_Single_Quarter"), - value: BI.DynamicDateCard.TYPE.QUARTER - }, { - text: BI.i18nText("BI-Basic_Month"), - value: BI.DynamicDateCard.TYPE.MONTH - }, { - text: BI.i18nText("BI-Basic_Week"), - value: BI.DynamicDateCard.TYPE.WEEK - }, { - text: BI.i18nText("BI-Basic_Day"), - value: BI.DynamicDateCard.TYPE.DAY - }], { - type: "bi.multi_select_item", - logic: { - dynamic: true - }, - iconWrapperWidth: 26, - }), - layouts: [{ - type: "bi.left", - rgap: 4 - }], - listeners: [{ - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - var value = self.checkgroup.getValue(); - if(value.length !== 0) { - self.workDayBox.setSelected(false); - } - - var plainValue = {}; - BI.each(self.resultPane.getAllButtons(), function (idx, button) { - var value = button.getValue(); - if(BI.isNotNull(value.dateType)) { - plainValue[value.dateType] = { - value: value.value, - offset: value.offset - }; - } - }); - self.resultPane.populate(self._getParamJson(BI.map(self.checkgroup.getValue(), function (idx, v) { - var obj = { - dateType: v - }; - if(BI.has(plainValue, v)) { - obj.value = plainValue[v].value; - obj.offset = plainValue[v].offset; - } - return obj; - }))); - self.position = BI.DynamicDateCard.OFFSET.CURRENT; - self.fireEvent("EVENT_CHANGE"); - } - }] - }, { - type: "bi.vertical_adapt", - lgap: 2, - items: [{ - el: { - type: "bi.multi_select_item", - iconWrapperWidth: 26, - ref: function () { - self.workDayBox = this; - }, - logic: { - dynamic: true - }, - text: BI.i18nText("BI-Basic_Work_Day"), - value: BI.DynamicDateCard.TYPE.WORK_DAY, - listeners: [{ - eventName: BI.MultiSelectItem.EVENT_CHANGE, - action: function () { - if(this.isSelected()) { - self.checkgroup.setValue(); - } - self.resultPane.populate(this.isSelected() ? self._getParamJson([{ - dateType: BI.DynamicDateCard.TYPE.WORK_DAY - }]) : []); - self.position = BI.DynamicDateCard.OFFSET.CURRENT; - self.fireEvent("EVENT_CHANGE"); - } - }] - } - }], - ref: function () { - self.workDay = this; - } - }, { - type: "bi.button_group", - items: this._getParamJson([{ - dateType: BI.DynamicDateCard.TYPE.YEAR - }]), - ref: function () { - self.resultPane = this; - }, - layouts: [{ - type: "bi.vertical", - bgap: 10, - hgap: 10 - }] - }] - }; - }, - - _getParamJson: function (values, positionValue) { - var self = this, o = this.options; - var items = BI.map(values, function (idx, value) { - return { - el: { - type: "bi.dynamic_date_param_item", - validationChecker: BI.bind(self._checkDate, self), - dateType: value.dateType, - value: value.value, - offset: value.offset, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-date-error"); - } - }] - }, - tgap: idx === 0 ? 5 : 0 - }; - }); - - if(values.length === 1 && values[0].dateType === BI.DynamicDateCard.TYPE.DAY) { - var comboItems = this._getText(BI.DynamicDateCard.TYPE.MONTH); - comboItems[0].text = BI.i18nText("BI-Basic_Empty"); - items.push({ - type: "bi.text_value_combo", - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - items: comboItems, - container: null, - value: positionValue || BI.DynamicDateCard.OFFSET.CURRENT, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.position = this.getValue()[0]; - this.setValue(self.position); - self.fireEvent("EVENT_CHANGE"); - } - }] - }); - }else{ - if(values.length !== 0 && BI.last(values).dateType !== BI.DynamicDateCard.TYPE.DAY && BI.last(values).dateType !== BI.DynamicDateCard.TYPE.WORK_DAY) { - items.push({ - type: "bi.text_value_combo", - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - container: null, - items: this._getText(BI.last(values).dateType), - value: positionValue || BI.DynamicDateCard.OFFSET.CURRENT, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.position = this.getValue()[0]; - this.setValue(self.position); - self.fireEvent("EVENT_CHANGE"); - } - }] - }); - - } - } - - return items; - }, - - _checkDate: function (obj) { - var o = this.options; - var date = BI.DynamicDateHelper.getCalculation(BI.extend(this._getValue(), this._digestDateTypeValue(obj))); - - return !BI.checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; - }, - - _getText: function (lastValue) { - switch (lastValue) { - case BI.DynamicDateCard.TYPE.YEAR: - return [{ - text: BI.i18nText("BI-Basic_Current_Day"), - value: BI.DynamicDateCard.OFFSET.CURRENT - }, { - text: BI.i18nText("BI-Basic_Year_Begin"), - value: BI.DynamicDateCard.OFFSET.BEGIN - }, { - text: BI.i18nText("BI-Basic_Year_End"), - value: BI.DynamicDateCard.OFFSET.END - }]; - case BI.DynamicDateCard.TYPE.QUARTER: - return [{ - text: BI.i18nText("BI-Basic_Current_Day"), - value: BI.DynamicDateCard.OFFSET.CURRENT - }, { - text: BI.i18nText("BI-Basic_Quarter_Begin"), - value: BI.DynamicDateCard.OFFSET.BEGIN - }, { - text: BI.i18nText("BI-Basic_Quarter_End"), - value: BI.DynamicDateCard.OFFSET.END - }]; - case BI.DynamicDateCard.TYPE.MONTH: - return [{ - text: BI.i18nText("BI-Basic_Current_Day"), - value: BI.DynamicDateCard.OFFSET.CURRENT - }, { - text: BI.i18nText("BI-Basic_Month_Begin"), - value: BI.DynamicDateCard.OFFSET.BEGIN - }, { - text: BI.i18nText("BI-Basic_Month_End"), - value: BI.DynamicDateCard.OFFSET.END - }]; - case BI.DynamicDateCard.TYPE.WEEK: - default: - return [{ - text: BI.i18nText("BI-Basic_Current_Day"), - value: BI.DynamicDateCard.OFFSET.CURRENT - }, { - text: BI.i18nText("BI-Basic_Week_Begin"), - value: BI.DynamicDateCard.OFFSET.BEGIN - }, { - text: BI.i18nText("BI-Basic_Week_End"), - value: BI.DynamicDateCard.OFFSET.END - }]; - } - }, - - _createValue: function (type, v) { - return { - dateType: type, - value: Math.abs(v), - offset: v > 0 ? 1 : 0 - }; - }, - - _digestDateTypeValue: function (value) { - var valueMap = {}; - switch (value.dateType) { - case BI.DynamicDateCard.TYPE.YEAR: - valueMap.year = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.QUARTER: - valueMap.quarter = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.MONTH: - valueMap.month = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.WEEK: - valueMap.week = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.DAY: - valueMap.day = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.WORK_DAY: - valueMap.workDay = (value.offset === 0 ? -value.value : +value.value); - break; - default: - break; - } - if (BI.isNull(value.dateType)) { - valueMap.position = this.position || BI.DynamicDateCard.OFFSET.CURRENT; - } - return valueMap; - }, - - setMinDate: function(minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - v = v || {}; - this.position = v.position || BI.DynamicDateCard.OFFSET.CURRENT; - var values = []; - var valuesItems = []; - if(BI.isNotNull(v.year)) { - values.push(BI.DynamicDateCard.TYPE.YEAR); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.YEAR, v.year)); - } - if(BI.isNotNull(v.quarter)) { - values.push(BI.DynamicDateCard.TYPE.QUARTER); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.QUARTER, v.quarter)); - } - if(BI.isNotNull(v.month)) { - values.push(BI.DynamicDateCard.TYPE.MONTH); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.MONTH, v.month)); - } - if(BI.isNotNull(v.week)) { - values.push(BI.DynamicDateCard.TYPE.WEEK); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.WEEK, v.week)); - } - if(BI.isNotNull(v.day)) { - values.push(BI.DynamicDateCard.TYPE.DAY); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.DAY, v.day)); - } - if(BI.isNotNull(v.workDay)) { - values.push(BI.DynamicDateCard.TYPE.WORK_DAY); - valuesItems.push(this._createValue(BI.DynamicDateCard.TYPE.WORK_DAY, v.workDay)); - } - this.checkgroup.setValue(values); - this.workDayBox.setSelected(BI.isNotNull(v.workDay)); - this.resultPane.populate(this._getParamJson(valuesItems, v.position)); - }, - - _getValue: function () { - var self = this; - var valueMap = {}; - var selectValues = this.checkgroup.getValue(); - var buttons = this.resultPane.getAllButtons(); - if(selectValues.length !== 0) { - BI.each(buttons, function (idx, button) { - var value = button.getValue(); - BI.extend(valueMap, self._digestDateTypeValue(value)); - }); - } - if(this.workDayBox.isSelected()) { - var value = buttons[0].getValue(); - valueMap.workDay = (value.offset === 0 ? -value.value : +value.value); - } - - return valueMap; - }, - - _getErrorText: function () { - var o = this.options; - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - - return BI.i18nText("BI-Basic_Date_Range_Error", - start.getFullYear(), - start.getMonth() + 1, - start.getDate(), - end.getFullYear(), - end.getMonth() + 1, - end.getDate() - ); - }, - - getValue: function () { - return this.checkValidation() ? this._getValue() : {}; - }, - - getInputValue: function () { - return this._getValue(); - }, - - checkValidation: function (show) { - var buttons = this.resultPane.getAllButtons(); - var errorText; - var invalid = BI.any(buttons, function (idx, button) { - return button.checkValidation && !button.checkValidation(); - }); - if (invalid) { - errorText = BI.i18nText("BI-Please_Input_Natural_Number"); - } else { - invalid = !this._checkDate(this._getValue()); - errorText = this._getErrorText(); - } - invalid && show && BI.Bubbles.show("dynamic-date-error", errorText, this.resultPane); - - return !invalid; - }, - -}); -BI.shortcut("bi.dynamic_date_card", BI.DynamicDateCard); - -BI.extend(BI.DynamicDateCard, { - TYPE: { - YEAR: 1, - QUARTER: 2, - MONTH: 3, - WEEK: 4, - DAY: 5, - WORK_DAY: 6 - }, - OFFSET: { - CURRENT: 1, - BEGIN: 2, - END: 3 - } - -}); \ No newline at end of file diff --git a/src/widget/dynamicdate/dynamicdate.combo.js b/src/widget/dynamicdate/dynamicdate.combo.js deleted file mode 100644 index 3219fb298..000000000 --- a/src/widget/dynamicdate/dynamicdate.combo.js +++ /dev/null @@ -1,333 +0,0 @@ -BI.DynamicDateCombo = BI.inherit(BI.Single, { - constants: { - popupHeight: 259, - popupWidth: 270, - comboAdjustHeight: 1, - border: 1, - iconWidth: 24 - }, - - props: { - baseCls: "bi-dynamic-date-combo", - height: 24, - minDate: "1900-01-01", - maxDate: "2099-12-31", - format: "", - allowEdit: true, - supportDynamic: true, - attributes: { - tabIndex: -1 - }, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false - }, - - _init: function () { - BI.DynamicDateCombo.superclass._init.apply(this, arguments); - }, - - render: function () { - var self = this, opts = this.options; - this.storeTriggerValue = ""; - var date = BI.getDate(); - this.storeValue = opts.value; - var border = opts.simple ? 1 : 2; - - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - cls: (opts.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - container: opts.container, - ref: function () { - self.combo = this; - }, - toggle: false, - isNeedAdjustHeight: opts.isNeedAdjustHeight, - isNeedAdjustWidth: opts.isNeedAdjustWidth, - destroyWhenHide: true, - el: { - type: "bi.horizontal_fill", - columnSize: [this.constants.iconWidth, "fill"], - height: BI.toPix(opts.height, border), - items: [{ - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-change-h-font", - width: BI.toPix(opts.height, border), - height: BI.toPix(opts.height, border), - ref: function () { - self.changeIcon = this; - } - }, - }, { - type: "bi.dynamic_date_trigger", - simple: opts.simple, - min: opts.minDate, - max: opts.maxDate, - format: opts.format, - allowEdit: opts.allowEdit, - watermark: opts.watermark, - iconWidth: BI.toPix(opts.height, border), - height: BI.toPix(opts.height, border), - value: opts.value, - ref: function () { - self.trigger = this; - }, - listeners: [{ - eventName: BI.DynamicDateTrigger.EVENT_KEY_DOWN, - action: function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } - self.fireEvent(BI.DynamicDateCombo.EVENT_KEY_DOWN, arguments); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_STOP, - action: function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_FOCUS, - action: function () { - self.storeTriggerValue = self.trigger.getKey(); - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - self.fireEvent(BI.DynamicDateCombo.EVENT_FOCUS); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_BLUR, - action: function () { - self.fireEvent(BI.DynamicDateCombo.EVENT_BLUR); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_ERROR, - action: function () { - self.storeValue = { - type: BI.DynamicDateCombo.Static, - value: { - year: date.getFullYear(), - month: date.getMonth() + 1 - } - }; - self.combo.element.addClass("error"); - self.fireEvent(BI.DynamicDateCombo.EVENT_ERROR); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_VALID, - action: function () { - self.storeValue = self.trigger.getValue(); - self.combo.element.removeClass("error"); - self.fireEvent(BI.DynamicDateCombo.EVENT_VALID); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateCombo.EVENT_CHANGE); - } - }, { - eventName: BI.DynamicDateTrigger.EVENT_CONFIRM, - action: function () { - var dateStore = self.storeTriggerValue; - var dateObj = self.trigger.getKey(); - if (self.combo.isViewVisible() || BI.isEqual(dateObj, dateStore)) { - return; - } - if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.trigger.getValue()); - } else if (BI.isEmptyString(dateObj)) { - self.storeValue = null; - self.trigger.setValue(); - } - self._checkDynamicValue(self.storeValue); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }] - }] - }, - adjustLength: this.constants.comboAdjustHeight, - popup: { - el: { - type: "bi.dynamic_date_popup", - width: opts.isNeedAdjustWidth ? opts.width : undefined, - supportDynamic: opts.supportDynamic, - behaviors: opts.behaviors, - min: opts.minDate, - max: opts.maxDate, - ref: function () { - self.popup = this; - }, - listeners: [{ - eventName: BI.DynamicDatePopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDatePopup.BUTTON_lABEL_EVENT_CHANGE, - action: function () { - var date = BI.getDate(); - self.setValue({ - type: BI.DynamicDateCombo.Static, - value: { - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - } - }); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDatePopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - var value = self.popup.getValue(); - if (self._checkValue(value)) { - self.setValue(value); - } - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDatePopup.EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDatePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, - action: function () { - self.fireEvent(BI.DynamicDateCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }] - }, - }, - // // DEC-4250 和复选下拉一样,点击triggerBtn不默认收起 - // hideChecker: function (e) { - // return self.triggerBtn.element.find(e.target).length === 0; - // }, - listeners: [{ - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.setMinDate(opts.minDate); - self.popup.setMaxDate(opts.maxDate); - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DynamicDateCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - }] - }; - }, - - created: function () { - this._checkDynamicValue(this.storeValue); - }, - - _checkDynamicValue: function (v) { - var o = this.options; - var type = null; - if (BI.isNotNull(v)) { - type = v.type; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.changeIcon.setVisible(true); - // this.comboWrapper.attr("items")[0].width = o.height - this.options.simple ? 1 : 2; - // this.comboWrapper.resize(); - break; - default: - // this.comboWrapper.attr("items")[0].width = 0; - // this.comboWrapper.resize(); - this.changeIcon.setVisible(false); - break; - } - }, - - _checkValue: function (v) { - var o = this.options; - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - var value = v.value || {}; - - return !BI.checkDateVoid(value.year, value.month, value.day, o.minDate, o.maxDate)[0]; - default: - return true; - } - }, - - _defaultState: function () { - - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.trigger.setMinDate(minDate); - this.popup && this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.trigger.setMaxDate(maxDate); - this.popup && this.popup.setMaxDate(maxDate); - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - this._checkDynamicValue(v); - }, - getValue: function () { - return this.storeValue; - }, - getKey: function () { - return this.trigger.getKey(); - }, - hidePopupView: function () { - this.combo.hideView(); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.DynamicDateCombo.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.DynamicDateCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicDateCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicDateCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.DynamicDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateCombo.EVENT_VALID = "EVENT_VALID"; -BI.DynamicDateCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicDateCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.DynamicDateCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; - -BI.shortcut("bi.dynamic_date_combo", BI.DynamicDateCombo); - -BI.extend(BI.DynamicDateCombo, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/dynamicdate/dynamicdate.param.item.js b/src/widget/dynamicdate/dynamicdate.param.item.js deleted file mode 100644 index ed8c4dea0..000000000 --- a/src/widget/dynamicdate/dynamicdate.param.item.js +++ /dev/null @@ -1,130 +0,0 @@ -BI.DynamicDateParamItem = BI.inherit(BI.Widget, { - - props: function() { - return { - baseCls: "bi-dynamic-date-param-item", - dateType: BI.DynamicDateCard.TYPE.YEAR, - validationChecker: function() { - return true; - }, - value: 0, - offset: 0, - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - } - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.htape", - items: [{ - el: { - type: "bi.sign_editor", - cls: "bi-border bi-focus-shadow bi-border-radius", - height: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 2), - validationChecker: function (v) { - return BI.isNaturalNumber(v); - }, - value: o.value, - ref: function () { - self.editor = this; - }, - errorText: function () { - return BI.i18nText("BI-Please_Input_Natural_Number"); - }, - allowBlank: false, - listeners: [{ - eventName: BI.SignEditor.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.DynamicDateParamItem.EVENT_CHANGE); - } - }, { - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateParamItem.EVENT_INPUT_CHANGE); - } - }] - }, - width: 60 - }, { - el: { - type: "bi.label", - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - text: this._getText() - }, - width: o.dateType === BI.DynamicDateCard.TYPE.WORK_DAY ? 60 : 20 - }, { - type: "bi.text_value_combo", - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - items: [{ - text: BI.i18nText("BI-Basic_Front"), - value: 0 - }, { - text: BI.i18nText("BI-Basic_Behind"), - value: 1 - }], - ref: function () { - self.offsetCombo = this; - }, - container: null, - value: o.offset, - listeners: [{ - eventName: BI.TextValueCombo.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateParamItem.EVENT_CHANGE); - } - }] - }] - }; - }, - - _getText: function () { - var text = ""; - switch (this.options.dateType) { - case BI.DynamicDateCard.TYPE.YEAR: - text = BI.i18nText("BI-Basic_Year"); - break; - case BI.DynamicDateCard.TYPE.QUARTER: - text = BI.i18nText("BI-Basic_Single_Quarter"); - break; - case BI.DynamicDateCard.TYPE.MONTH: - text = BI.i18nText("BI-Basic_Month"); - break; - case BI.DynamicDateCard.TYPE.WEEK: - text = BI.i18nText("BI-Basic_Week"); - break; - case BI.DynamicDateCard.TYPE.DAY: - text = BI.i18nText("BI-Basic_Day"); - break; - case BI.DynamicDateCard.TYPE.WORK_DAY: - default: - text = BI.i18nText("BI-Basic_Work_Day"); - break; - } - return text; - }, - - checkValidation: function () { - return BI.isNaturalNumber(this.editor.getValue()); - }, - - setValue: function (v) { - v = v || {}; - v.value = v.value || 0; - v.offset = v.offset || 0; - this.editor.setValue(v.value); - this.offsetCombo.setValue(v.offset); - }, - - getValue: function () { - return { - dateType: this.options.dateType, - value: this.editor.getValue(), - offset: this.offsetCombo.getValue()[0] - }; - } - -}); -BI.DynamicDateParamItem.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateParamItem.EVENT_INPUT_CHANGE = "EVENT_INPUT_CHANGE"; -BI.shortcut("bi.dynamic_date_param_item", BI.DynamicDateParamItem); diff --git a/src/widget/dynamicdate/dynamicdate.popup.js b/src/widget/dynamicdate/dynamicdate.popup.js deleted file mode 100644 index 1f0967e58..000000000 --- a/src/widget/dynamicdate/dynamicdate.popup.js +++ /dev/null @@ -1,257 +0,0 @@ -BI.DynamicDatePopup = BI.inherit(BI.Widget, { - constants: { - tabHeight: 40, - }, - - props: { - baseCls: "bi-dynamic-date-popup", - width: 272, - supportDynamic: true, - }, - - _init: function () { - BI.DynamicDatePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options, c = this.constants; - this.storeValue = {type: BI.DynamicDateCombo.Static}; - BI.createWidget({ - element: this, - type: "bi.vertical", - items: [{ - el: this._getTabJson() - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDatePopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - shadow: true, - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - text: BI.i18nText("BI-Multi_Date_Today"), - disabled: this._checkTodayValid(), - ref: function () { - self.todayButton = this; - }, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDatePopup.BUTTON_lABEL_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicDatePopup.BUTTON_OK_EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicDatePopup.BUTTON_OK_EVENT_CHANGE); - } - } - }] - }]], - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT - }, - }] - }); - this.setValue(opts.value); - }, - - _getTabJson: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - logic: { - dynamic: true - }, - ref: function () { - self.dateTab = this; - }, - tab: { - type: "bi.linear_segment", - invisible: !o.supportDynamic, - cls: "bi-split-bottom", - height: this.constants.tabHeight, - items: BI.createItems([{ - text: BI.i18nText("BI-Multi_Date_YMD"), - value: BI.DynamicDateCombo.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicDateCombo.Dynamic - }], { - textAlign: "center" - }) - }, - cardCreator: function (v) { - switch (v) { - case BI.DynamicDateCombo.Dynamic: - return { - type: "bi.dynamic_date_card", - cls: "dynamic-date-pane", - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self._setInnerValue(self.year, v); - } - }], - min: self.options.min, - max: self.options.max, - ref: function () { - self.dynamicPane = this; - } - }; - case BI.DynamicDateCombo.Static: - default: - return { - type: "bi.date_calendar_popup", - behaviors: o.behaviors, - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: BI.DateCalendarPopup.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDatePopup.EVENT_CHANGE); - } - }, { - eventName: BI.DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, - action: function () { - self.fireEvent(BI.DynamicDatePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }], - ref: function () { - self.ymd = this; - } - }; - } - }, - listeners: [{ - eventName: BI.Tab.EVENT_CHANGE, - action: function () { - var v = self.dateTab.getSelect(); - switch (v) { - case BI.DynamicDateCombo.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Dynamic: - default: - if(self.storeValue && self.storeValue.type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.setValue(self.storeValue.value); - }else{ - self.dynamicPane.setValue({ - year: 0 - }); - } - self._setInnerValue(); - break; - } - } - }] - }; - }, - - _setInnerValue: function () { - if (this.dateTab.getSelect() === BI.DynamicDateCombo.Static) { - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - this.todayButton.setEnable(!this._checkTodayValid()); - } else { - var date = BI.DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); - date = BI.print(date, "%Y-%X-%d"); - this.todayButton.setValue(date); - this.todayButton.setEnable(false); - } - }, - - _checkValueValid: function (value) { - return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); - }, - - _checkTodayValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.ymd && this.ymd.setMinDate(minDate); - this.dynamicPane && this.dynamicPane.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.ymd && this.ymd.setMaxDate(maxDate); - this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - this.storeValue = v; - var self = this; - var type, value; - v = v || {}; - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Static: - default: - if (this._checkValueValid(value)) { - var date = BI.getDate(); - this.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - } else { - this.ymd.setValue(value); - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - } - this.todayButton.setEnable(!this._checkTodayValid()); - break; - } - }, - - getValue: function () { - return { - type: this.dateTab.getSelect(), - value: this.dateTab.getValue() - }; - } -}); -BI.DynamicDatePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDatePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DynamicDatePopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; -BI.DynamicDatePopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; -BI.DynamicDatePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.dynamic_date_popup", BI.DynamicDatePopup); \ No newline at end of file diff --git a/src/widget/dynamicdate/dynamicdate.trigger.js b/src/widget/dynamicdate/dynamicdate.trigger.js deleted file mode 100644 index 9ecaa3cd9..000000000 --- a/src/widget/dynamicdate/dynamicdate.trigger.js +++ /dev/null @@ -1,341 +0,0 @@ -BI.DynamicDateTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - vgap: 2, - yearLength: 4, - yearMonthLength: 6, - yearFullMonthLength: 7, - compareFormat: "%Y-%X-%d", - iconWidth: 24 - }, - - props: () => ({ - extraCls: "bi-date-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - iconWidth: 24, - format: "", // 显示的日期格式化方式 - allowEdit: true, // 是否允许编辑 - watermark: BI.i18nText("BI-Basic_Unrestricted"), - }), - - _init: function () { - BI.DynamicDateTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.storeTriggerValue = ""; - this.editor = BI.createWidget({ - type: "bi.sign_editor", - simple: o.simple, - height: o.height, - validationChecker: function (v) { - var formatStr = self._getStandardDateStr(v); - var date = formatStr.match(/\d+/g); - !BI.isKey(o.format) && self._autoAppend(v, date); - return self._dateCheck(formatStr) && BI.checkDateLegal(formatStr) && self._checkVoid({ - year: date[0] | 0, - month: date[1] | 0, - day: date[2] | 0 - }); - }, - quitChecker: function () { - return false; - }, - hgap: c.hgap, - vgap: c.vgap, - allowBlank: true, - watermark: o.watermark, - errorText: function (v) { - var str = ""; - if (!BI.isKey(o.format)) { - if (!self._dateCheck(v)) { - str = self.editor.isEditing() ? BI.i18nText("BI-Date_Trigger_Error_Text") : BI.i18nText("BI-Year_Trigger_Invalid_Text"); - } else { - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - str = BI.i18nText("BI-Basic_Date_Range_Error", - start.getFullYear(), - start.getMonth() + 1, - start.getDate(), - end.getFullYear(), - end.getMonth() + 1, - end.getDate() - ); - } - } - - return str; - }, - title: BI.bind(this._getTitle, this) - }); - this.editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.storeTriggerValue = self.getKey(); - self.fireEvent(BI.DynamicDateTrigger.EVENT_FOCUS); - }); - this.editor.on(BI.SignEditor.EVENT_BLUR, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_BLUR); - }); - this.editor.on(BI.SignEditor.EVENT_STOP, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_STOP); - }); - this.editor.on(BI.SignEditor.EVENT_VALID, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_VALID); - }); - this.editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_ERROR); - }); - this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { - var value = self.editor.getValue(); - if (BI.isNotNull(value)) { - self.editor.setState(value); - } - - if (BI.isNotEmptyString(value) && !BI.isEqual(self.storeTriggerValue, self.getKey())) { - var formatStr = self._getStandardDateStr(value); - var date = formatStr.match(/\d+/g); - self.storeValue = { - type: BI.DynamicDateCombo.Static, - value: { - year: date[0] | 0, - month: date[1] | 0, - day: date[2] | 0 - } - }; - } - self.fireEvent(BI.DynamicDateTrigger.EVENT_CONFIRM); - }); - this.editor.on(BI.SignEditor.EVENT_SPACE, function () { - if (self.editor.isValid()) { - self.editor.blur(); - } - }); - this.editor.on(BI.SignEditor.EVENT_START, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_START); - }); - this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { - self.fireEvent(BI.DynamicDateTrigger.EVENT_CHANGE); - }); - BI.createWidget({ - type: "bi.htape", - element: this, - columnSize: ["", this._const.iconWidth], - items: [{ - el: this.editor - }, { - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-font", - width: this._const.iconWidth - }, - width: this._const.iconWidth - }] - }); - !o.allowEdit && BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.text", - title: BI.bind(this._getTitle, this) - }, - left: 0, - right: o.iconWidth, - top: 0, - bottom: 0 - }] - }); - this.setValue(o.value); - }, - - _getTitle: function () { - var storeValue = this.storeValue || {}; - if (BI.isEmptyObject(storeValue)) { - return this.options.watermark; - } - var type = storeValue.type || BI.DynamicDateCombo.Static; - var value = storeValue.value; - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - var date = BI.getDate(); - date = BI.DynamicDateHelper.getCalculation(value); - var dateStr = BI.print(date, this._getFormatString()); - return BI.isEmptyString(text) ? dateStr : (text + ":" + dateStr); - case BI.DynamicDateCombo.Static: - default: - if (BI.isNull(value) || BI.isNull(value.day)) { - return ""; - } - return BI.print(BI.getDate(value.year, (value.month - 1), value.day), this._getFormatString()); - } - }, - - _getStandardDateStr: function (v) { - var c = this._const; - var result = [0, 1, 2]; - var formatArray = this._getFormatString().match(/%./g); - BI.each(formatArray, function (idx, v) { - switch (v) { - case "%Y": - case "%y": - result[0] = idx; - break; - case "%X": - case "%x": - result[1] = idx; - break; - case "%d": - case "%e": - default: - result[2] = idx; - break; - } - }); - // 这边不能直接用\d+去切日期, 因为format格式可能是20190607这样的没有分割符的 = = - // 先看一下是否是合法的, 如果合法就变成标准格式的走原来的流程, 不合法不关心 - var date = BI.parseDateTime(v, this._getFormatString()); - if(BI.print(date, this._getFormatString()) === v) { - v = BI.print(date, c.compareFormat); - result = [0, 1, 2]; - } - var dateArray = v.match(/\d+/g); - var newArray = []; - BI.each(dateArray, function (idx) { - newArray[idx] = dateArray[result[idx]]; - }); - // 这边之所以不直接返回join结果是因为年的格式可能只有2位,所以需要format一下 - if(newArray.length === result.length && newArray[0].length === 2) { - return BI.print(BI.parseDateTime(newArray.join("-"), c.compareFormat), c.compareFormat); - } - // 这边format成-20-也没关系, 反正都是不合法的 - return newArray.join("-"); - }, - - _getFormatString: function () { - return this.options.format || this._const.compareFormat; - }, - - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date; - }, - _checkVoid: function (obj) { - return !BI.checkDateVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0]; - }, - _autoAppend: function (v, dateObj) { - if (BI.isNotNull(dateObj) && BI.checkDateLegal(v)) { - switch (v.length) { - case this._const.yearLength: - if (this._yearCheck(v)) { - this.editor.setValue(v + "-"); - } - break; - case this._const.yearMonthLength: - case this._const.yearFullMonthLength: - var splitMonth = v.split("-")[1]; - if ((BI.isNotNull(splitMonth) && splitMonth.length === 2) || this._monthCheck(v)) { - this.editor.setValue(v + "-"); - } - break; - } - } - }, - - _yearCheck: function (v) { - var date = BI.print(BI.parseDateTime(v, this._getFormatString()), this._const.compareFormat); - return BI.print(BI.parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; - }, - - _monthCheck: function (v) { - var date = BI.parseDateTime(v, this._getFormatString()); - var dateStr = BI.print(date, this._const.compareFormat); - return (date.getMonth() >= 0 && (BI.print(BI.parseDateTime(v, "%Y-%X"), "%Y-%X") === v || - BI.print(BI.parseDateTime(v, "%Y-%x"), "%Y-%x") === v)) && dateStr >= this.options.min && dateStr <= this.options.max; - }, - - _setInnerValue: function (date) { - var dateStr = BI.print(date, this._getFormatString()); - this.editor.setState(dateStr); - this.editor.setValue(dateStr); - }, - - _getText: function (obj) { - return BI.DynamicDateHelper.getDescription(obj); - }, - - setValue: function (v) { - var type, value, self = this; - var date = BI.getDate(); - this.storeValue = v; - if (BI.isNotNull(v)) { - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - date = BI.DynamicDateHelper.getCalculation(value); - this._setInnerValue(date, text); - break; - case BI.DynamicDateCombo.Static: - default: - if (BI.isNull(value) || BI.isNull(value.day)) { - this.editor.setState(""); - this.editor.setValue(""); - } else { - var dateStr = BI.print(BI.getDate(value.year, (value.month - 1), value.day), this._getFormatString()); - this.editor.setState(dateStr); - this.editor.setValue(dateStr); - } - break; - } - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - getKey: function () { - return this.editor.getValue(); - }, - getValue: function () { - return this.storeValue; - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); - -BI.DynamicDateTrigger.EVENT_BLUR = "EVENT_BLUR"; -BI.DynamicDateTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicDateTrigger.EVENT_START = "EVENT_START"; -BI.DynamicDateTrigger.EVENT_STOP = "EVENT_STOP"; -BI.DynamicDateTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicDateTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateTrigger.EVENT_VALID = "EVENT_VALID"; -BI.DynamicDateTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicDateTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.DynamicDateTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.shortcut("bi.dynamic_date_trigger", BI.DynamicDateTrigger); diff --git a/src/widget/dynamicdatetime/dynamicdatetime.combo.js b/src/widget/dynamicdatetime/dynamicdatetime.combo.js deleted file mode 100644 index 54a445415..000000000 --- a/src/widget/dynamicdatetime/dynamicdatetime.combo.js +++ /dev/null @@ -1,341 +0,0 @@ -BI.DynamicDateTimeCombo = BI.inherit(BI.Single, { - constants: { - popupHeight: 259, - popupWidth: 270, - comboAdjustHeight: 1, - border: 1, - iconWidth: 24 - }, - - props: { - baseCls: "bi-dynamic-date--time-combo", - height: 24, - minDate: "1900-01-01", - maxDate: "2099-12-31", - format: "", - allowEdit: true, - supportDynamic: true, - attributes: { - tabIndex: -1 - }, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false - }, - - _init: function () { - BI.DynamicDateTimeCombo.superclass._init.apply(this, arguments); - }, - - render: function () { - var self = this, opts = this.options; - this.storeTriggerValue = ""; - var date = BI.getDate(); - this.storeValue = opts.value; - var border = opts.simple ? 1 : 2; - - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - cls: (opts.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - destroyWhenHide: true, - container: opts.container, - ref: function () { - self.combo = this; - }, - toggle: false, - isNeedAdjustHeight: opts.isNeedAdjustHeight, - isNeedAdjustWidth: opts.isNeedAdjustWidth, - el: { - type: "bi.horizontal_fill", - columnSize: [this.constants.iconWidth, "fill"], - height: BI.toPix(opts.height, border), - items: [{ - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-change-h-font", - width: this.constants.iconWidth, - height: BI.toPix(opts.height, border), - ref: function () { - self.changeIcon = this; - } - }, - }, { - type: "bi.dynamic_date_time_trigger", - simple: opts.simple, - min: opts.minDate, - max: opts.maxDate, - allowEdit: opts.allowEdit, - watermark: opts.watermark, - format: opts.format, - iconWidth: this.constants.iconWidth, - height: BI.toPix(opts.height, border), - value: opts.value, - ref: function () { - self.trigger = this; - }, - listeners: [{ - eventName: BI.DynamicDateTimeTrigger.EVENT_KEY_DOWN, - action: function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_KEY_DOWN, arguments); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_STOP, - action: function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_TRIGGER_CLICK, - action: function () { - self.combo.toggle(); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_FOCUS, - action: function () { - self.storeTriggerValue = self.trigger.getKey(); - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_FOCUS); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_BLUR, - action: function () { - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_BLUR); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_ERROR, - action: function () { - self.storeValue = { - type: BI.DynamicDateTimeCombo.Static, - value: { - year: date.getFullYear(), - month: date.getMonth() + 1 - } - }; - self.combo.element.addClass("error"); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_ERROR); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_VALID, - action: function () { - self.storeValue = self.trigger.getValue(); - self.combo.element.removeClass("error"); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_VALID); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CHANGE); - } - }, { - eventName: BI.DynamicDateTimeTrigger.EVENT_CONFIRM, - action: function () { - var dateStore = self.storeTriggerValue; - var dateObj = self.trigger.getKey(); - if (self.combo.isViewVisible() || BI.isEqual(dateObj, dateStore)) { - return; - } - if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.trigger.getValue()); - } else if (BI.isEmptyString(dateObj)) { - self.storeValue = null; - self.trigger.setValue(); - } - self._checkDynamicValue(self.storeValue); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CONFIRM); - } - }] - }] - }, - adjustLength: this.constants.comboAdjustHeight, - popup: { - el: { - type: "bi.dynamic_date_time_popup", - width: opts.isNeedAdjustWidth ? opts.width : undefined, - supportDynamic: opts.supportDynamic, - behaviors: opts.behaviors, - min: opts.minDate, - max: opts.maxDate, - ref: function () { - self.popup = this; - }, - listeners: [{ - eventName: BI.DynamicDateTimePopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDateTimePopup.BUTTON_lABEL_EVENT_CHANGE, - action: function () { - var date = BI.getDate(); - self.setValue({ - type: BI.DynamicDateTimeCombo.Static, - value: { - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate(), - hour: 0, - minute: 0, - second: 0 - } - }); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - var value = self.popup.getValue(); - if (self._checkValue(value)) { - self.setValue(value); - } - self.combo.hideView(); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDateTimePopup.EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicDateTimePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, - action: function () { - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }] - }, - }, - listeners: [{ - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.setMinDate(opts.minDate); - self.popup.setMaxDate(opts.maxDate); - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DynamicDateTimeCombo.EVENT_BEFORE_POPUPVIEW); - } - }], - // // DEC-4250 和复选下拉一样,点击不收起 - // hideChecker: function (e) { - // return self.triggerBtn.element.find(e.target).length === 0; - // } - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - }] - }; - }, - - created: function () { - this._checkDynamicValue(this.storeValue); - }, - - _checkDynamicValue: function (v) { - var o = this.options; - var type = null; - if (BI.isNotNull(v)) { - type = v.type; - } - switch (type) { - case BI.DynamicDateTimeCombo.Dynamic: - this.changeIcon.setVisible(true); - // this.comboWrapper.attr("items")[0].width = o.height - (this.options.simple ? 1 : 2); - // this.comboWrapper.resize(); - break; - default: - // this.comboWrapper.attr("items")[0].width = 0; - // this.comboWrapper.resize(); - this.changeIcon.setVisible(false); - break; - } - }, - - _checkValue: function (v) { - var o = this.options; - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - var value = v.value || {}; - - return !BI.checkDateVoid(value.year, value.month, value.day, o.minDate, o.maxDate)[0]; - default: - return true; - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.trigger.setMinDate(minDate); - this.popup && this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.trigger.setMaxDate(maxDate); - this.popup && this.popup.setMaxDate(maxDate); - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - this._checkDynamicValue(v); - }, - getValue: function () { - return this.storeValue; - }, - getKey: function () { - return this.trigger.getKey(); - }, - hidePopupView: function () { - this.combo.hideView(); - }, - - isValid: function () { - return this.trigger.isValid(); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.DynamicDateTimeCombo.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.DynamicDateTimeCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicDateTimeCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicDateTimeCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.DynamicDateTimeCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateTimeCombo.EVENT_VALID = "EVENT_VALID"; -BI.DynamicDateTimeCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicDateTimeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.DynamicDateTimeCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; - -BI.shortcut("bi.dynamic_date_time_combo", BI.DynamicDateTimeCombo); - -BI.extend(BI.DynamicDateTimeCombo, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/dynamicdatetime/dynamicdatetime.popup.js b/src/widget/dynamicdatetime/dynamicdatetime.popup.js deleted file mode 100644 index e7858ba35..000000000 --- a/src/widget/dynamicdatetime/dynamicdatetime.popup.js +++ /dev/null @@ -1,271 +0,0 @@ -BI.DynamicDateTimePopup = BI.inherit(BI.Widget, { - constants: { - tabHeight: 40, - buttonHeight: 24 - }, - - props: { - baseCls: "bi-dynamic-date-time-popup", - width: 272, - supportDynamic: true, - }, - - _init: function () { - BI.DynamicDateTimePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options, c = this.constants; - this.storeValue = {type: BI.DynamicDateCombo.Static}; - BI.createWidget({ - element: this, - type: "bi.vertical", - items: [{ - el: this._getTabJson() - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateTimePopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Multi_Date_Today"), - disabled: this._checkTodayValid(), - ref: function () { - self.todayButton = this; - }, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicDateTimePopup.BUTTON_lABEL_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE) - } - } - }] - }]], - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT - } - }] - }); - this.setValue(opts.value); - }, - - _getTabJson: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - logic: { - dynamic: true - }, - ref: function () { - self.dateTab = this; - }, - tab: { - type: "bi.linear_segment", - invisible: !o.supportDynamic, - cls: "bi-split-bottom", - height: this.constants.tabHeight, - items: BI.createItems([{ - text: BI.i18nText("BI-Multi_Date_YMD"), - value: BI.DynamicDateCombo.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicDateCombo.Dynamic - }], { - textAlign: "center" - }) - }, - cardCreator: function (v) { - switch (v) { - case BI.DynamicDateCombo.Dynamic: - return { - type: "bi.dynamic_date_card", - cls: "dynamic-date-pane", - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self._setInnerValue(self.year, v); - } - }], - ref: function () { - self.dynamicPane = this; - }, - min: self.options.min, - max: self.options.max, - }; - case BI.DynamicDateCombo.Static: - default: - return { - type: "bi.vertical", - items: [{ - type: "bi.date_calendar_popup", - behaviors: o.behaviors, - min: self.options.min, - max: self.options.max, - ref: function () { - self.ymd = this; - }, - listeners: [{ - eventName: BI.DateCalendarPopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, - action: function () { - self.fireEvent(BI.DynamicDateTimePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }], - }, { - el: { - type: "bi.dynamic_date_time_select", - cls: "bi-split-top", - ref: function () { - self.timeSelect = this; - }, - height: 40 - } - }] - }; - } - }, - listeners: [{ - eventName: BI.Tab.EVENT_CHANGE, - action: function () { - var v = self.dateTab.getSelect(); - switch (v) { - case BI.DynamicDateCombo.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - self.timeSelect.setValue(); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Dynamic: - default: - if(self.storeValue && self.storeValue.type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.setValue(self.storeValue.value); - }else{ - self.dynamicPane.setValue({ - year: 0 - }); - } - self._setInnerValue(); - break; - } - } - }] - }; - }, - - _setInnerValue: function () { - if (this.dateTab.getSelect() === BI.DynamicDateCombo.Static) { - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - this.todayButton.setEnable(!this._checkTodayValid()); - } else { - var date = BI.DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); - date = BI.print(date, "%Y-%X-%d"); - this.todayButton.setValue(date); - this.todayButton.setEnable(false); - } - }, - - _checkValueValid: function (value) { - return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); - }, - - _checkTodayValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.ymd.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.ymd.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - this.storeValue = v; - var self = this; - var type, value; - v = v || {}; - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Static: - default: - if (this._checkValueValid(value)) { - var date = BI.getDate(); - this.ymd.setValue({ - year: date.getFullYear(), - month: date.getMonth() + 1, - day: date.getDate() - }); - this.timeSelect.setValue(); - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - } else { - this.ymd.setValue(value); - this.timeSelect.setValue({ - hour: value.hour, - minute: value.minute, - second: value.second - }); - this.todayButton.setValue(BI.i18nText("BI-Multi_Date_Today")); - } - this.todayButton.setEnable(!this._checkTodayValid()); - break; - } - }, - - getValue: function () { - var type = this.dateTab.getSelect(); - return { - type: type, - value: type === BI.DynamicDateTimeCombo.Static ? BI.extend(this.ymd.getValue(), this.timeSelect.getValue()) : this.dynamicPane.getValue() - }; - } -}); -BI.DynamicDateTimePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateTimePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DynamicDateTimePopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; -BI.DynamicDateTimePopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; -BI.DynamicDateTimePopup.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.dynamic_date_time_popup", BI.DynamicDateTimePopup); \ No newline at end of file diff --git a/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js b/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js deleted file mode 100644 index 0599042cd..000000000 --- a/src/widget/dynamicdatetime/dynamicdatetime.timeselect.js +++ /dev/null @@ -1,217 +0,0 @@ -BI.DynamicDateTimeSelect = BI.inherit(BI.Widget, { - - props: function () { - return { - baseCls: "bi-date-time-select", - editorHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }; - }, - - render: function () { - var self = this; - var o = this.options; - - return { - type: "bi.center_adapt", - items: [{ - type: "bi.vertical_adapt", - items: [{ - el: { - type: "bi.number_editor", - ref: function () { - self.hour = this; - }, - validationChecker: function (v) { - return BI.isNaturalNumber(v) && BI.parseInt(v) < 24; - }, - errorText: function (v) { - if(BI.isNumeric(v)) { - return BI.i18nText("BI-Basic_Input_From_To_Number", "\"00-23\""); - } - return BI.i18nText("BI-Numerical_Interval_Input_Data"); - }, - listeners: [{ - eventName: BI.SignEditor.EVENT_CONFIRM, - action: function () { - var value = this.getValue(); - self._checkHour(value); - this.setValue(self._formatValueToDoubleDigit(value)); - self.fireEvent(BI.DynamicDateTimeSelect.EVENT_CONFIRM); - } - }, { - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - var value = self._autoSwitch(this.getValue(), BI.DynamicDateTimeSelect.HOUR); - this.setValue(value); - } - }], - width: 60, - height: o.editorHeight, - } - }, { - type: "bi.label", - text: ":", - width: 20 - }, { - type: "bi.number_editor", - ref: function () { - self.minute = this; - }, - validationChecker: function (v) { - return BI.isNaturalNumber(v) && BI.parseInt(v) < 60; - }, - errorText: function (v) { - if(BI.isNumeric(v)) { - return BI.i18nText("BI-Basic_Input_From_To_Number", "\"00-59\""); - } - return BI.i18nText("BI-Numerical_Interval_Input_Data"); - }, - listeners: [{ - eventName: BI.SignEditor.EVENT_CONFIRM, - action: function () { - var value = this.getValue(); - self._checkMinute(value); - this.setValue(self._formatValueToDoubleDigit(value), BI.DynamicDateTimeSelect.MINUTE); - self.fireEvent(BI.DynamicDateTimeSelect.EVENT_CONFIRM); - } - }, { - eventName: BI.SignEditor.EVENT_CHANGE, - action: function () { - var value = self._autoSwitch(this.getValue(), BI.DynamicDateTimeSelect.MINUTE); - this.setValue(value); - } - }], - width: 60, - height: o.editorHeight, - }, { - type: "bi.label", - text: ":", - width: 20 - }, { - type: "bi.number_editor", - ref: function () { - self.second = this; - }, - validationChecker: function (v) { - return BI.isNaturalNumber(v) && BI.parseInt(v) < 60; - }, - errorText: function (v) { - if(BI.isNumeric(v)) { - return BI.i18nText("BI-Basic_Input_From_To_Number", "\"00-59\""); - } - return BI.i18nText("BI-Numerical_Interval_Input_Data"); - }, - listeners: [{ - eventName: BI.SignEditor.EVENT_CONFIRM, - action: function () { - var value = this.getValue(); - self._checkSecond(value); - this.setValue(self._formatValueToDoubleDigit(value)); - self.fireEvent(BI.DynamicDateTimeSelect.EVENT_CONFIRM); - } - }], - width: 60, - height: o.editorHeight, - }] - }] - }; - }, - - _checkBorder: function (v) { - v = v || {}; - this._checkHour(v.hour); - this._checkMinute(v.minute); - this._checkSecond(v.second); - }, - - _checkHour: function (value) { - this.hour.setDownEnable(BI.parseInt(value) > 0); - this.hour.setUpEnable(BI.parseInt(value) < 23); - }, - - _checkMinute: function (value) { - this.minute.setDownEnable(BI.parseInt(value) > 0); - this.minute.setUpEnable(BI.parseInt(value) < 59); - }, - - _checkSecond: function (value) { - this.second.setDownEnable(BI.parseInt(value) > 0); - this.second.setUpEnable(BI.parseInt(value) < 59); - }, - - _autoSwitch: function (v, type) { - var limit = 0; - var value = v + ""; - switch (type) { - case BI.DynamicDateTimeSelect.HOUR: - limit = 2; - break; - case BI.DynamicDateTimeSelect.MINUTE: - limit = 5; - break; - default: - break; - } - if(value.length === 1 && BI.parseInt(value) > limit) { - value = "0" + value; - } - if (value.length === 2) { - switch (type) { - case BI.DynamicDateTimeSelect.HOUR: - this.hour.isEditing() && this.minute.focus(); - break; - case BI.DynamicDateTimeSelect.MINUTE: - this.minute.isEditing() && this.second.focus(); - break; - case BI.DynamicDateTimeSelect.SECOND: - default: - break; - } - } - return value; - }, - - _formatValueToDoubleDigit: function (v) { - if(BI.isNull(v) || BI.isEmptyString(v)) { - v = 0; - } - var value = BI.parseInt(v); - if(value < 10) { - value = "0" + value; - } - return value; - }, - - _assertValue: function (v) { - v = v || {}; - v.hour = this._formatValueToDoubleDigit(v.hour) || "00"; - v.minute = this._formatValueToDoubleDigit(v.minute) || "00"; - v.second = this._formatValueToDoubleDigit(v.second) || "00"; - return v; - }, - - getValue: function () { - return { - hour: BI.parseInt(this.hour.getValue()), - minute: BI.parseInt(this.minute.getValue()), - second: BI.parseInt(this.second.getValue()) - }; - }, - - setValue: function (v) { - v = this._assertValue(v); - this.hour.setValue(v.hour); - this.minute.setValue(v.minute); - this.second.setValue(v.second); - this._checkBorder(v); - } - -}); -BI.DynamicDateTimeSelect.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.dynamic_date_time_select", BI.DynamicDateTimeSelect); - -BI.extend(BI.DynamicDateTimeSelect, { - HOUR: 1, - MINUTE: 2, - SECOND: 3 -}); \ No newline at end of file diff --git a/src/widget/dynamicdatetime/dynamicdatetime.trigger.js b/src/widget/dynamicdatetime/dynamicdatetime.trigger.js deleted file mode 100644 index 86a942fe7..000000000 --- a/src/widget/dynamicdatetime/dynamicdatetime.trigger.js +++ /dev/null @@ -1,413 +0,0 @@ -BI.DynamicDateTimeTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - vgap: 2, - yearLength: 4, - yearMonthLength: 6, - yearFullMonthLength: 7, - compareFormat: "%Y-%X-%d %H:%M:%S", - iconWidth: 24 - }, - - props: () => ({ - extraCls: "bi-date-time-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - iconWidth: 24, - format: "", // 显示的日期格式化方式 - allowEdit: true, // 是否允许编辑 - watermark: BI.i18nText("BI-Basic_Unrestricted"), - }), - - _init: function () { - BI.DynamicDateTimeTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.storeTriggerValue = ""; - this.editor = BI.createWidget({ - type: "bi.sign_editor", - simple: o.simple, - height: o.height, - validationChecker: function (v) { - var formatStr = self._getStandardDateStr(v); - var date = formatStr.match(/\d+/g); - !BI.isKey(o.format) && self._autoAppend(v, date); - return self._dateCheck(formatStr) && BI.checkDateLegal(formatStr) && self._checkVoid({ - year: date[0] | 0, - month: date[1] | 0, - day: date[2] | 0 - }); - }, - quitChecker: function () { - return false; - }, - hgap: c.hgap, - vgap: c.vgap, - allowBlank: true, - watermark: o.watermark, - errorText: function (v) { - var str = ""; - if (!BI.isKey(o.format)) { - if (!self._dateCheck(v)) { - str = self.editor.isEditing() ? BI.i18nText("BI-Date_Trigger_Error_Text") : BI.i18nText("BI-Year_Trigger_Invalid_Text"); - } else { - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - str = BI.i18nText("BI-Basic_Date_Range_Error", - start.getFullYear(), - start.getMonth() + 1, - start.getDate(), - end.getFullYear(), - end.getMonth() + 1, - end.getDate() - ); - } - } - - return str; - }, - title: BI.bind(this._getTitle, this) - }); - this.editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.storeTriggerValue = self.getKey(); - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_FOCUS); - }); - this.editor.on(BI.SignEditor.EVENT_BLUR, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_BLUR); - }); - this.editor.on(BI.SignEditor.EVENT_STOP, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_STOP); - }); - this.editor.on(BI.SignEditor.EVENT_VALID, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_VALID); - }); - this.editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_ERROR); - }); - this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { - var value = self.editor.getValue(); - if (BI.isNotNull(value)) { - self.editor.setState(value); - } - - if (BI.isNotEmptyString(value) && !BI.isEqual(self.storeTriggerValue, self.getKey())) { - var formatStr = self._getStandardDateStr(value); - var date = formatStr.match(/\d+/g); - self.storeValue = { - type: BI.DynamicDateCombo.Static, - value: { - year: date[0] | 0, - month: date[1] | 0, - day: date[2] | 0, - hour: date[3] | 0, - minute: date[4] | 0, - second: date[5] | 0 - } - }; - } - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_CONFIRM); - }); - this.editor.on(BI.SignEditor.EVENT_START, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_START); - }); - this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { - self.fireEvent(BI.DynamicDateTimeTrigger.EVENT_CHANGE); - }); - BI.createWidget({ - type: "bi.htape", - element: this, - columnSize: ["", this._const.iconWidth], - items: [{ - el: this.editor - }, { - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-font", - }, - width: o.iconWidth - }] - }); - - !o.allowEdit && BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.text", - title: BI.bind(this._getTitle, this) - }, - left: 0, - right: o.iconWidth, - top: 0, - bottom: 0 - }] - }); - this.setValue(o.value); - }, - - _getTitle: function () { - var o = this.options; - var storeValue = this.storeValue || {}; - if (BI.isEmptyObject(storeValue)) { - return o.watermark; - } - var type = storeValue.type || BI.DynamicDateCombo.Static; - var value = storeValue.value; - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - var date = BI.DynamicDateHelper.getCalculation(value); - var dateStr = BI.print(date, this._getFormatString()); - return BI.isEmptyString(text) ? dateStr : (text + ":" + dateStr); - case BI.DynamicDateCombo.Static: - default: - if (BI.isNull(value) || BI.isNull(value.day)) { - return ""; - } - return BI.print(BI.getDate(value.year, (value.month - 1), value.day, value.hour || 0, value.minute || 0, - value.second || 0), this._getFormatString()); - } - }, - - _getStandardDateStr: function (v) { - var c = this._const; - var result = []; - var hasSecond = false; - var formatArray = this._getFormatString().match(/%./g); - BI.each(formatArray, function (idx, v) { - switch (v) { - case "%Y": - case "%y": - result[0] = idx; - break; - case "%X": - case "%x": - result[1] = idx; - break; - case "%d": - case "%e": - result[2] = idx; - break; - case "%S": - hasSecond = true; - break; - default: - break; - } - }); - // 这边不能直接用\d+去切日期, 因为format格式可能是20190607这样的没有分割符的 = = - // 先看一下是否是合法的, 如果合法就变成标准格式的走原来的流程, 不合法不关心 - var date = BI.parseDateTime(v, this._getFormatString()); - if (BI.print(date, this._getFormatString()) === v) { - v = BI.print(date, c.compareFormat); - result = [0, 1, 2]; - } - var dateArray = v.match(/\d+/g) || []; - var newArray = []; - // 处理乱序的年月日 - BI.each(dateArray.slice(0, 3), function (idx) { - newArray[idx] = dateArray[result[idx]]; - }); - // 拼接时分秒和pm - var suffixArray = dateArray.slice(3); - // 时分秒补0 - BI.each(suffixArray, function (idx, v) { - BI.isNumeric(v) && v.length === 1 && (suffixArray[idx] = "0" + v); - }); - // hh:mm - if (suffixArray.length === 2 && !hasSecond) { - suffixArray.push("00"); - } - var suffixString = suffixArray.join(":"); - var dateString = newArray.slice(0, 3).join("-"); - if (BI.isNotEmptyString(suffixString)) { - dateString += " " + suffixString; - } - return dateString; - }, - - _getFormatString: function () { - return this.options.format || this._const.compareFormat; - }, - - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%x-%d %H:%M:%S"), "%Y-%x-%d %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%x-%e %H:%M:%S"), "%Y-%x-%e %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%e %H:%M:%S"), "%Y-%X-%e %H:%M:%S") === date || - - BI.print(BI.parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date; - }, - _checkVoid: function (obj) { - return !BI.checkDateVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0]; - }, - _autoAppend: function (v, dateObj) { - if (BI.isNotNull(dateObj) && BI.checkDateLegal(v)) { - switch (v.length) { - case this._const.yearLength: - if (this._yearCheck(v)) { - this.editor.setValue(v + "-"); - } - break; - case this._const.yearMonthLength: - case this._const.yearFullMonthLength: - var splitMonth = v.split("-")[1]; - if ((BI.isNotNull(splitMonth) && splitMonth.length === 2) || this._monthCheck(v)) { - this.editor.setValue(v + "-"); - } - break; - } - } - }, - - _yearCheck: function (v) { - var date = BI.print(BI.parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); - return BI.print(BI.parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; - }, - - _monthCheck: function (v) { - var date = BI.parseDateTime(v, "%Y-%X-%d"); - var dateStr = BI.print(date, "%Y-%X-%d"); - return (date.getMonth() > 0 && (BI.print(BI.parseDateTime(v, "%Y-%X"), "%Y-%X") === v || - BI.print(BI.parseDateTime(v, "%Y-%x"), "%Y-%x") === v)) && dateStr >= this.options.min && dateStr <= this.options.max; - }, - - _setInnerValue: function (date) { - var dateStr = BI.print(date, this._getFormatString()); - this.editor.setState(dateStr); - this.editor.setValue(dateStr); - }, - - _getText: function (obj) { - var value = ""; - var endText = ""; - if (BI.isNotNull(obj.year)) { - if (BI.parseInt(obj.year) !== 0) { - value += Math.abs(obj.year) + BI.i18nText("BI-Basic_Year") + (obj.year < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Year"), obj.position); - } - if (BI.isNotNull(obj.quarter)) { - if (BI.parseInt(obj.quarter) !== 0) { - value += Math.abs(obj.quarter) + BI.i18nText("BI-Basic_Single_Quarter") + (obj.quarter < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Single_Quarter"), obj.position); - } - if (BI.isNotNull(obj.month)) { - if (BI.parseInt(obj.month) !== 0) { - value += Math.abs(obj.month) + BI.i18nText("BI-Basic_Month") + (obj.month < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Month"), obj.position); - } - if (BI.isNotNull(obj.week)) { - if (BI.parseInt(obj.week) !== 0) { - value += Math.abs(obj.week) + BI.i18nText("BI-Basic_Week") + (obj.week < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = getPositionText(BI.i18nText("BI-Basic_Week"), obj.position); - } - if (BI.isNotNull(obj.day)) { - if (BI.parseInt(obj.day) !== 0) { - value += Math.abs(obj.day) + BI.i18nText("BI-Basic_Day") + (obj.day < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - endText = BI.size(obj) === 1 ? getPositionText(BI.i18nText("BI-Basic_Month"), obj.position) : ""; - } - if (BI.isNotNull(obj.workDay) && BI.parseInt(obj.workDay) !== 0) { - value += Math.abs(obj.workDay) + BI.i18nText("BI-Basic_Work_Day") + (obj.workDay < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - return value + endText; - - function getPositionText(baseText, position) { - switch (position) { - case BI.DynamicDateCard.OFFSET.BEGIN: - return baseText + BI.i18nText("BI-Basic_Begin_Start"); - case BI.DynamicDateCard.OFFSET.END: - return baseText + BI.i18nText("BI-Basic_End_Stop"); - case BI.DynamicDateCard.OFFSET.CURRENT: - default: - return BI.i18nText("BI-Basic_Current_Day"); - } - } - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - var type, value, self = this; - var date = BI.getDate(); - this.storeValue = v; - if (BI.isNotNull(v)) { - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - date = BI.DynamicDateHelper.getCalculation(value); - this._setInnerValue(date, text); - break; - case BI.DynamicDateCombo.Static: - default: - if (BI.isNull(value) || BI.isNull(value.day)) { - this.editor.setState(""); - this.editor.setValue(""); - } else { - var dateStr = BI.print(BI.getDate(value.year, (value.month - 1), value.day, value.hour || 0, value.minute || 0, - value.second || 0), this._getFormatString()); - this.editor.setState(dateStr); - this.editor.setValue(dateStr); - } - break; - } - }, - - getKey: function () { - return this.editor.getValue(); - }, - getValue: function () { - return this.storeValue; - }, - - isValid: function () { - return this.editor.isValid(); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); - -BI.DynamicDateTimeTrigger.EVENT_BLUR = "EVENT_BLUR"; -BI.DynamicDateTimeTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicDateTimeTrigger.EVENT_START = "EVENT_START"; -BI.DynamicDateTimeTrigger.EVENT_STOP = "EVENT_STOP"; -BI.DynamicDateTimeTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicDateTimeTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DynamicDateTimeTrigger.EVENT_VALID = "EVENT_VALID"; -BI.DynamicDateTimeTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicDateTimeTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.DynamicDateTimeTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.shortcut("bi.dynamic_date_time_trigger", BI.DynamicDateTimeTrigger); diff --git a/src/widget/editor/editor.search.js b/src/widget/editor/editor.search.js deleted file mode 100644 index bd40ae5a9..000000000 --- a/src/widget/editor/editor.search.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Created by roy on 15/9/14. - */ -BI.SearchEditor = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - var conf = BI.SearchEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-search-editor bi-focus-shadow " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24, - errorText: "", - watermark: BI.i18nText("BI-Basic_Search"), - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - value: "" - }); - }, - _init: function () { - BI.SearchEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.editor", - simple: o.simple, - height: BI.toPix(o.height, o.simple ? 1 : 2), - watermark: o.watermark, - allowBlank: true, - hgap: 1, - errorText: o.errorText, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - value: o.value, - autoTrim: o.autoTrim, - }); - this.clear = BI.createWidget({ - type: "bi.icon_button", - stopEvent: true, - cls: "close-font", - invisible: !BI.isKey(o.value) - }); - this.clear.on(BI.IconButton.EVENT_CHANGE, function () { - self.setValue(""); - self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, self.getValue()); - // 从有内容到无内容的清空也是一次change - self.fireEvent(BI.SearchEditor.EVENT_CHANGE); - self.fireEvent(BI.SearchEditor.EVENT_CLEAR); - }); - BI.createWidget({ - element: this, - height: BI.toPix(o.height, o.simple ? 1 : 2), - type: "bi.htape", - items: [ - { - el: { - type: "bi.icon_label", - cls: "search-font" - }, - width: 24 - }, - { - el: self.editor - }, - { - el: this.clear, - width: 24 - } - ] - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.SearchEditor.EVENT_FOCUS); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.SearchEditor.EVENT_BLUR); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.SearchEditor.EVENT_CLICK); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self._checkClear(); - self.fireEvent(BI.SearchEditor.EVENT_CHANGE); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.SearchEditor.EVENT_KEY_DOWN, v); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function () { - self.fireEvent(BI.SearchEditor.EVENT_SPACE); - }); - this.editor.on(BI.Editor.EVENT_BACKSPACE, function () { - self.fireEvent(BI.SearchEditor.EVENT_BACKSPACE); - }); - - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.fireEvent(BI.SearchEditor.EVENT_VALID); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.fireEvent(BI.SearchEditor.EVENT_ERROR); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.SearchEditor.EVENT_ENTER); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.SearchEditor.EVENT_RESTRICT); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self._checkClear(); - self.fireEvent(BI.SearchEditor.EVENT_EMPTY); - }); - this.editor.on(BI.Editor.EVENT_REMOVE, function () { - self.fireEvent(BI.SearchEditor.EVENT_REMOVE); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self.fireEvent(BI.SearchEditor.EVENT_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self.fireEvent(BI.SearchEditor.EVENT_CHANGE_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.SearchEditor.EVENT_START); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.SearchEditor.EVENT_PAUSE); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.SearchEditor.EVENT_STOP); - }); - }, - - _checkClear: function () { - if (!this.getValue()) { - this.clear.invisible(); - } else { - this.clear.visible(); - } - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - getValue: function () { - if (this.isValid()) { - return this.editor.getValue(); - } - }, - - getKeywords: function () { - var val = this.editor.getLastChangedValue(); - var keywords = val.match(/[\S]+/g); - if (BI.isEndWithBlank(val)) { - return keywords.concat([" "]); - } - return keywords; - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (v) { - this.editor.setValue(v); - if (BI.isKey(v)) { - this.clear.visible(); - } - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - showClearIcon: function () { - this.clear.visible(); - }, - - hideClearIcon: function () { - this.clear.invisible(); - } -}); -BI.SearchEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SearchEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.SearchEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.SearchEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.SearchEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.SearchEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; -BI.SearchEditor.EVENT_CLEAR = "EVENT_CLEAR"; - -BI.SearchEditor.EVENT_START = "EVENT_START"; -BI.SearchEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SearchEditor.EVENT_STOP = "EVENT_STOP"; -BI.SearchEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.SearchEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.SearchEditor.EVENT_VALID = "EVENT_VALID"; -BI.SearchEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.SearchEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.SearchEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.SearchEditor.EVENT_REMOVE = "EVENT_REMOVE"; -BI.SearchEditor.EVENT_EMPTY = "EVENT_EMPTY"; -BI.shortcut("bi.search_editor", BI.SearchEditor); diff --git a/src/widget/editor/editor.search.small.js b/src/widget/editor/editor.search.small.js deleted file mode 100644 index 145108f0d..000000000 --- a/src/widget/editor/editor.search.small.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 小号搜索框 - * Created by GUY on 2015/9/29. - * @class BI.SmallSearchEditor - * @extends BI.SearchEditor - */ -BI.SmallSearchEditor = BI.inherit(BI.SearchEditor, { - _defaultConfig: function () { - var conf = BI.SmallSearchEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-small-search-editor", - height: 20 - }); - }, - - _init: function () { - BI.SmallSearchEditor.superclass._init.apply(this, arguments); - } -}); -BI.shortcut("bi.small_search_editor", BI.SmallSearchEditor); \ No newline at end of file diff --git a/src/widget/editor/editor.text.js b/src/widget/editor/editor.text.js deleted file mode 100644 index 022b5f2ad..000000000 --- a/src/widget/editor/editor.text.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * guy - * @class BI.TextEditor - * @extends BI.Single - */ -BI.TextEditor = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - var conf = BI.TextEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-text-editor bi-focus-shadow " + (config.simple ? "bi-border-bottom" : "bi-border"), - hgap: 4, - vgap: 2, - lgap: 0, - rgap: 0, - tgap: 0, - bgap: 0, - validationChecker: BI.emptyFn, - quitChecker: BI.emptyFn, - allowBlank: false, - watermark: "", - errorText: "", - height: 24 - }); - }, - - render: function () { - var self = this, o = this.options; - var border = o.simple ? 1 : 2; - this.editor = BI.createWidget({ - type: "bi.editor", - element: this, - width: BI.toPix(o.width, border), - height: BI.toPix(o.height, border), - simple: o.simple, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - value: o.value, - title: o.title, - tipType: o.tipType, - validationChecker: o.validationChecker, - quitChecker: o.quitChecker, - allowBlank: o.allowBlank, - watermark: o.watermark, - errorText: o.errorText, - inputType: o.inputType, - autocomplete: o.autocomplete, - autoTrim: o.autoTrim, - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.editor.on(BI.Editor.EVENT_FOCUS, function () { - self.fireEvent(BI.TextEditor.EVENT_FOCUS); - }); - this.editor.on(BI.Editor.EVENT_BLUR, function () { - self.fireEvent(BI.TextEditor.EVENT_BLUR); - }); - this.editor.on(BI.Editor.EVENT_CLICK, function () { - self.fireEvent(BI.TextEditor.EVENT_CLICK); - }); - this.editor.on(BI.Editor.EVENT_CHANGE, function () { - self.fireEvent(BI.TextEditor.EVENT_CHANGE); - }); - this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { - self.fireEvent(BI.TextEditor.EVENT_KEY_DOWN); - }); - this.editor.on(BI.Editor.EVENT_SPACE, function (v) { - self.fireEvent(BI.TextEditor.EVENT_SPACE); - }); - this.editor.on(BI.Editor.EVENT_BACKSPACE, function (v) { - self.fireEvent(BI.TextEditor.EVENT_BACKSPACE); - }); - - - this.editor.on(BI.Editor.EVENT_VALID, function () { - self.element.removeClass("error"); - self.fireEvent(BI.TextEditor.EVENT_VALID); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self.fireEvent(BI.TextEditor.EVENT_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self.fireEvent(BI.TextEditor.EVENT_CHANGE_CONFIRM); - }); - this.editor.on(BI.Editor.EVENT_REMOVE, function (v) { - self.fireEvent(BI.TextEditor.EVENT_REMOVE); - }); - this.editor.on(BI.Editor.EVENT_START, function () { - self.fireEvent(BI.TextEditor.EVENT_START); - }); - this.editor.on(BI.Editor.EVENT_PAUSE, function () { - self.fireEvent(BI.TextEditor.EVENT_PAUSE); - }); - this.editor.on(BI.Editor.EVENT_STOP, function () { - self.fireEvent(BI.TextEditor.EVENT_STOP); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self.element.addClass("error"); - self.fireEvent(BI.TextEditor.EVENT_ERROR, arguments); - }); - this.editor.on(BI.Editor.EVENT_ENTER, function () { - self.fireEvent(BI.TextEditor.EVENT_ENTER); - }); - this.editor.on(BI.Editor.EVENT_RESTRICT, function () { - self.fireEvent(BI.TextEditor.EVENT_RESTRICT); - }); - this.editor.on(BI.Editor.EVENT_EMPTY, function () { - self.fireEvent(BI.TextEditor.EVENT_EMPTY); - }); - }, - - setWaterMark: function (v) { - this.options.watermark = v; - this.editor.setWaterMark(v); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setValue: function (v) { - this.editor.setValue(v); - }, - - getValue: function () { - return this.editor.getValue(); - } -}); -BI.TextEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.TextEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.TextEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.TextEditor.EVENT_CLICK = "EVENT_CLICK"; -BI.TextEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.TextEditor.EVENT_SPACE = "EVENT_SPACE"; -BI.TextEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; - -BI.TextEditor.EVENT_START = "EVENT_START"; -BI.TextEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.TextEditor.EVENT_STOP = "EVENT_STOP"; -BI.TextEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.TextEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.TextEditor.EVENT_VALID = "EVENT_VALID"; -BI.TextEditor.EVENT_ERROR = "EVENT_ERROR"; -BI.TextEditor.EVENT_ENTER = "EVENT_ENTER"; -BI.TextEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; -BI.TextEditor.EVENT_REMOVE = "EVENT_REMOVE"; -BI.TextEditor.EVENT_EMPTY = "EVENT_EMPTY"; - -BI.shortcut("bi.text_editor", BI.TextEditor); diff --git a/src/widget/editor/editor.text.small.js b/src/widget/editor/editor.text.small.js deleted file mode 100644 index cb7a9eb96..000000000 --- a/src/widget/editor/editor.text.small.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 小号搜索框 - * Created by GUY on 2015/9/29. - * @class BI.SmallTextEditor - * @extends BI.SearchEditor - */ -BI.SmallTextEditor = BI.inherit(BI.TextEditor, { - _defaultConfig: function () { - var conf = BI.SmallTextEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-small-text-editor", - height: 20 - }); - }, - - _init: function () { - BI.SmallTextEditor.superclass._init.apply(this, arguments); - } -}); -BI.shortcut("bi.small_text_editor", BI.SmallTextEditor); \ No newline at end of file diff --git a/src/widget/intervalslider/intervalslider.js b/src/widget/intervalslider/intervalslider.js deleted file mode 100644 index 6c70c33a3..000000000 --- a/src/widget/intervalslider/intervalslider.js +++ /dev/null @@ -1,563 +0,0 @@ -/** - * Created by zcf on 2016/9/26. - */ -BI.IntervalSlider = BI.inherit(BI.Single, { - _constant: { - EDITOR_WIDTH: 58, - EDITOR_R_GAP: 60, - EDITOR_HEIGHT: 20, - SLIDER_WIDTH_HALF: 15, - SLIDER_WIDTH: 30, - SLIDER_HEIGHT: 30, - TRACK_HEIGHT: 24 - }, - - props: { - baseCls: "bi-interval-slider bi-slider-track", - digit: false, - unit: "", - min: 0, - max: 100, - value: { - min: "", - max: "", - } - }, - - beforeMount: function () { - const { value, min, max } = this.options; - this._setMinAndMax({ - min, - max, - }); - this.setValue(value); - this.populate(); - }, - - render: function () { - - var self = this; - var c = this._constant; - this.enable = false; - this.valueOne = ""; - this.valueTwo = ""; - - this.calculation = new BI.AccurateCalculationModel(); - this.grayTrack = BI.createWidget({ - type: "bi.layout", - cls: "gray-track", - height: 6 - }); - this.blueTrack = BI.createWidget({ - type: "bi.layout", - cls: "blue-track bi-high-light-background", - height: 6 - }); - this.track = this._createTrackWrapper(); - - this.labelOne = BI.createWidget({ - type: "bi.sign_text_editor", - cls: "slider-editor-button", - text: this.options.unit, - allowBlank: false, - width: BI.toPix(c.EDITOR_WIDTH, 2), - height: BI.toPix(c.EDITOR_HEIGHT, 2), - validationChecker: function (v) { - return self._checkValidation(v); - } - }); - this.labelOne.element.hover(function () { - self.labelOne.element.removeClass("bi-border").addClass("bi-border"); - }, function () { - self.labelOne.element.removeClass("bi-border"); - }); - this.labelOne.on(BI.Editor.EVENT_CONFIRM, function () { - var oldValueOne = self.valueOne; - var v = BI.parseFloat(this.getValue()); - self.valueOne = v; - var percent = self._getPercentByValue(v); - var significantPercent = BI.parseFloat(percent.toFixed(1));// 分成1000份 - self._setSliderOnePosition(significantPercent); - self._setBlueTrack(); - self._checkLabelPosition(oldValueOne, self.valueTwo, self.valueOne, self.valueTwo); - self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); - }); - - this.labelTwo = BI.createWidget({ - type: "bi.sign_text_editor", - cls: "slider-editor-button", - text: this.options.unit, - allowBlank: false, - width: BI.toPix(c.EDITOR_WIDTH, 2), - height: BI.toPix(c.EDITOR_HEIGHT, 2), - validationChecker: function (v) { - return self._checkValidation(v); - } - }); - this.labelTwo.element.hover(function () { - self.labelTwo.element.removeClass("bi-border").addClass("bi-border"); - }, function () { - self.labelTwo.element.removeClass("bi-border"); - }); - this.labelTwo.on(BI.Editor.EVENT_CONFIRM, function () { - var oldValueTwo = self.valueTwo; - var v = BI.parseFloat(this.getValue()); - self.valueTwo = v; - var percent = self._getPercentByValue(v, true); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setSliderTwoPosition(significantPercent); - self._setBlueTrack(); - self._checkLabelPosition(self.valueOne, oldValueTwo, self.valueOne, self.valueTwo); - self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); - }); - - this.sliderOne = BI.createWidget({ - type: "bi.single_slider_button" - }); - this.sliderTwo = BI.createWidget({ - type: "bi.single_slider_button" - }); - this._draggable(this.sliderOne, true); - this._draggable(this.sliderTwo, false); - this._setVisible(false); - - return { - type: "bi.vertical_fill", - rowSize: [30, 30], - items: [ - this._createLabelWrapper(), - { - type: "bi.absolute", - items: [ - { - el: { - type: "bi.horizontal", - horizontalAlign: "stretch", - verticalAlign: "middle", - columnSize: ["fill"], - items: [{ - el: this.track, - }], - hgap: 10, - }, - inset: 0 - }, - this._createSliderWrapper(), - ] - } - ] - }; - }, - - _rePosBySizeAfterMove: function (size, isLeft) { - var o = this.options; - var percent = size * 100 / (this._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - var v = this._getValueByPercent(significantPercent); - v = this._assertValue(v); - v = o.digit === false ? v : v.toFixed(o.digit); - var oldValueOne = this.valueOne, oldValueTwo = this.valueTwo; - if(isLeft) { - this._setSliderOnePosition(significantPercent); - this.labelOne.setValue(v); - this.valueOne = v; - this._checkLabelPosition(oldValueOne, oldValueTwo, v, this.valueTwo); - }else{ - this._setSliderTwoPosition(significantPercent); - this.labelTwo.setValue(v); - this.valueTwo = v; - this._checkLabelPosition(oldValueOne, oldValueTwo, this.valueOne, v); - } - this._setBlueTrack(); - }, - - _rePosBySizeAfterStop: function (size, isLeft) { - var percent = size * 100 / (this._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - isLeft ? this._setSliderOnePosition(significantPercent) : this._setSliderTwoPosition(significantPercent); - }, - - _draggable: function (widget, isLeft) { - var self = this, o = this.options; - var startDrag = false; - var size = 0, offset = 0, defaultSize = 0; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { - if (mouseMoveTracker.isDragging()) { - startDrag = true; - offset += deltaX; - size = optimizeSize(defaultSize + offset); - widget.element.addClass("dragging"); - self._rePosBySizeAfterMove(size, isLeft); - } - }, function () { - if (startDrag === true) { - size = optimizeSize(size); - self._rePosBySizeAfterStop(size, isLeft); - size = 0; - offset = 0; - defaultSize = size; - startDrag = false; - } - widget.element.removeClass("dragging"); - mouseMoveTracker.releaseMouseMoves(); - self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); - }, window); - widget.element.on("mousedown", function (event) { - if(!widget.isEnabled()) { - return; - } - defaultSize = this.offsetLeft; - optimizeSize(defaultSize); - mouseMoveTracker.captureMouseMoves(event); - }); - - function optimizeSize (s) { - return BI.clamp(s, 0, self._getGrayTrackLength()); - } - }, - - _createLabelWrapper: function () { - var c = this._constant; - return { - el: { - type: "bi.vertical", - items: [{ - type: "bi.absolute", - items: [{ - el: this.labelOne, - top: 0, - left: 0, - }] - }, { - type: "bi.absolute", - items: [{ - el: this.labelTwo, - top: 0, - right: 0, - }] - }], - rgap: c.EDITOR_R_GAP, - height: c.SLIDER_HEIGHT - }, - top: 0, - left: 0, - width: "100%" - }; - }, - - _createSliderWrapper: function () { - var c = this._constant; - return { - el: { - type: "bi.horizontal", - horizontalAlign: "stretch", - verticalAlign: "middle", - items: [ - { - type: "bi.absolute", - height: 12, - width: "fill", - items: [ - { - el: this.sliderOne, - top: 0, - bottom: 0, - left: 0 - }, { - el: this.sliderTwo, - top: 0, - bottom: 0, - left: "100%" - } - ], - } - ], - hgap: 10, - }, - inset: 0 - }; - }, - - _createTrackWrapper: function () { - return BI.createWidget({ - type: "bi.horizontal", - cls: "track-wrapper", - horizontalAlign: "stretch", - verticalAlign: "middle", - columnSize: ["fill"], - scrollx: false, - items: [ - { - type: "bi.absolute", - height: 6, - items: [{ - el: this.grayTrack, - top: 0, - left: 0, - bottom: 0, - width: "100%" - }, { - el: this.blueTrack, - top: 0, - left: 0, - bottom: 0, - width: "0%" - }] - } - ], - }); - }, - - _checkValidation: function (v) { - var o = this.options; - var valid = false; - // 像90.这样的既不属于整数又不属于小数,是不合法的值 - var dotText = (v + "").split(".")[1]; - if (BI.isEmptyString(dotText)) { - }else{ - if (BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max)) { - // 虽然规定了所填写的小数位数,但是我们认为所有的整数都是满足设置的小数位数的 - // 100等价于100.0 100.00 100.000 - if(o.digit === false || BI.isInteger(v)) { - valid = true; - }else{ - dotText = dotText || ""; - valid = (dotText.length === o.digit); - } - } - } - return valid; - }, - - _checkOverlap: function () { - var labelOneLeft = this.labelOne.element[0].offsetLeft; - var labelTwoLeft = this.labelTwo.element[0].offsetLeft; - if (labelOneLeft <= labelTwoLeft) { - if ((labelTwoLeft - labelOneLeft) < 90) { - this.labelTwo.element.css({top: 40}); - } else { - this.labelTwo.element.css({top: 0}); - } - } else { - if ((labelOneLeft - labelTwoLeft) < 90) { - this.labelTwo.element.css({top: 40}); - } else { - this.labelTwo.element.css({top: 0}); - } - } - }, - - _checkLabelPosition: function (oldValueOne, oldValueTwo, valueOne, valueTwo, isLeft) { - oldValueOne = BI.parseFloat(oldValueOne); - oldValueTwo = BI.parseFloat(oldValueTwo); - valueOne = BI.parseFloat(valueOne); - valueTwo = BI.parseFloat(valueTwo); - if((oldValueOne <= oldValueTwo && valueOne > valueTwo) || (oldValueOne >= oldValueTwo && valueOne < valueTwo)) { - var isSliderOneLeft = BI.parseFloat(this.labelOne.getValue()) < BI.parseFloat(this.labelTwo.getValue()); - this._resetLabelPosition(!isSliderOneLeft); - } - }, - - _resetLabelPosition: function(needReverse) { - this.labelOne.element.css({left: needReverse ? "100%" : "0%"}); - this.labelTwo.element.css({left: needReverse ? "0%" : "100%"}); - }, - - _setSliderOnePosition: function (percent) { - this.sliderOne.element.css({left: percent + "%"}); - }, - - _setSliderTwoPosition: function (percent) { - this.sliderTwo.element.css({left: percent + "%"}); - }, - - _setBlueTrackLeft: function (percent) { - this.blueTrack.element.css({left: percent + "%"}); - }, - - _setBlueTrackWidth: function (percent) { - this.blueTrack.element.css({width: percent + "%"}); - }, - - _setBlueTrack: function () { - var percentOne = this._getPercentByValue(this.labelOne.getValue()); - var percentTwo = this._getPercentByValue(this.labelTwo.getValue(), true); - if (percentOne <= percentTwo) { - this._setBlueTrackLeft(percentOne); - this._setBlueTrackWidth(percentTwo - percentOne); - } else { - this._setBlueTrackLeft(percentTwo); - this._setBlueTrackWidth(percentOne - percentTwo); - } - }, - - _setAllPosition: function (one, two) { - this._setSliderOnePosition(one); - this._setSliderTwoPosition(two); - this._setBlueTrack(); - }, - - _setVisible: function (visible) { - this.sliderOne.setVisible(visible); - this.sliderTwo.setVisible(visible); - this.labelOne.setVisible(visible); - this.labelTwo.setVisible(visible); - }, - - _setErrorText: function () { - var errorText = BI.i18nText("BI-Basic_Please_Enter_Number_Between", this.min, this.max); - this.labelOne.setErrorText(errorText); - this.labelTwo.setErrorText(errorText); - }, - - _getGrayTrackLength: function () { - return this.grayTrack.element[0].scrollWidth; - }, - - // 其中取max-min后保留4为有效数字后的值的小数位数为最终value的精度 - // 端点处的值有可能因为min,max相差量级很大(precision很大)而丢失精度,此时直接返回端点值即可 - _getValueByPercent: function (percent) {// return (((max-min)*percent)/100+min) - if (percent === 0) { - return this.min; - } - if (percent === 100) { - return this.max; - } - var sub = this.calculation.accurateSubtraction(this.max, this.min); - var mul = this.calculation.accurateMultiplication(sub, percent); - var div = this.calculation.accurateDivisionTenExponent(mul, 2); - if(this.precision < 0) { - var value = BI.parseFloat(this.calculation.accurateAddition(div, this.min)); - var reduceValue = Math.round(this.calculation.accurateDivisionTenExponent(value, -this.precision)); - return this.calculation.accurateMultiplication(reduceValue, Math.pow(10, -this.precision)); - } - return BI.parseFloat(this.calculation.accurateAddition(div, this.min).toFixed(this.precision)); - - }, - - _getPercentByValue: function (v, isLast) { - if (this.max === this.min) { - return isLast ? 100 : 0; - } - - return (v - this.min) * 100 / (this.max - this.min); - }, - - _getPrecision: function () { - // 计算每一份值的精度(最大值和最小值的差值保留4为有效数字后的精度) - // 如果差值的整数位数大于4,toPrecision(4)得到的是科学计数法123456 => 1.235e+5 - // 返回非负值: 保留的小数位数 - // 返回负值: 保留的10^n精度中的n - var sub = this.calculation.accurateSubtraction(this.max, this.min); - var pre = sub.toPrecision(4); - // 科学计数法 - var eIndex = pre.indexOf("e"); - var arr = []; - if(eIndex > -1) { - arr = pre.split("e"); - var decimalPartLength = BI.size(arr[0].split(".")[1]); - var sciencePartLength = BI.parseInt(arr[1].substring(1)); - return decimalPartLength - sciencePartLength; - } - arr = pre.split("."); - return arr.length > 1 ? arr[1].length : 0; - - }, - - _assertValue: function (value) { - if(value <= this.min) { - return this.min; - } - if(value >= this.max) { - return this.max; - } - return value; - }, - - _setEnable: function (b) { - BI.IntervalSlider.superclass._setEnable.apply(this, [b]); - if(b) { - this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); - } else { - this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); - } - }, - - getValue: function () { - if (this.valueOne <= this.valueTwo) { - return {min: this.valueOne, max: this.valueTwo}; - } - return {min: this.valueTwo, max: this.valueOne}; - - }, - - _setMinAndMax: function (v) { - var minNumber = BI.parseFloat(v.min); - var maxNumber = BI.parseFloat(v.max); - if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber >= minNumber)) { - this.min = minNumber; - this.max = maxNumber; - this.valueOne = minNumber; - this.valueTwo = maxNumber; - this.precision = this._getPrecision(); - } - }, - - setMinAndMax: function (v) { - this._setMinAndMax(v); - this.setEnable(v.min <= v.max); - }, - - setValue: function (v) { - var o = this.options; - var valueOne = BI.parseFloat(v.min); - var valueTwo = BI.parseFloat(v.max); - valueOne = o.digit === false ? valueOne : BI.parseFloat(valueOne.toFixed(o.digit)); - valueTwo = o.digit === false ? valueTwo : BI.parseFloat(valueTwo.toFixed(o.digit)); - if (!isNaN(valueOne) && !isNaN(valueTwo)) { - if (this._checkValidation(valueOne)) { - this.valueOne = (this.valueOne <= this.valueTwo ? valueOne : valueTwo); - } - if (this._checkValidation(valueTwo)) { - this.valueTwo = (this.valueOne <= this.valueTwo ? valueTwo : valueOne); - } - if (valueOne < this.min) { - this.valueOne = this.min; - } - if (valueTwo > this.max) { - this.valueTwo = this.max; - } - } - }, - - reset: function () { - this._setVisible(false); - this.enable = false; - this.valueOne = ""; - this.valueTwo = ""; - this.min = NaN; - this.max = NaN; - this._setBlueTrackWidth(0); - }, - - populate: function () { - var o = this.options; - if (!isNaN(this.min) && !isNaN(this.max)) { - this.enable = true; - this._setVisible(true); - this._setErrorText(); - if ((BI.isNumeric(this.valueOne) || BI.isNotEmptyString(this.valueOne)) && (BI.isNumeric(this.valueTwo) || BI.isNotEmptyString(this.valueTwo))) { - this.labelOne.setValue(o.digit === false ? this.valueOne : BI.parseFloat(this.valueOne).toFixed(o.digit)); - this.labelTwo.setValue(o.digit === false ? this.valueTwo : BI.parseFloat(this.valueTwo).toFixed(o.digit)); - this._setAllPosition(this._getPercentByValue(this.valueOne), this._getPercentByValue(this.valueTwo, true)); - } else { - this.labelOne.setValue(this.min); - this.labelTwo.setValue(this.max); - this._setAllPosition(0, 100); - } - this._resetLabelPosition(this.valueOne > this.valueTwo); - } - } -}); -BI.IntervalSlider.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.interval_slider", BI.IntervalSlider); diff --git a/src/widget/intervalslider/model.accuratecalculation.js b/src/widget/intervalslider/model.accuratecalculation.js deleted file mode 100644 index aa430dad1..000000000 --- a/src/widget/intervalslider/model.accuratecalculation.js +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Created by zcf on 2017/3/1. - * 万恶的IEEE-754 - * 使用字符串精确计算含小数加法、减法、乘法和10的指数倍除法,支持负数 - */ -BI.AccurateCalculationModel = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.AccurateCalculationModel.superclass._defaultConfig.apply(this, arguments), { - baseCls: "" - }); - }, - - _init: function () { - BI.AccurateCalculationModel.superclass._init.apply(this, arguments); - }, - - _getMagnitude: function (n) { - var magnitude = "1"; - for (var i = 0; i < n; i++) { - magnitude += "0"; - } - return BI.parseInt(magnitude); - }, - - _formatDecimal: function (stringNumber1, stringNumber2) { - if (stringNumber1.numDecimalLength === stringNumber2.numDecimalLength) { - return; - } - var magnitudeDiff = stringNumber1.numDecimalLength - stringNumber2.numDecimalLength; - if (magnitudeDiff > 0) { - var needAddZero = stringNumber2; - } else { - var needAddZero = stringNumber1; - magnitudeDiff = (0 - magnitudeDiff); - } - for (var i = 0; i < magnitudeDiff; i++) { - if (needAddZero.numDecimal === "0" && i === 0) { - continue; - } - needAddZero.numDecimal += "0"; - } - }, - - _stringNumberFactory: function (num) { - var strNum = num.toString(); - var numStrArray = strNum.split("."); - var numInteger = numStrArray[0]; - if (numStrArray.length === 1) { - var numDecimal = "0"; - var numDecimalLength = 0; - } else { - var numDecimal = numStrArray[1]; - var numDecimalLength = numStrArray[1].length; - } - return { - numInteger: numInteger, - numDecimal: numDecimal, - numDecimalLength: numDecimalLength - }; - }, - - _accurateSubtraction: function (num1, num2) {// num1-num2 && num1>num2 - var stringNumber1 = this._stringNumberFactory(num1); - var stringNumber2 = this._stringNumberFactory(num2); - // 整数部分计算 - var integerResult = BI.parseInt(stringNumber1.numInteger) - BI.parseInt(stringNumber2.numInteger); - // 小数部分 - this._formatDecimal(stringNumber1, stringNumber2); - var decimalMaxLength = getDecimalMaxLength(stringNumber1, stringNumber2); - - if (BI.parseInt(stringNumber1.numDecimal) >= BI.parseInt(stringNumber2.numDecimal)) { - var decimalResultTemp = (BI.parseInt(stringNumber1.numDecimal) - BI.parseInt(stringNumber2.numDecimal)).toString(); - var decimalResult = addZero(decimalResultTemp, decimalMaxLength); - } else {// 否则借位 - integerResult--; - var borrow = this._getMagnitude(decimalMaxLength); - var decimalResultTemp = (borrow + BI.parseInt(stringNumber1.numDecimal) - BI.parseInt(stringNumber2.numDecimal)).toString(); - var decimalResult = addZero(decimalResultTemp, decimalMaxLength); - } - var result = integerResult + "." + decimalResult; - return BI.parseFloat(result); - - function getDecimalMaxLength (num1, num2) { - if (num1.numDecimal.length >= num2.numDecimal.length) { - return num1.numDecimal.length; - } - return num2.numDecimal.length; - } - - function addZero (resultTemp, length) { - var diff = length - resultTemp.length; - for (var i = 0; i < diff; i++) { - resultTemp = "0" + resultTemp; - } - return resultTemp; - } - }, - - _accurateAddition: function (num1, num2) {// 加法结合律 - var stringNumber1 = this._stringNumberFactory(num1); - var stringNumber2 = this._stringNumberFactory(num2); - // 整数部分计算 - var integerResult = BI.parseInt(stringNumber1.numInteger) + BI.parseInt(stringNumber2.numInteger); - // 小数部分 - this._formatDecimal(stringNumber1, stringNumber2); - - var decimalResult = (BI.parseInt(stringNumber1.numDecimal) + BI.parseInt(stringNumber2.numDecimal)).toString(); - - if (decimalResult !== "0") { - if (decimalResult.length <= stringNumber1.numDecimal.length) { - decimalResult = addZero(decimalResult, stringNumber1.numDecimal.length); - } else { - integerResult++;// 进一 - decimalResult = decimalResult.slice(1); - } - } - var result = integerResult + "." + decimalResult; - return BI.parseFloat(result); - - function addZero (resultTemp, length) { - var diff = length - resultTemp.length; - for (var i = 0; i < diff; i++) { - resultTemp = "0" + resultTemp; - } - return resultTemp; - } - }, - - _accurateMultiplication: function (num1, num2) {// 乘法分配律 - var stringNumber1 = this._stringNumberFactory(num1); - var stringNumber2 = this._stringNumberFactory(num2); - // 整数部分计算 - var integerResult = BI.parseInt(stringNumber1.numInteger) * BI.parseInt(stringNumber2.numInteger); - // num1的小数和num2的整数 - var dec1Int2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numDecimal) * BI.parseInt(stringNumber2.numInteger), stringNumber1.numDecimalLength); - // num1的整数和num2的小数 - var int1dec2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numInteger) * BI.parseInt(stringNumber2.numDecimal), stringNumber2.numDecimalLength); - // 小数*小数 - var dec1dec2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numDecimal) * BI.parseInt(stringNumber2.numDecimal), (stringNumber1.numDecimalLength + stringNumber2.numDecimalLength)); - - return this._accurateAddition(this._accurateAddition(this._accurateAddition(integerResult, dec1Int2), int1dec2), dec1dec2); - }, - - _accurateDivisionTenExponent: function (num, n) {// num/10^n && n>0 - var stringNumber = this._stringNumberFactory(num); - if (stringNumber.numInteger.length > n) { - var integerResult = stringNumber.numInteger.slice(0, (stringNumber.numInteger.length - n)); - var partDecimalResult = stringNumber.numInteger.slice(-n); - } else { - var integerResult = "0"; - var partDecimalResult = addZero(stringNumber.numInteger, n); - } - var result = integerResult + "." + partDecimalResult + stringNumber.numDecimal; - return BI.parseFloat(result); - - function addZero (resultTemp, length) { - var diff = length - resultTemp.length; - for (var i = 0; i < diff; i++) { - resultTemp = "0" + resultTemp; - } - return resultTemp; - } - }, - - accurateSubtraction: function (num1, num2) { - if (num1 >= 0 && num2 >= 0) { - if (num1 >= num2) { - return this._accurateSubtraction(num1, num2); - } - return -this._accurateSubtraction(num2, num1); - } - if (num1 >= 0 && num2 < 0) { - return this._accurateAddition(num1, -num2); - } - if (num1 < 0 && num2 >= 0) { - return -this._accurateAddition(-num1, num2); - } - if (num1 < 0 && num2 < 0) { - if (num1 >= num2) { - return this._accurateSubtraction(-num2, -num1); - } - return this._accurateSubtraction(-num1, -num2); - } - }, - - accurateAddition: function (num1, num2) { - if (num1 >= 0 && num2 >= 0) { - return this._accurateAddition(num1, num2); - } - if (num1 >= 0 && num2 < 0) { - return this.accurateSubtraction(num1, -num2); - } - if (num1 < 0 && num2 >= 0) { - return this.accurateSubtraction(num2, -num1); - } - if (num1 < 0 && num2 < 0) { - return -this._accurateAddition(-num1, -num2); - } - }, - - accurateMultiplication: function (num1, num2) { - if (num1 >= 0 && num2 >= 0) { - return this._accurateMultiplication(num1, num2); - } - if (num1 >= 0 && num2 < 0) { - return -this._accurateMultiplication(num1, -num2); - } - if (num1 < 0 && num2 >= 0) { - return -this._accurateMultiplication(-num1, num2); - } - if (num1 < 0 && num2 < 0) { - return this._accurateMultiplication(-num1, -num2); - } - }, - - accurateDivisionTenExponent: function (num1, n) { - if (num1 >= 0) { - return this._accurateDivisionTenExponent(num1, n); - } - return -this._accurateDivisionTenExponent(-num1, n); - } -}); \ No newline at end of file diff --git a/src/widget/multilayerdownlist/combo.downlist.js b/src/widget/multilayerdownlist/combo.downlist.js deleted file mode 100644 index e2e333827..000000000 --- a/src/widget/multilayerdownlist/combo.downlist.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Created by roy on 15/8/14. - */ -BI.MultiLayerDownListCombo = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerDownListCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-down-list-combo", - height: 24, - items: [], - adjustLength: 0, - direction: "bottom", - trigger: "click", - container: null, - stopPropagation: false, - el: {} - }); - }, - - _init: function () { - BI.MultiLayerDownListCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.popupview = BI.createWidget({ - type: "bi.multi_layer_down_list_popup", - items: o.items, - chooseType: o.chooseType, - value: o.value - }); - - this.popupview.on(BI.MultiLayerDownListPopup.EVENT_CHANGE, function (value) { - self.fireEvent(BI.MultiLayerDownListCombo.EVENT_CHANGE, value); - self.downlistcombo.hideView(); - }); - - this.popupview.on(BI.MultiLayerDownListPopup.EVENT_SON_VALUE_CHANGE, function (value, fatherValue) { - self.fireEvent(BI.MultiLayerDownListCombo.EVENT_SON_VALUE_CHANGE, value, fatherValue); - self.downlistcombo.hideView(); - }); - - - this.downlistcombo = BI.createWidget({ - element: this, - type: "bi.combo", - trigger: o.trigger, - isNeedAdjustWidth: false, - container: o.container, - adjustLength: o.adjustLength, - direction: o.direction, - stopPropagation: o.stopPropagation, - el: BI.createWidget(o.el, { - type: "bi.icon_trigger", - extraCls: o.iconCls ? o.iconCls : "pull-down-font", - width: o.width, - height: o.height - }), - popup: { - el: this.popupview, - stopPropagation: o.stopPropagation, - maxHeight: 1000 - } - }); - - this.downlistcombo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.MultiLayerDownListCombo.EVENT_BEFORE_POPUPVIEW); - }); - }, - - hideView: function () { - this.downlistcombo.hideView(); - }, - - showView: function (e) { - this.downlistcombo.showView(e); - }, - - populate: function (items) { - this.popupview.populate(items); - }, - - setValue: function (v) { - this.popupview.setValue(v); - }, - getValue: function () { - return this.popupview.getValue(); - } -}); -BI.MultiLayerDownListCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerDownListCombo.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; -BI.MultiLayerDownListCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - -BI.shortcut("bi.multi_layer_down_list_combo", BI.MultiLayerDownListCombo); \ No newline at end of file diff --git a/src/widget/multilayerdownlist/popup.downlist.js b/src/widget/multilayerdownlist/popup.downlist.js deleted file mode 100644 index 8fbacd285..000000000 --- a/src/widget/multilayerdownlist/popup.downlist.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Created by roy on 15/9/8. - * 处理popup中的item分组样式 - * 一个item分组中的成员大于一时,该分组设置为单选,并且默认状态第一个成员设置为已选择项 - */ -BI.MultiLayerDownListPopup = BI.inherit(BI.Pane, { - constants: { - nextIcon: "pull-right-e-font", - height: 25, - iconHeight: 12, - iconWidth: 12, - hgap: 0, - vgap: 0, - border: 1 - }, - _defaultConfig: function () { - var conf = BI.MultiLayerDownListPopup.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: "bi-down-list-popup", - items: [], - chooseType: BI.Selection.Multi - }); - }, - _init: function () { - BI.MultiLayerDownListPopup.superclass._init.apply(this, arguments); - this.singleValues = []; - this.childValueMap = {}; - this.fatherValueMap = {}; - this.items = []; - var self = this, o = this.options, children = this._createPopupItems(o.items); - this.popup = BI.createWidget({ - type: "bi.button_tree", - items: BI.createItems(children, - {}, { - adjustLength: -2 - } - ), - layouts: [{ - type: "bi.vertical", - hgap: this.constants.hgap, - vgap: this.constants.vgap - }], - value: this._digest(o.value), - chooseType: o.chooseType - }); - - this.popup.on(BI.ButtonTree.EVENT_CHANGE, function (value, object) { - var changedValue = value; - if (BI.isNotNull(self.childValueMap[value])) { - changedValue = self.childValueMap[value]; - var fatherValue = self.fatherValueMap[value]; - var fatherArrayValue = (fatherValue + "").split(BI.BlankSplitChar); - self.fireEvent(BI.MultiLayerDownListPopup.EVENT_SON_VALUE_CHANGE, changedValue, fatherArrayValue.length > 1 ? fatherArrayValue : fatherValue); - } else { - self.fireEvent(BI.MultiLayerDownListPopup.EVENT_CHANGE, changedValue, object); - } - - - if (!BI.contains(self.singleValues, changedValue)) { - var item = self.getValue(); - var result = []; - BI.each(item, function (i, valueObject) { - if (valueObject.value != changedValue) { - result.push(valueObject); - } - }); - self.setValue(result); - } - - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.popup], - vgap: 5 - }); - - }, - _createPopupItems: function (items) { - var self = this, result = []; - BI.each(items, function (i, it) { - var item_done = { - type: "bi.down_list_group", - items: [] - }; - var storeItem = []; - - BI.each(it, function (i, sourceItem) { - var item = BI.extend({}, sourceItem); - if (BI.isNotEmptyArray(sourceItem.children) && !BI.isEmpty(sourceItem.el)) { - item.type = "bi.combo_group"; - item.cls = "down-list-group"; - item.trigger = "hover"; - item.isNeedAdjustWidth = false; - item.el = sourceItem.el; - item.el.title = sourceItem.el.title || sourceItem.el.text; - item.el.type = "bi.down_list_group_item"; - item.el.logic = { - dynamic: true - }; - item.el.height = sourceItem.el.height || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT; - item.el.iconCls2 = self.constants.nextIcon; - item.popup = { - lgap: 1, - el: { - type: "bi.button_tree", - chooseType: 0, - layouts: [{ - type: "bi.vertical" - }] - - }, - innerVgap: 5, - maxHeight: 378, - }; - self._createChildren(item, sourceItem); - } else { - item.type = sourceItem.type || "bi.down_list_item"; - item.title = sourceItem.title || sourceItem.text; - item.textRgap = 10; - item.isNeedAdjustWidth = false; - item.logic = { - dynamic: true - }; - } - var el_done = {}; - el_done.el = item; - item_done.items.push(el_done); - storeItem.push(item); - }); - if (self._isGroup(item_done.items)) { - BI.each(item_done.items, function (i, item) { - self.singleValues.push(item.el.value); - }); - } - - result.push(item_done); - self.items.push(storeItem); - if (self._needSpliter(i, items.length)) { - var spliter_container = BI.createWidget({ - type: "bi.vertical", - items: [{ - el: { - type: "bi.layout", - cls: "bi-down-list-spliter bi-border-top cursor-pointer", - height: 0 - } - - }], - cls: "bi-down-list-spliter-container cursor-pointer", - vgap: 5, - hgap: 12, - }); - result.push(spliter_container); - } - }); - return result; - }, - - _createChildren: function (targetItem, sourceItem) { - var self = this; - this._formatEL(targetItem).el.childValues = []; - targetItem.items = targetItem.children = []; - BI.each(sourceItem.children, function (i, child) { - var item = child.el ? BI.extend({}, child.el, {children: child.children}) : BI.extend({}, child); - var fatherValue = BI.deepClone(self._formatEL(targetItem).el.value); - var childValue = BI.deepClone(item.value); - self.singleValues.push(item.value); - item.type = item.type || "bi.down_list_item"; - item.extraCls = " child-down-list-item"; - item.title = item.title || item.text; - item.textRgap = 10; - item.isNeedAdjustWidth = false; - item.logic = { - dynamic: true - }; - item.father = fatherValue; - self.fatherValueMap[self._createChildValue(fatherValue, childValue)] = fatherValue; - self.childValueMap[self._createChildValue(fatherValue, childValue)] = childValue; - item.value = self._createChildValue(fatherValue, childValue); - self._formatEL(targetItem).el.childValues.push(item.value); - if (BI.isNotEmptyArray(child.children)) { - item.type = "bi.down_list_group_item"; - item.iconCls2 = self.constants.nextIcon; - item.height = child.height || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT; - self._createChildren(item, child); - } - targetItem.items.push(item); - }); - }, - - _formatEL: function(obj) { - if (obj && obj.el) { - return obj; - } - - return { - el: obj - }; - }, - - _isGroup: function (i) { - return i.length > 1; - }, - - _needSpliter: function (i, itemLength) { - return i < itemLength - 1; - }, - - _createChildValue: function (fatherValue, childValue) { - var fValue = fatherValue; - if(BI.isArray(fatherValue)) { - fValue = fatherValue.join(BI.BlankSplitChar); - } - return fValue + BI.BlankSplitChar + childValue; - }, - - _digest: function (valueItem) { - var self = this; - var valueArray = []; - BI.each(valueItem, function (i, item) { - var value; - if (BI.isNotNull(item.childValue)) { - value = self._createChildValue(item.value, item.childValue); - } else { - value = item.value; - } - valueArray.push(value); - } - ); - return valueArray; - }, - - _checkValues: function (values) { - var self = this, o = this.options; - var value = []; - BI.each(this.items, function (idx, itemGroup) { - BI.each(itemGroup, function (id, item) { - if(BI.isNotNull(item.children)) { - var childValues = getChildrenValue(item); - var v = joinValue(childValues, values[idx]); - if(BI.isNotEmptyString(v)) { - value.push(v); - } - }else{ - if(item.value === values[idx][0]) { - value.push(values[idx][0]); - } - } - }); - }); - return value; - - function joinValue (sources, targets) { - var value = ""; - BI.some(sources, function (idx, s) { - return BI.some(targets, function (id, t) { - if(s === t) { - value = s; - return true; - } - }); - }); - return value; - } - - function getChildrenValue (item) { - var children = []; - if(BI.isNotNull(item.children)) { - BI.each(item.children, function (idx, child) { - children = BI.concat(children, getChildrenValue(child)); - }); - } else { - children.push(item.value); - } - return children; - } - }, - - populate: function (items) { - BI.MultiLayerDownListPopup.superclass.populate.apply(this, arguments); - var self = this; - self.childValueMap = {}; - self.fatherValueMap = {}; - self.singleValues = []; - this.items = []; - var children = self._createPopupItems(items); - var popupItem = BI.createItems(children, - {}, { - adjustLength: -2 - } - ); - self.popup.populate(popupItem); - }, - - setValue: function (valueItem) { - this.popup.setValue(this._digest(valueItem)); - }, - - _getValue: function () { - var v = []; - BI.each(this.popup.getAllButtons(), function (i, item) { - i % 2 === 0 && v.push(item.getValue()); - }); - return v; - }, - - getValue: function () { - var self = this, result = []; - var values = this._checkValues(this._getValue()); - BI.each(values, function (i, value) { - var valueItem = {}; - if (BI.isNotNull(self.childValueMap[value])) { - var fartherValue = self.fatherValueMap[value]; - valueItem.childValue = self.childValueMap[value]; - var fatherArrayValue = (fartherValue + "").split(BI.BlankSplitChar); - valueItem.value = fatherArrayValue.length > 1 ? fatherArrayValue : fartherValue; - } else { - valueItem.value = value; - } - result.push(valueItem); - }); - return result; - } - - -}); - -BI.MultiLayerDownListPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerDownListPopup.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; -BI.shortcut("bi.multi_layer_down_list_popup", BI.MultiLayerDownListPopup); diff --git a/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js b/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js deleted file mode 100644 index 8674a4f8b..000000000 --- a/src/widget/multilayerselecttree/__test__/multilayerselecttree.combo.test.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2019/9/18 - */ - -describe("multilayer_select_tree", function () { - - var items = [{id: -1, pId: -2, value: "根目录", text: "根目录"}, - {id: 1, pId: -1, value: "第一级目录1", text: "第一级目录1"}, - {id: 11, pId: 1, value: "第二级文件1", text: "第二级文件1"}, - {id: 12, pId: 1, value: "第二级目录2", text: "第二级目录2"}, - {id: 121, pId: 12, value: "第三级目录1", text: "第三级目录1"}, - {id: 122, pId: 12, value: "第三级文件1", text: "第三级文件1"}, - {id: 1211, pId: 121, value: "第四级目录1", text: "第四级目录1"}, - { - id: 12111, - pId: 1211, - value: "第五级文件1", - text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" - }, - {id: 2, pId: -1, value: "第一级目录2", text: "第一级目录2"}, - {id: 21, pId: 2, value: "第二级目录3", text: "第二级目录3"}, - {id: 22, pId: 2, value: "第二级文件2", text: "第二级文件2"}, - {id: 211, pId: 21, value: "第三级目录2", text: "第三级目录2"}, - {id: 212, pId: 21, value: "第三级文件2", text: "第三级文件2"}, - {id: 2111, pId: 211, value: "第四级文件1", text: "第四级文件1"}]; - - /** - * test_author_windy - **/ - it("defaultValue_allowEdit", function () { - var tree = BI.Test.createWidget({ - type: "bi.multilayer_select_tree_combo", - width: 300, - height: 24, - allowEdit: true, - items: BI.deepClone(items), - value: "第一级目录2" - }); - expect(tree.getValue()).to.equal("第一级目录2"); - tree.destroy(); - }); - - /** - * test_author_windy - **/ - it("defaultValue_not_allowEdit", function () { - var tree = BI.Test.createWidget({ - type: "bi.multilayer_select_tree_combo", - width: 300, - height: 24, - items: BI.deepClone(items), - value: "第一级目录2" - }); - expect(tree.getValue()).to.equal("第一级目录2"); - tree.destroy(); - }); - - /** - * test_author_windy - **/ - it("点选选值", function (done) { - var tree = BI.Test.createWidget({ - type: "bi.multilayer_select_tree_combo", - width: 300, - height: 24, - allowEdit: true, - items: BI.deepClone(items), - value: "第一级目录2" - }); - tree.element.find(".bi-multi-layer-select-tree-trigger").click(); - BI.nextTick(function () { - tree.element.find(".bi-select-tree-plus-group-node").click(); - expect(tree.getValue()[0]).to.equal("根目录"); - tree.destroy(); - done(); - }); - }); - - /** - * test_author_windy - **/ - it("搜索选值", function (done) { - var tree = BI.Test.createWidget({ - type: "bi.multilayer_select_tree_combo", - width: 300, - height: 24, - allowEdit: true, - items: BI.deepClone(items) - }); - BI.nextTick(function () { - tree.element.find(".bi-multi-layer-select-tree-trigger .tip-text-style").click(); - // 这边为啥要加呢,因为input的setValue中有nextTick - BI.nextTick(function () { - BI.Test.triggerKeyDown(tree.element.find(".bi-multi-layer-select-tree-trigger .bi-input"), "2", 50, function () { - BI.nextTick(function () { - tree.element.find(".bi-select-tree-mid-plus-group-node").click(); - expect(tree.getValue()[0]).to.equal("第一级目录2"); - tree.destroy(); - done(); - }); - }); - }); - }); - }); - - /** - * test_author_windy - **/ - it("新增值", function (done) { - var tree = BI.Test.createWidget({ - type: "bi.multilayer_select_tree_combo", - width: 300, - height: 24, - allowEdit: true, - allowInsertValue: true, - items: BI.deepClone(items) - }); - BI.nextTick(function () { - tree.element.find(".bi-multi-layer-select-tree-trigger .tip-text-style").click(); - // 这边为啥要加呢,因为input的setValue中有nextTick - BI.nextTick(function () { - BI.Test.triggerKeyDown(tree.element.find(".bi-multi-layer-select-tree-trigger .bi-input"), "z", 50, function () { - BI.nextTick(function () { - tree.element.find(".bi-text-button:contains(+点击新增\"z\")").click(); - expect(tree.getValue()[0]).to.equal("z"); - tree.destroy(); - done(); - }); - }); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/widget/multilayerselecttree/multilayerselecttree.combo.js b/src/widget/multilayerselecttree/multilayerselecttree.combo.js deleted file mode 100644 index ec2a9a393..000000000 --- a/src/widget/multilayerselecttree/multilayerselecttree.combo.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @class BI.MultiLayerSelectTreeCombo - * @extends BI.Widget - */ -BI.MultiLayerSelectTreeCombo = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSelectTreeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-select-tree-combo", - isDefaultInit: false, - height: 24, - text: "", - defaultText: "", - itemsCreator: BI.emptyFn, - items: [], - allowEdit: false, - allowSearchValue: false, - allowInsertValue: false, - isNeedAdjustWidth: true, - status: "", // "error","warning" - }); - }, - - render: function () { - var self = this, o = this.options; - - var cls = (o.simple ? "bi-border-bottom " : "bi-border bi-border-radius ") + (BI.isKey(o.status) ? ("status-" + o.status) : ""); - - var baseConfig = this._getBaseConfig(); - - if (o.allowEdit) { - return { - type: "bi.absolute", - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - cls, - items: [ - { - el: BI.extend(baseConfig, this._getSearchConfig()), - top: 0, bottom: 0, right: 0, left: 0 - }, { - el: self._getTriggerIconButton(), - top: 0, bottom: 0, right: 0, - }, - ] - }; - } - - return BI.extend(baseConfig, { - el: { - type: "bi.single_tree_trigger", - ref: function (_ref) { - self.textTrigger = _ref; - }, - text: o.text, - defaultText: o.defaultText, - height: BI.toPix(o.height, 2), - items: o.items, - value: o.value, - tipType: o.tipType, - warningTitle: o.warningTitle, - valueFormatter: o.valueFormatter, - } - }, { cls }); - }, - - _getBaseConfig: function () { - var self = this, o = this.options; - return { - type: "bi.combo", - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - container: o.container, - destroyWhenHide: o.destroyWhenHide, - adjustLength: 2, - ref: function (_ref) { - self.combo = _ref; - }, - popup: { - el: { - type: "bi.multilayer_select_tree_popup", - isDefaultInit: o.isDefaultInit, - itemsCreator: o.itemsCreator, - items: o.items, - ref: function (_ref) { - self.trigger && self.trigger.getSearcher().setAdapter(_ref); - }, - listeners: [{ - eventName: BI.MultiLayerSelectTreePopup.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE); - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - } - }], - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - }); - } - }, - value: o.value, - maxHeight: 400, - maxWidth: o.isNeedAdjustWidth ? "auto" : 500, - minHeight: 240 - }, - isNeedAdjustWidth: o.isNeedAdjustWidth, - listeners: [{ - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }; - }, - - _getSearchConfig: function () { - var self = this, o = this.options; - return { - el: { - type: "bi.multilayer_select_tree_trigger", - container: o.container, - allowInsertValue: o.allowInsertValue, - allowSearchValue: o.allowSearchValue, - allowEdit: o.allowEdit, - cls: "multilayer-select-tree-trigger", - ref: function (_ref) { - self.trigger = _ref; - }, - items: o.items, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - watermark: o.watermark, - height: BI.toPix(o.height, 2), - text: o.text, - defaultText: o.defaultText, - value: o.value, - tipType: o.tipType, - warningTitle: o.warningTitle, - title: o.title, - listeners: [{ - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE); - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - } - }, { - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_STOP, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM, - action: function () { - var value = self.trigger.getSearcher().getKeyword(); - self.combo.setValue([value]); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE); - } - }] - }, - toggle: !o.allowEdit, - hideChecker: function (e) { - // 新增传配置container后对应hideChecker的修改 - // IE11下,popover(position: fixed)下放置下拉控件(position: fixed), 滚动的时候会异常卡顿 - // 通过container参数将popup放置于popover之外解决此问题, 其他下拉控件由于元素少或者有分页,所以 - // 卡顿不明显, 先在此做尝试, 并在FineUI特殊处理待解决文档中标记跟踪 - return (o.container && self.trigger.getSearcher().isSearching() && self.trigger.getSearcher().getView().element.find(e.target).length > 0) ? false : self.triggerBtn?.element.find(e.target).length === 0; - - }, - listeners: [{ - eventName: BI.Combo.EVENT_AFTER_HIDEVIEW, - action: function () { - self.trigger.stopEditing(); - } - }, { - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }; - }, - - _getTriggerIconButton: function () { - var self = this, o = this.options; - return { - type: "bi.trigger_icon_button", - cls: "bi-trigger trigger-icon-button", - ref: function (_ref) { - self.triggerBtn = _ref; - }, - width: BI.toPix(o.height, 2), - height: BI.toPix(o.height, 2), - listeners: [ - { - eventName: BI.TriggerIconButton.EVENT_CHANGE, - action: function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - } - } - ] - }; - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - getSearcher: function () { - return this.trigger ? this.trigger.getSearcher() : this.textTrigger.getTextor(); - }, - - clear: function () { - // do some work - }, - - setStatus: function (status) { - if (BI.isKey(this.options.status)) { - this.element.removeClass("status-" + this.options.status); - } - this.element.addClass("status-" + status); - this.options.status = status; - }, - - setTipType: function (v) { - this.trigger ? this.trigger.setTipType(v) : this.textTrigger.setTipType(v); - }, - - populate: function (items) { - this.combo.populate(items); - }, - - focus: function () { - this.trigger ? this.trigger.focus() : this.textTrigger.focus(); - }, - - blur: function () { - this.trigger ? this.trigger.blur() : this.textTrigger.blur(); - }, - - showView: function () { - this.combo.showView(); - }, - - setWaterMark: function (v) { - this.trigger ? this.trigger.setWaterMark(v) : this.textTrigger.setWaterMark(v); - } -}); - -BI.MultiLayerSelectTreeCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiLayerSelectTreeCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiLayerSelectTreeCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiLayerSelectTreeCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerSelectTreeCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiLayerSelectTreeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiLayerSelectTreeCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.shortcut("bi.multilayer_select_tree_combo", BI.MultiLayerSelectTreeCombo); diff --git a/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js b/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js deleted file mode 100644 index 8c59f5992..000000000 --- a/src/widget/multilayerselecttree/multilayerselecttree.insert.search.pane.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Created by GUY on 2016/1/26. - * - * @class BI.MultiLayerSelectTreeInsertSearchPane - * @extends BI.Pane - */ - -BI.MultiLayerSelectTreeInsertSearchPane = BI.inherit(BI.Widget, { - - props: function() { - return { - baseCls: "bi-multilayer-select-tree-popup", - tipText: BI.i18nText("BI-No_Selected_Item"), - isDefaultInit: false, - itemsCreator: BI.emptyFn, - items: [], - value: "" - }; - }, - - render: function() { - var self = this, o = this.options; - this.tree = BI.createWidget({ - type: "bi.multilayer_select_level_tree", - isDefaultInit: o.isDefaultInit, - items: o.items, - itemsCreator: o.itemsCreator === BI.emptyFn ? BI.emptyFn : function (op, callback) { - o.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(o.keywordGetter()); - }); - }, - keywordGetter: o.keywordGetter, - value: o.value, - scrollable: null, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.MultiLayerSelectLevelTree.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeInsertSearchPane.EVENT_CHANGE); - } - }] - }); - return { - type: "bi.vertical", - scrolly: false, - scrollable: true, - vgap: 5, - items: [{ - type: "bi.text_button", - invisible: true, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: 24, - cls: "bi-high-light", - hgap: 5, - ref: function (_ref) { - self.addNotMatchTip = _ref; - }, - handler: function () { - self.fireEvent(BI.MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM, o.keywordGetter()); - } - }, this.tree] - }; - }, - - setKeyword: function (keyword) { - var showTip = BI.isEmptyArray(this.tree.getAllLeaves()); - this.addNotMatchTip.setVisible(showTip); - showTip && this.addNotMatchTip.setText(BI.i18nText("BI-Basic_Click_To_Add_Text", keyword)); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - this.tree.populate(items); - } -}); - -BI.MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; -BI.MultiLayerSelectTreeInsertSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multilayer_select_tree_insert_search_pane", BI.MultiLayerSelectTreeInsertSearchPane); \ No newline at end of file diff --git a/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js b/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js deleted file mode 100644 index 9072c3284..000000000 --- a/src/widget/multilayerselecttree/multilayerselecttree.leveltree.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * guy - * 二级树 - * @class BI.MultiLayerSelectLevelTree - * @extends BI.Pane - */ -BI.MultiLayerSelectLevelTree = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSelectLevelTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-select-level-tree", - isDefaultInit: false, - items: [], - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn, - value: "", - scrollable: true - }); - }, - - _init: function () { - var o = this.options; - BI.MultiLayerSelectLevelTree.superclass._init.apply(this, arguments); - - this.storeValue = o.value; - - this.initTree(this.options.items); - - this.check(); - }, - - _formatItems: function (nodes, layer, pNode) { - var self = this, o = this.options; - var keyword = o.keywordGetter(); - BI.each(nodes, function (i, node) { - var extend = { - isFirstNode: i === 0, - isLastNode: i === nodes.length - 1, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT - }; - node.layer = layer; - if (!BI.isKey(node.id)) { - node.id = BI.UUID(); - } - node.keyword = node.keyword || keyword; - extend.pNode = pNode; - if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) { - extend.type = "bi.tree_node"; - extend.selectable = true; - BI.defaults(node, extend); - self._formatItems(node.children, layer + 1, node); - } else { - extend.type = "bi.tree_item"; - BI.defaults(node, extend); - } - }); - return nodes; - }, - - _assertId: function (sNodes) { - BI.each(sNodes, function (i, node) { - node.id = node.id || BI.UUID(); - }); - }, - - // 构造树结构, - initTree: function (nodes) { - var self = this, o = this.options; - var hasNext = false; - this.empty(); - this._assertId(nodes); - this.tree = BI.createWidget({ - type: "bi.custom_tree", - cls: "tree-view display-table", - expander: { - // type: "bi.select_tree_expander", - type: "bi.tree_expander", - selectable: true, - isDefaultInit: o.isDefaultInit, - el: {}, - popup: { - type: "bi.custom_tree" - } - }, - - items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), - itemsCreator: function (op, callback) { - (op.times === 1 && !op.node) && BI.nextTick(function () { - self.loading(); - }); - o.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - (op.times === 1 && !op.node) && self._populate(ob.items); - callback(self._formatItems(BI.Tree.transformToTreeFormat(ob.items), op.node ? op.node.layer + 1 : 0, op.node)); - self.setValue(self.storeValue); - (op.times === 1 && !op.node) && BI.nextTick(function () { - self.loaded(); - }); - }); - }, - value: o.value, - - el: { - type: "bi.loader", - isDefaultInit: o.itemsCreator !== BI.emptyFn, - el: { - type: "bi.button_tree", - chooseType: o.chooseType === BI.Selection.None ? BI.Selection.None : BI.Selection.Default, // 不使用buttontree内部getValue逻辑 - behaviors: o.behaviors, - layouts: [{ - type: "bi.vertical" - }] - }, - hasNext: function () { - return hasNext; - } - } - }); - this.tree.on(BI.Controller.EVENT_CHANGE, function (type, value) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.setValue(value); - self.fireEvent(BI.MultiLayerSelectLevelTree.EVENT_CHANGE, arguments); - } - }); - - BI.createWidget({ - type: "bi.adaptive", - element: this, - scrollable: o.scrollable, - items: [this.tree] - }); - }, - - _populate: function () { - BI.MultiLayerSelectLevelTree.superclass.populate.apply(this, arguments); - }, - - populate: function (nodes) { - this._populate(nodes); - BI.isNull(nodes) ? this.tree.populate() : this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0)); - }, - - setValue: function (v) { - // getValue依赖于storeValue, 那么不选的时候就不要更新storeValue了 - if (this.options.chooseType === BI.Selection.None) { - } else { - this.storeValue = v; - this.tree.setValue(v); - } - }, - - getValue: function () { - return BI.isArray(this.storeValue) ? - this.storeValue : BI.isNull(this.storeValue) ? - [] : [this.storeValue]; - }, - - getAllLeaves: function () { - return this.tree.getAllLeaves(); - }, - - getNodeById: function (id) { - return this.tree.getNodeById(id); - }, - - getNodeByValue: function (id) { - return this.tree.getNodeByValue(id); - } -}); -BI.MultiLayerSelectLevelTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.multilayer_select_level_tree", BI.MultiLayerSelectLevelTree); diff --git a/src/widget/multilayerselecttree/multilayerselecttree.popup.js b/src/widget/multilayerselecttree/multilayerselecttree.popup.js deleted file mode 100644 index 34dce3a58..000000000 --- a/src/widget/multilayerselecttree/multilayerselecttree.popup.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Created by GUY on 2016/1/26. - * - * @class BI.MultiLayerSelectTreePopup - * @extends BI.Pane - */ - -BI.MultiLayerSelectTreePopup = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSelectTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-select-tree-popup", - tipText: BI.i18nText("BI-No_Selected_Item"), - isDefaultInit: false, - itemsCreator: BI.emptyFn, - items: [], - value: "", - onLoaded: BI.emptyFn, - minHeight: 240 - }); - }, - - _init: function () { - BI.MultiLayerSelectTreePopup.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.tree = BI.createWidget({ - type: "bi.multilayer_select_level_tree", - isDefaultInit: o.isDefaultInit, - items: o.items, - itemsCreator: o.itemsCreator, - keywordGetter: o.keywordGetter, - value: o.value, - scrollable: null, - onLoaded: function () { - self.tree.check(); - o.onLoaded(); - } - }); - - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - scrollable: true, - element: this, - vgap: 5, - items: [this.tree] - }); - - this.tree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.tree.on(BI.MultiLayerSelectLevelTree.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiLayerSelectTreePopup.EVENT_CHANGE); - }); - - this.tree.css("min-height", BI.pixFormat(o.minHeight - 10)); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - this.tree.populate(items); - } -}); - -BI.MultiLayerSelectTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multilayer_select_tree_popup", BI.MultiLayerSelectTreePopup); \ No newline at end of file diff --git a/src/widget/multilayerselecttree/multilayerselecttree.trigger.js b/src/widget/multilayerselecttree/multilayerselecttree.trigger.js deleted file mode 100644 index 08f9f9a9e..000000000 --- a/src/widget/multilayerselecttree/multilayerselecttree.trigger.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Created by Windy on 2018/2/2. - */ -BI.MultiLayerSelectTreeTrigger = BI.inherit(BI.Trigger, { - - props: function () { - return { - extraCls: "bi-multi-layer-select-tree-trigger", - height: 24, - itemsCreator: BI.emptyFn, - watermark: BI.i18nText("BI-Basic_Search"), - allowSearchValue: false, - title: BI.bind(this._getShowText, this) - }; - }, - - render: function () { - var self = this, o = this.options; - if (o.itemsCreator === BI.emptyFn) { - this._initData(); - } - - return { - type: "bi.horizontal_fill", - items: [ - { - el: { - type: "bi.searcher", - ref: function () { - self.searcher = this; - }, - masker: BI.isNotNull(o.container) ? { - offset: {}, - container: o.container - } : { - offset: {} - }, - isAutoSearch: false, - el: { - type: "bi.default_text_editor", - ref: function () { - self.editor = this; - }, - defaultText: o.defaultText, - text: BI.isKey(o.value) ? this._digest(o.value) : o.text, - value: o.value, - height: o.height, - tipText: "", - watermark: o.watermark, - listeners: [{ - eventName: BI.StateEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_FOCUS); - } - }, { - eventName: BI.StateEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_BLUR); - } - }, { - eventName: BI.StateEditor.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_SEARCHING); - } - }] - }, - popup: { - type: o.allowInsertValue ? "bi.multilayer_select_tree_insert_search_pane" : "bi.multilayer_select_tree_popup", - itemsCreator: o.itemsCreator === BI.emptyFn ? BI.emptyFn : function (op, callback) { - op.keyword = self.editor.getValue(); - o.itemsCreator(op, callback); - }, - keywordGetter: function () { - return self.editor.getValue(); - }, - cls: "bi-card", - listeners: [{ - eventName: BI.MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM, - action: function () { - self.options.text = self.getSearcher().getKeyword(); - self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM); - } - }], - ref: function (_ref) { - self.popup = _ref; - } - }, - onSearch: function (obj, callback) { - var keyword = obj.keyword; - if (o.itemsCreator === BI.emptyFn) { - callback(self._getSearchItems(keyword)); - o.allowInsertValue && self.popup.setKeyword(keyword); - } else { - callback(); - } - }, - listeners: [{ - eventName: BI.Searcher.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE); - } - }] - }, - width: "fill", - rgap: 24 - }, - ] - }; - }, - - _initData: function () { - var o = this.options; - this.tree = new BI.Tree(); - this.nodes = BI.Tree.treeFormat(BI.deepClone(o.items)); - this.tree.initTree(this.nodes); - }, - - _getSearchItems: function (keyword) { - var self = this, o = this.options; - // 把数组搜索换成用BI.tree搜索节点, 搜到了就不再往下搜索 - var items = []; - this.tree.traverse(function (node) { - var find = BI.Func.getSearchResult(self.tree.isRoot(node) ? [] : BI.concat([node.text], (o.allowSearchValue ? [node.value] : [])), keyword); - if (find.find.length > 0 || find.match.length > 0) { - items.push(node); - return true; - } - }); - return this._fillTreeStructure4Search(items, "id"); - }, - - _createJson: function (node, open) { - return { - id: node.id, - pId: node.pId, - text: node.text, - value: node.value, - isParent: BI.isNotEmptyArray(node.children), - open: open - }; - }, - - _getChildren: function (node) { - var self = this; - node.children = node.children || []; - var nodes = []; - BI.each(node.children, function (idx, child) { - var children = self._getChildren(child); - nodes = nodes.concat(children); - }); - return node.children.concat(nodes); - }, - - // 将搜索到的节点进行补充,构造成一棵完整的树 - _fillTreeStructure4Search: function (leaves) { - var self = this; - var result = []; - var queue = []; - BI.each(leaves, function (idx, node) { - queue.push({ pId: node.pId }); - result.push(node); - result = result.concat(self._getChildren(node)); - }); - queue.reverse(); - while (BI.isNotEmptyArray(queue)) { - var node = queue.pop(); - var pNode = this.tree.search(this.tree.getRoot(), node.pId, "id"); - if (pNode != null) { - pNode.open = true; - queue.push({ pId: pNode.pId }); - result.push(pNode); - } - } - return BI.uniqBy(BI.map(result, function (idx, node) { - return self._createJson(node, node.open); - }), "id"); - }, - - _digest: function (v) { - var o = this.options; - if (BI.isFunction(o.valueFormatter)) { - return o.valueFormatter(v); - } - - var result = BI.find(o.items, function (i, item) { - return item.value === v; - }); - - return BI.isNotNull(result) ? result.text : (o.text ?? v); - }, - - _getShowText: function () { - return this.editor.getText(); - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - getSearcher: function () { - return this.searcher; - }, - - populate: function (items) { - this.options.items = items; - this._initData(items); - }, - - setValue: function (v) { - this.editor.setState(this._digest(v[0])); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - focus: function () { - this.searcher.focus(); - }, - - blur: function () { - this.searcher.blur(); - }, - - setWaterMark: function (v) { - this.searcher.setWaterMark(v); - } -}); - -BI.MultiLayerSelectTreeTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiLayerSelectTreeTrigger.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiLayerSelectTreeTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiLayerSelectTreeTrigger.EVENT_STOP = "EVENT_STOP"; -BI.MultiLayerSelectTreeTrigger.EVENT_START = "EVENT_START"; -BI.MultiLayerSelectTreeTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; -BI.shortcut("bi.multilayer_select_tree_trigger", BI.MultiLayerSelectTreeTrigger); diff --git a/src/widget/multilayerselecttree/node/node.first.plus.js b/src/widget/multilayerselecttree/node/node.first.plus.js deleted file mode 100644 index c187ab7a5..000000000 --- a/src/widget/multilayerselecttree/node/node.first.plus.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSelectTreeFirstPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSelectTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-select-tree-first-plus-group-node bi-list-item-active", - layer: 0, // 第几层级 - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = BI.createWidget({ - type: "bi.select_tree_first_plus_group_node", - cls: "bi-list-item-none", - stopPropagation: true, - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - keyword: o.keyword, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py - }); - this.node.on(BI.Controller.EVENT_CHANGE, function (type) { - self.setSelected(self.isSelected()); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - // BI.count(0, o.layer, function (index) { - // items.push({ - // type: "bi.layout", - // cls: BI.contains(needBlankLayers, index) ? "" : "base-line-conn-background", - // width: 12, - // height: o.height - // }); - // }); - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - isSelected: function () { - return this.node.isSelected(); - }, - - setSelected: function (b) { - BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass.setSelected.apply(this, arguments); - this.node.setSelected(b); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); - this.node.setOpened(v); - } -}); - -BI.shortcut("bi.multilayer_select_tree_first_plus_group_node", BI.MultiLayerSelectTreeFirstPlusGroupNode); diff --git a/src/widget/multilayerselecttree/node/node.last.plus.js b/src/widget/multilayerselecttree/node/node.last.plus.js deleted file mode 100644 index 89f4a1efa..000000000 --- a/src/widget/multilayerselecttree/node/node.last.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSelectTreeLastPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSelectTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSelectTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-select-tree-last-plus-group-node bi-list-item-active", - layer: 0, // 第几层级 - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSelectTreeLastPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = BI.createWidget({ - type: "bi.select_tree_last_plus_group_node", - cls: "bi-list-item-none", - stopPropagation: true, - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - keyword: o.keyword, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py - }); - this.node.on(BI.Controller.EVENT_CHANGE, function (type) { - self.setSelected(self.isSelected()); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - isSelected: function () { - return this.node.isSelected(); - }, - - setSelected: function (b) { - BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.setSelected.apply(this, arguments); - this.node.setSelected(b); - }, - - doClick: function () { - BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); - this.node.setOpened(v); - } -}); - -BI.shortcut("bi.multilayer_select_tree_last_plus_group_node", BI.MultiLayerSelectTreeLastPlusGroupNode); diff --git a/src/widget/multilayerselecttree/node/node.mid.plus.js b/src/widget/multilayerselecttree/node/node.mid.plus.js deleted file mode 100644 index 6dad3105f..000000000 --- a/src/widget/multilayerselecttree/node/node.mid.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSelectTreeMidPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSelectTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSelectTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-select-tree-mid-plus-group-node bi-list-item-active", - layer: 0, // 第几层级 - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSelectTreeMidPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = BI.createWidget({ - type: "bi.select_tree_mid_plus_group_node", - cls: "bi-list-item-none", - stopPropagation: true, - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - keyword: o.keyword, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py - }); - this.node.on(BI.Controller.EVENT_CHANGE, function (type) { - self.setSelected(self.isSelected()); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - isSelected: function () { - return this.node.isSelected(); - }, - - setSelected: function (b) { - BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.setSelected.apply(this, arguments); - this.node.setSelected(b); - }, - - doClick: function () { - BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); - this.node.setOpened(v); - } -}); - -BI.shortcut("bi.multilayer_select_tree_mid_plus_group_node", BI.MultiLayerSelectTreeMidPlusGroupNode); diff --git a/src/widget/multilayerselecttree/node/node.plus.js b/src/widget/multilayerselecttree/node/node.plus.js deleted file mode 100644 index d63d2d9d8..000000000 --- a/src/widget/multilayerselecttree/node/node.plus.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSelectTreePlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSelectTreePlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSelectTreePlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-select-tree-first-plus-group-node bi-list-item-active", - layer: 0, // 第几层级 - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSelectTreePlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = BI.createWidget({ - type: "bi.select_tree_plus_group_node", - cls: "bi-list-item-none", - stopPropagation: true, - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - keyword: o.keyword, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py - }); - this.node.on(BI.Controller.EVENT_CHANGE, function (type) { - self.setSelected(self.isSelected()); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - isSelected: function () { - return this.node.isSelected(); - }, - - setSelected: function (b) { - BI.MultiLayerSelectTreePlusGroupNode.superclass.setSelected.apply(this, arguments); - this.node.setSelected(b); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSelectTreePlusGroupNode.superclass.setOpened.apply(this, arguments); - this.node.setOpened(v); - } -}); - -BI.shortcut("bi.multilayer_select_tree_plus_group_node", BI.MultiLayerSelectTreePlusGroupNode); diff --git a/src/widget/multilayersingletree/multilayersingletree.combo.js b/src/widget/multilayersingletree/multilayersingletree.combo.js deleted file mode 100644 index 4e26c1a0c..000000000 --- a/src/widget/multilayersingletree/multilayersingletree.combo.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * 多层级下拉单选树 - * Created by GUY on 2016/1/26. - * - * @class BI.MultiLayerSingleTreeCombo - * @extends BI.Widget - */ -BI.MultiLayerSingleTreeCombo = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleTreeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-single-tree-combo", - isDefaultInit: false, - height: 24, - text: "", - defaultText: "", - itemsCreator: BI.emptyFn, - items: [], - allowEdit: false, - allowSearchValue: false, - allowInsertValue: false, - isNeedAdjustWidth: true, - }); - }, - - render: function () { - var self = this, o = this.options; - - var cls = (o.simple ? "bi-border-bottom bi-focus-shadow " : "bi-border bi-border-radius bi-focus-shadow ") + (BI.isKey(o.status) ? ("status-" + o.status) : ""); - - var baseConfig = this._getBaseConfig(); - - if (o.allowEdit) { - return { - type: "bi.absolute", - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - cls, - items: [ - { - el: BI.extend(baseConfig, this._getSearchConfig()), - top: 0, bottom: 0, right: 0, left: 0 - }, { - el: self._getTriggerIconButton(), - top: 0, bottom: 0, right: 0, - }, - ] - }; - } - - return BI.extend(baseConfig, { - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - el: { - type: "bi.single_tree_trigger", - ref: function (_ref) { - self.textTrigger = _ref; - }, - text: o.text, - defaultText: o.defaultText, - height: BI.toPix(o.height, 2), - items: o.items, - value: o.value, - tipType: o.tipType, - warningTitle: o.warningTitle, - valueFormatter: o.valueFormatter, - }, - }, { cls }); - }, - - _getBaseConfig: function () { - var self = this, o = this.options; - return { - type: "bi.combo", - container: o.container, - destroyWhenHide: o.destroyWhenHide, - adjustLength: 2, - ref: function (_ref) { - self.combo = _ref; - }, - popup: { - el: { - type: "bi.multilayer_single_tree_popup", - isDefaultInit: o.isDefaultInit, - itemsCreator: o.itemsCreator, - items: o.items, - ref: function (_ref) { - self.trigger && self.trigger.getSearcher().setAdapter(_ref); - }, - listeners: [{ - eventName: BI.MultiLayerSingleTreePopup.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE); - } - }], - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - }); - } - }, - value: o.value, - maxHeight: 400, - maxWidth: o.isNeedAdjustWidth ? "auto" : 500, - minHeight: 240 - }, - isNeedAdjustWidth: o.isNeedAdjustWidth, - listeners: [{ - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }; - }, - - _getSearchConfig: function () { - var self = this, o = this.options; - return { - el: { - type: "bi.multilayer_single_tree_trigger", - container: o.container, - allowInsertValue: o.allowInsertValue, - allowSearchValue: o.allowSearchValue, - cls: "multilayer-single-tree-trigger", - ref: function (_ref) { - self.trigger = _ref; - }, - watermark: o.watermark, - items: o.items, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - height: BI.toPix(o.height, 2), - text: o.text, - defaultText: o.defaultText, - value: o.value, - tipType: o.tipType, - warningTitle: o.warningTitle, - title: o.title, - listeners: [{ - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE, - action: function () { - self.setValue(this.getValue()); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE); - } - }, { - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_FOCUS); - } - }, { - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_BLUR); - } - }, { - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_SEARCHING, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_SEARCHING); - } - }, { - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_STOP, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_STOP); - } - }, { - eventName: BI.MultiLayerSingleTreeTrigger.EVENT_ADD_ITEM, - action: function () { - var value = self.trigger.getSearcher().getKeyword(); - self.combo.setValue([value]); - self.combo.hideView(); - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE); - } - }] - }, - toggle: !o.allowEdit, - hideChecker: function (e) { - // 新增传配置container后对应hideChecker的修改 - // IE11下,popover(position: fixed)下放置下拉控件(position: fixed), 滚动的时候会异常卡顿 - // 通过container参数将popup放置于popover之外解决此问题, 其他下拉控件由于元素少或者有分页,所以 - // 卡顿不明显, 先在此做尝试, 并在FineUI特殊处理待解决文档中标记跟踪 - return (o.container && self.trigger.getSearcher().isSearching() && self.trigger.getSearcher().getView().element.find(e.target).length > 0) ? false : self.triggerBtn?.element.find(e.target).length === 0; - }, - listeners: [{ - eventName: BI.Combo.EVENT_AFTER_HIDEVIEW, - action: function () { - self.trigger.stopEditing(); - } - }, { - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_BEFORE_POPUPVIEW); - } - }] - }; - }, - - _getTriggerIconButton: function () { - var self = this, o = this.options; - return { - type: "bi.trigger_icon_button", - cls: "bi-trigger trigger-icon-button", - ref: function (_ref) { - self.triggerBtn = _ref; - }, - width: BI.toPix(o.height, 2), - height: BI.toPix(o.height, 2), - listeners: [ - { - eventName: BI.TriggerIconButton.EVENT_CHANGE, - action: function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - } - } - ] - }; - }, - - getSearcher: function () { - return this.trigger ? this.trigger.getSearcher() : this.textTrigger.getTextor(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.combo.setValue(v); - }, - - getValue: function () { - return this.combo.getValue(); - }, - - setStatus: function (status) { - if (BI.isKey(this.options.status)) { - this.element.removeClass("status-" + this.options.status); - } - this.element.addClass("status-" + status); - this.options.status = status; - }, - - setTipType: function (v) { - this.trigger ? this.trigger.setTipType(v) : this.textTrigger.setTipType(v); - }, - - populate: function (items) { - this.combo.populate(items); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - showView: function () { - this.combo.showView(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.MultiLayerSingleTreeCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiLayerSingleTreeCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiLayerSingleTreeCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiLayerSingleTreeCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerSingleTreeCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiLayerSingleTreeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.multilayer_single_tree_combo", BI.MultiLayerSingleTreeCombo); diff --git a/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js b/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js deleted file mode 100644 index 8e7fa06de..000000000 --- a/src/widget/multilayersingletree/multilayersingletree.insert.search.pane.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Created by GUY on 2016/1/26. - * - * @class BI.MultiLayerSingleTreeInsertSearchPane - * @extends BI.Pane - */ - -BI.MultiLayerSingleTreeInsertSearchPane = BI.inherit(BI.Widget, { - - props: function() { - return { - baseCls: "bi-multilayer-single-tree-popup", - tipText: BI.i18nText("BI-No_Selected_Item"), - isDefaultInit: false, - itemsCreator: BI.emptyFn, - items: [], - value: "" - }; - }, - - render: function() { - var self = this, o = this.options; - this.tree = BI.createWidget({ - type: "bi.multilayer_single_level_tree", - isDefaultInit: o.isDefaultInit, - items: o.items, - itemsCreator: o.itemsCreator === BI.emptyFn ? BI.emptyFn : function (op, callback) { - o.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(o.keywordGetter()); - }); - }, - keywordGetter: o.keywordGetter, - value: o.value, - scrollable: null, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.MultiLayerSelectLevelTree.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeInsertSearchPane.EVENT_CHANGE); - } - }] - }); - return { - type: "bi.vertical", - scrolly: false, - scrollable: true, - vgap: 5, - items: [{ - type: "bi.text_button", - invisible: true, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: 24, - cls: "bi-high-light", - hgap: 5, - ref: function (_ref) { - self.addNotMatchTip = _ref; - }, - handler: function () { - self.fireEvent(BI.MultiLayerSingleTreeInsertSearchPane.EVENT_ADD_ITEM, o.keywordGetter()); - } - }, this.tree] - }; - }, - - setKeyword: function (keyword) { - var showTip = BI.isEmptyArray(this.tree.getAllLeaves()); - this.addNotMatchTip.setVisible(showTip); - showTip && this.addNotMatchTip.setText(BI.i18nText("BI-Basic_Click_To_Add_Text", keyword)); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - this.tree.populate(items); - } -}); - -BI.MultiLayerSingleTreeInsertSearchPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; -BI.MultiLayerSingleTreeInsertSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multilayer_single_tree_insert_search_pane", BI.MultiLayerSingleTreeInsertSearchPane); \ No newline at end of file diff --git a/src/widget/multilayersingletree/multilayersingletree.leveltree.js b/src/widget/multilayersingletree/multilayersingletree.leveltree.js deleted file mode 100644 index 8e14aa749..000000000 --- a/src/widget/multilayersingletree/multilayersingletree.leveltree.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * guy - * 二级树 - * @class BI.MultiLayerSingleLevelTree - * @extends BI.Single - */ -BI.MultiLayerSingleLevelTree = BI.inherit(BI.Pane, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleLevelTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-single-level-tree", - isDefaultInit: false, - items: [], - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn, - chooseType: BI.Selection.Single, - scrollable: true - }); - }, - - _init: function () { - var o = this.options; - BI.MultiLayerSingleLevelTree.superclass._init.apply(this, arguments); - - this.storeValue = o.value; - - this.initTree(this.options.items); - - this.check(); - }, - - _formatItems: function (nodes, layer, pNode) { - var self = this, o = this.options; - var keyword = o.keywordGetter(); - BI.each(nodes, function (i, node) { - var extend = { - isFirstNode: i === 0, - isLastNode: i === nodes.length - 1, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT - }; - node.layer = layer; - if (!BI.isKey(node.id)) { - node.id = BI.UUID(); - } - node.keyword = node.keyword || keyword; - extend.pNode = pNode; - if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) { - extend.type = "bi.tree_node"; - extend.selectable = false; - BI.defaults(node, extend); - self._formatItems(node.children, layer + 1, node); - } else { - extend.type = "bi.tree_item"; - BI.defaults(node, extend); - } - }); - return nodes; - }, - - _assertId: function (sNodes) { - BI.each(sNodes, function (i, node) { - node.id = node.id || BI.UUID(); - }); - }, - - // 构造树结构, - initTree: function (nodes) { - var self = this, o = this.options; - var hasNext = false; - this.empty(); - this._assertId(nodes); - this.tree = BI.createWidget({ - type: "bi.custom_tree", - cls: "tree-view display-table", - expander: { - type: "bi.tree_expander", - isDefaultInit: o.isDefaultInit, - el: {}, - popup: { - type: "bi.custom_tree" - } - }, - - items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), - value: o.value, - itemsCreator: function (op, callback) { - (op.times === 1 && !op.node) && BI.nextTick(function () { - self.loading(); - }); - o.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - (op.times === 1 && !op.node) && self._populate(ob.items); - callback(self._formatItems(BI.Tree.transformToTreeFormat(ob.items), op.node ? op.node.layer + 1 : 0, op.node)); - self.setValue(self.storeValue); - (op.times === 1 && !op.node) && BI.nextTick(function () { - self.loaded(); - }); - }); - }, - - el: { - type: "bi.loader", - isDefaultInit: o.itemsCreator !== BI.emptyFn, - el: { - type: "bi.button_tree", - chooseType: o.chooseType === BI.Selection.None ? BI.Selection.None : BI.Selection.Default, // 不使用buttontree内部getValue逻辑 - behaviors: o.behaviors, - layouts: [{ - type: "bi.vertical" - }] - }, - hasNext: function () { - return hasNext; - } - } - }); - this.tree.on(BI.Controller.EVENT_CHANGE, function (type, v) { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.setValue(v); - self.fireEvent(BI.MultiLayerSingleLevelTree.EVENT_CHANGE, v); - } - }); - - BI.createWidget({ - type: "bi.adaptive", - element: this, - scrollable: o.scrollable, - items: [this.tree] - }); - }, - - _populate: function () { - BI.MultiLayerSelectLevelTree.superclass.populate.apply(this, arguments); - }, - - populate: function (nodes) { - this._populate(nodes); - BI.isNull(nodes) ? this.tree.populate() : this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0)); - }, - - setValue: function (v) { - // getValue依赖于storeValue, 那么不选的时候就不要更新storeValue了 - if (this.options.chooseType === BI.Selection.None) { - } else { - this.storeValue = v; - this.tree.setValue(v); - } - }, - - getValue: function () { - return BI.isArray(this.storeValue) ? - this.storeValue : BI.isNull(this.storeValue) ? - [] : [this.storeValue]; - }, - - getAllLeaves: function () { - return this.tree.getAllLeaves(); - }, - - getNodeById: function (id) { - return this.tree.getNodeById(id); - }, - - getNodeByValue: function (id) { - return this.tree.getNodeByValue(id); - } -}); -BI.MultiLayerSingleLevelTree.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.multilayer_single_level_tree", BI.MultiLayerSingleLevelTree); diff --git a/src/widget/multilayersingletree/multilayersingletree.popup.js b/src/widget/multilayersingletree/multilayersingletree.popup.js deleted file mode 100644 index 630c38237..000000000 --- a/src/widget/multilayersingletree/multilayersingletree.popup.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Created by GUY on 2016/1/26. - * - * @class BI.MultiLayerSingleTreePopup - * @extends BI.Pane - */ - -BI.MultiLayerSingleTreePopup = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multilayer-singletree-popup", - tipText: BI.i18nText("BI-No_Selected_Item"), - isDefaultInit: false, - itemsCreator: BI.emptyFn, - items: [], - onLoaded: BI.emptyFn, - minHeight: 240 - }); - }, - - _init: function () { - BI.MultiLayerSingleTreePopup.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.tree = BI.createWidget({ - type: "bi.multilayer_single_level_tree", - isDefaultInit: o.isDefaultInit, - items: o.items, - itemsCreator: o.itemsCreator, - keywordGetter: o.keywordGetter, - value: o.value, - scrollable: null, - onLoaded: function () { - self.tree.check(); - o.onLoaded(); - } - }); - - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - scrollable: true, - element: this, - vgap: 5, - items: [this.tree] - }); - - this.tree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.tree.on(BI.MultiLayerSingleLevelTree.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiLayerSingleTreePopup.EVENT_CHANGE); - }); - - this.tree.css("min-height", BI.pixFormat(o.minHeight - 10)); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - this.tree.populate(items); - } -}); - -BI.MultiLayerSingleTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multilayer_single_tree_popup", BI.MultiLayerSingleTreePopup); \ No newline at end of file diff --git a/src/widget/multilayersingletree/multilayersingletree.trigger.js b/src/widget/multilayersingletree/multilayersingletree.trigger.js deleted file mode 100644 index 617c70d7b..000000000 --- a/src/widget/multilayersingletree/multilayersingletree.trigger.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Created by Windy on 2018/2/2. - */ -BI.MultiLayerSingleTreeTrigger = BI.inherit(BI.Trigger, { - - props: function () { - return { - extraCls: "bi-multi-layer-single-tree-trigger", - height: 24, - itemsCreator: BI.emptyFn, - watermark: BI.i18nText("BI-Basic_Search"), - allowSearchValue: false, - title: BI.bind(this._getShowText, this) - }; - }, - - render: function () { - var self = this, o = this.options; - if (o.itemsCreator === BI.emptyFn) { - this._initData(); - } - - return { - type: "bi.horizontal_fill", - items: [ - { - el: { - type: "bi.searcher", - ref: function () { - self.searcher = this; - }, - masker: BI.isNotNull(o.container) ? { - offset: {}, - container: o.container - } : { - offset: {} - }, - isAutoSearch: false, - el: { - type: "bi.default_text_editor", - ref: function () { - self.editor = this; - }, - defaultText: o.defaultText, - text: BI.isKey(o.value) ? this._digest(o.value) : o.text, - value: o.value, - height: o.height, - tipText: "", - watermark: o.watermark, - listeners: [{ - eventName: BI.StateEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_FOCUS); - } - }, { - eventName: BI.StateEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_BLUR); - } - }, { - eventName: BI.StateEditor.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_SEARCHING); - } - }] - }, - popup: { - type: o.allowInsertValue ? "bi.multilayer_single_tree_insert_search_pane" : "bi.multilayer_single_tree_popup", - itemsCreator: o.itemsCreator === BI.emptyFn ? BI.emptyFn : function (op, callback) { - op.keyword = self.editor.getValue(); - o.itemsCreator(op, callback); - }, - keywordGetter: function () { - return self.editor.getValue(); - }, - cls: "bi-card", - listeners: [{ - eventName: BI.MultiLayerSingleTreeInsertSearchPane.EVENT_ADD_ITEM, - action: function () { - self.options.text = self.getSearcher().getKeyword(); - self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_ADD_ITEM); - } - }], - ref: function (_ref) { - self.popup = _ref; - } - }, - onSearch: function (obj, callback) { - var keyword = obj.keyword; - if (o.itemsCreator === BI.emptyFn) { - callback(self._getSearchItems(keyword)); - o.allowInsertValue && self.popup.setKeyword(keyword); - } else { - callback(); - } - }, - listeners: [{ - eventName: BI.Searcher.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE); - } - }] - }, - width: "fill", - rgap: 24, - }, - ] - }; - }, - - _initData: function () { - var o = this.options; - this.tree = new BI.Tree(); - this.nodes = BI.Tree.treeFormat(BI.deepClone(o.items)); - this.tree.initTree(this.nodes); - }, - - _getSearchItems: function (keyword) { - var self = this, o = this.options; - // 把数组搜索换成用BI.tree搜索节点, 搜到了就不再往下搜索 - var items = []; - this.tree.traverse(function (node) { - var find = BI.Func.getSearchResult(self.tree.isRoot(node) ? [] : BI.concat([node.text], (o.allowSearchValue ? [node.value] : [])), keyword); - if (find.find.length > 0 || find.match.length > 0) { - items.push(node); - return true; - } - }); - return this._fillTreeStructure4Search(items, "id"); - }, - - _createJson: function (node, open) { - return { - id: node.id, - pId: node.pId, - text: node.text, - value: node.value, - isParent: BI.isNotEmptyArray(node.children), - open: open - }; - }, - - _getChildren: function (node) { - var self = this; - node.children = node.children || []; - var nodes = []; - BI.each(node.children, function (idx, child) { - var children = self._getChildren(child); - nodes = nodes.concat(children); - }); - return node.children.concat(nodes); - }, - - // 将搜索到的节点进行补充,构造成一棵完整的树 - _fillTreeStructure4Search: function (leaves) { - var self = this; - var result = []; - var queue = []; - BI.each(leaves, function (idx, node) { - queue.push({ pId: node.pId }); - result.push(node); - result = result.concat(self._getChildren(node)); - }); - queue.reverse(); - while (BI.isNotEmptyArray(queue)) { - var node = queue.pop(); - var pNode = this.tree.search(this.tree.getRoot(), node.pId, "id"); - if (pNode != null) { - pNode.open = true; - queue.push({ pId: pNode.pId }); - result.push(pNode); - } - } - return BI.uniqBy(BI.map(result, function (idx, node) { - return self._createJson(node, node.open); - }), "id"); - }, - - _digest: function (v) { - var o = this.options; - - if (BI.isFunction(o.valueFormatter)) { - return o.valueFormatter(v); - } - - var result = BI.find(o.items, function (i, item) { - return item.value === v; - }); - - return BI.isNotNull(result) ? result.text : (o.text ?? v); - }, - - _getShowText: function () { - return this.editor.getText(); - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - getSearcher: function () { - return this.searcher; - }, - - populate: function (items) { - this.options.items = items; - this._initData(); - }, - - setValue: function (v) { - this.editor.setState(this._digest(v[0])); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - focus: function () { - this.searcher.focus(); - }, - - blur: function () { - this.searcher.blur(); - }, - - setWaterMark: function (v) { - this.searcher.setWaterMark(v); - } -}); -BI.MultiLayerSingleTreeTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiLayerSingleTreeTrigger.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiLayerSingleTreeTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiLayerSingleTreeTrigger.EVENT_STOP = "EVENT_STOP"; -BI.MultiLayerSingleTreeTrigger.EVENT_START = "EVENT_START"; -BI.MultiLayerSingleTreeTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiLayerSingleTreeTrigger.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; -BI.shortcut("bi.multilayer_single_tree_trigger", BI.MultiLayerSingleTreeTrigger); diff --git a/src/widget/multilayersingletree/node/node.first.plus.js b/src/widget/multilayersingletree/node/node.first.plus.js deleted file mode 100644 index 51177bcce..000000000 --- a/src/widget/multilayersingletree/node/node.first.plus.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeFirstPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSingleTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-single-tree-first-plus-group-node bi-list-item", - layer: 0, // 第几层级 - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = this._createNode(); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - doClick: function () { - BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.node)) { - this.node.setOpened(v); - } - }, - - _createNode: function () { - var self = this, o = this.options; - - return BI.createWidget({ - type: "bi.first_plus_group_node", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - open: o.open, - isLastNode: o.isLastNode, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }] - }); - } -}); - -BI.shortcut("bi.multilayer_single_tree_first_plus_group_node", BI.MultiLayerSingleTreeFirstPlusGroupNode); diff --git a/src/widget/multilayersingletree/node/node.last.plus.js b/src/widget/multilayersingletree/node/node.last.plus.js deleted file mode 100644 index 007837f5c..000000000 --- a/src/widget/multilayersingletree/node/node.last.plus.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeLastPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSingleTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSingleTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-single-tree-last-plus-group-node bi-list-item", - layer: 0, // 第几层级 - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeLastPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = this._createNode(); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - doClick: function () { - BI.MultiLayerSingleTreeLastPlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSingleTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.node)) { - this.node.setOpened(v); - } - }, - - _createNode: function () { - var self = this, o = this.options; - - return BI.createWidget({ - type: "bi.last_plus_group_node", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }] - }); - } -}); - -BI.shortcut("bi.multilayer_single_tree_last_plus_group_node", BI.MultiLayerSingleTreeLastPlusGroupNode); diff --git a/src/widget/multilayersingletree/node/node.mid.plus.js b/src/widget/multilayersingletree/node/node.mid.plus.js deleted file mode 100644 index e8709cf78..000000000 --- a/src/widget/multilayersingletree/node/node.mid.plus.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * 加号表示的组节点 - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeMidPlusGroupNode - * @extends BI.NodeButton - */ -BI.MultiLayerSingleTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSingleTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-single-tree-mid-plus-group-node bi-list-item", - layer: 0, // 第几层级 - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeMidPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = this._createNode(); - - var items = []; - - items.push({ - el: this.node, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, 12), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - doClick: function () { - BI.MultiLayerSingleTreeMidPlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSingleTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.node)) { - this.node.setOpened(v); - } - }, - - _createNode: function () { - var self = this, o = this.options; - - return BI.createWidget({ - type: "bi.mid_plus_group_node", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - open: o.open, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }] - }); - } -}); - -BI.shortcut("bi.multilayer_single_tree_mid_plus_group_node", BI.MultiLayerSingleTreeMidPlusGroupNode); diff --git a/src/widget/multilayersingletree/node/node.plus.js b/src/widget/multilayersingletree/node/node.plus.js deleted file mode 100644 index bcff49737..000000000 --- a/src/widget/multilayersingletree/node/node.plus.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - *@desc 根节点,既是第一个又是最后一个 - *@author dailer - *@date 2018/09/16 - */ -BI.MultiLayerSingleTreePlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.MultiLayerSingleTreePlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-multilayer-single-tree-plus-group-node bi-list-item", - layer: 0, // 第几层级 - id: "", - pId: "", - open: false, - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreePlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.node = this._createNode(); - - var needBlankLayers = []; - var pNode = o.pNode; - while (pNode) { - if (pNode.isLastNode) { - needBlankLayers.push(pNode.layer) - } - pNode = pNode.pNode; - } - - var items = []; - BI.count(0, o.layer, function (index) { - items.push({ - type: "bi.layout", - cls: BI.contains(needBlankLayers, index) ? "" : "base-line-conn-background", - width: 12, - height: o.height - }); - }); - items.push(this.node); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, 12), - items: items - }); - }, - - doRedMark: function () { - this.node.doRedMark.apply(this.node, arguments); - }, - - unRedMark: function () { - this.node.unRedMark.apply(this.node, arguments); - }, - - doClick: function () { - BI.MultiLayerSingleTreePlusGroupNode.superclass.doClick.apply(this, arguments); - this.node.setSelected(this.isSelected()); - }, - - setOpened: function (v) { - BI.MultiLayerSingleTreePlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.node)) { - this.node.setOpened(v); - } - }, - - _createNode: function () { - var self = this, o = this.options; - - return BI.createWidget({ - type: "bi.plus_group_node", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - open: o.open, - isLastNode: o.isLastNode, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }] - }); - } -}); - -BI.shortcut("bi.multilayer_single_tree_plus_group_node", BI.MultiLayerSingleTreePlusGroupNode); \ No newline at end of file diff --git a/src/widget/multilayersingletree/treeitem/item.first.treeleaf.js b/src/widget/multilayersingletree/treeitem/item.first.treeleaf.js deleted file mode 100644 index 4cc5203e4..000000000 --- a/src/widget/multilayersingletree/treeitem/item.first.treeleaf.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeFirstTreeLeafItem - * @extends BI.BasicButton - */ -BI.MultiLayerSingleTreeFirstTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multilayer-single-tree-first-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - layer: 0, - id: "", - pId: "", - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.item = BI.createWidget({ - type: "bi.first_tree_leaf_item", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.item.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.item, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doHighLight: function () { - this.item.doHighLight.apply(this.item, arguments); - }, - - unHighLight: function () { - this.item.unHighLight.apply(this.item, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - }, - - doClick: function () { - BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass.doClick.apply(this, arguments); - this.item.setSelected(this.isSelected()); - }, - - setSelected: function (v) { - BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass.setSelected.apply(this, arguments); - this.item.setSelected(v); - } -}); - -BI.shortcut("bi.multilayer_single_tree_first_tree_leaf_item", BI.MultiLayerSingleTreeFirstTreeLeafItem); diff --git a/src/widget/multilayersingletree/treeitem/item.last.treeleaf.js b/src/widget/multilayersingletree/treeitem/item.last.treeleaf.js deleted file mode 100644 index 9aa604737..000000000 --- a/src/widget/multilayersingletree/treeitem/item.last.treeleaf.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeLastTreeLeafItem - * @extends BI.BasicButton - */ -BI.MultiLayerSingleTreeLastTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleTreeLastTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multilayer-single-tree-last-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - layer: 0, - id: "", - pId: "", - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeLastTreeLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.item = BI.createWidget({ - type: "bi.last_tree_leaf_item", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.item.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.item, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doHighLight: function () { - this.item.doHighLight.apply(this.item, arguments); - }, - - unHighLight: function () { - this.item.unHighLight.apply(this.item, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - }, - - doClick: function () { - BI.MultiLayerSingleTreeLastTreeLeafItem.superclass.doClick.apply(this, arguments); - this.item.setSelected(this.isSelected()); - }, - - setSelected: function (v) { - BI.MultiLayerSingleTreeLastTreeLeafItem.superclass.setSelected.apply(this, arguments); - this.item.setSelected(v); - } -}); - -BI.shortcut("bi.multilayer_single_tree_last_tree_leaf_item", BI.MultiLayerSingleTreeLastTreeLeafItem); diff --git a/src/widget/multilayersingletree/treeitem/item.mid.treeleaf.js b/src/widget/multilayersingletree/treeitem/item.mid.treeleaf.js deleted file mode 100644 index eed7d553c..000000000 --- a/src/widget/multilayersingletree/treeitem/item.mid.treeleaf.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * - * Created by GUY on 2016/1/27. - * @class BI.MultiLayerSingleTreeMidTreeLeafItem - * @extends BI.BasicButton - */ -BI.MultiLayerSingleTreeMidTreeLeafItem = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.MultiLayerSingleTreeMidTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-multilayer-single-tree-mid-tree-leaf-item bi-list-item-active", - logic: { - dynamic: false - }, - layer: 0, - id: "", - pId: "", - height: 24 - }); - }, - _init: function () { - BI.MultiLayerSingleTreeMidTreeLeafItem.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.item = BI.createWidget({ - type: "bi.mid_tree_leaf_item", - cls: "bi-list-item-none", - logic: { - dynamic: true - }, - id: o.id, - pId: o.pId, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - py: o.py, - keyword: o.keyword - }); - this.item.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) {// 本身实现click功能 - return; - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - var items = []; - - items.push({ - el: this.item, - lgap: o.layer * BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2 - }); - BI.createWidget({ - type: "bi.horizontal_adapt", - element: this, - columnSize: BI.makeArray(o.layer, BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT / 2), - items: items - }); - }, - - doHighLight: function () { - this.item.doHighLight.apply(this.item, arguments); - }, - - unHighLight: function () { - this.item.unHighLight.apply(this.item, arguments); - }, - - getId: function () { - return this.options.id; - }, - - getPId: function () { - return this.options.pId; - }, - - doClick: function () { - BI.MultiLayerSingleTreeMidTreeLeafItem.superclass.doClick.apply(this, arguments); - this.item.setSelected(this.isSelected()); - }, - - setSelected: function (v) { - BI.MultiLayerSingleTreeMidTreeLeafItem.superclass.setSelected.apply(this, arguments); - this.item.setSelected(v); - } -}); - -BI.shortcut("bi.multilayer_single_tree_mid_tree_leaf_item", BI.MultiLayerSingleTreeMidTreeLeafItem); diff --git a/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js b/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js deleted file mode 100644 index a7750bb26..000000000 --- a/src/widget/multiselect/__test__/multiselect.loader.nobar.test.js +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2019/9/18 - */ - -describe("multi_select_no_bar_series", function () { - - var _getItemsByTimes, _itemsCreator, itemSelectorGetter, searchItemSelectorGetter, _hasNextByTimes, items; - before(function () { - _getItemsByTimes = function (items, times) { - var res = []; - for (var i = (times - 1) * 100; items[i] && i < times * 100; i++) { - res.push(items[i]); - } - return res; - }; - - _hasNextByTimes = function (items, times) { - return times * 100 < items.length; - }; - - _itemsCreator = function (options, callback) { - var items = BI.map(BI.makeArray(100, null), function(idx, v) { - return { - text: idx, - value: idx, - title: idx - }; - }); - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.match.concat(search.find); - }); - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - callback({ - items: _getItemsByTimes(items, options.times), - hasNext: _hasNextByTimes(items, options.times) - }); - }; - - itemSelectorGetter = function (array) { - return BI.map(array, function (idx, num) { - return ".bi-multi-select-popup-view .bi-loader .bi-button-group .bi-multi-select-item:nth-child(" + num + ")"; - }); - }; - - searchItemSelectorGetter = function (array) { - return BI.map(array, function (idx, num) { - return ".bi-multi-select-search-pane .bi-loader .bi-button-group .bi-multi-select-item:nth-child(" + num + ")"; - }); - }; - - }) - - /** - * test_author_windy - **/ - it("setValue", function () { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - widget.setValue([1, 2]); - expect(widget.getValue()).to.deep.equal([1, 2]); - widget.destroy(); - }); - - /** - * test_author_windy - **/ - it("getValue", function () { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator, - value: [1, 2, 3] - }); - expect(widget.getValue()).to.deep.equal([1, 2, 3]); - widget.destroy(); - }); - - /** - * test_author_windy - **/ - it("点选选值", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - widget.element.find(".bi-multi-select-trigger").click(); - // 为什么要delay 300呢,因为按钮有debounce - BI.delay(function () { - // 点选1、2、3 - BI.each(itemSelectorGetter([1,2,3]), function (idx, selector) { - widget.element.find(selector).click(); - }); - // 取消勾选1、2 - BI.delay(function () { - BI.each(itemSelectorGetter([1,2]), function (idx, selector) { - widget.element.find(selector).click(); - }); - expect(widget.getValue()).to.deep.equal([2]); - widget.destroy(); - done(); - }, 300); - }, 300); - }); - - /** - * test_author_windy - **/ - it("搜索选值", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - BI.nextTick(function () { - widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); - // 这边为啥要加呢,因为input的setValue中有nextTick - BI.nextTick(function () { - BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "2", 50, function () { - BI.nextTick(function () { - BI.each(searchItemSelectorGetter([1,2]), function (idx, selector) { - widget.element.find(selector).click(); - }); - expect(widget.getValue()).to.deep.equal([2, 12]); - widget.destroy(); - done(); - }); - }); - }); - }); - }); - - /** - * test_author_windy - **/ - it("查看已选", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_no_bar_combo", - width: 220, - itemsCreator: function (op, callback) { - callback({ - items: items, - hasNext: false - }); - }, - value: [1, 2] - }); - BI.nextTick(function () { - widget.element.find(".bi-multi-select-check-selected-button").click(); - BI.delay(function () { - expect(widget.element.find(".display-list-item").length).to.equal(2); - widget.destroy(); - done(); - }, 300); - }); - }); - - /** - * test_author_windy - **/ - it("setValue", function () { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - widget.setValue([1, 2]); - expect(widget.getValue()).to.deep.equal([1, 2]); - widget.destroy(); - }); - - /** - * test_author_windy - **/ - it("getValue", function () { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator, - value: [1, 2, 3] - }); - expect(widget.getValue()).to.deep.equal([1, 2, 3]); - widget.destroy(); - }); - - - /** - * test_author_windy - **/ - it("点选选值1", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - widget.element.find(".bi-multi-select-trigger").click(); - // 为什么要delay 300呢,因为按钮有debounce - BI.delay(function () { - // 点选1、2、3 - BI.each(itemSelectorGetter([1,2,3]), function (idx, selector) { - widget.element.find(selector).click(); - }); - // 取消勾选1、2、3 - BI.delay(function () { - BI.each(itemSelectorGetter([1,2]), function (idx, selector) { - widget.element.find(selector).click(); - }); - expect(widget.getValue()).to.deep.equal([2]); - widget.destroy(); - done(); - }, 300); - }, 300); - }); - - /** - * test_author_windy - **/ - it("搜索选值1", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - BI.nextTick(function () { - widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); - // 这边为啥要加呢,因为input的setValue中有nextTick - BI.nextTick(function () { - BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "2", 50, function () { - BI.nextTick(function () { - BI.each(searchItemSelectorGetter([1,2]), function (idx, selector) { - widget.element.find(selector).click(); - }); - expect(widget.getValue()).to.deep.equal([2, 12]); - widget.destroy(); - done(); - }); - }); - }); - }); - }); - - /** - * test_author_windy - **/ - it("新增值1", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator - }); - BI.nextTick(function () { - widget.element.find(".bi-multi-select-trigger .tip-text-style").click(); - // 这边为啥要加呢,因为input的setValue中有nextTick - BI.nextTick(function () { - BI.Test.triggerKeyDown(widget.element.find(".bi-multi-select-trigger .bi-input"), "z", 50, function () { - BI.nextTick(function () { - widget.element.find(".bi-text-button:contains(+点击新增\"z\")").click(); - expect(widget.getValue()).to.deep.equal(["z"]); - widget.destroy(); - done(); - }); - }); - }); - }); - }); - - /** - * test_author_windy - **/ - it("查看已选1", function (done) { - var widget = BI.Test.createWidget({ - type: "bi.multi_select_insert_no_bar_combo", - width: 220, - itemsCreator: _itemsCreator, - value: { - type: 1, - value: [1, 2] - } - }); - BI.nextTick(function () { - widget.element.find(".bi-multi-select-check-selected-button").click(); - BI.delay(function () { - expect(widget.element.find(".display-list-item").length).to.equal(2); - widget.destroy(); - done(); - }, 300); - }); - }); -}); \ No newline at end of file diff --git a/src/widget/multiselect/__test__/multiselect.loader.test.js b/src/widget/multiselect/__test__/multiselect.loader.test.js deleted file mode 100644 index 324598714..000000000 --- a/src/widget/multiselect/__test__/multiselect.loader.test.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2019/9/18 - */ \ No newline at end of file diff --git a/src/widget/multiselect/__test__/multiselectcombo.test.js b/src/widget/multiselect/__test__/multiselectcombo.test.js deleted file mode 100644 index 324598714..000000000 --- a/src/widget/multiselect/__test__/multiselectcombo.test.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2019/9/18 - */ \ No newline at end of file diff --git a/src/widget/multiselect/__test__/multiselectinsert.combo.test.js b/src/widget/multiselect/__test__/multiselectinsert.combo.test.js deleted file mode 100644 index 324598714..000000000 --- a/src/widget/multiselect/__test__/multiselectinsert.combo.test.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2019/9/18 - */ \ No newline at end of file diff --git a/src/widget/multiselect/check/multiselect.check.pane.js b/src/widget/multiselect/check/multiselect.check.pane.js deleted file mode 100644 index 958375876..000000000 --- a/src/widget/multiselect/check/multiselect.check.pane.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * - * @class BI.MultiSelectCheckPane - * @extends BI.Widget - */ -BI.MultiSelectCheckPane = BI.inherit(BI.Widget, { - - constants: { - height: 12, - lgap: 10, - tgap: 10, - bgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectCheckPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-check-pane bi-background", - items: [], - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - onClickContinueSelect: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiSelectCheckPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.storeValue = opts.value || {}; - this.display = BI.createWidget({ - type: "bi.display_selected_list", - items: opts.items, - itemsCreator: function (op, callback) { - op = BI.extend(op || {}, { - selectedValues: self.storeValue.value - }); - if (self.storeValue.type === BI.Selection.Multi) { - callback({ - items: BI.map(self.storeValue.value, function (i, v) { - var txt = opts.valueFormatter(v) || v; - - return { - text: txt, - value: v, - title: txt - }; - }) - }); - - return; - } - opts.itemsCreator(op, callback); - } - }); - - this.continueSelect = BI.createWidget({ - type: "bi.text_button", - title: BI.i18nText("BI-Continue_Select"), - text: BI.i18nText("BI-Continue_Select"), - cls: "multi-select-check-selected bi-high-light" - }); - - this.continueSelect.on(BI.TextButton.EVENT_CHANGE, function () { - opts.onClickContinueSelect(); - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - height: this.constants.height, - el: { - type: "bi.vertical_adapt", - columnSize: ["auto", "auto"], - cls: "multi-select-continue-select", - items: [ - { - el: { - type: "bi.label", - title: BI.i18nText("BI-Selected_Data"), - text: BI.i18nText("BI-Selected_Data") - }, - lgap: this.constants.lgap - }, - { - el: this.continueSelect, - hgap: this.constants.lgap - }] - }, - tgap: this.constants.tgap - }, { - height: "fill", - el: this.display, - tgap: this.constants.bgap - }] - }); - }, - - setValue: function (v) { - this.storeValue = v || {}; - }, - - empty: function () { - this.display.empty(); - }, - - populate: function () { - this.display.populate.apply(this.display, arguments); - } -}); - -BI.shortcut("bi.multi_select_check_pane", BI.MultiSelectCheckPane); diff --git a/src/widget/multiselect/check/multiselect.display.js b/src/widget/multiselect/check/multiselect.display.js deleted file mode 100644 index 30442583c..000000000 --- a/src/widget/multiselect/check/multiselect.display.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * - * - * 查看已选弹出层的展示面板 - * @class BI.DisplaySelectedList - * @extends BI.Widget - */ -BI.DisplaySelectedList = BI.inherit(BI.Pane, { - - constants: { - height: 24, - lgap: 10 - }, - - _defaultConfig: function () { - return BI.extend(BI.DisplaySelectedList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-display-list", - itemsCreator: BI.emptyFn, - items: [] - }); - }, - - _init: function () { - BI.DisplaySelectedList.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.hasNext = false; - var cacheItems = []; - - this.button_group = BI.createWidget({ - type: "bi.list_pane", - element: this, - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - items: this._createItems(opts.items), - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - layouts: [ - { - type: "bi.vertical", - lgap: 10 - } - ] - }, - itemsCreator: function (options, callback) { - if (options.times === 1) { - cacheItems = []; - } - - if (cacheItems.length > 0) { - var renderedItems = cacheItems.slice(0, 100); - cacheItems = cacheItems.slice(100); - self.hasNext = cacheItems.length > 0; - callback(self._createItems(renderedItems)); - return; - } - - opts.itemsCreator(options, function (ob) { - self.hasNext = !!ob.hasNext; - var firstItemsCount = 100 + ob.items.length % 100; - if (ob.items.length > 100) { - cacheItems = ob.items.slice(firstItemsCount); - self.hasNext = (firstItemsCount === ob.items.length) ? false : true; - } - callback(self._createItems(ob.items.slice(0, firstItemsCount))); - }); - }, - hasNext: function () { - return self.hasNext; - } - }); - }, - - _createItems: function (items) { - return BI.createItems(items, { - type: "bi.icon_text_item", - cls: "cursor-default check-font icon-size-12 display-list-item bi-tips", - once: true, - invalid: true, - selected: true, - height: this.constants.height, - logic: { - dynamic: true - } - }); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - if (arguments.length === 0) { - this.button_group.populate(); - } else { - this.button_group.populate(this._createItems(items)); - } - } -}); - -BI.shortcut("bi.display_selected_list", BI.DisplaySelectedList); diff --git a/src/widget/multiselect/loader.js b/src/widget/multiselect/loader.js deleted file mode 100644 index 0101d8908..000000000 --- a/src/widget/multiselect/loader.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * 加载控件 - * - * Created by GUY on 2015/8/31. - * @class BI.Loader - * @extends BI.Widget - */ -BI.MultiSelectInnerLoader = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInnerLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-inner-loader", - - direction: "top", - isDefaultInit: true, // 是否默认初始化数据 - logic: { - dynamic: true, - scrolly: true - }, - - // 下面是button_group的属性 - el: { - type: "bi.button_group", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [ - { - type: "bi.vertical" - } - ] - }, - - items: [], - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, - - // 下面是分页信息 - count: false, - prev: false, - next: {}, - hasPrev: BI.emptyFn, - hasNext: BI.emptyFn - }); - }, - - _nextLoad: function () { - var self = this, o = this.options; - this.next.setLoading(); - if (this.cachItems && this.cachItems.length > 0) { - this.next.setLoaded(); - this.addItems(this.cachItems.slice(0, 100)); - this.cachItems = this.cachItems.slice(100); - return; - } - o.itemsCreator.apply(this, [ - { times: ++this.times }, function () { - self.next.setLoaded(); - self.addItems.apply(self, arguments); - } - ]); - }, - - render: function () { - var self = this, o = this.options; - if (o.itemsCreator === false) { - o.next = false; - } - this.button_group = BI.createWidget(o.el, { - type: "bi.button_group", - chooseType: 0, - items: o.items, - behaviors: {}, - layouts: [ - { - type: "bi.vertical" - } - ], - value: o.value - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - var node = self.cachGroup.getNodeByValue(value); - if (node) { - node.setSelected(obj.isSelected()); - } - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - if (type === BI.Events.CLICK) { - self.fireEvent(BI.Loader.EVENT_CHANGE, obj); - } - }); - - var renderEngine = BI.Widget._renderEngine; - BI.Widget.registerRenderEngine(BI.Element.renderEngine); - this.cachGroup = BI.createWidget(o.el, { - type: "bi.button_group", - root: true, - chooseType: 0, - items: o.items, - behaviors: {}, - layouts: [ - { - type: "bi.vertical" - } - ], - value: o.value - }); - BI.Widget.registerRenderEngine(renderEngine); - - if (o.next !== false) { - this.next = BI.createWidget(BI.extend({ - type: "bi.loading_bar" - }, o.next)); - this.next.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self._nextLoad(); - } - }); - } - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.button_group, this.next] - }); - - o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { - o.isDefaultInit && BI.isEmpty(o.items) && this._populate(); - }, this)); - }, - - hasNext: function () { - var o = this.options; - if (BI.isNumber(o.count)) { - return this.count < o.count; - } - if (this.cachItems && this.cachItems.length > 0) { - return true; - } - return !!o.hasNext.apply(this, [ - { - times: this.times, - count: this.count - } - ]); - }, - - addItems: function (items) { - this.count += items.length; - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.options.items = this.options.items.concat(items); - this.next.setLoaded(); - } else { - this.next.setEnd(); - } - } - // cacheGroup渲染的是全量的,如果这次加载更多add的items是从cacheItems里面拿的,那不用再add了 - if (this.cachItems.length > 0) { - this.button_group.addItems(...arguments); - return; - } - var renderEngine = BI.Widget._renderEngine; - BI.Widget.registerRenderEngine(BI.Element.renderEngine); - this.cachGroup.addItems.apply(this.cachGroup, arguments); - BI.Widget.registerRenderEngine(renderEngine); - this.button_group.addItems.apply(this.button_group, arguments); - }, - - _populate: function (items) { - var self = this, o = this.options; - if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { - o.itemsCreator.apply(this, [ - { times: 1 }, function (items, keyword) { - if (arguments.length === 0) { - throw new Error("Parameter cannot be empty"); - } - self.populate.apply(self, arguments); - o.onLoaded(); - } - ]); - return false; - } - this.options.items = (items || []).slice(0, 100 + (items || []).length % 100); - this.times = 1; - this.count = 0; - this.count += items.length; - return true; - }, - - populate: function (items, keyword) { - if (this._populate.apply(this, arguments)) { - this.cachItems = []; - var firstItemsCount = 100 + items.length % 100; - if (items.length > firstItemsCount) { - this.cachItems = items.slice(firstItemsCount); - } - var renderEngine = BI.Widget._renderEngine; - BI.Widget.registerRenderEngine(BI.Element.renderEngine); - this.cachGroup.populate.call(this.cachGroup, items, keyword); - BI.Widget.registerRenderEngine(renderEngine); - this.button_group.populate.call(this.button_group, items.slice(0, firstItemsCount), keyword); - - // hasNext依赖的是cacheItems计算,所以从_populate挪到populate里面 - if (BI.isObject(this.next)) { - if (this.hasNext()) { - this.next.setLoaded(); - } else { - this.next.invisible(); - } - } - } - }, - - setNotSelectedValue: function () { - this.button_group.setNotSelectedValue.apply(this.button_group, arguments); - this.cachGroup.setNotSelectedValue.apply(this.cachGroup, arguments); - }, - - getNotSelectedValue: function () { - return this.cachGroup.getNotSelectedValue(); - }, - - setAllSelected: function (v) { - this.button_group.setAllSelected(v); - this.cachGroup.setAllSelected(v); - }, - - setValue: function (value) { - var map = BI.makeObject(BI.isArray(value) ? value : [value]); - this.cachGroup.setValueMap.call(this.cachGroup, map); - this.button_group.setValueMap.call(this.button_group, map); - }, - - getValue: function () { - return this.cachGroup.getValue.apply(this.cachGroup, arguments); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - getAllLeaves: function () { - return this.button_group.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.button_group.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.button_group.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.button_group.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.button_group.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.button_group.getNodeByValue(value); - }, - - empty: function () { - this.button_group.empty(); - this.cachGroup.empty(); - BI.each([this.prev, this.next], function (i, ob) { - ob && ob.setVisible(false); - }); - } -}); -BI.MultiSelectInnerLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_inner_loader", BI.MultiSelectInnerLoader); diff --git a/src/widget/multiselect/multiselect.combo.js b/src/widget/multiselect/multiselect.combo.js deleted file mode 100644 index 5651fa04f..000000000 --- a/src/widget/multiselect/multiselect.combo.js +++ /dev/null @@ -1,484 +0,0 @@ -/** - * - * @class BI.MultiSelectCombo - * @extends BI.Single - */ -BI.MultiSelectCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-combo", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: 24, - allowEdit: true, - }); - }, - - _init: function () { - var self = this; - var o = this.options; - BI.MultiSelectCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - if (BI.isKey(self._startValue)) { - if (self.storeValue.type === BI.Selection.All) { - BI.remove(self.storeValue.value, self._startValue); - self.storeValue.assist = self.storeValue.assist || []; - BI.pushDistinct(self.storeValue.assist, self._startValue); - } else { - BI.pushDistinct(self.storeValue.value, self._startValue); - BI.remove(self.storeValue.assist, self._startValue); - } - } - - self.trigger.getSearcher().setState(self.storeValue); - self.numberCounter.setButtonChecked(self.storeValue); - }; - this.storeValue = BI.deepClone(o.value) || {}; - - this._assertValue(this.storeValue); - - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_trigger", - allowEdit: o.allowEdit, - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - defaultText: o.defaultText, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - itemHeight: o.itemHeight, - value: this.storeValue, - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self._setStartValue(""); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self._setStartValue(""); - self.fireEvent(BI.MultiSelectCombo.EVENT_STOP); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function (keywords) { - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.combo.setValue(self.storeValue); - assertShowValue(); - self.combo.populate(); - self._setStartValue(""); - } else { - self.combo.setValue(self.storeValue); - assertShowValue(); - } - self._dataChange = true; - }); - } - self.fireEvent(BI.MultiSelectCombo.EVENT_SEARCHING); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectCombo.EVENT_CLICK_ITEM); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectCombo.EVENT_CLICK_ITEM); - }); - } - self._dataChange = true; - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { - // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) - // 只需要更新查看面板的selectedValue用以请求已选数据 - self.numberCounter.updateSelectedValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: !o.allowEdit, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_select_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [{ - eventName: BI.MultiSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - }); - self.fireEvent(BI.MultiSelectCombo.EVENT_CLICK_ITEM); - }, - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, - action: function () { - self._defaultState(); - }, - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, - action: function () { - self._dataChange = true; - self.setValue(); - self._defaultState(); - }, - }], - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - }, - }, - value: o.value, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && self.numberCounter.element.find(e.target).length === 0; - }, - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self._populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self._stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.MultiSelectCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button", - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - value: this.storeValue, - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - this.updateSelectedValue(self.storeValue); - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0, - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0, - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter], - }, - right: o.height, - top: 0, - height: o.height, - }], - }); - }, - - _itemsCreator4Trigger: function (op, callback) { - var self = this; - var o = this.options; - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(BI.deepClone(self.getValue())); - } - callback.apply(self, arguments); - }); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this; - var o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - o.itemsCreator({ - type: BI.MultiSelectCombo.REQ_GET_ALL_DATA, - keywords: keywords, - }, function (ob) { - var values = BI.map(ob.items, "value"); - digest(values); - }); - - function digest(items) { - var selectedMap = self._makeMap(items); - BI.each(keywords, function (i, val) { - if (BI.isNotNull(selectedMap[val])) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - } - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this; - var o = this.options; - this._assertValue(res); - this.requesting = true; - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKey()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - this._adjust(callback); - return; - } - o.itemsCreator({ - type: BI.MultiSelectCombo.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKey()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - BI.remove(self.storeValue.assist, item); - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this; - var o = this.options; - adjust(); - callback(); - - function adjust() { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.MultiSelectCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _join: function (res, callback) { - var self = this; - var o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - BI.remove(self.storeValue.assist, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - _populate: function () { - this.combo.populate.apply(this.combo, arguments); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.combo.setValue(this.storeValue); - this.numberCounter.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - populate: function () { - this._populate.apply(this, arguments); - this.numberCounter.populateSwitcher.apply(this.numberCounter, arguments); - }, -}); - -BI.extend(BI.MultiSelectCombo, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1, -}); - -BI.MultiSelectCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiSelectCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiSelectCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - -BI.shortcut("bi.multi_select_combo", BI.MultiSelectCombo); diff --git a/src/widget/multiselect/multiselect.combo.nobar.js b/src/widget/multiselect/multiselect.combo.nobar.js deleted file mode 100644 index d757ebbca..000000000 --- a/src/widget/multiselect/multiselect.combo.nobar.js +++ /dev/null @@ -1,508 +0,0 @@ -/** - * - * @class BI.MultiSelectNoBarCombo - * @extends BI.Single - */ -BI.MultiSelectNoBarCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectNoBarCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-combo-no-bar", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: 24, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiSelectNoBarCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - if (BI.isKey(self._startValue)) { - if (self.storeValue.type === BI.Selection.All) { - BI.remove(self.storeValue.value, self._startValue); - self.storeValue.assist = self.storeValue.assist || []; - BI.pushDistinct(self.storeValue.assist, self._startValue); - } else { - BI.pushDistinct(self.storeValue.value, self._startValue); - BI.remove(self.storeValue.assist, self._startValue); - } - } - self.trigger.getSearcher().setState(self.storeValue); - self.numberCounter.setButtonChecked(self.storeValue); - }; - this.storeValue = { - type: BI.Selection.Multi, - value: BI.deepClone(o.value) || [] - }; - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_trigger", - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - defaultText: o.defaultText, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - itemFormatter: o.itemFormatter, - itemHeight: o.itemHeight, - value: { - type: BI.Selection.Multi, - value: o.value - } - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self._setStartValue(""); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self._setStartValue(""); - self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_STOP); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function (keywords) { - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.combo.setValue(self.storeValue); - assertShowValue(); - self.combo.populate(); - self._setStartValue(""); - } else { - self.combo.setValue(self.storeValue); - assertShowValue(); - } - self._dataChange = true; - }); - } - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - }); - } - self._dataChange = true; - self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_CLICK_ITEM); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { - // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) - // 只需要更新查看面板的selectedValue用以请求已选数据 - self.numberCounter.updateSelectedValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: false, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_select_no_bar_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [ - { - eventName: BI.MultiSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - }); - self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_CLICK_ITEM); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, - action: function () { - self._defaultState(); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, - action: function () { - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - } - ], - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - value: { - type: BI.Selection.Multi, - value: o.value - }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && self.numberCounter.element.find(e.target).length === 0; - } - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self._populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self._stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - value: { - type: BI.Selection.Multi, - value: o.value - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - this.updateSelectedValue(self.storeValue); - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - height: o.height - } - ] - }); - }, - - _addItem: function (assertShowValue, matched) { - var self = this; - var keyword = this.trigger.getSearcher().getKeyword(); - this._join({ - type: BI.Selection.Multi, - value: [keyword] - }, function () { - // 如果在不选的状态下直接把该值添加进来 - if (self.storeValue.type === BI.Selection.Multi) { - BI.pushDistinct(self.storeValue.value, keyword); - } - self.combo.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.populate(); - self._setStartValue(""); - self._dataChange = true; - }); - }, - - _itemsCreator4Trigger: function (op, callback) { - var self = this, o = this.options; - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(BI.deepClone(self.storeValue)); - } - callback.apply(self, arguments); - }); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - o.itemsCreator({ - type: BI.MultiSelectNoBarCombo.REQ_GET_ALL_DATA, - keywords: keywords - }, function (ob) { - var values = BI.map(ob.items, "value"); - digest(values); - }); - - function digest(items) { - var selectedMap = self._makeMap(items); - BI.each(keywords, function (i, val) { - if (BI.isNotNull(selectedMap[val])) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - } - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this.requesting = true; - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKey()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - this._adjust(callback); - return; - } - o.itemsCreator({ - type: BI.MultiSelectNoBarCombo.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKey()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - BI.remove(self.storeValue.assist, item); - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - adjust(); - callback(); - - function adjust() { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.MultiSelectNoBarCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - BI.remove(self.storeValue.assist, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - _populate: function () { - this.combo.populate.apply(this.combo, arguments); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue = { - type: BI.Selection.Multi, - value: v || [] - }; - this.combo.setValue(this.storeValue); - this.numberCounter.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this._populate.apply(this, arguments); - this.numberCounter.populateSwitcher.apply(this.numberCounter, arguments); - } -}); - -BI.extend(BI.MultiSelectNoBarCombo, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectNoBarCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiSelectNoBarCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectNoBarCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectNoBarCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectNoBarCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiSelectNoBarCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - -BI.shortcut("bi.multi_select_no_bar_combo", BI.MultiSelectNoBarCombo); diff --git a/src/widget/multiselect/multiselect.insert.combo.js b/src/widget/multiselect/multiselect.insert.combo.js deleted file mode 100644 index c18aa6d90..000000000 --- a/src/widget/multiselect/multiselect.insert.combo.js +++ /dev/null @@ -1,499 +0,0 @@ -/** - * - * @class BI.MultiSelectInsertCombo - * @extends BI.Single - */ -BI.MultiSelectInsertCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-insert-combo", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - allowEdit: true - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiSelectInsertCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - if (BI.isKey(self._startValue)) { - if (self.storeValue.type === BI.Selection.All) { - BI.remove(self.storeValue.value, self._startValue); - self.storeValue.assist = self.storeValue.assist || []; - BI.pushDistinct(self.storeValue.assist, self._startValue); - } else { - BI.pushDistinct(self.storeValue.value, self._startValue); - BI.remove(self.storeValue.assist, self._startValue); - } - } - self.trigger.getSearcher().setState(self.storeValue); - self.numberCounter.setButtonChecked(self.storeValue); - }; - this.storeValue = BI.deepClone(o.value) || {}; - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_insert_trigger", - allowEdit: o.allowEdit, - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - watermark: o.watermark, - defaultText: o.defaultText, - // adapter: this.popup, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - } - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - itemFormatter: o.itemFormatter, - itemHeight: o.itemHeight, - value: this.storeValue, - }); - - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_START, function () { - self._setStartValue(""); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_STOP, function () { - self._setStartValue(""); - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_STOP); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_PAUSE, function () { - self._addItem(assertShowValue, true); - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_ADD_ITEM, this.getSearcher().getKeyword()); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_SEARCHING, function (keywords) { - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.combo.setValue(self.storeValue); - assertShowValue(); - self.combo.populate(); - self._setStartValue(""); - } else { - self.combo.setValue(self.storeValue); - assertShowValue(); - } - self._dataChange = true; - }); - this.getSearcher().getKeywordsLength() > 2000 && BI.Msg.alert(BI.i18nText("BI-Basic_Prompt"), BI.i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); - } - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_SEARCHING); - }); - - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_CHANGE, function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CLICK_ITEM); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CLICK_ITEM); - }); - } - self._dataChange = true; - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { - // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) - // 只需要更新查看面板的selectedValue用以请求已选数据 - self.numberCounter.updateSelectedValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: !o.allowEdit, - el: this.trigger, - adjustLength: 1, - container: o.container, - popup: { - type: "bi.multi_select_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [ - { - eventName: BI.MultiSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - }); - self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CLICK_ITEM); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, - action: function () { - self._defaultState(); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, - action: function () { - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - } - ], - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - itemHeight: o.itemHeight, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - value: o.value, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && - self.numberCounter.element.find(e.target).length === 0; - } - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self._populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self._stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - } - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - value: o.value - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - this.updateSelectedValue(self.storeValue); - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - height: o.height, - } - ] - }); - }, - - _itemsCreator4Trigger: function (op, callback) { - var self = this, o = this.options; - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(BI.deepClone(self.getValue())); - } - callback.apply(self, arguments); - }); - }, - - _addItem: function (assertShowValue) { - var self = this; - var keyword = this.trigger.getSearcher().getKeyword(); - this._join({ - type: BI.Selection.Multi, - value: [keyword] - }, function () { - // 如果在不选的状态下直接把该值添加进来 - if (self.storeValue.type === BI.Selection.Multi) { - BI.pushDistinct(self.storeValue.value, keyword); - } - self.combo.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.populate(); - self._setStartValue(""); - self._dataChange = true; - }); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - - digest(); - - function digest() { - BI.each(keywords, function (i, val) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this.requesting = true; - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKey()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - this._adjust(callback); - return; - } - o.itemsCreator({ - type: BI.MultiSelectInsertCombo.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKey()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - BI.remove(self.storeValue.assist, item); - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - adjust(); - callback(); - - function adjust() { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - // value更新的时候assist也需要更新 - BI.remove(self.storeValue.assist, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - _populate: function () { - this.combo.populate.apply(this.combo, arguments); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.combo.setValue(this.storeValue); - this.numberCounter.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - populate: function () { - this._populate.apply(this, arguments); - this.numberCounter.populateSwitcher.apply(this.numberCounter, arguments); - } -}); - -BI.extend(BI.MultiSelectInsertCombo, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiSelectInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiSelectInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.MultiSelectInsertCombo.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; - -BI.shortcut("bi.multi_select_insert_combo", BI.MultiSelectInsertCombo); diff --git a/src/widget/multiselect/multiselect.insert.combo.nobar.js b/src/widget/multiselect/multiselect.insert.combo.nobar.js deleted file mode 100644 index d3fbc3862..000000000 --- a/src/widget/multiselect/multiselect.insert.combo.nobar.js +++ /dev/null @@ -1,490 +0,0 @@ -/** - * - * @class BI.MultiSelectInsertCombo - * @extends BI.Single - */ -BI.MultiSelectInsertNoBarCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertNoBarCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-insert-combo-no-bar", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - height: 24, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiSelectInsertNoBarCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - if (BI.isKey(self._startValue)) { - if (self.storeValue.type === BI.Selection.All) { - BI.remove(self.storeValue.value, self._startValue); - self.storeValue.assist = self.storeValue.assist || []; - BI.pushDistinct(self.storeValue.assist, self._startValue); - } else { - BI.pushDistinct(self.storeValue.value, self._startValue); - BI.remove(self.storeValue.assist, self._startValue); - } - } - self.trigger.getSearcher().setState(self.storeValue); - self.numberCounter.setButtonChecked(self.storeValue); - }; - this.storeValue = { - type: BI.Selection.Multi, - value: BI.deepClone(o.value) || [] - }; - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_insert_trigger", - height: BI.toPix(o.height, o.simple ? 1 : 2), - text: o.text, - // adapter: this.popup, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - } - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - itemFormatter: o.itemFormatter, - itemHeight: o.itemHeight, - value: { - type: BI.Selection.Multi, - value: o.value - } - }); - - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_START, function () { - self._setStartValue(""); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_STOP, function () { - self._setStartValue(""); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_PAUSE, function () { - self._addItem(assertShowValue, true); - self.fireEvent(BI.MultiSelectInsertNoBarCombo.EVENT_ADD_ITEM, this.getSearcher().getKeyword()); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_SEARCHING, function (keywords) { - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.combo.setValue(self.storeValue); - assertShowValue(); - self.combo.populate(); - self._setStartValue(""); - } else { - self.combo.setValue(self.storeValue); - assertShowValue(); - } - self._dataChange = true; - }); - this.getSearcher().getKeywordsLength() > 2000 && BI.Msg.alert(BI.i18nText("BI-Basic_Prompt"), BI.i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); - } - }); - - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_CHANGE, function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - }); - } - self._dataChange = true; - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { - // counter的值随点击项的改变而改变, 点击counter的时候不需要setValue(counter会请求刷新计数) - // 只需要更新查看面板的selectedValue用以请求已选数据 - self.numberCounter.updateSelectedValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectInsertTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: false, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_select_no_bar_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [ - { - eventName: BI.MultiSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - }); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, - action: function () { - self._defaultState(); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, - action: function () { - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - } - ], - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - value: { - type: BI.Selection.Multi, - value: o.value - }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && - self.numberCounter.element.find(e.target).length === 0; - } - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self._populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self._stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.MultiSelectInsertNoBarCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - } - }, - valueFormatter: o.valueFormatter, - itemsCreator: BI.bind(this._itemsCreator4Trigger, this), - value: { - type: BI.Selection.Multi, - value: o.value - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - this.updateSelectedValue(self.storeValue); - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - height: o.height - } - ] - }); - }, - - _itemsCreator4Trigger: function (op, callback) { - var self = this, o = this.options; - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(BI.deepClone(self.storeValue)); - } - callback.apply(self, arguments); - }); - }, - - _addItem: function (assertShowValue) { - var self = this; - var keyword = this.trigger.getSearcher().getKeyword(); - this._join({ - type: BI.Selection.Multi, - value: [keyword] - }, function () { - // 如果在不选的状态下直接把该值添加进来 - if (self.storeValue.type === BI.Selection.Multi) { - BI.pushDistinct(self.storeValue.value, keyword); - } - self.combo.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.populate(); - self._setStartValue(""); - self._dataChange = true; - }); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - - digest(); - - function digest() { - BI.each(keywords, function (i, val) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this.requesting = true; - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKey()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - this._adjust(callback); - return; - } - o.itemsCreator({ - type: BI.MultiSelectInsertNoBarCombo.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKey()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - BI.remove(self.storeValue.assist, item); - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - adjust(); - callback(); - - function adjust() { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.MultiSelectInsertNoBarCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - self.storeValue.value.push(v); - BI.remove(self.storeValue.assist, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - _populate: function () { - this.combo.populate.apply(this.combo, arguments); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue = { - type: BI.Selection.Multi, - value: v || [] - }; - this.combo.setValue(this.storeValue); - this.numberCounter.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this._populate.apply(this, arguments); - this.numberCounter.populateSwitcher.apply(this.numberCounter, arguments); - } -}); - -BI.extend(BI.MultiSelectInsertNoBarCombo, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectInsertNoBarCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.MultiSelectInsertNoBarCombo.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; - -BI.shortcut("bi.multi_select_insert_no_bar_combo", BI.MultiSelectInsertNoBarCombo); diff --git a/src/widget/multiselect/multiselect.insert.trigger.js b/src/widget/multiselect/multiselect.insert.trigger.js deleted file mode 100644 index 4ed1b19ef..000000000 --- a/src/widget/multiselect/multiselect.insert.trigger.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * - * 复选下拉框 - * @class BI.MultiSelectInsertTrigger - * @extends BI.Trigger - */ - -BI.MultiSelectInsertTrigger = BI.inherit(BI.Trigger, { - - constants: { - height: 14, - rgap: 4, - lgap: 4 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-trigger", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - itemHeight: 24, - searcher: {}, - switcher: {}, - - adapter: null, - masker: {}, - allowEdit: true - }); - }, - - _init: function () { - BI.MultiSelectInsertTrigger.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.searcher = BI.createWidget(o.searcher, { - type: "bi.multi_select_insert_searcher", - height: o.height, - text: o.text, - defaultText: o.defaultText, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - itemHeight: o.itemHeight, - watermark: o.watermark, - popup: {}, - adapter: o.adapter, - masker: o.masker, - value: o.value - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_START, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_START); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_PAUSE, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_PAUSE); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_SEARCHING, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_SEARCHING, arguments); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_STOP); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_BLUR); - }); - this.searcher.on(BI.MultiSelectInsertSearcher.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectInsertTrigger.EVENT_FOCUS); - }); - - this.wrapNumberCounter = BI.createWidget({ - type: "bi.layout" - }); - - this.wrapper = BI.createWidget({ - type: "bi.htape", - element: this, - items: [ - { - el: this.searcher, - width: "fill" - }, { - el: this.wrapNumberCounter, - width: 0 - }, { - el: BI.createWidget(), - width: 24 - } - ] - }); - - !o.allowEdit && BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: { - type: "bi.text", - title: function () { - return self.searcher.getState(); - } - }, - left: 0, - right: 24, - top: 0, - bottom: 0 - } - ] - }); - }, - - /** - * 重新调整numberCounter的空白占位符 - */ - refreshPlaceHolderWidth: function (width) { - this.wrapper.attr("items")[1].width = width; - this.wrapper.resize(); - }, - - getSearcher: function () { - return this.searcher; - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setValue: function (ob) { - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.searcher.getKey(); - }, - - getValue: function () { - return this.searcher.getValue(); - } -}); - -BI.MultiSelectInsertTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.MultiSelectInsertTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; -BI.MultiSelectInsertTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectInsertTrigger.EVENT_START = "EVENT_START"; -BI.MultiSelectInsertTrigger.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectInsertTrigger.EVENT_PAUSE = "EVENT_PAUSE"; -BI.MultiSelectInsertTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectInsertTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; -BI.MultiSelectInsertTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectInsertTrigger.EVENT_BLUR = "EVENT_BLUR"; - -BI.shortcut("bi.multi_select_insert_trigger", BI.MultiSelectInsertTrigger); diff --git a/src/widget/multiselect/multiselect.loader.js b/src/widget/multiselect/multiselect.loader.js deleted file mode 100644 index 2aa22aad5..000000000 --- a/src/widget/multiselect/multiselect.loader.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * 多选加载数据面板 - * Created by guy on 15/11/2. - * @class BI.MultiSelectLoader - * @extends Widget - */ -BI.MultiSelectLoader = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-loader", - logic: { - dynamic: true - }, - el: { - height: 400 - }, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemFormatter: BI.emptyFn, - onLoaded: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - isDefaultInit: false, - }); - }, - - _init: function () { - BI.MultiSelectLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - - this.storeValue = opts.value || {}; - this._assertValue(this.storeValue); - - this.button_group = BI.createWidget({ - type: "bi.select_list", - logic: opts.logic, - toolbar: { - type: "bi.multi_select_bar", - cls: "bi-list-item-active", - height: this.options.itemHeight || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - iconWrapperWidth: 36 - }, - el: BI.extend({ - onLoaded: opts.onLoaded, - el: { - type: "bi.multi_select_inner_loader", - isDefaultInit: opts.isDefaultInit, - } - }, opts.el), - itemsCreator: function (op, callback) { - var startValue = self._startValue; - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: BI.isKey(startValue) && self.storeValue.type === BI.Selection.Multi - ? self.storeValue.value.concat(startValue) : self.storeValue.value - })); - opts.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && self.storeValue) { - var json = BI.map(self.storeValue.value, function (i, v) { - var txt = opts.valueFormatter(v) || v; - return { - text: txt, - value: v, - title: txt, - selected: self.storeValue.type === BI.Selection.Multi, - }; - }); - if (BI.isKey(self._startValue) && !BI.contains(self.storeValue.value, self._startValue)) { - var txt = opts.valueFormatter(startValue) || startValue; - json.unshift({ - text: txt, - value: startValue, - title: txt, - selected: true, - }); - } - firstItems = self._createItems(json); - } - callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); - if (op.times === 1 && self.storeValue) { - BI.isKey(startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, startValue) : BI.pushDistinct(self.storeValue.value, startValue)); - self.setValue(self.storeValue); - } - (op.times === 1) && self._scrollToTop(); - }); - }, - hasNext: function () { - return hasNext; - }, - value: this.storeValue - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Top), BI.extend({ - scrolly: true, - vgap: 5 - }, opts.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Top, this.button_group) - })))); - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button_group.on(BI.SelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - var allSelected = this.isAllSelected(); - var itemFormatter = this.options.itemFormatter; - return BI.map(items, (i, item) => { - return { - type: "bi.multi_select_item", - logic: this.options.logic, - cls: "bi-list-item-active", - height: this.options.itemHeight || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - selected: allSelected, - iconWrapperWidth: 36, - ...item, - ...itemFormatter(item), - }; - }); - }, - - _scrollToTop: function () { - var self = this; - BI.delay(function () { - self.button_group.element.scrollTop(0); - }, 30); - }, - - isAllSelected: function () { - return this.button_group.isAllSelected(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - setStartValue: function (v) { - this._startValue = v; - }, - - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.button_group.setValue(this.storeValue); - }, - - getValue: function () { - return this.button_group.getValue(); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - // arguments.length为0时对arguments[0]赋值后不同环境对其length的取值不同(nashorn) - if (BI.isNotNull(items)) { - arguments[0] = this._createItems(items); - } - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.resetHeight(h - 10); - }, - - resetWidth: function (w) { - this.button_group.resetWidth(w); - } -}); - -BI.MultiSelectLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_loader", BI.MultiSelectLoader); diff --git a/src/widget/multiselect/multiselect.loader.nobar.js b/src/widget/multiselect/multiselect.loader.nobar.js deleted file mode 100644 index 274d51f6c..000000000 --- a/src/widget/multiselect/multiselect.loader.nobar.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * 多选加载数据面板 - * Created by guy on 15/11/2. - * @class BI.MultiSelectNoBarLoader - * @extends Widget - */ -BI.MultiSelectNoBarLoader = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectNoBarLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-loader", - logic: { - dynamic: true - }, - el: { - height: 400 - }, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - onLoaded: BI.emptyFn, - itemFormatter: BI.emptyFn, - }); - }, - - _init: function () { - BI.MultiSelectNoBarLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - - this.storeValue = opts.value || {}; - this._assertValue(this.storeValue); - - this.button_group = BI.createWidget(BI.extend({ - type: "bi.list_pane", - onLoaded: opts.onLoaded, - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [{ - type: "bi.vertical" - }] - } - }, - itemsCreator: function (op, callback) { - var startValue = self._startValue; - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: BI.isKey(startValue) && self.storeValue.type === BI.Selection.Multi - ? self.storeValue.value.concat(startValue) : self.storeValue.value - })); - opts.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && self.storeValue) { - var json = BI.map(self.storeValue.value, function (i, v) { - var txt = opts.valueFormatter(v) || v; - return { - text: txt, - value: v, - title: txt, - selected: self.storeValue.type === BI.Selection.Multi - }; - }); - if (BI.isKey(self._startValue) && !BI.contains(self.storeValue.value, self._startValue)) { - var txt = opts.valueFormatter(startValue) || startValue; - json.unshift({ - text: txt, - value: startValue, - title: txt, - selected: true - }); - } - firstItems = self._createItems(json); - } - callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); - if (op.times === 1 && self.storeValue) { - BI.isKey(startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, startValue) : BI.pushDistinct(self.storeValue.value, startValue)); - self.setValue(self.storeValue); - } - (op.times === 1) && self._scrollToTop(); - }); - }, - hasNext: function () { - return hasNext; - }, - value: this.storeValue - }, opts.el)); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Top), BI.extend({ - scrolly: true, - vgap: 5 - }, opts.logic, { - items: BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Top, this.button_group) - })))); - - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button_group.on(BI.SelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectNoBarLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - return BI.map(items, (index, item) => { - return { - type: "bi.multi_select_item", - cls: "bi-list-item-active", - logic: this.options.logic, - height: this.options.itemHeight || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - iconWrapperWidth: 36, - ...item, - ...this.options.itemFormatter(item), - }; - }); - }, - - _scrollToTop: function () { - var self = this; - BI.delay(function () { - self.button_group.element.scrollTop(0); - }, 30); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - setStartValue: function (v) { - this._startValue = v; - }, - - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.button_group.setValue(this.storeValue.value); - }, - - getValue: function () { - return { - type: BI.Selection.Multi, - value: this.button_group.getValue() - }; - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - arguments[0] = this._createItems(items); - } - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.element.css({ "max-height": BI.toPix(h) }); - }, - - resetWidth: function () { - - } -}); - -BI.MultiSelectNoBarLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_no_bar_loader", BI.MultiSelectNoBarLoader); diff --git a/src/widget/multiselect/multiselect.popup.view.js b/src/widget/multiselect/multiselect.popup.view.js deleted file mode 100644 index 1e11376d2..000000000 --- a/src/widget/multiselect/multiselect.popup.view.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 带加载的多选下拉面板 - * @class BI.MultiSelectPopupView - * @extends Widget - */ -BI.MultiSelectPopupView = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectPopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-popup-view", - maxWidth: "auto", - minWidth: 135, - maxHeight: 400, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }); - }, - - _init: function () { - BI.MultiSelectPopupView.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - - this.loader = BI.createWidget({ - type: "bi.multi_select_loader", - itemsCreator: opts.itemsCreator, - itemHeight: opts.itemHeight, - valueFormatter: opts.valueFormatter, - itemFormatter: opts.itemFormatter, - onLoaded: opts.onLoaded, - value: opts.value - }); - - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - element: this, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_OK")], - el: this.loader, - value: opts.value - }); - - this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectPopupView.EVENT_CHANGE); - }); - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.MultiSelectPopupView.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM); - break; - } - }); - }, - - isAllSelected: function () { - return this.loader.isAllSelected(); - }, - - setStartValue: function (v) { - this.loader.setStartValue(v); - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - populate: function (items) { - this.popupView.populate.apply(this.popupView, arguments); - }, - - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, - - resetWidth: function (w) { - this.popupView.resetWidth(w); - }, - - setDirection: function (direction, position) { - this.popupView.setDirection(direction, position); - }, -}); - -BI.MultiSelectPopupView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiSelectPopupView.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - - -BI.shortcut("bi.multi_select_popup_view", BI.MultiSelectPopupView); diff --git a/src/widget/multiselect/multiselect.popup.view.nobar.js b/src/widget/multiselect/multiselect.popup.view.nobar.js deleted file mode 100644 index c0007f85a..000000000 --- a/src/widget/multiselect/multiselect.popup.view.nobar.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * 带加载的多选下拉面板 - * @class BI.MultiSelectPopupView - * @extends Widget - */ -BI.MultiSelectNoBarPopupView = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectNoBarPopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-popup-view", - maxWidth: "auto", - minWidth: 135, - maxHeight: 400, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - onLoaded: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiSelectNoBarPopupView.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - - this.loader = BI.createWidget({ - type: "bi.multi_select_no_bar_loader", - itemsCreator: opts.itemsCreator, - itemHeight: opts.itemHeight, - valueFormatter: opts.valueFormatter, - itemFormatter: opts.itemFormatter, - onLoaded: opts.onLoaded, - value: opts.value - }); - - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - element: this, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_OK")], - el: this.loader, - value: opts.value - }); - - this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectNoBarPopupView.EVENT_CHANGE); - }); - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.MultiSelectNoBarPopupView.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.MultiSelectNoBarPopupView.EVENT_CLICK_CONFIRM); - break; - } - }); - }, - - setStartValue: function (v) { - this.loader.setStartValue(v); - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - populate: function (items) { - this.popupView.populate.apply(this.popupView, arguments); - }, - - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, - - resetWidth: function (w) { - this.popupView.resetWidth(w); - }, - - setDirection: function (direction, position) { - this.popupView.setDirection(direction, position); - }, -}); - -BI.MultiSelectNoBarPopupView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectNoBarPopupView.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiSelectNoBarPopupView.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - - -BI.shortcut("bi.multi_select_no_bar_popup_view", BI.MultiSelectNoBarPopupView); diff --git a/src/widget/multiselect/multiselect.trigger.js b/src/widget/multiselect/multiselect.trigger.js deleted file mode 100644 index f8f95c02b..000000000 --- a/src/widget/multiselect/multiselect.trigger.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * - * 复选下拉框 - * @class BI.MultiSelectTrigger - * @extends BI.Trigger - */ - -BI.MultiSelectTrigger = BI.inherit(BI.Trigger, { - - constants: { - height: 14, - rgap: 4, - lgap: 4 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-trigger", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcher: {}, - switcher: {}, - - adapter: null, - masker: {}, - allowEdit: true, - itemHeight: 24 - }); - }, - - _init: function () { - BI.MultiSelectTrigger.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.searcher = BI.createWidget(o.searcher, { - type: "bi.multi_select_searcher", - height: o.height, - text: o.text, - defaultText: o.defaultText, - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - watermark: o.watermark, - popup: {}, - adapter: o.adapter, - masker: o.masker, - value: o.value - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_START, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_START); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_PAUSE, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_PAUSE); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_SEARCHING, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_SEARCHING, arguments); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_STOP); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_BLUR); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectTrigger.EVENT_FOCUS); - }); - - this.wrapNumberCounter = BI.createWidget({ - type: "bi.layout" - }); - - this.wrapper = BI.createWidget({ - type: "bi.htape", - element: this, - items: [ - { - el: this.searcher, - width: "fill", - rgap: 24 - } - ] - }); - - !o.allowEdit && BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: { - type: "bi.text", - title: function () { - /** 修正REPORT-73699引入,需要考虑到传递过来的值是方法的情况 */ - var state = self.searcher.getState(); - if (BI.isFunction(state)) { - return state(); - } - return state; - } - }, - left: 0, - right: 24, - top: 0, - bottom: 0 - } - ] - }); - }, - - /** - * 重新调整numberCounter的空白占位符 - */ - refreshPlaceHolderWidth: function (width) { - this.wrapper.attr("items")[0].rgap = 24 + width; - this.wrapper.resize(); - }, - - getSearcher: function () { - return this.searcher; - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setValue: function (ob) { - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.searcher.getKey(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - focus: function () { - this.searcher.focus(); - }, - - blur: function () { - this.searcher.blur(); - }, - - setWaterMark: function (v) { - this.searcher.setWaterMark(v); - } -}); - -BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.MultiSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; -BI.MultiSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectTrigger.EVENT_START = "EVENT_START"; -BI.MultiSelectTrigger.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; -BI.MultiSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; -BI.MultiSelectTrigger.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiSelectTrigger.EVENT_FOCUS = "EVENT_FOCUS"; - -BI.shortcut("bi.multi_select_trigger", BI.MultiSelectTrigger); diff --git a/src/widget/multiselect/search/multiselect.search.insert.pane.js b/src/widget/multiselect/search/multiselect.search.insert.pane.js deleted file mode 100644 index 8def90700..000000000 --- a/src/widget/multiselect/search/multiselect.search.insert.pane.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiSelectSearchInsertPane - * @extends Widget - */ - -BI.MultiSelectSearchInsertPane = BI.inherit(BI.Widget, { - - constants: { - height: 24, - lgap: 10, - tgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectSearchInsertPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-search-pane bi-card", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - keywordGetter: BI.emptyFn, - allowSelectAll: true, - itemHeight: 24, - }); - }, - - _init: function () { - BI.MultiSelectSearchInsertPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.addNotMatchTip = BI.createWidget({ - type: "bi.label", - text: BI.i18nText("BI-Basic_Press_Enter_To_Add_Text", ""), - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - cls: "bi-keyword-red-mark", - hgap: 5, - }); - - this.loader = BI.createWidget({ - type: "bi.multi_select_search_loader", - keywordGetter: o.keywordGetter, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator.apply(self, [op, function (res) { - callback(res); - self.setKeyword(o.keywordGetter()); - }]); - }, - itemHeight: o.itemHeight, - value: o.value, - allowSelectAll: o.allowSelectAll, - }); - this.loader.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.resizer = BI.createWidget({ - type: "bi.vertical_fill", - rowSize: ["", "fill"], - element: this, - items: [{ - el: this.addNotMatchTip, - }, { - el: this.loader, - }], - }); - }, - - setKeyword: function (keyword) { - this.addNotMatchTip.setText(BI.i18nText("BI-Basic_Press_Enter_To_Add_Text", keyword)); - }, - - isAllSelected: function () { - return this.loader.isAllSelected(); - }, - - hasMatched: function () { - return false; - }, - - setValue: function (v) { - this.loader.setValue(v); - }, - - getValue: function () { - return this.loader.getValue(); - }, - - empty: function () { - this.loader.empty(); - }, - - populate: function (items) { - this.loader.populate.apply(this.loader, arguments); - } -}); - -BI.MultiSelectSearchInsertPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.multi_select_search_insert_pane", BI.MultiSelectSearchInsertPane); diff --git a/src/widget/multiselect/search/multiselect.search.loader.js b/src/widget/multiselect/search/multiselect.search.loader.js deleted file mode 100644 index a4a3d8ed5..000000000 --- a/src/widget/multiselect/search/multiselect.search.loader.js +++ /dev/null @@ -1,235 +0,0 @@ -/** - * 多选加载数据搜索loader面板 - * Created by guy on 15/11/4. - * @class BI.MultiSelectSearchLoader - * @extends Widget - */ -BI.MultiSelectSearchLoader = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectSearchLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-search-loader", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn, - valueFormatter: BI.emptyFn, - itemFormatter: BI.emptyFn, - allowSelectAll: true, - itemHeight: 24 - }); - }, - - _init: function () { - BI.MultiSelectSearchLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - this.storeValue = BI.deepClone(opts.value); - this.button_group = BI.createWidget(opts.allowSelectAll ? { - type: "bi.select_list", - toolbar: { - type: "bi.multi_select_bar", - cls: "bi-list-item-active", - iconWrapperWidth: 36 - }, - element: this, - logic: { - dynamic: false - }, - value: opts.value, - el: { - tipText: BI.i18nText("BI-No_Select"), - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [ - { - type: "bi.vertical" - } - ] - } - } - }, - itemsCreator: function (op, callback) { - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: self.storeValue.value - })); - opts.itemsCreator(op, function (ob) { - var keyword = ob.keyword = opts.keywordGetter(); - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && self.storeValue) { - var json = self._filterValues(self.storeValue); - firstItems = self._createItems(json); - } - var context = { - tipText: ob.tipText, - }; - callback(firstItems.concat(self._createItems(ob.items)), keyword, context); - if (op.times === 1 && self.storeValue) { - self.setValue(self.storeValue); - } - }); - }, - hasNext: function () { - return hasNext; - } - } : { - type: "bi.list_pane", - logic: { - dynamic: true, - innerVgap: 5, - rowSize: ["", "fill"], - verticalAlign: BI.VerticalAlign.Stretch - }, - element: this, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [ - { - type: "bi.vertical" - } - ] - }, - itemsCreator: function (op, callback) { - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: self.storeValue.value - })); - opts.itemsCreator(op, function (ob) { - var keyword = ob.keyword = opts.keywordGetter(); - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && self.storeValue) { - var json = self._filterValues(self.storeValue); - firstItems = self._createItems(json); - } - var context = { - tipText: ob.tipText, - }; - callback(firstItems.concat(self._createItems(ob.items)), keyword, context); - if (op.times === 1 && self.storeValue) { - self.setValue(self.storeValue); - } - }); - }, - value: opts.value, - height: "fill", - }); - - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - var searchLoaderEventChangeName = opts.allowSelectAll ? BI.SelectList.EVENT_CHANGE : BI.ListPane.EVENT_CHANGE - this.button_group.on(searchLoaderEventChangeName, function () { - self.fireEvent(BI.MultiSelectSearchLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - var allSelected = this.isAllSelected(); - var itemFormatter = this.options.itemFormatter; - - return BI.map(items, (index, item) => { - return { - type: "bi.multi_select_item", - logic: { - dynamic: false - }, - height: this.options.itemHeight || BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - selected: allSelected, - cls: "bi-list-item-active", - iconWrapperWidth: 36, - ...item, - ...itemFormatter(item) - }; - }); - }, - - isAllSelected: function () { - var o = this.options; - return o.allowSelectAll ? this.button_group.isAllSelected() : false; - }, - - _filterValues: function (src) { - var o = this.options; - var keyword = o.keywordGetter(); - var values = BI.deepClone(src.value) || []; - var newValues = BI.map(values, function (i, v) { - return { - text: o.valueFormatter(v) || v, - value: v, - }; - }); - if (BI.isKey(keyword)) { - var search = BI.Func.getSearchResult(newValues, keyword); - values = search.match.concat(search.find); - } - return BI.map(values, function (i, v) { - return { - text: v.text, - title: v.text, - value: v.value, - selected: src.type === BI.Selection.All, - ...o.itemFormatter(v), - }; - }); - }, - - setValue: function (v) { - v || (v = {}); - var o = this.options; - // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 - this.storeValue = BI.deepClone(v); - o.allowSelectAll ? (this.button_group.setValue(v)) : (this.button_group.setValue(v.value)); - }, - - getValue: function () { - var o = this.options; - if (o.allowSelectAll) { - return this.button_group.getValue(); - } - return { - type: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - value: this.button_group.getValue(), - assist: this.button_group.getNotSelectedValue() - }; - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.resetHeight(h); - }, - - resetWidth: function (w) { - this.button_group.resetWidth(w); - } -}); - -BI.MultiSelectSearchLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_search_loader", BI.MultiSelectSearchLoader); diff --git a/src/widget/multiselect/search/multiselect.search.pane.js b/src/widget/multiselect/search/multiselect.search.pane.js deleted file mode 100644 index 98c733348..000000000 --- a/src/widget/multiselect/search/multiselect.search.pane.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiSelectSearchPane - * @extends Widget - */ - -BI.MultiSelectSearchPane = BI.inherit(BI.Widget, { - - constants: { - height: 24, - lgap: 10, - tgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-search-pane bi-card", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - keywordGetter: BI.emptyFn, - itemHeight: 24, - }); - }, - - _init: function () { - BI.MultiSelectSearchPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.loader = BI.createWidget({ - type: "bi.multi_select_search_loader", - keywordGetter: o.keywordGetter, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator.apply(self, [op, function (res) { - callback(res); - }]); - }, - itemHeight: o.itemHeight, - value: o.value - }); - this.loader.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.resizer = BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.loader, - left: 0, - right: 0, - bottom: 0, - top: 0, - }], - }); - }, - - isAllSelected: function () { - return this.loader.isAllSelected(); - }, - - hasMatched: function () { - }, - - setValue: function (v) { - this.loader.setValue(v); - }, - - getValue: function () { - return this.loader.getValue(); - }, - - empty: function () { - this.loader.empty(); - }, - - populate: function (items) { - this.loader.populate.apply(this.loader, arguments); - } -}); - -BI.MultiSelectSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.multi_select_search_pane", BI.MultiSelectSearchPane); diff --git a/src/widget/multiselect/trigger/button.checkselected.js b/src/widget/multiselect/trigger/button.checkselected.js deleted file mode 100644 index 17468061f..000000000 --- a/src/widget/multiselect/trigger/button.checkselected.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * 查看已选按钮 - * Created by guy on 15/11/3. - * @class BI.MultiSelectCheckSelectedButton - * @extends BI.Single - */ -BI.MultiSelectCheckSelectedButton = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectCheckSelectedButton.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-check-selected-button", - itemsCreator: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiSelectCheckSelectedButton.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.numberCounter = BI.createWidget({ - type: "bi.text_button", - element: this, - hgap: 4, - text: "0", - textAlign: "center", - textHeight: 16, - cls: "bi-high-light-background count-tip" - }); - this.numberCounter.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.numberCounter.on(BI.TextButton.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); - }); - - this.numberCounter.element.hover(function () { - self.numberCounter.setTag(self.numberCounter.getText()); - self.numberCounter.setText(BI.i18nText("BI-Check_Selected")); - }, function () { - self.numberCounter.setText(self.numberCounter.getTag()); - }); - this.setVisible(false); - if (BI.isNotNull(o.value)) { - this.setValue(o.value); - } - }, - - _populate: function (ob) { - var self = this, o = this.options; - if (ob.type === BI.Selection.All) { - o.itemsCreator({ - type: BI.MultiSelectCombo.REQ_GET_DATA_LENGTH - }, function (res) { - if (self.options.value.type !== BI.Selection.All) { - return; - } - if (BI.isNotEmptyString(res.count)) { - BI.nextTick(function () { - self.numberCounter.setText(res.count); - self.setVisible(true); - }); - - return; - } - var length = res.count - ob.value.length; - BI.nextTick(function () { - self.numberCounter.setText(length); - self.setVisible(length > 0); - }); - }); - return; - } - BI.nextTick(function () { - self.numberCounter.setText(ob.value.length); - self.setVisible(ob.value.length > 0); - }); - }, - - _assertValue: function (ob) { - ob || (ob = {}); - ob.type || (ob.type = BI.Selection.Multi); - ob.value || (ob.value = []); - return ob; - }, - - setValue: function (ob) { - ob = this._assertValue(ob); - this.options.value = ob; - this._populate(ob); - }, - - populate: function () { - this._populate(this._assertValue(this.options.value)); - }, - - getValue: function () { - - } -}); - -BI.MultiSelectCheckSelectedButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_check_selected_button", BI.MultiSelectCheckSelectedButton); diff --git a/src/widget/multiselect/trigger/editor.multiselect.js b/src/widget/multiselect/trigger/editor.multiselect.js deleted file mode 100644 index db9acc9a4..000000000 --- a/src/widget/multiselect/trigger/editor.multiselect.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * 多选输入框 - * Created by guy on 15/11/3. - * @class BI.MultiSelectEditor - * @extends Widget - */ -BI.MultiSelectEditor = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectEditor.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-editor", - el: {}, - watermark: BI.i18nText("BI-Basic_Search") - }); - }, - - _init: function () { - BI.MultiSelectEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.select_patch_editor", - element: this, - height: o.height, - watermark: o.watermark, - allowBlank: true, - value: o.value, - defaultText: o.defaultText, - text: o.text, - tipType: o.tipType, - warningTitle: o.warningTitle, - }); - - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.StateEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiSelectEditor.EVENT_FOCUS); - }); - this.editor.on(BI.StateEditor.EVENT_BLUR, function () { - self.fireEvent(BI.MultiSelectEditor.EVENT_BLUR); - }); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setState: function (state) { - this.editor.setState(state); - }, - - setValue: function (v) { - this.editor.setValue(v); - }, - - setTipType: function (v) { - this.editor.setTipType(v); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.editor.getText(); - }, - - getKeywords: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - if (/\u200b\s\u200b$/.test(val)) { - return keywords.concat([BI.BlankSplitChar]); - } - - return keywords; - }, - - getKeyword: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - return BI.isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; - }, - - populate: function (items) { - - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); - -BI.MultiSelectEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiSelectEditor.EVENT_PAUSE = "EVENT_PAUSE"; -BI.shortcut("bi.multi_select_editor", BI.MultiSelectEditor); diff --git a/src/widget/multiselect/trigger/editor/editor.patch.js b/src/widget/multiselect/trigger/editor/editor.patch.js deleted file mode 100644 index bec2ae7db..000000000 --- a/src/widget/multiselect/trigger/editor/editor.patch.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/5/18 - */ -BI.SelectPatchEditor = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-patch-select-editor", - height: 24, - }, - - render: function () { - var self = this, o = this.options; - - var debounceInputChange = BI.debounce(BI.bind(this._dealChange, this), 300); - - return BI.extend({ - type: "bi.state_editor", - ref: function (_ref) { - self.editor = _ref; - }, - hgap: o.hgap, - vgap: o.vgap, - lgap: o.lgap, - rgap: o.rgap, - tgap: o.tgap, - bgap: o.bgap, - height: o.height, - watermark: o.watermark, - allowBlank: true, - value: o.value, - defaultText: o.defaultText, - text: o.text, - tipType: o.tipType, - warningTitle: o.warningTitle, - el: { - type: 'bi.textarea_editor', - scrolly: false, - validationChecker: function () { - return true; - }, - throttle: true, - }, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type, v) { - if (BI.contains(v, "\n")) { - self._dealChange(type, v); - } else { - debounceInputChange(type, v); - } - }, - }, { - eventName: BI.Editor.EVENT_KEY_DOWN, - action: function (keyCode) { - if (keyCode === BI.KeyCode.ENTER) { - self._clearSplitValue(); - } - }, - }, { - eventName: BI.Editor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.SelectPatchEditor.EVENT_FOCUS, arguments); - }, - }, { - eventName: BI.Editor.EVENT_BLUR, - action: function () { - self._start = false; - self.fireEvent(BI.SelectPatchEditor.EVENT_BLUR, arguments); - }, - }], - }, o.el); - }, - - _clearSplitValue: function () { - this.editor.setValue(""); - }, - - _dealChange: function (type, v) { - var value = ""; - if (v !== this.editor.getValue()) { - return; - } - if (BI.isKey(v)) { - value = this._formatText(v); - } - if (type === BI.Events.CHANGE) { - this._setValue(value); - if (this._trimValue(value) !== "") { - if (!this._start || !BI.isKey(this._lastValue) || (this._pause === true && this._trimValue(this._lastValue) !== this._trimValue(value))) { - this._start = true; - this._pause = false; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); - } - } - if (this._trimValue(this._lastValue) !== this._trimValue(value)) { - this.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - if (BI.endWith(value, BI.BlankSplitChar)) { - this._pause = true; - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); - } - } - if (type === BI.Events.EMPTY || type === BI.Events.STOPEDIT) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY); - } - this._lastValue = value; - }, - - _trimValue: function (v) { - return BI.trim(BI.replaceAll(v || "", BI.BlankSplitChar, "")); - }, - - _formatText: function (v) { - return BI.replaceAll(v || "", "\n", BI.BlankSplitChar); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - }, - - doRedMark: function () { - this.editor.doRedMark.apply(this.editor, arguments); - }, - - unRedMark: function () { - this.editor.unRedMark.apply(this.editor, arguments); - }, - - doHighLight: function () { - this.editor.doHighLight.apply(this.editor, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - _setValue: function (v) { - this.editor.setValue(this._formatText(v)); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (v) { - this._setValue(v); - this._lastValue = this._trimValue(v); - }, - - getValue: function () { - return BI.trim(this.editor.getValue()); - }, - - getState: function () { - return this.editor.getState(); - }, - - setState: function (v) { - this.editor.setState(v); - }, - - setTipType: function (v) { - this.editor.setTipType(v); - }, - - getText: function () { - return this.editor.getText(); - }, -}); -BI.SelectPatchEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SelectPatchEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SelectPatchEditor.EVENT_BLUR = "EVENT_BLUR"; - -BI.shortcut("bi.select_patch_editor", BI.SelectPatchEditor); diff --git a/src/widget/multiselect/trigger/searcher.multiselect.insert.js b/src/widget/multiselect/trigger/searcher.multiselect.insert.js deleted file mode 100644 index ec31d3d31..000000000 --- a/src/widget/multiselect/trigger/searcher.multiselect.insert.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiSelectInsertSearcher - * @extends Widget - */ -BI.MultiSelectInsertSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-searcher", - itemsCreator: BI.emptyFn, - itemHeight: 24, - el: {}, - popup: {}, - valueFormatter: BI.emptyFn, - adapter: null, - masker: {}, - watermark: BI.i18nText("BI-Basic_Search_And_Patch_Paste"), - }); - }, - - _init: function () { - BI.MultiSelectInsertSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.multi_select_editor", - watermark: o.watermark, - height: o.height, - text: o.text, - defaultText: o.defaultText, - listeners: [ - { - eventName: BI.MultiSelectEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_BLUR); - } - } - ] - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - height: o.height, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - el: this.editor, - - popup: BI.extend({ - type: "bi.multi_select_search_insert_pane", - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - keywordGetter: function () { - return self.editor.getKeyword(); - }, - itemsCreator: function (op, callback) { - var keyword = self.editor.getKeyword(); - op.keywords = [keyword]; - this.setKeyword(keyword); - o.itemsCreator(op, function () { - if (keyword === self.editor.getValue()) { - callback.apply(null, arguments); - } - }); - }, - itemHeight: o.itemHeight, - value: o.value, - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - if (this.hasMatched()) { - - } - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { - var keywords = this.getKeywords(); - self.fireEvent(BI.MultiSelectInsertSearcher.EVENT_SEARCHING, keywords.length > 2000 ? keywords.slice(0, 2000).concat([BI.BlankSplitChar]) : keywords.slice(0, 2000)); - }); - if (BI.isNotNull(o.value)) { - this.setState(o.value); - } - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeywordsLength: function () { - var keywords = this.editor.getKeywords(); - - return keywords[keywords.length - 1] === BI.BlankSplitChar ? keywords.length - 1 : keywords.length; - }, - - getKeyword: function () { - var keywords = this.editor.getKeywords().slice(0, 2000); - if (keywords[keywords.length - 1] === BI.BlankSplitChar) { - keywords = keywords.slice(0, keywords.length - 1); - } - - return BI.isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setState: function (ob) { - var o = this.options; - ob || (ob = {}); - ob.value || (ob.value = []); - if (ob.type === BI.Selection.All) { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.All); - } else if (BI.size(ob.assist) <= 20) { - var state = ""; - BI.each(ob.assist, function (i, v) { - if (i === 0) { - state += "" + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } else { - state += "," + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } else { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.None); - } else if (BI.size(ob.value) <= 20) { - var state = ""; - BI.each(ob.value, function (i, v) { - if (i === 0) { - state += "" + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } else { - state += "," + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } - }, - - getState: function () { - return this.editor.getState(); - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - } -}); - -BI.MultiSelectInsertSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiSelectInsertSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectInsertSearcher.EVENT_START = "EVENT_START"; -BI.MultiSelectInsertSearcher.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectInsertSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.MultiSelectInsertSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectInsertSearcher.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectInsertSearcher.EVENT_BLUR = "EVENT_BLUR"; -BI.shortcut("bi.multi_select_insert_searcher", BI.MultiSelectInsertSearcher); diff --git a/src/widget/multiselect/trigger/searcher.multiselect.js b/src/widget/multiselect/trigger/searcher.multiselect.js deleted file mode 100644 index e7ed00874..000000000 --- a/src/widget/multiselect/trigger/searcher.multiselect.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiSelectSearcher - * @extends Widget - */ -BI.MultiSelectSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-searcher", - itemsCreator: BI.emptyFn, - el: {}, - popup: {}, - valueFormatter: BI.emptyFn, - adapter: null, - masker: {}, - defaultText: BI.i18nText("BI-Basic_Please_Select"), - itemHeight: 24 - }); - }, - - _init: function () { - BI.MultiSelectSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.multi_select_editor", - height: o.height, - text: o.text, - defaultText: o.defaultText, - watermark: o.watermark, - listeners: [ - { - eventName: BI.MultiSelectEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_BLUR); - } - } - ] - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - height: o.height, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - el: this.editor, - popup: BI.extend({ - type: "bi.multi_select_search_pane", - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - keywordGetter: function () { - return self.editor.getValue(); - }, - itemsCreator: function (op, callback) { - var keyword = self.editor.getValue(); - op.keywords = [keyword]; - o.itemsCreator(op, function () { - var keyword = self.editor.getValue(); - op.keywords = [keyword]; - o.itemsCreator(op, function () { - if (keyword === self.editor.getValue()) { - callback.apply(null, arguments); - } - }); - }); - }, - itemHeight: o.itemHeight, - value: o.value - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - if (this.hasMatched()) { - - } - self.fireEvent(BI.MultiSelectSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { - var keywords = this.getKeywords(); - self.fireEvent(BI.MultiSelectSearcher.EVENT_SEARCHING, keywords); - }); - if (BI.isNotNull(o.value)) { - this.setState(o.value); - } - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeyword: function () { - return this.editor.getValue(); - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setState: function (ob) { - var o = this.options; - ob || (ob = {}); - ob.value || (ob.value = []); - if (ob.type === BI.Selection.All) { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.All); - } else if (BI.size(ob.assist) <= 20) { - var state = ""; - BI.each(ob.assist, function (i, v) { - if (i === 0) { - state += "" + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } else { - state += "," + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } else { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.None); - } else if (BI.size(ob.value) <= 20) { - var state = ""; - BI.each(ob.value, function (i, v) { - if (i === 0) { - state += "" + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } else { - state += "," + (v === null ? "" : (o.valueFormatter(v + "") || v)); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } - }, - - getState: function () { - return this.editor.getState(); - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - } -}); - -BI.MultiSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiSelectSearcher.EVENT_START = "EVENT_START"; -BI.MultiSelectSearcher.EVENT_STOP = "EVENT_STOP"; -BI.MultiSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.MultiSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiSelectSearcher.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiSelectSearcher.EVENT_BLUR = "EVENT_BLUR"; -BI.shortcut("bi.multi_select_searcher", BI.MultiSelectSearcher); diff --git a/src/widget/multiselect/trigger/switcher.checkselected.js b/src/widget/multiselect/trigger/switcher.checkselected.js deleted file mode 100644 index 6804c2c5e..000000000 --- a/src/widget/multiselect/trigger/switcher.checkselected.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 查看已选switcher - * Created by guy on 15/11/3. - * @class BI.MultiSelectCheckSelectedSwitcher - * @extends Widget - */ -BI.MultiSelectCheckSelectedSwitcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectCheckSelectedSwitcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-check-selected-switcher", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - el: {}, - popup: {}, - adapter: null, - masker: {} - }); - }, - - _init: function () { - BI.MultiSelectCheckSelectedSwitcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.button = BI.createWidget(o.el, { - type: "bi.multi_select_check_selected_button", - itemsCreator: o.itemsCreator, - value: o.value - }); - this.button.on(BI.Events.VIEW, function () { - self.fireEvent(BI.Events.VIEW, arguments); - }); - this.switcher = BI.createWidget({ - type: "bi.switcher", - toggle: false, - element: this, - el: this.button, - popup: BI.extend({ - type: "bi.multi_select_check_pane", - valueFormatter: o.valueFormatter, - itemsCreator: o.itemsCreator, - onClickContinueSelect: function () { - self.switcher.hideView(); - }, - ref: function (_ref) { - self.checkPane = _ref; - }, - value: o.value - }, o.popup), - adapter: o.adapter, - masker: o.masker - }); - this.switcher.on(BI.Switcher.EVENT_TRIGGER_CHANGE, function () { - self.fireEvent(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE); - }); - this.switcher.on(BI.Switcher.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW); - }); - this.switcher.on(BI.Switcher.EVENT_AFTER_HIDEVIEW, function () { - self.fireEvent(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW); - }); - this.switcher.on(BI.Switcher.EVENT_AFTER_POPUPVIEW, function () { - var me = this; - BI.nextTick(function () { - me._populate(); - }); - }); - }, - - adjustView: function () { - this.switcher.adjustView(); - }, - - hideView: function () { - this.switcher.empty(); - this.switcher.hideView(); - }, - - setAdapter: function (adapter) { - this.switcher.setAdapter(adapter); - }, - - setValue: function (v) { - this.switcher.setValue(v); - }, - - // 与setValue的区别是只更新查看已选面板的的selectedValue, 不会更新按钮的计数 - updateSelectedValue: function (v) { - this.checkPane.setValue(v); - }, - - setButtonChecked: function (v) { - this.button.setValue(v); - }, - - getValue: function () { - - }, - - populate: function (items) { - this.switcher.populate.apply(this.switcher, arguments); - }, - - populateSwitcher: function () { - this.button.populate.apply(this.button, arguments); - } -}); - -BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; -BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; -BI.shortcut("bi.multi_select_check_selected_switcher", BI.MultiSelectCheckSelectedSwitcher); \ No newline at end of file diff --git a/src/widget/multiselectlist/multiselectlist.insert.js b/src/widget/multiselectlist/multiselectlist.insert.js deleted file mode 100644 index 4c7da6df9..000000000 --- a/src/widget/multiselectlist/multiselectlist.insert.js +++ /dev/null @@ -1,362 +0,0 @@ -/** - * Created by zcf_1 on 2017/5/2. - */ -BI.MultiSelectInsertList = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-insert-list", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcherHeight: BI.SIZE_CONSANTS.TRIGGER_HEIGHT, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - simple: false, - }); - }, - _init: function () { - BI.MultiSelectInsertList.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - this.storeValue = this._assertValue(BI.deepClone(o.value) || {}); - - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, self._startValue) : BI.pushDistinct(self.storeValue.value, self._startValue)); - // self.trigger.setValue(self.storeValue); - }; - - this.adapter = BI.createWidget({ - type: "bi.multi_select_loader", - cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - logic: { - dynamic: false - }, - // onLoaded: o.onLoaded, - el: {}, - isDefaultInit: true, - value: o.value - }); - this.adapter.on(BI.MultiSelectLoader.EVENT_CHANGE, function () { - self.storeValue = this.getValue(); - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); - }); - - this.searcherPane = BI.createWidget({ - type: "bi.multi_select_search_insert_pane", - cls: "bi-border-left bi-border-right bi-border-bottom", - valueFormatter: o.valueFormatter, - itemFormatter: o.itemFormatter, - keywordGetter: function () { - return self.trigger.getKeyword(); - }, - itemsCreator: function (op, callback) { - var keyword = self.trigger.getKeyword(); - if (BI.isNotEmptyString(keyword)) { - op.keywords = [keyword]; - this.setKeyword(op.keywords[0]); - o.itemsCreator(op, callback); - } - }, - itemHeight: o.itemHeight, - }); - this.searcherPane.setVisible(false); - - this.trigger = BI.createWidget({ - type: "bi.searcher", - el: { - type: "bi.select_patch_editor", - el: { - type: "bi.search_editor", - watermark: BI.i18nText("BI-Basic_Search_And_Patch_Paste"), - simple: o.simple, - }, - ref: function (ref) { - self.editor = ref; - }, - }, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - adapter: this.adapter, - popup: this.searcherPane, - masker: false, - listeners: [{ - eventName: BI.Searcher.EVENT_START, - action: function () { - self._showSearcherPane(); - self._setStartValue(""); - this.setValue(BI.deepClone(self.storeValue)); - } - }, { - eventName: BI.Searcher.EVENT_STOP, - action: function () { - self._showAdapter(); - self._setStartValue(""); - self.adapter.setValue(self.storeValue); - // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 - self.adapter.populate(); - } - }, { - eventName: BI.Searcher.EVENT_PAUSE, - action: function () { - var keywords = self._getKeywords(); - if (keywords[keywords.length - 1] === BI.BlankSplitChar) { - keywords = keywords.slice(0, keywords.length - 1); - } - var keyword = BI.isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; - self._join({ - type: BI.Selection.Multi, - value: [keyword] - }, function () { - if (self.storeValue.type === BI.Selection.Multi) { - BI.pushDistinct(self.storeValue.value, keyword); - } - self._showAdapter(); - self.adapter.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(""); - self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); - }); - self._showAdapter(); - } - }, { - eventName: BI.Searcher.EVENT_SEARCHING, - action: function () { - var keywords = self._getKeywords(); - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.adapter.setValue(self.storeValue); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(""); - } else { - self.adapter.setValue(self.storeValue); - assertShowValue(); - } - self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); - }); - self._getKeywordsLength() > 2000 && BI.Msg.alert(BI.i18nText("BI-Basic_Prompt"), BI.i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); - } - } - }, { - eventName: BI.Searcher.EVENT_CHANGE, - action: function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); - }); - } - } - }], - value: o.value - }); - - BI.createWidget({ - type: "bi.vertical_fill", - rowSize: ["", "fill"], - element: this, - items: [{ - el: this.trigger, - }, { - el: this.adapter, - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.searcherPane, - top: o.searcherHeight || BI.SIZE_CONSANTS.TRIGGER_HEIGHT, - bottom: 0, - left: 0, - right: 0 - }] - }); - }, - - _getKeywords: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - if (/\u200b\s\u200b$/.test(val)) { - keywords = keywords.concat([BI.BlankSplitChar]); - } - - return keywords.length > 2000 ? keywords.slice(0, 2000).concat([BI.BlankSplitChar]) : keywords.slice(0, 2000); - }, - - _getKeywordsLength: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - - return keywords.length - 1; - }, - - _showAdapter: function () { - this.adapter.setVisible(true); - this.searcherPane.setVisible(false); - }, - - _showSearcherPane: function () { - this.searcherPane.setVisible(true); - this.adapter.setVisible(false); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - return val; - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - // 和复选下拉框同步,allData做缓存是会爆炸的 - - digest(); - - function digest() { - BI.each(keywords, function (i, val) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - }); - callback(); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKeyword()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - callback(); - return; - } - o.itemsCreator({ - type: BI.MultiSelectInsertList.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKeyword()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - callback(); - }); - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - callback(); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.adapter.setStartValue(value); - }, - - isAllSelected: function () { - return this.adapter.isAllSelected(); - }, - - resize: function () { - // this.trigger.getCounter().adjustView(); - // this.trigger.adjustView(); - }, - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.adapter.setValue(this.storeValue); - this.trigger.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - populate: function () { - this.adapter.populate.apply(this.adapter, arguments); - this.trigger.populate.apply(this.trigger, arguments); - } -}); - -BI.extend(BI.MultiSelectInsertList, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectInsertList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_insert_list", BI.MultiSelectInsertList); diff --git a/src/widget/multiselectlist/multiselectlist.insert.nobar.js b/src/widget/multiselectlist/multiselectlist.insert.nobar.js deleted file mode 100644 index aa322378b..000000000 --- a/src/widget/multiselectlist/multiselectlist.insert.nobar.js +++ /dev/null @@ -1,367 +0,0 @@ -/** - * Created by zcf_1 on 2017/5/2. - */ -BI.MultiSelectInsertNoBarList = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectInsertNoBarList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-insert-list", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcherHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }); - }, - _init: function () { - BI.MultiSelectInsertNoBarList.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - this.storeValue = { - type: BI.Selection.Multi, - value: BI.deepClone(o.value) || [] - }; - - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, self._startValue) : BI.pushDistinct(self.storeValue.value, self._startValue)); - // self.trigger.setValue(self.storeValue); - }; - - this.adapter = BI.createWidget({ - type: "bi.multi_select_no_bar_loader", - cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", - itemsCreator: o.itemsCreator, - itemHeight: o.itemHeight, - valueFormatter: o.valueFormatter, - logic: { - dynamic: false - }, - // onLoaded: o.onLoaded, - el: {}, - value: { - type: BI.Selection.Multi, - value: o.value || [] - } - }); - this.adapter.on(BI.MultiSelectLoader.EVENT_CHANGE, function () { - self.storeValue = this.getValue(); - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertNoBarList.EVENT_CHANGE); - }); - - this.searcherPane = BI.createWidget({ - type: "bi.multi_select_search_insert_pane", - cls: "bi-border-left bi-border-right bi-border-bottom", - valueFormatter: o.valueFormatter, - keywordGetter: function () { - return self.trigger.getKeyword(); - }, - itemsCreator: function (op, callback) { - var keyword = self.trigger.getKeyword(); - if (BI.isNotEmptyString(keyword)) { - op.keywords = [keyword]; - this.setKeyword(op.keywords[0]); - o.itemsCreator(op, callback); - } - }, - allowSelectAll: false, - }); - this.searcherPane.setVisible(false); - - this.trigger = BI.createWidget({ - type: "bi.searcher", - el: { - type: "bi.select_patch_editor", - el: { - type: "bi.search_editor", - watermark: BI.i18nText("BI-Basic_Search_And_Patch_Paste"), - }, - ref: function (ref) { - self.editor = ref; - }, - height: o.searcherHeight - }, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - adapter: this.adapter, - popup: this.searcherPane, - height: 200, - masker: false, - listeners: [{ - eventName: BI.Searcher.EVENT_START, - action: function () { - self._showSearcherPane(); - self._setStartValue(""); - this.setValue(BI.deepClone(self.storeValue)); - } - }, { - eventName: BI.Searcher.EVENT_STOP, - action: function () { - self._showAdapter(); - self._setStartValue(""); - self.adapter.setValue(self.storeValue); - // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 - self.adapter.populate(); - } - }, { - eventName: BI.Searcher.EVENT_PAUSE, - action: function () { - var keywords = self._getKeywords(); - if (keywords[keywords.length - 1] === BI.BlankSplitChar) { - keywords = keywords.slice(0, keywords.length - 1); - } - var keyword = BI.isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; - self._join({ - type: BI.Selection.Multi, - value: [keyword] - }, function () { - if (self.storeValue.type === BI.Selection.Multi) { - BI.pushDistinct(self.storeValue.value, keyword); - } - self._showAdapter(); - self.adapter.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(""); - self.fireEvent(BI.MultiSelectInsertNoBarList.EVENT_CHANGE); - }); - } - }, { - eventName: BI.Searcher.EVENT_SEARCHING, - action: function () { - var keywords = self._getKeywords(); - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.adapter.setValue(self.storeValue); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(""); - } else { - self.adapter.setValue(self.storeValue); - assertShowValue(); - } - self.fireEvent(BI.MultiSelectInsertNoBarList.EVENT_CHANGE); - }); - self._getKeywordsLength() > 2000 && BI.Msg.alert(BI.i18nText("BI-Basic_Prompt"), BI.i18nText("BI-Basic_Too_Much_Value_Get_Two_Thousand")); - } - } - }, { - eventName: BI.Searcher.EVENT_CHANGE, - action: function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertNoBarList.EVENT_CHANGE); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectInsertNoBarList.EVENT_CHANGE); - }); - } - } - }], - value: { - type: BI.Selection.Multi, - value: o.value || [] - } - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - el: this.trigger, - height: o.searcherHeight - }, { - el: this.adapter, - height: "fill" - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.searcherPane, - top: o.searcherHeight, - bottom: 0, - left: 0, - right: 0 - }] - }); - }, - - _getKeywords: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - if (/\u200b\s\u200b$/.test(val)) { - keywords = keywords.concat([BI.BlankSplitChar]); - } - - return keywords.length > 2000 ? keywords.slice(0, 2000).concat([BI.BlankSplitChar]) : keywords.slice(0, 2000); - }, - - _getKeywordsLength: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - - return keywords.length - 1; - }, - - _showAdapter: function () { - this.adapter.setVisible(true); - this.searcherPane.setVisible(false); - }, - - _showSearcherPane: function () { - this.searcherPane.setVisible(true); - this.adapter.setVisible(false); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - // 和复选下拉框同步,allData做缓存是会爆炸的 - digest(); - - function digest(items) { - BI.each(keywords, function (i, val) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - }); - callback(); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKeyword()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - callback(); - return; - } - o.itemsCreator({ - type: BI.MultiSelectInsertNoBarList.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKeyword()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - callback(); - }); - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - callback(); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.adapter.setStartValue(value); - }, - - isAllSelected: function () { - return this.adapter.isAllSelected(); - }, - - resize: function () { - // this.trigger.getCounter().adjustView(); - // this.trigger.adjustView(); - }, - setValue: function (v) { - this.storeValue = { - type: BI.Selection.Multi, - value: v || [] - }; - this.adapter.setValue(this.storeValue); - this.trigger.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this.adapter.populate.apply(this.adapter, arguments); - this.trigger.populate.apply(this.trigger, arguments); - } -}); - -BI.extend(BI.MultiSelectInsertNoBarList, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectInsertNoBarList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_insert_no_bar_list", BI.MultiSelectInsertNoBarList); diff --git a/src/widget/multiselectlist/multiselectlist.js b/src/widget/multiselectlist/multiselectlist.js deleted file mode 100644 index 7255963df..000000000 --- a/src/widget/multiselectlist/multiselectlist.js +++ /dev/null @@ -1,371 +0,0 @@ -/** - * Created by zcf_1 on 2017/5/2. - */ -BI.MultiSelectList = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-list", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcherHeight: 24, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }); - }, - _init: function () { - BI.MultiSelectList.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - this.storeValue = this._assertValue(BI.deepClone(o.value) || {}); - - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, self._startValue) : BI.pushDistinct(self.storeValue.value, self._startValue)); - // self.trigger.setValue(self.storeValue); - }; - - this.adapter = BI.createWidget({ - type: "bi.multi_select_loader", - cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - itemHeight: o.itemHeight, - logic: { - dynamic: false - }, - value: o.value, - isDefaultInit: true, - // onLoaded: o.onLoaded, - el: {} - }); - this.adapter.on(BI.MultiSelectLoader.EVENT_CHANGE, function () { - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); - }); - }); - - this.searcherPane = BI.createWidget({ - type: "bi.multi_select_search_pane", - cls: "bi-border-left bi-border-right bi-border-bottom", - valueFormatter: o.valueFormatter, - keywordGetter: function () { - return self.trigger.getKeyword(); - }, - itemsCreator: function (op, callback) { - var keyword = self.trigger.getKeyword(); - if (BI.isNotEmptyString(keyword)) { - op.keywords = [keyword]; - o.itemsCreator(op, callback); - } - }, - itemHeight: o.itemHeight - }); - this.searcherPane.setVisible(false); - - this.trigger = BI.createWidget({ - type: "bi.searcher", - el: { - type: "bi.select_patch_editor", - el: { - type: "bi.search_editor", - }, - ref: function (ref) { - self.editor = ref; - }, - height: o.searcherHeight - }, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - adapter: this.adapter, - popup: this.searcherPane, - height: 200, - masker: false, - listeners: [{ - eventName: BI.Searcher.EVENT_START, - action: function () { - self._showSearcherPane(); - self._setStartValue(""); - this.setValue(BI.deepClone(self.storeValue)); - } - }, { - eventName: BI.Searcher.EVENT_STOP, - action: function () { - self._showAdapter(); - self._setStartValue(""); - self.adapter.setValue(self.storeValue); - // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 - self.adapter.populate(); - } - }, { - eventName: BI.Searcher.EVENT_PAUSE, - action: function () { - self._showAdapter(); - self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); - }, - }, { - eventName: BI.Searcher.EVENT_SEARCHING, - action: function () { - var keywords = this.getKeyword(); - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.adapter.setValue(self.storeValue); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(""); - } else { - self.adapter.setValue(self.storeValue); - assertShowValue(); - } - self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); - }); - } - } - }, { - eventName: BI.Searcher.EVENT_CHANGE, - action: function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); - }); - } - } - }] - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - el: this.trigger, - height: o.searcherHeight - }, { - el: this.adapter, - height: "fill" - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.searcherPane, - top: o.searcherHeight, - bottom: 0, - left: 0, - right: 0 - }] - }); - }, - - _getKeywords: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - if (/\u200b\s\u200b$/.test(val)) { - return keywords.concat([BI.BlankSplitChar]); - } - - return keywords; - }, - - _showAdapter: function () { - this.adapter.setVisible(true); - this.searcherPane.setVisible(false); - }, - - _showSearcherPane: function () { - this.searcherPane.setVisible(true); - this.adapter.setVisible(false); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - return val; - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - // 和复选下拉框同步,allData做缓存是会爆炸的 - o.itemsCreator({ - type: BI.MultiSelectList.REQ_GET_ALL_DATA, - keywords: keywords - }, function (ob) { - var values = BI.map(ob.items, "value"); - digest(values); - }); - - function digest(items) { - var selectedMap = self._makeMap(items); - BI.each(keywords, function (i, val) { - if (BI.isNotNull(selectedMap[val])) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - } - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - if (this.storeValue.type === res.type) { - var result = BI.Func.getSearchResult(BI.map(this.storeValue.value, function (_i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }), this.trigger.getKeyword()); - var change = false; - var map = this._makeMap(this.storeValue.value); - BI.each(BI.concat(result.match, result.find), function (i, obj) { - var v = obj.value; - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - this._adjust(callback); - return; - } - o.itemsCreator({ - type: BI.MultiSelectList.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKeyword()], - selectedValues: BI.filter(this.storeValue.value, function (_i, v) { - return !BI.contains(res.value, v); - }), - }, function (ob) { - var items = BI.map(ob.items, "value"); - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - if (!this._count) { - o.itemsCreator({ - type: BI.MultiSelectList.REQ_GET_DATA_LENGTH - }, function (res) { - self._count = res.count; - adjust(); - callback(); - }); - } else { - adjust(); - callback(); - } - - function adjust() { - if (self.storeValue.type === BI.Selection.All && self.storeValue.value.length >= self._count) { - self.storeValue = { - type: BI.Selection.Multi, - value: [] - }; - } else if (self.storeValue.type === BI.Selection.Multi && self.storeValue.value.length >= self._count) { - self.storeValue = { - type: BI.Selection.All, - value: [] - }; - } - } - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - BI.pushDistinct(self.storeValue.value, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.adapter.setStartValue(value); - }, - - isAllSelected: function () { - return this.adapter.isAllSelected(); - }, - - resize: function () { - // this.trigger.getCounter().adjustView(); - // this.trigger.adjustView(); - }, - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.adapter.setValue(this.storeValue); - this.trigger.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - populate: function () { - this.adapter.populate.apply(this.adapter, arguments); - this.trigger.populate.apply(this.trigger, arguments); - } -}); - -BI.extend(BI.MultiSelectList, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.MultiSelectList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_list", BI.MultiSelectList); diff --git a/src/widget/multiselecttree/multiselecttree.js b/src/widget/multiselecttree/multiselecttree.js deleted file mode 100644 index ef77287d9..000000000 --- a/src/widget/multiselecttree/multiselecttree.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Created by zcf_1 on 2017/5/11. - */ -BI.MultiSelectTree = BI.inherit(BI.Single, { - _constant: { - EDITOR_HEIGHT: 24 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiSelectTree.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-tree", - itemsCreator: BI.emptyFn, - simple: false, - }); - }, - - _init: function () { - BI.MultiSelectTree.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.storeValue = {value: {}}; - - this.adapter = BI.createWidget({ - type: "bi.multi_select_tree_popup", - itemsCreator: o.itemsCreator, - showLine: o.showLine - }); - this.adapter.on(BI.MultiSelectTreePopup.EVENT_CHANGE, function () { - if (self.searcher.isSearching()) { - self.storeValue = {value: self.searcherPane.getValue()}; - } else { - self.storeValue = {value: self.adapter.getValue()}; - } - self.setSelectedValue(self.storeValue.value); - self.fireEvent(BI.MultiSelectTree.EVENT_CHANGE); - }); - - // 搜索中的时候用的是parttree,同adapter中的synctree不一样 - this.searcherPane = BI.createWidget({ - type: "bi.multi_tree_search_pane", - cls: "bi-border-left bi-border-right bi-border-bottom", - keywordGetter: function () { - return self.searcher.getKeyword(); - }, - itemsCreator: function (op, callback) { - op.keyword = self.searcher.getKeyword(); - o.itemsCreator(op, callback); - } - }); - this.searcherPane.setVisible(false); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - isAutoSearch: false, - isAutoSync: false, - simple: o.simple, - onSearch: function (op, callback) { - callback({ - keyword: self.searcher.getKeyword() - }); - }, - adapter: this.adapter, - popup: this.searcherPane, - masker: false, - listeners: [{ - eventName: BI.Searcher.EVENT_START, - action: function () { - self._showSearcherPane(); - // self.storeValue = {value: self.adapter.getValue()}; - // self.searcherPane.setSelectedValue(self.storeValue.value); - } - }, { - eventName: BI.Searcher.EVENT_STOP, - action: function () { - self._showAdapter(); - // self.storeValue = {value: self.searcherPane.getValue()}; - // self.adapter.setSelectedValue(self.storeValue.value); - BI.nextTick(function () { - self.adapter.populate(); - }); - } - }, { - eventName: BI.Searcher.EVENT_CHANGE, - action: function () { - if (self.searcher.isSearching()) { - self.storeValue = {value: self.searcherPane.getValue()}; - } else { - self.storeValue = {value: self.adapter.getValue()}; - } - self.setSelectedValue(self.storeValue.value); - self.fireEvent(BI.MultiSelectTree.EVENT_CHANGE); - } - }, { - eventName: BI.Searcher.EVENT_PAUSE, - action: function () { - self._showAdapter(); - // BI-64732 pause 和stop一致, 都应该刷新adapter - BI.nextTick(function () { - self.adapter.populate(); - }); - } - }] - }); - - BI.createWidget({ - type: "bi.vertical_fill", - element: this, - items: [{ - el: this.searcher, - height: "" - }, { - el: this.adapter, - height: "fill" - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.searcherPane, - top: this._constant.EDITOR_HEIGHT, - bottom: 0, - left: 0, - right: 0 - }] - }); - - }, - - _showAdapter: function () { - this.adapter.setVisible(true); - this.searcherPane.setVisible(false); - }, - - _showSearcherPane: function () { - this.searcherPane.setVisible(true); - this.adapter.setVisible(false); - }, - - resize: function () { - - }, - - setSelectedValue: function (v) { - this.storeValue.value = v || {}; - this.adapter.setSelectedValue(v); - this.searcherPane.setSelectedValue(v); - this.searcher.setValue({ - value: v || {} - }); - }, - - setValue: function (v) { - this.adapter.setValue(v); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - updateValue: function (v) { - this.adapter.updateValue(v); - }, - - getValue: function () { - return this.storeValue.value; - }, - - populate: function () { - this.adapter.populate(); - } -}); -BI.MultiSelectTree.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_tree", BI.MultiSelectTree); diff --git a/src/widget/multiselecttree/multiselecttree.popup.js b/src/widget/multiselecttree/multiselecttree.popup.js deleted file mode 100644 index 95af718ce..000000000 --- a/src/widget/multiselecttree/multiselecttree.popup.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Created by zcf on 2016/12/21. - */ -BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { - _defaultConfig: function () { - return BI.extend(BI.MultiSelectTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-tree-popup bi-border-left bi-border-right bi-border-bottom", - itemsCreator: BI.emptyFn - }); - }, - _init: function () { - BI.MultiSelectTreePopup.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.popup = BI.createWidget({ - type: "bi.async_tree", - showLine: o.showLine, - element: this, - itemsCreator: o.itemsCreator - }); - this.popup.on(BI.TreeView.EVENT_AFTERINIT, function () { - self.fireEvent(BI.MultiSelectTreePopup.EVENT_AFTER_INIT); - }); - this.popup.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectTreePopup.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.popup.hasChecked(); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - setValue: function (v) { - v || (v = {}); - this.popup.setValue(v); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.popup.setSelectedValue(v); - }, - - updateValue: function (v) { - this.popup.updateValue(v); - this.popup.refresh(); - }, - - populate: function (config) { - this.popup.stroke(config); - } - -}); -BI.MultiSelectTreePopup.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; -BI.MultiSelectTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_select_tree_popup", BI.MultiSelectTreePopup); \ No newline at end of file diff --git a/src/widget/multitree/check/multi.tree.check.pane.js b/src/widget/multitree/check/multi.tree.check.pane.js deleted file mode 100644 index 4adbe1f90..000000000 --- a/src/widget/multitree/check/multi.tree.check.pane.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * - * @class BI.MultiTreeCheckPane - * @extends BI.Pane - */ -BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { - - constants: { - height: 25, - lgap: 10, - tgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn, - el: { - type: "bi.display_tree" - } - }); - }, - - _init: function () { - BI.MultiTreeCheckPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.selectedValues = {}; - - var continueSelect = BI.createWidget({ - type: "bi.text_button", - title: BI.i18nText("BI-Continue_Select"), - text: BI.i18nText("BI-Continue_Select"), - cls: "bi-high-light", - }); - continueSelect.on(BI.TextButton.EVENT_CHANGE, function () { - opts.onClickContinueSelect(); - BI.nextTick(function () { - self.empty(); - }); - }); - - var backToPopup = BI.createWidget({ - type: "bi.vertical_adapt", - columnSize: ["auto", "auto"], - cls: "multi-tree-continue-select", - items: [ - { - el: { - type: "bi.label", - title: BI.i18nText("BI-Selected_Data"), - text: BI.i18nText("BI-Selected_Data") - }, - lgap: this.constants.lgap, - tgap: this.constants.tgap - }, - { - el: continueSelect, - hgap: this.constants.lgap, - tgap: this.constants.tgap - }] - }); - - this.display = BI.createWidget(opts.el, { - type: "bi.display_tree", - cls: "bi-multi-tree-display", - itemsCreator: function (op, callback) { - op.type = BI.TreeView.REQ_TYPE_GET_SELECTED_DATA; - opts.itemsCreator(op, callback); - }, - value: (opts.value || {}).value - }); - - this.display.on(BI.Events.AFTERINIT, function () { - self.fireEvent(BI.Events.AFTERINIT); - }); - - this.display.on(BI.TreeView.EVENT_INIT, function () { - backToPopup.setVisible(false); - }); - - this.display.on(BI.TreeView.EVENT_AFTERINIT, function () { - backToPopup.setVisible(true); - }); - - BI.createWidget({ - type: "bi.vtape", - element: this, - items: [{ - height: this.constants.height, - el: backToPopup - }, { - height: "fill", - el: this.display - }] - }); - }, - - empty: function () { - this.display.empty(); - }, - - populate: function (configs) { - this.display.stroke(configs); - }, - - setValue: function (v) { - v || (v = {}); - this.display.setSelectedValue(v.value); - }, - - getValue: function () { - - } -}); - -BI.MultiTreeCheckPane.EVENT_CONTINUE_CLICK = "EVENT_CONTINUE_CLICK"; - - -BI.shortcut("bi.multi_tree_check_pane", BI.MultiTreeCheckPane); diff --git a/src/widget/multitree/multi.tree.combo.js b/src/widget/multitree/multi.tree.combo.js deleted file mode 100644 index 5fca0ca4f..000000000 --- a/src/widget/multitree/multi.tree.combo.js +++ /dev/null @@ -1,393 +0,0 @@ -/** - * - * @class BI.MultiTreeCombo - * @extends BI.Single - */ - -BI.MultiTreeCombo = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.MultiTreeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-combo", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - allowEdit: true, - isNeedAdjustWidth: true, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiTreeCombo.superclass._init.apply(this, arguments); - var isInit = false; - var want2showCounter = false; - - this.storeValue = { value: o.value || {} }; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_trigger", - allowEdit: o.allowEdit, - height: BI.toPix(o.height, o.simple ? 1 : 2), - valueFormatter: o.valueFormatter, - text: o.text, - defaultText: o.defaultText, - watermark: o.watermark, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - searcher: { - type: "bi.multi_tree_searcher", - itemsCreator: o.itemsCreator, - listeners: [ - { - eventName: BI.MultiTreeSearcher.EVENT_CLICK_TREE_NODE, - action: function () { - self._dataChange = true; - } - } - ], - }, - value: { value: o.value || {} } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: !o.allowEdit, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_tree_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [ - { - eventName: BI.MultiTreePopup.EVENT_AFTERINIT, - action: function () { - self.numberCounter.adjustView(); - isInit = true; - if (want2showCounter === true) { - showCounter(); - } - } - }, { - eventName: BI.MultiTreePopup.EVENT_CHANGE, - action: function () { - change = true; - var val = { - type: BI.Selection.Multi, - value: this.hasChecked() ? this.getValue() : {} - }; - self.trigger.getSearcher().setState(val); - self.numberCounter.setButtonChecked(val); - self.storeValue = { value: self.combo.getValue() }; - self.fireEvent(BI.MultiTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - self._dataChange = true; - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, - action: function () { - self.combo.hideView(); - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, - action: function () { - clear = true; - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - } - ], - itemsCreator: o.itemsCreator, - onLoaded: function () { - BI.nextTick(function () { - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - }, - maxWidth: o.isNeedAdjustWidth ? "auto" : 500, - }, - isNeedAdjustWidth: o.isNeedAdjustWidth, - value: { value: o.value || {} }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && - self.numberCounter.element.find(e.target).length === 0; - } - }); - - var change = false; - var clear = false; // 标识当前是否点击了清空 - - var isSearching = function () { - return self.trigger.getSearcher().isSearching(); - }; - - var isPopupView = function () { - return self.combo.isViewVisible(); - }; - - this.trigger.on(BI.MultiSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiTreeCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiTreeCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self.storeValue = { value: self.combo.getValue() }; - this.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self.storeValue = { value: this.getValue() }; - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - BI.nextTick(function () { - if (isPopupView()) { - self.combo.populate(); - } - }); - self.fireEvent(BI.MultiTreeCombo.EVENT_STOP); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function () { - self.fireEvent(BI.MultiTreeCombo.EVENT_SEARCHING); - }); - - function showCounter() { - if (isSearching()) { - self.storeValue = { value: self.trigger.getValue() }; - } else if (isPopupView()) { - self.storeValue = { value: self.combo.getValue() }; - } - self.trigger.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - } - - this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { - self.combo.toggle(); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { - var checked = this.getSearcher().hasChecked(); - var val = { - type: BI.Selection.Multi, - value: checked ? { 1: 1 } : {} - }; - this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); - self.numberCounter.setButtonChecked(val); - self.fireEvent(BI.MultiTreeCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - self._dataChange = true; - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (isSearching()) { - return; - } - if (!this.isViewVisible()) { - self._dataChange = false; // 标记数据是否发生变化 - } - if (change === true) { - self.storeValue = { value: self.combo.getValue() }; - change = false; - } - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - self.populate(); - self.fireEvent(BI.MultiTreeCombo.EVENT_BEFORE_POPUPVIEW); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { - if (isSearching()) { - self._stopEditing(); - self._dataChange && self.fireEvent(BI.MultiTreeCombo.EVENT_CONFIRM); - } else { - if (isPopupView()) { - self._stopEditing(); - self.storeValue = { value: self.combo.getValue() }; - if (clear === true) { - self.storeValue = { value: {} }; - } - self._dataChange && self.fireEvent(BI.MultiTreeCombo.EVENT_CONFIRM); - } - } - clear = false; - change = false; - }); - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - self.fireEvent(BI.MultiTreeCombo.EVENT_AFTER_HIDEVIEW); - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - el: { - type: "bi.multi_tree_check_selected_button" - }, - popup: { - type: "bi.multi_tree_check_pane" - }, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - value: { value: o.value || {} } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - if (want2showCounter === false) { - want2showCounter = true; - } - if (isInit === true) { - want2showCounter = null; - showCounter(); - } - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - bottom: 0 - } - ] - }); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue.value = v || {}; - this.combo.setValue({ - value: v || {} - }); - this.numberCounter.setValue({ - value: v || {} - }); - }, - - getSearcher: function () { - return this.trigger.getSearcher(); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this.combo.populate(); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.MultiTreeCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiTreeCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiTreeCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiTreeCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiTreeCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiTreeCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.MultiTreeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiTreeCombo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; - -BI.shortcut("bi.multi_tree_combo", BI.MultiTreeCombo); diff --git a/src/widget/multitree/multi.tree.insert.combo.js b/src/widget/multitree/multi.tree.insert.combo.js deleted file mode 100644 index acacbb875..000000000 --- a/src/widget/multitree/multi.tree.insert.combo.js +++ /dev/null @@ -1,406 +0,0 @@ -/** - * 可以往当前选中节点下添加新值的下拉树 - * @class BI.MultiTreeInsertCombo - * @extends BI.Single - */ - -BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-insert-combo", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - allowEdit: true, - isNeedAdjustWidth: true, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiTreeInsertCombo.superclass._init.apply(this, arguments); - var isInit = false; - var want2showCounter = false; - - this.storeValue = { value: o.value || {} }; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_trigger", - allowEdit: o.allowEdit, - height: BI.toPix(o.height, o.simple ? 1 : 2), - valueFormatter: o.valueFormatter, - text: o.text, - defaultText: o.defaultText, - watermark: o.watermark, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - searcher: { - type: "bi.multi_tree_searcher", - - itemsCreator: o.itemsCreator, - popup: { - type: "bi.multi_tree_search_insert_pane", - listeners: [ - { - eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, - action: function () { - self.storeValue.value[self.trigger.getSearcher().getKeyword()] = {}; - self._assertShowValue(); - // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - self._stopEditing(); - self._dataChange = true; - } - }, { - eventName: BI.MultiTreeSearchInsertPane.EVENT_CLICK_TREE_NODE, - action: function () { - self._dataChange = true; - } - } - ] - } - }, - value: { value: o.value || {} } - - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: !o.allowEdit, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_tree_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - listeners: [ - { - eventName: BI.MultiTreePopup.EVENT_AFTERINIT, - action: function () { - self.numberCounter.adjustView(); - isInit = true; - if (want2showCounter === true) { - showCounter(); - } - } - }, { - eventName: BI.MultiTreePopup.EVENT_CHANGE, - action: function () { - change = true; - var val = { - type: BI.Selection.Multi, - value: this.hasChecked() ? this.getValue() : {} - }; - self.trigger.getSearcher().setState(val); - self.numberCounter.setButtonChecked(val); - self.storeValue = { value: self.combo.getValue() }; - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_CLICK_ITEM, self.getValue()); - self._dataChange = true; - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, - action: function () { - self.combo.hideView(); - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, - action: function () { - clear = true; - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - } - ], - itemsCreator: o.itemsCreator, - onLoaded: function () { - BI.nextTick(function () { - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - }, - maxWidth: o.isNeedAdjustWidth ? "auto" : 500, - }, - isNeedAdjustWidth: o.isNeedAdjustWidth, - value: { value: o.value || {} }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && - self.numberCounter.element.find(e.target).length === 0; - } - }); - - var change = false; - var clear = false; // 标识当前是否点击了清空 - - var isSearching = function () { - return self.trigger.getSearcher().isSearching(); - }; - - var isPopupView = function () { - return self.combo.isViewVisible(); - }; - - this.trigger.on(BI.MultiSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self.storeValue = { value: self.combo.getValue() }; - this.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self.storeValue = { value: this.getValue() }; - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - BI.nextTick(function () { - if (isPopupView()) { - self.combo.populate(); - } - }); - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_STOP); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function () { - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_SEARCHING); - }); - - function showCounter() { - if (isSearching()) { - self.storeValue = { value: self.trigger.getValue() }; - } else if (isPopupView()) { - self.storeValue = { value: self.combo.getValue() }; - } - self.trigger.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - } - - this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { - self.combo.toggle(); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { - var checked = this.getSearcher().hasChecked(); - var val = { - type: BI.Selection.Multi, - value: checked ? { 1: 1 } : {} - }; - this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); - self.numberCounter.setButtonChecked(val); - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - self._dataChange = true; - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (isSearching()) { - return; - } - if (!this.isViewVisible()) { - self._dataChange = false; // 标记数据是否发生变化 - } - if (change === true) { - self.storeValue = { value: self.combo.getValue() }; - change = false; - } - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - self.populate(); - self.fireEvent(BI.MultiTreeInsertCombo.EVENT_BEFORE_POPUPVIEW); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { - if (isSearching()) { - self._stopEditing(); - self._dataChange && self.fireEvent(BI.MultiTreeInsertCombo.EVENT_CONFIRM); - } else { - if (isPopupView()) { - self._stopEditing(); - self.storeValue = { value: self.combo.getValue() }; - if (clear === true) { - self.storeValue = { value: {} }; - } - self._dataChange && self.fireEvent(BI.MultiTreeInsertCombo.EVENT_CONFIRM); - } - } - clear = false; - change = false; - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - el: { - type: "bi.multi_tree_check_selected_button" - }, - popup: { - type: "bi.multi_tree_check_pane" - }, - itemsCreator: o.itemsCreator, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - value: o.value - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - if (want2showCounter === false) { - want2showCounter = true; - } - if (isInit === true) { - want2showCounter = null; - showCounter(); - } - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - height: o.height, - } - ] - }); - }, - - _assertShowValue: function () { - this.trigger.getSearcher().setState(this.storeValue); - this.numberCounter.setButtonChecked(this.storeValue); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - getSearcher: function () { - return this.trigger.getSearcher(); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue.value = v || {}; - this.combo.setValue({ - value: v || {} - }); - this.numberCounter.setValue({ - value: v || {} - }); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this.combo.populate(); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.MultiTreeInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiTreeInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiTreeInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiTreeInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiTreeInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiTreeInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.MultiTreeInsertCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - -BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo); diff --git a/src/widget/multitree/multi.tree.list.combo.js b/src/widget/multitree/multi.tree.list.combo.js deleted file mode 100644 index a3a016179..000000000 --- a/src/widget/multitree/multi.tree.list.combo.js +++ /dev/null @@ -1,412 +0,0 @@ -/** - * 选中节点不影响父子节点状态的下拉树 - * @class BI.MultiTreeListCombo - * @extends BI.Single - */ - -BI.MultiTreeListCombo = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-list-combo", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - allowEdit: true, - allowInsertValue: true, - isNeedAdjustWidth: true, - text: "", - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.MultiTreeListCombo.superclass._init.apply(this, arguments); - var isInit = false; - var want2showCounter = false; - - this.storeValue = { value: o.value || [] }; - - this.trigger = BI.createWidget({ - type: "bi.multi_select_trigger", - allowEdit: o.allowEdit, - text: o.text, - defaultText: o.defaultText, - watermark: o.watermark, - height: BI.toPix(o.height, o.simple ? 1 : 2), - valueFormatter: o.valueFormatter, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - searcher: { - type: "bi.multi_list_tree_searcher", - itemsCreator: o.itemsCreator, - popup: { - type: o.allowInsertValue ? "bi.multi_tree_search_insert_pane" : "bi.multi_tree_search_pane", - el: { - type: "bi.list_part_tree" - }, - listeners: [{ - eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, - action: function () { - self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); - self._assertShowValue(); - // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - self._stopEditing(); - self._dataChange = true; - } - }] - } - }, - switcher: { - el: { - type: "bi.multi_tree_check_selected_button" - }, - popup: { - type: "bi.multi_tree_check_pane", - el: { - type: "bi.list_display_tree" - }, - itemsCreator: o.itemsCreator - } - }, - value: this.storeValue - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - toggle: !o.allowEdit, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.multi_tree_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - self.numberCounter.setAdapter(this); - }, - el: { - type: "bi.list_async_tree" - }, - listeners: [{ - eventName: BI.MultiTreePopup.EVENT_AFTERINIT, - action: function () { - self.numberCounter.adjustView(); - isInit = true; - if (want2showCounter === true) { - showCounter(); - } - } - }, { - eventName: BI.MultiTreePopup.EVENT_CHANGE, - action: function () { - change = true; - var val = { - type: BI.Selection.Multi, - value: this.hasChecked() ? this.getValue() : [] - }; - self.trigger.getSearcher().setState(val); - self.numberCounter.setButtonChecked(val); - self.storeValue = { value: self.combo.getValue() }; - self.fireEvent(BI.MultiTreeListCombo.EVENT_CLICK_ITEM, self.getValue()); - self._dataChange = true; - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, - action: function () { - self.combo.hideView(); - } - }, { - eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, - action: function () { - clear = true; - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - }], - itemsCreator: o.itemsCreator, - onLoaded: function () { - BI.nextTick(function () { - self.numberCounter.adjustView(); - self.trigger.getSearcher().adjustView(); - }); - }, - maxWidth: o.isNeedAdjustWidth ? "auto" : 500, - }, - isNeedAdjustWidth: o.isNeedAdjustWidth, - value: this.storeValue, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0 && - self.numberCounter.element.find(e.target).length === 0; - } - }); - - var change = false; - var clear = false; // 标识当前是否点击了清空 - - var isSearching = function () { - return self.trigger.getSearcher().isSearching(); - }; - - var isPopupView = function () { - return self.combo.isViewVisible(); - }; - - this.trigger.on(BI.MultiSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.MultiTreeListCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.MultiTreeListCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self.storeValue = { value: self.combo.getValue() }; - this.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self.storeValue = { value: this.getValue() }; - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - BI.nextTick(function () { - if (isPopupView()) { - self.combo.populate(); - } - }); - self.fireEvent(BI.MultiTreeListCombo.EVENT_STOP); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function () { - self.fireEvent(BI.MultiTreeListCombo.EVENT_SEARCHING); - }); - - function showCounter() { - if (isSearching()) { - self.storeValue = { value: self.trigger.getValue() }; - } else if (isPopupView()) { - self.storeValue = { value: self.combo.getValue() }; - } - self.trigger.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - } - - this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { - self.combo.toggle(); - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { - var checked = this.getSearcher().hasChecked(); - var val = { - type: BI.Selection.Multi, - value: checked ? { 1: 1 } : {} - }; - this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); - self.numberCounter.setButtonChecked(val); - self.fireEvent(BI.MultiTreeListCombo.EVENT_CLICK_ITEM, self.combo.getValue()); - self._dataChange = true; - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (isSearching()) { - return; - } - if (!this.isViewVisible()) { - self._dataChange = false; // 标记数据是否发生变化 - } - if (change === true) { - self.storeValue = { value: self.combo.getValue() }; - change = false; - } - self.combo.setValue(self.storeValue); - self.numberCounter.setValue(self.storeValue); - self.populate(); - self.fireEvent(BI.MultiTreeListCombo.EVENT_BEFORE_POPUPVIEW); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { - if (isSearching()) { - self.trigger.stopEditing(); - self._dataChange && self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); - } else { - if (isPopupView()) { - self._stopEditing(); - self.storeValue = { value: self.combo.getValue() }; - if (clear === true) { - self.storeValue = { value: [] }; - } - self._dataChange && self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); - } - } - clear = false; - change = false; - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.numberCounter.hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - - this.numberCounter = BI.createWidget({ - type: "bi.multi_select_check_selected_switcher", - el: { - type: "bi.multi_tree_check_selected_button" - }, - popup: { - type: "bi.multi_tree_check_pane" - }, - itemsCreator: o.itemsCreator, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - valueFormatter: o.valueFormatter, - value: o.value - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - if (want2showCounter === false) { - want2showCounter = true; - } - if (isInit === true) { - want2showCounter = null; - showCounter(); - } - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - self.trigger.refreshPlaceHolderWidth((b === true ? self.numberCounter.element.outerWidth() + 8 : 0)); - }); - }); - - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_AFTER_HIDEVIEW, function () { - BI.nextTick(function () {// 收起时自动调整宽度 - self.trigger.refreshPlaceHolderWidth(0); - }); - }); - - this.trigger.element.click(function (e) { - if (self.trigger.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.vertical_adapt", - items: [this.numberCounter] - }, - right: o.height, - top: 0, - height: o.height, - }] - }); - }, - - _assertShowValue: function () { - this.trigger.getSearcher().setState(this.storeValue); - this.numberCounter.setButtonChecked(this.storeValue); - }, - - _stopEditing: function () { - this.trigger.stopEditing(); - this.numberCounter.hideView(); - }, - - _defaultState: function () { - this._stopEditing(); - this.combo.hideView(); - }, - - showView: function () { - this.combo.showView(); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getSearcher: function () { - return this.trigger.getSearcher(); - }, - - setValue: function (v) { - this.storeValue.value = v || []; - this.combo.setValue({ - value: v || [] - }); - this.numberCounter.setValue({ - value: v || [] - }); - }, - - getValue: function () { - return BI.deepClone(this.storeValue.value); - }, - - populate: function () { - this.combo.populate(); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); - -BI.MultiTreeListCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.MultiTreeListCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.MultiTreeListCombo.EVENT_STOP = "EVENT_STOP"; -BI.MultiTreeListCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.MultiTreeListCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiTreeListCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.MultiTreeListCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - -BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo); diff --git a/src/widget/multitree/multi.tree.popup.js b/src/widget/multitree/multi.tree.popup.js deleted file mode 100644 index 970c76cc6..000000000 --- a/src/widget/multitree/multi.tree.popup.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * 带加载的多选下拉面板 - * @class BI.MultiTreePopup - * @extends BI.Pane - */ -BI.MultiTreePopup = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-popup", - maxWidth: "auto", - minWidth: 140, - maxHeight: 400, - onLoaded: BI.emptyFn, - el: { - type: "bi.async_tree" - } - }); - }, - - _init: function () { - BI.MultiTreePopup.superclass._init.apply(this, arguments); - - var self = this, opts = this.options, v = opts.value; - - this.selectedValues = {}; - - this.tree = BI.createWidget(opts.el, { - type: "bi.async_tree", - showLine: opts.showLine, - height: 400, - cls: "popup-view-tree", - itemsCreator: opts.itemsCreator, - onLoaded: opts.onLoaded, - value: v.value || {} - }); - - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - element: this, - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_OK")], - el: this.tree - }); - - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); - break; - } - }); - - this.tree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); - }); - - this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); - }); - - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v || (v = {}); - this.tree.setSelectedValue(v.value); - }, - - populate: function (config) { - this.tree.stroke(config); - }, - - hasChecked: function () { - return this.tree.hasChecked(); - }, - - setDirection: function (direction, position) { - this.popupView.setDirection(direction, position); - }, - - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, - - resetWidth: function (w) { - this.popupView.resetWidth(w); - } -}); - -BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; - - -BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup); diff --git a/src/widget/multitree/trigger/multi.tree.button.checkselected.js b/src/widget/multitree/trigger/multi.tree.button.checkselected.js deleted file mode 100644 index 5efd65b2e..000000000 --- a/src/widget/multitree/trigger/multi.tree.button.checkselected.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 查看已选按钮 - * Created by guy on 15/11/3. - * @class BI.MultiTreeCheckSelectedButton - * @extends BI.Single - */ -BI.MultiTreeCheckSelectedButton = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeCheckSelectedButton.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-check-selected-button", - itemsCreator: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeCheckSelectedButton.superclass._init.apply(this, arguments); - var self = this; - this.indicator = BI.createWidget({ - type: "bi.icon_button", - cls: "check-font trigger-check-selected icon-size-12", - width: 16, - height: 16, - stopPropagation: true - }); - - this.checkSelected = BI.createWidget({ - type: "bi.text_button", - cls: "bi-high-light-background trigger-check-text", - invisible: true, - hgap: 4, - text: BI.i18nText("BI-Check_Selected"), - textAlign: "center", - }); - this.checkSelected.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.checkSelected.on(BI.TextButton.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); - }); - - BI.createWidget({ - type: "bi.horizontal", - element: this, - items: [this.indicator, this.checkSelected] - }); - - this.element.hover(function () { - self.indicator.setVisible(false); - self.checkSelected.setVisible(true); - }, function () { - self.indicator.setVisible(true); - self.checkSelected.setVisible(false); - }); - this.setVisible(false); - }, - - setValue: function (v) { - v || (v = {}); - var show = BI.size(v.value) > 0; - this.setVisible(show); - } -}); - -BI.MultiTreeCheckSelectedButton.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.multi_tree_check_selected_button", BI.MultiTreeCheckSelectedButton); diff --git a/src/widget/multitree/trigger/multi.tree.search.insert.pane.js b/src/widget/multitree/trigger/multi.tree.search.insert.pane.js deleted file mode 100644 index 345d8dab2..000000000 --- a/src/widget/multitree/trigger/multi.tree.search.insert.pane.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchInsertPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { - - constants: { - height: 24, - }, - - props: { - baseCls: "bi-multi-tree-search-insert-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn, - el: { - type: "bi.part_tree" - } - }, - - render: function () { - var self = this, opts = this.options; - - return { - type: "bi.absolute", - items: [ - { - el: { - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; - }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } - }, - top: 5, - left: 0, - right: 0 - }, { - el: BI.extend({ - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [ - { - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }, { - eventName: BI.PartTree.EVENT_CLICK_TREE_NODE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CLICK_TREE_NODE); - } - } - ] - }, opts.el), - left: 0, - top: 0, - bottom: 0, - right: 0 - } - ] - }; - }, - - setKeyword: function (keyword, nodes) { - var isAddTipVisible = BI.isEmptyArray(nodes); - this.addTip.setVisible(isAddTipVisible); - this.partTree.setVisible(!isAddTipVisible); - isAddTipVisible && this.addTip.setText(BI.i18nText("BI-Basic_Click_To_Add_Text", keyword)); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchInsertPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchInsertPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; -BI.MultiTreeSearchInsertPane.EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; - -BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane); diff --git a/src/widget/multitree/trigger/multi.tree.search.pane.js b/src/widget/multitree/trigger/multi.tree.search.pane.js deleted file mode 100644 index 82c221d18..000000000 --- a/src/widget/multitree/trigger/multi.tree.search.pane.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - props: { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }, - - render: function () { - var self = this, opts = this.options; - - return BI.extend({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value, - listeners: [ - { - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - } - }, { - eventName: BI.PartTree.EVENT_CLICK_TREE_NODE, - action: function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CLICK_TREE_NODE); - } - } - ], - ref: function (_ref) { - self.partTree = _ref; - } - }, opts.el); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.MultiTreeSearchPane.EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane); diff --git a/src/widget/multitree/trigger/searcher.list.multi.tree.js b/src/widget/multitree/trigger/searcher.list.multi.tree.js deleted file mode 100644 index 8c54afe63..000000000 --- a/src/widget/multitree/trigger/searcher.list.multi.tree.js +++ /dev/null @@ -1,188 +0,0 @@ -/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiListTreeSearcher - * @extends Widget - */ -BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-list-tree-searcher", - itemsCreator: BI.emptyFn, - valueFormatter: function (v) { - return v; - }, - popup: {}, - - adapter: null, - masker: {} - }); - }, - - _init: function () { - BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.multi_select_editor", - height: o.height, - text: o.text, - defaultText: o.defaultText, - watermark: o.watermark, - el: { - type: "bi.simple_state_editor", - height: o.height - }, - listeners: [{ - eventName: BI.MultiSelectEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_BLUR); - } - }] - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback({ - keyword: self.editor.getValue() - }); - }, - el: this.editor, - - popup: BI.extend({ - type: "bi.multi_tree_search_pane", - keywordGetter: function () { - return self.editor.getValue(); - }, - itemsCreator: function (op, callback) { - op.keyword = self.editor.getValue(); - o.itemsCreator(op, callback); - }, - value: o.value - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - if (this.hasMatched()) { - - } - self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); - }); - if (BI.isNotNull(o.value)) { - this.setState(o.value); - } - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeyword: function () { - return this.editor.getValue(); - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setState: function (ob) { - var o = this.options; - ob || (ob = {}); - ob.value || (ob.value = []); - var count = 0; - if (BI.isNumber(ob)) { - this.editor.setState(ob); - } else if (BI.size(ob.value) === 0) { - this.editor.setState(BI.Selection.None); - } else { - var text = ""; - BI.each(ob.value, function (idx, path) { - var childValue = BI.last(path); - text += (path === "null" ? "" : (o.valueFormatter(childValue + "") || childValue) + "; "); - count++; - }); - - if (count > 20) { - this.editor.setState(BI.Selection.Multi); - } else { - this.editor.setState(text); - } - } - }, - - getState: function () { - return this.editor.getState(); - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); - -BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; -BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; -BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher); diff --git a/src/widget/multitree/trigger/searcher.multi.tree.js b/src/widget/multitree/trigger/searcher.multi.tree.js deleted file mode 100644 index 1b2dc6983..000000000 --- a/src/widget/multitree/trigger/searcher.multi.tree.js +++ /dev/null @@ -1,220 +0,0 @@ -/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiTreeSearcher - * @extends Widget - */ -BI.MultiTreeSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-searcher", - itemsCreator: BI.emptyFn, - valueFormatter: function (v) { - return v; - }, - popup: {}, - - adapter: null, - masker: {} - }); - }, - - _init: function () { - BI.MultiTreeSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.multi_select_editor", - watermark: o.watermark, - height: o.height, - el: { - type: "bi.simple_state_editor", - text: o.text, - defaultText: o.defaultText, - height: o.height - }, - listeners: [ - { - eventName: BI.MultiSelectEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_FOCUS); - } - }, { - eventName: BI.MultiSelectEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.MultiSelectSearcher.EVENT_BLUR); - } - } - ] - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback({ - keyword: self.editor.getValue() - }); - }, - el: this.editor, - - popup: BI.extend({ - type: "bi.multi_tree_search_pane", - keywordGetter: function () { - return self.editor.getValue(); - }, - itemsCreator: function (op, callback) { - op.keyword = self.editor.getValue(); - o.itemsCreator(op, callback); - }, - listeners: [ - { - eventName: BI.MultiTreeSearchPane.EVENT_CLICK_TREE_NODE, - action: function () { - self.fireEvent(BI.MultiTreeSearcher.EVENT_CLICK_TREE_NODE, arguments); - } - } - ], - value: o.value - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.MultiTreeSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - self.fireEvent(BI.MultiTreeSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.MultiTreeSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearcher.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { - var keywords = this.getKeywords(); - self.fireEvent(BI.MultiTreeSearcher.EVENT_SEARCHING, keywords); - }); - if (BI.isNotNull(o.value)) { - this.setState(o.value); - } - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeyword: function () { - return this.editor.getValue(); - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setState: function (ob) { - var o = this.options; - ob || (ob = {}); - ob.value || (ob.value = {}); - var count = 0; - if (BI.isNumber(ob)) { - this.editor.setState(ob); - } else if (BI.size(ob.value) === 0) { - this.editor.setState(BI.Selection.None); - } else { - var text = ""; - var value = ob.value; - var names = BI.Func.getSortedResult(BI.keys(value)); - BI.each(names, function (idx, name) { - var childNodes = getChildrenNode(value[name]); - text += (name === "null" ? "" : (o.valueFormatter(name + "") || name)) + (childNodes === "" ? (BI.isEmptyObject(value[name]) ? "" : ":") : (":" + childNodes)) + "; "; - if (childNodes === "") { - count++; - } - }); - - if (count > 20) { - this.editor.setState(BI.Selection.Multi); - } else { - this.editor.setState(text); - } - } - - function getChildrenNode(ob) { - var text = ""; - var index = 0, size = BI.size(ob); - var names = BI.Func.getSortedResult(BI.keys(ob)); - BI.each(names, function (idx, name) { - index++; - var childNodes = getChildrenNode(ob[name]); - text += (name === "null" ? "" : (o.valueFormatter(name + "") || name)) + (childNodes === "" ? "" : (":" + childNodes)) + (index === size ? "" : ","); - if (childNodes === "") { - count++; - } - }); - return text; - } - }, - - getState: function () { - return this.editor.getState(); - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); - -BI.MultiTreeSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.MultiTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.MultiTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiTreeSearcher.EVENT_START = "EVENT_START"; -BI.MultiTreeSearcher.EVENT_STOP = "EVENT_STOP"; -BI.MultiTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.MultiTreeSearcher.EVENT_CLICK_TREE_NODE = "EVENT_CLICK_TREE_NODE"; -BI.shortcut("bi.multi_tree_searcher", BI.MultiTreeSearcher); diff --git a/src/widget/numbereditor/number.editor.js b/src/widget/numbereditor/number.editor.js deleted file mode 100644 index 13f360baa..000000000 --- a/src/widget/numbereditor/number.editor.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Created by windy on 2017/3/13. - * 数值微调器 - */ -BI.NumberEditor = BI.inherit(BI.Widget, { - _defaultConfig: function (conf) { - return BI.extend(BI.NumberEditor.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-number-editor bi-focus-shadow " + (conf.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - validationChecker: BI.emptyFn, - valueFormatter: function (v) { - return v; - }, - valueParser: function (v) { - return v; - }, - value: 0, - allowBlank: false, - errorText: "", - step: 1, - min: BI.MIN, - max: BI.MAX, - watermark: "", - }); - }, - - _init: function () { - BI.NumberEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.sign_editor", - height: BI.toPix(o.height, 2), - simple: o.simple, - allowBlank: o.allowBlank, - watermark: o.watermark, - value: o.valueFormatter(o.value), - validationChecker: function (v) { - // 不设置validationChecker就自动检测 - var parsedValue = o.valueParser(v); - if (o.validationChecker === BI.emptyFn && !self._checkValueInRange(parsedValue)) { - return false; - } - - return o.validationChecker(parsedValue); - }, - errorText: o.errorText, - listeners: [ - { - eventName: BI.SignEditor.EVENT_QUICK_DOWN, - action: e => { - if ([BI.KeyCode.UP, BI.KeyCode.DOWN].includes(e.keyCode)) { - e.preventDefault(); - } - }, - }, - { - eventName: BI.SignEditor.EVENT_KEY_DOWN, - action: (keycode) => { - if (keycode === BI.KeyCode.UP) { - this._finetuning(o.step); - - return; - } - if (keycode === BI.KeyCode.DOWN) { - this._finetuning(-o.step); - } - }, - } - ], - }); - this.editor.on(BI.TextEditor.EVENT_CHANGE, function () { - // 大多数时候valueFormatter往往需要配合valueParser一起使用 - var value = this.getValue(); - var parsedValue = o.valueParser(value); - this.setValue(o.valueFormatter(parsedValue)); - self.fireEvent(BI.NumberEditor.EVENT_CHANGE); - }); - this.editor.on(BI.TextEditor.EVENT_ERROR, function () { - o.value = BI.parseFloat(this.getLastValidValue()); - self._checkAdjustDisabled(o.value); - self.element.addClass("error"); - }); - this.editor.on(BI.TextEditor.EVENT_VALID, function () { - o.value = BI.parseFloat(this.getValue()); - self._checkAdjustDisabled(o.value); - self.element.removeClass("error"); - }); - this.editor.on(BI.TextEditor.EVENT_CONFIRM, function () { - self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); - }); - this.topBtn = BI.createWidget({ - type: "bi.icon_button", - forceNotSelected: true, - trigger: "lclick,", - debounce: false, - cls: (o.simple ? "solid-triangle-top-font " : "add-up-font bi-border-left ") + "top-button bi-list-item-active2 icon-size-12", - }); - this.topBtn.on(BI.IconButton.EVENT_CHANGE, function () { - self._finetuning(o.step); - self.fireEvent(BI.NumberEditor.EVENT_CHANGE); - self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); - }); - this.bottomBtn = BI.createWidget({ - type: "bi.icon_button", - trigger: "lclick,", - forceNotSelected: true, - debounce: false, - cls: (o.simple ? "solid-triangle-bottom-font " : "minus-down-font bi-border-left ") + "bottom-button bi-list-item-active2 icon-size-12", - }); - this.bottomBtn.on(BI.IconButton.EVENT_CHANGE, function () { - self._finetuning(-o.step); - self.fireEvent(BI.NumberEditor.EVENT_CHANGE); - self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); - }); - BI.createWidget({ - type: "bi.htape", - height: BI.toPix(o.height, 2), - element: this, - items: [ - this.editor, { - el: { - type: "bi.grid", - columns: 1, - rows: 2, - items: [ - { - column: 0, - row: 0, - el: this.topBtn, - }, { - column: 0, - row: 1, - el: this.bottomBtn, - } - ], - }, - width: 23, - } - ], - }); - }, - - focus: function () { - this.editor.focus(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - _checkValueInRange: function (v) { - var o = this.options; - - return !!(BI.isNumeric(v) && BI.parseFloat(v) >= o.min && BI.parseFloat(v) <= o.max); - }, - - _checkAdjustDisabled: function (v) { - if (this.options.validationChecker === BI.emptyFn) { - this.bottomBtn.setEnable(BI.parseFloat(v) > this.options.min); - this.topBtn.setEnable(BI.parseFloat(v) < this.options.max); - } - }, - - // 微调 - _finetuning: function (add) { - const { max, min } = this.options; - let v = BI.parseFloat(this.getValue()); - v = BI.add(v, add); - v = BI.clamp(v, min, max); - this.setValue(v); - }, - - setUpEnable: function (v) { - this.topBtn.setEnable(!!v); - }, - - setDownEnable: function (v) { - this.bottomBtn.setEnable(!!v); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - getValue: function () { - return this.options.value; - }, - - setValue: function (v) { - var o = this.options; - o.value = v; - this.editor.setValue(o.valueFormatter(v)); - this._checkAdjustDisabled(o.value); - }, - -}); -BI.NumberEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.NumberEditor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.number_editor", BI.NumberEditor); diff --git a/src/widget/numberinterval/numberinterval.js b/src/widget/numberinterval/numberinterval.js deleted file mode 100644 index 0c3c488bd..000000000 --- a/src/widget/numberinterval/numberinterval.js +++ /dev/null @@ -1,565 +0,0 @@ -// 小于号的值为:0,小于等于号的值为:1 -// closeMIn:最小值的符号,closeMax:最大值的符号 -/** - * Created by roy on 15/9/17. - * - */ -BI.NumberInterval = BI.inherit(BI.Single, { - constants: { - typeError: "typeBubble", - numberError: "numberBubble", - signalError: "signalBubble", - editorWidth: 114, - columns: 5, - width: 24, - rows: 1, - numberErrorCls: "number-error", - border: 1, - less: 0, - less_equal: 1, - numTip: "", - adjustYOffset: 2 - }, - _defaultConfig: function () { - var conf = BI.NumberInterval.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-number-interval" + ((BI.isIE() && BI.getIEVersion() < 10) ? " hack" : ""), - height: 24, - validation: "valid", - closeMin: true, - allowBlank: true, - watermark: BI.i18nText("BI-Basic_Unrestricted") - }); - }, - _init: function () { - var self = this, c = this.constants, o = this.options; - BI.NumberInterval.superclass._init.apply(this, arguments); - this.smallEditor = BI.createWidget({ - type: "bi.number_interval_single_editor", - height: BI.toPix(o.height, o.simple ? 1 : 2), - watermark: o.watermark, - allowBlank: o.allowBlank, - value: o.min, - level: "warning", - tipType: "success", - title: function () { - return self.smallEditor && self.smallEditor.getValue(); - }, - quitChecker: function () { - return false; - }, - validationChecker: function (v) { - if (!BI.isNumeric(v)) { - self.smallEditorBubbleType = c.typeError; - return false; - } - return true; - }, - cls: "number-interval-small-editor bi-focus-shadow " + (o.simple ? "bi-border-bottom" : "bi-border bi-border-corner-left-radius") - }); - - this.smallTip = BI.createWidget({ - type: "bi.label", - text: o.numTip, - height: BI.toPix(o.height, o.simple ? 1 : 2), - invisible: true - }); - BI.createWidget({ - type: "bi.absolute", - element: this.smallEditor, - items: [{ - el: this.smallTip, - top: 0, - right: 5 - }] - }); - - this.bigEditor = BI.createWidget({ - type: "bi.number_interval_single_editor", - height: BI.toPix(o.height, o.simple ? 1 : 2), - watermark: o.watermark, - allowBlank: o.allowBlank, - value: o.max, - title: function () { - return self.bigEditor && self.bigEditor.getValue(); - }, - quitChecker: function () { - return false; - }, - validationChecker: function (v) { - if (!BI.isNumeric(v)) { - self.bigEditorBubbleType = c.typeError; - return false; - } - return true; - }, - cls: "number-interval-big-editor bi-focus-shadow" + (o.simple ? " bi-border-bottom" : " bi-border bi-border-corner-right-radius") - }); - - this.bigTip = BI.createWidget({ - type: "bi.label", - text: o.numTip, - height: BI.toPix(o.height, o.simple ? 1 : 2), - invisible: true - }); - BI.createWidget({ - type: "bi.absolute", - element: this.bigEditor, - items: [{ - el: this.bigTip, - top: 0, - right: 5 - }] - }); - this.smallCombo = BI.createWidget({ - type: "bi.icon_combo", - cls: "number-interval-small-combo" + (o.simple ? "" : " bi-border-top bi-border-bottom bi-border-right bi-border-corner-right-radius"), - height: BI.toPix(o.height, o.simple ? 0 : 2), - width: BI.toPix(c.width, c.border), - items: [{ - text: "(" + BI.i18nText("BI-Less_Than") + ")", - iconCls: "less-font", - value: 0 - }, { - text: "(" + BI.i18nText("BI-Less_And_Equal") + ")", - value: 1, - iconCls: "less-equal-font" - }] - }); - if (o.closeMin === true) { - this.smallCombo.setValue(1); - } else { - this.smallCombo.setValue(0); - } - this.bigCombo = BI.createWidget({ - type: "bi.icon_combo", - cls: "number-interval-big-combo" + (o.simple ? "" : " bi-border-top bi-border-bottom bi-border-left bi-border-corner-left-radius"), - height: BI.toPix(o.height, o.simple ? 0 : 2), - width: BI.toPix(c.width, c.border), - items: [{ - text: "(" + BI.i18nText("BI-Less_Than") + ")", - iconCls: "less-font", - value: 0 - }, { - text: "(" + BI.i18nText("BI-Less_And_Equal") + ")", - value: 1, - iconCls: "less-equal-font" - }] - }); - if (o.closeMax === true) { - this.bigCombo.setValue(1); - } else { - this.bigCombo.setValue(0); - } - this.label = BI.createWidget({ - type: "bi.label", - text: BI.i18nText("BI-Basic_Value"), - textHeight: o.height, - // width: BI.toPix(o.width, o.simple ? 0 : c.border * 2), - hgap: 5, - height: o.height, - level: "warning", - tipType: "warning" - }); - this.left = BI.createWidget({ - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [{ - el: self.smallEditor - }, { - el: self.smallCombo, - }] - - }); - this.right = BI.createWidget({ - type: "bi.horizontal_fill", - columnSize: ["", "fill"], - items: [{ - el: self.bigCombo, - }, { - el: self.bigEditor, - // BI-23883 间距考虑边框 - // lgap: 1 - }] - }); - - BI.createWidget({ - element: self, - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: self.label - }, { - el: self.right - }] - }); - - // BI.createWidget({ - // element: self, - // type: "bi.horizontal_auto", - // items: [ - // self.label - // ] - // }); - - // BI.createWidget({ - // element: self, - // type: "bi.center", - // hgap: 15, - // height: o.height, - // items: [ - // { - // type: "bi.absolute", - // items: [{ - // el: self.left, - // left: -15, - // right: 0, - // top: 0, - // bottom: 0 - // }] - // }, { - // type: "bi.absolute", - // items: [{ - // el: self.right, - // left: 0, - // right: -15, - // top: 0, - // bottom: 0 - // }] - // } - // ] - // }); - - self._setValidEvent(self.bigEditor, c.bigEditor); - self._setValidEvent(self.smallEditor, c.smallEditor); - self._setErrorEvent(self.bigEditor, c.bigEditor); - self._setErrorEvent(self.smallEditor, c.smallEditor); - self._setBlurEvent(self.bigEditor); - self._setBlurEvent(self.smallEditor); - self._setFocusEvent(self.bigEditor); - self._setFocusEvent(self.smallEditor); - self._setComboValueChangedEvent(self.bigCombo); - self._setComboValueChangedEvent(self.smallCombo); - self._setEditorValueChangedEvent(self.bigEditor); - self._setEditorValueChangedEvent(self.smallEditor); - - self._checkValidation(); - }, - - _checkValidation: function () { - var self = this, c = this.constants, o = this.options; - self._setTitle(""); - BI.Bubbles.hide(c.typeError); - BI.Bubbles.hide(c.numberError); - BI.Bubbles.hide(c.signalError); - if (!self.smallEditor.isValid() || !self.bigEditor.isValid()) { - self.element.removeClass("number-error"); - o.validation = "invalid"; - return c.typeError; - } - if (BI.isEmptyString(self.smallEditor.getValue()) || BI.isEmptyString(self.bigEditor.getValue())) { - self.element.removeClass("number-error"); - o.validation = "valid"; - return ""; - } - var smallValue = parseFloat(self.smallEditor.getValue()), bigValue = parseFloat(self.bigEditor.getValue()), - bigComboValue = self.bigCombo.getValue(), smallComboValue = self.smallCombo.getValue(); - if (bigComboValue[0] === c.less_equal && smallComboValue[0] === c.less_equal) { - if (smallValue > bigValue) { - self.element.addClass("number-error"); - o.validation = "invalid"; - return c.numberError; - } - self.element.removeClass("number-error"); - o.validation = "valid"; - return ""; - - } - if (smallValue > bigValue) { - self.element.addClass("number-error"); - o.validation = "invalid"; - return c.numberError; - } else if (smallValue === bigValue) { - self.element.addClass("number-error"); - o.validation = "invalid"; - return c.signalError; - } - self.element.removeClass("number-error"); - o.validation = "valid"; - return ""; - - - - - - }, - - _setTitle: function (v) { - this.label.setTitle(v); - }, - - _setFocusEvent: function (w) { - var self = this, c = this.constants; - w.on(BI.NumberIntervalSingleEidtor.EVENT_FOCUS, function () { - self._setTitle(""); - switch (self._checkValidation()) { - case c.typeError: - BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - case c.numberError: - BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - case c.signalError: - BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - default : - return; - } - - }); - }, - _setBlurEvent: function (w) { - var c = this.constants, self = this; - w.on(BI.NumberIntervalSingleEidtor.EVENT_BLUR, function () { - BI.Bubbles.hide(c.typeError); - BI.Bubbles.hide(c.numberError); - BI.Bubbles.hide(c.signalError); - switch (self._checkValidation()) { - case c.typeError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Input_Data")); - break; - case c.numberError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Number_Value")); - break; - case c.signalError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Signal_Value")); - break; - default: - self._setTitle(""); - } - }); - }, - - _setErrorEvent: function (w) { - var c = this.constants, self = this; - w.on(BI.NumberIntervalSingleEidtor.EVENT_ERROR, function () { - self._checkValidation(); - BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - }); - }, - - - _setValidEvent: function (w) { - var self = this, c = this.constants; - w.on(BI.NumberIntervalSingleEidtor.EVENT_VALID, function () { - switch (self._checkValidation()) { - case c.numberError: - BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - break; - case c.signalError: - BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - break; - default: - self.fireEvent(BI.NumberInterval.EVENT_VALID); - } - }); - }, - - - _setEditorValueChangedEvent: function (w) { - var self = this, c = this.constants; - w.on(BI.NumberIntervalSingleEidtor.EVENT_CHANGE, function () { - switch (self._checkValidation()) { - case c.typeError: - BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - case c.numberError: - BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - case c.signalError: - BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { - offsetStyle: "left", - adjustYOffset: c.adjustYOffset - }); - break; - default : - break; - } - self.fireEvent(BI.NumberInterval.EVENT_CHANGE); - }); - w.on(BI.NumberIntervalSingleEidtor.EVENT_CONFIRM, function () { - self.fireEvent(BI.NumberInterval.EVENT_CONFIRM); - }); - }, - - _setComboValueChangedEvent: function (w) { - var self = this, c = this.constants; - w.on(BI.IconCombo.EVENT_CHANGE, function () { - switch (self._checkValidation()) { - case c.typeError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Input_Data")); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - break; - case c.numberError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Number_Value")); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - break; - case c.signalError: - self._setTitle(BI.i18nText("BI-Numerical_Interval_Signal_Value")); - self.fireEvent(BI.NumberInterval.EVENT_ERROR); - break; - default : - self.fireEvent(BI.NumberInterval.EVENT_CHANGE); - self.fireEvent(BI.NumberInterval.EVENT_CONFIRM); - self.fireEvent(BI.NumberInterval.EVENT_VALID); - } - }); - }, - - isStateValid: function () { - return this.options.validation === "valid"; - }, - - setMinEnable: function (b) { - this.smallEditor.setEnable(b); - }, - - setCloseMinEnable: function (b) { - this.smallCombo.setEnable(b); - }, - - setMaxEnable: function (b) { - this.bigEditor.setEnable(b); - }, - - setCloseMaxEnable: function (b) { - this.bigCombo.setEnable(b); - }, - - showNumTip: function () { - this.smallTip.setVisible(true); - this.bigTip.setVisible(true); - }, - - hideNumTip: function () { - this.smallTip.setVisible(false); - this.bigTip.setVisible(false); - }, - - setNumTip: function (numTip) { - this.smallTip.setText(numTip); - this.bigTip.setText(numTip); - }, - - getNumTip: function () { - return this.smallTip.getText(); - }, - - setValue: function (data) { - data = data || {}; - var self = this, combo_value; - if (BI.isNumeric(data.min) || BI.isEmptyString(data.min)) { - self.smallEditor.setValue(data.min); - } - - if (!BI.isNotNull(data.min)) { - self.smallEditor.setValue(""); - } - - if (BI.isNumeric(data.max) || BI.isEmptyString(data.max)) { - self.bigEditor.setValue(data.max); - } - - if (!BI.isNotNull(data.max)) { - self.bigEditor.setValue(""); - } - - if (!BI.isNull(data.closeMin)) { - if (data.closeMin === true) { - combo_value = 1; - } else { - combo_value = 0; - } - self.smallCombo.setValue(combo_value); - } - - if (!BI.isNull(data.closeMax)) { - if (data.closeMax === true) { - combo_value = 1; - } else { - combo_value = 0; - } - self.bigCombo.setValue(combo_value); - } - - this._checkValidation(); - }, - - - getValue: function () { - var self = this, value = {}, minComboValue = self.smallCombo.getValue(), maxComboValue = self.bigCombo.getValue(); - value.min = self.smallEditor.getValue(); - value.max = self.bigEditor.getValue(); - if (minComboValue[0] === 0) { - value.closeMin = false; - } else { - value.closeMin = true; - } - - if (maxComboValue[0] === 0) { - value.closeMax = false; - } else { - value.closeMax = true; - } - return value; - }, - - focusMinEditor: function () { - this.smallEditor.focus(); - }, - - focusMaxEditor: function () { - this.bigEditor.focus(); - }, - - destroyed: function () { - var c = this.constants; - BI.Bubbles.remove(c.typeError); - BI.Bubbles.remove(c.numberError); - BI.Bubbles.remove(c.signalError); - } -}); -BI.NumberInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.NumberInterval.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.NumberInterval.EVENT_VALID = "EVENT_VALID"; -BI.NumberInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.shortcut("bi.number_interval", BI.NumberInterval); diff --git a/src/widget/numberinterval/singleeditor/single.editor.js b/src/widget/numberinterval/singleeditor/single.editor.js deleted file mode 100644 index ac7738d9f..000000000 --- a/src/widget/numberinterval/singleeditor/single.editor.js +++ /dev/null @@ -1,89 +0,0 @@ -BI.NumberIntervalSingleEidtor = BI.inherit(BI.Single, { - props: { - baseCls: "bi-number-interval-single-editor", - tipType: "success", - title: "" - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vertical", - items: [{ - type: "bi.editor", - simple: o.simple, - ref: function (_ref) { - self.editor = _ref; - }, - height: o.height, - watermark: o.watermark, - allowBlank: o.allowBlank, - value: o.value, - quitChecker: o.quitChecker, - validationChecker: o.validationChecker, - listeners: [{ - eventName: BI.Editor.EVENT_ERROR, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_ERROR, arguments); - } - }, { - eventName: BI.Editor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_FOCUS, arguments); - } - }, { - eventName: BI.Editor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_BLUR, arguments); - } - }, { - eventName: BI.Editor.EVENT_VALID, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_VALID, arguments); - } - }, { - eventName: BI.Editor.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.Editor.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_CONFIRM, arguments); - } - }, { - eventName: BI.Editor.EVENT_CHANGE_CONFIRM, - action: function () { - self.fireEvent(BI.NumberIntervalSingleEidtor.EVENT_CHANGE_CONFIRM, arguments); - } - }] - }] - }; - }, - - isValid: function () { - return this.editor.isValid(); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - setValue: function (v) { - return this.editor.setValue(v); - }, - - focus: function () { - this.editor.focus(); - } -}); - -BI.NumberIntervalSingleEidtor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.NumberIntervalSingleEidtor.EVENT_BLUR = "EVENT_BLUR"; -BI.NumberIntervalSingleEidtor.EVENT_ERROR = "EVENT_ERROR"; -BI.NumberIntervalSingleEidtor.EVENT_VALID = "EVENT_VALID"; -BI.NumberIntervalSingleEidtor.EVENT_CHANGE = "EVENT_CHANGE"; -BI.NumberIntervalSingleEidtor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.NumberIntervalSingleEidtor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.shortcut("bi.number_interval_single_editor", BI.NumberIntervalSingleEidtor); \ No newline at end of file diff --git a/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js b/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js deleted file mode 100644 index 4fdbf42ee..000000000 --- a/src/widget/searchmultitextvaluecombo/multitextvalue.combo.search.js +++ /dev/null @@ -1,481 +0,0 @@ -/** - * - * @class BI.SearchMultiTextValueCombo - * @extends BI.Single - */ -BI.SearchMultiTextValueCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.SearchMultiTextValueCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-combo bi-search-multi-text-value-combo", - height: 24, - items: [] - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.SearchMultiTextValueCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, self._startValue) : BI.pushDistinct(self.storeValue.value, self._startValue)); - self._updateAllValue(); - self._checkError(); - self.trigger.getSearcher().setState(self.storeValue); - self.trigger.getCounter().setButtonChecked(self.storeValue); - }; - this.storeValue = BI.deepClone(o.value || {}); - this._updateAllValue(); - - this._assertValue(this.storeValue); - this._checkError(); - - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.search_multi_select_trigger", - text: o.text, - height: BI.toPix(o.height, o.simple ? 1 : 2), - // adapter: this.popup, - masker: { - offset: { - left: 0, - top: 0, - right: 0, - bottom: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1, - }, - }, - allValueGetter: function () { - return self.allValue; - }, - valueFormatter: o.valueFormatter, - itemsCreator: function (op, callback) { - self._itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(BI.deepClone(self.getValue())); - } - callback.apply(self, arguments); - }); - }, - value: this.storeValue, - warningTitle: o.warningTitle - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { - self._setStartValue(""); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { - self._setStartValue(""); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function (keywords) { - var last = BI.last(keywords); - keywords = BI.initial(keywords || []); - if (keywords.length > 0) { - self._joinKeywords(keywords, function () { - if (BI.endWith(last, BI.BlankSplitChar)) { - self.combo.setValue(self.storeValue); - assertShowValue(); - self.combo.populate(); - self._setStartValue(""); - } else { - self.combo.setValue(self.storeValue); - assertShowValue(); - } - self._dataChange = true; - }); - } - }); - - this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function (value, obj) { - if (obj instanceof BI.MultiSelectBar) { - self._joinAll(this.getValue(), function () { - assertShowValue(); - }); - } else { - self._join(this.getValue(), function () { - assertShowValue(); - }); - } - self._dataChange = true; - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { - this.getCounter().setValue(self.storeValue); - }); - this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: o.simple ? "bi-border-bottom" : "bi-border bi-border-radius", - toggle: false, - container: o.container, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.search_multi_select_popup_view", - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - }, - listeners: [{ - eventName: BI.MultiSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - }); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, - action: function () { - self._defaultState(); - } - }, { - eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, - action: function () { - self._dataChange = true; - self.setValue(); - self._defaultState(); - } - }], - itemsCreator: BI.bind(self._itemsCreator, this), - valueFormatter: o.valueFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.trigger.getCounter().adjustView(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - value: o.value, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0; - } - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self._populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self.trigger.stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - /** - * 在存在标红的情况,如果popover没有发生改变就确认需要同步trigger的值,否则对外value值和trigger样式不统一 - */ - assertShowValue(); - self._dataChange && self.fireEvent(BI.SearchMultiTextValueCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "multi-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - self.trigger.getCounter().hideView(); - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }] - }); - this._checkError(); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - var o = this.options; - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - BI.remove(val.value, function (idx, value) { - return !BI.contains(BI.map(o.items, "value"), value); - }); - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - this._itemsCreator({ - type: BI.SearchMultiTextValueCombo.REQ_GET_ALL_DATA, - keywords: keywords - }, function (ob) { - var values = BI.map(ob.items, "value"); - digest(values); - }); - - function digest (items) { - var selectedMap = self._makeMap(items); - BI.each(keywords, function (i, val) { - if (BI.isNotNull(selectedMap[val])) { - self.storeValue.type === BI.Selection.Multi ? BI.pushDistinct(self.storeValue.value, val) : BI.remove(self.storeValue.value, val); - } - }); - self._adjust(callback); - } - }, - - _joinAll: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this.requesting = true; - this._itemsCreator({ - type: BI.SearchMultiTextValueCombo.REQ_GET_ALL_DATA, - keywords: [this.trigger.getKey()] - }, function (ob) { - var items = BI.map(ob.items, "value"); - if (self.storeValue.type === res.type) { - var change = false; - var map = self._makeMap(self.storeValue.value); - BI.each(items, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (self.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - var selectedMap = self._makeMap(self.storeValue.value); - var notSelectedMap = self._makeMap(res.value); - var newItems = []; - BI.each(items, function (i, item) { - if (BI.isNotNull(selectedMap[items[i]])) { - self.storeValue.assist && self.storeValue.assist.push(selectedMap[items[i]]); - delete selectedMap[items[i]]; - } - if (BI.isNull(notSelectedMap[items[i]])) { - BI.remove(self.storeValue.assist, item); - newItems.push(item); - } - }); - self.storeValue.value = newItems.concat(BI.values(selectedMap)); - self._adjust(callback); - }); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - if (!this._count) { - this._itemsCreator({ - type: BI.SearchMultiTextValueCombo.REQ_GET_DATA_LENGTH - }, function (res) { - self._count = res.count; - adjust(); - callback(); - }); - } else { - adjust(); - callback(); - - } - - function adjust () { - if (self.storeValue.type === BI.Selection.All && self.storeValue.value.length >= self._count) { - self.storeValue = { - type: BI.Selection.Multi, - value: [] - }; - } else if (self.storeValue.type === BI.Selection.Multi && self.storeValue.value.length >= self._count) { - self.storeValue = { - type: BI.Selection.All, - value: [] - }; - } - self._updateAllValue(); - self._checkError(); - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.SearchMultiTextValueCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _join: function (res, callback) { - var self = this, o = this.options; - this._assertValue(res); - this._assertValue(this.storeValue); - if (this.storeValue.type === res.type) { - var map = this._makeMap(this.storeValue.value); - BI.each(res.value, function (i, v) { - if (!map[v]) { - self.storeValue.value.push(v); - BI.remove(self.storeValue.assist, v); - map[v] = v; - } - }); - var change = false; - BI.each(res.assist, function (i, v) { - if (BI.isNotNull(map[v])) { - change = true; - self.storeValue.assist && self.storeValue.assist.push(map[v]); - delete map[v]; - } - }); - change && (this.storeValue.value = BI.values(map)); - self._adjust(callback); - return; - } - this._joinAll(res, callback); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * 100; items[i] && i < times * 100; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * 100 < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - var items = o.items; - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.match.concat(search.find); - }); - if (options.selectedValues) {// 过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type == BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type == BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - callback({ - items: self._getItemsByTimes(items, options.times), - hasNext: self._hasNextByTimes(items, options.times) - }); - }, - - _checkError: function () { - var v = this.storeValue.value || []; - if(BI.isNotEmptyArray(v)) { - v = BI.isArray(v) ? v : [v]; - var result = BI.find(this.allValue, function (idx, value) { - return !BI.contains(v, value); - }); - if (BI.isNull(result)) { - BI.isNotNull(this.trigger) && (this.trigger.setTipType("success")); - this.element.removeClass("combo-error"); - } else { - BI.isNotNull(this.trigger) && (this.trigger.setTipType("warning")); - this.element.addClass("combo-error"); - } - } else { - if(v.length === this.allValue.length){ - BI.isNotNull(this.trigger) && (this.trigger.setTipType("success")); - this.element.removeClass("combo-error"); - }else { - BI.isNotNull(this.trigger) && (this.trigger.setTipType("warning")); - this.element.addClass("combo-error"); - } - } - }, - - _updateAllValue: function () { - this.storeValue = this.storeValue || {}; - this.allValue = BI.deepClone(this.storeValue.value || []); - }, - - setValue: function (v) { - this.storeValue = BI.deepClone(v || {}); - this._updateAllValue(); - this._assertValue(this.storeValue); - this.combo.setValue(this.storeValue); - this._checkError(); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - _populate: function () { - this._count = null; - this.combo.populate(); - }, - - populate: function (items) { - this.options.items = items; - this._populate(); - } -}); - -BI.extend(BI.SearchMultiTextValueCombo, { - REQ_GET_DATA_LENGTH: 1, - REQ_GET_ALL_DATA: -1 -}); - -BI.SearchMultiTextValueCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - -BI.shortcut("bi.search_multi_text_value_combo", BI.SearchMultiTextValueCombo); diff --git a/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js b/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js deleted file mode 100644 index 3256994ae..000000000 --- a/src/widget/searchmultitextvaluecombo/multitextvalue.combo.trigger.search.js +++ /dev/null @@ -1,154 +0,0 @@ -BI.SearchMultiSelectTrigger = BI.inherit(BI.Trigger, { - - constants: { - height: 14, - rgap: 4, - lgap: 4 - }, - - _defaultConfig: function () { - return BI.extend(BI.SearchMultiSelectTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-trigger", - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcher: {}, - switcher: {}, - - adapter: null, - masker: {} - }); - }, - - _init: function () { - BI.SearchMultiSelectTrigger.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.searcher = BI.createWidget(o.searcher, { - type: "bi.search_multi_select_searcher", - height: o.height, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - allValueGetter: o.allValueGetter, - popup: {}, - adapter: o.adapter, - masker: o.masker, - value: o.value, - text: o.text, - tipType: o.tipType, - warningTitle: o.warningTitle - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_START, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_START); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_PAUSE, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_PAUSE); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_SEARCHING, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_SEARCHING, arguments); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_STOP, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_STOP); - }); - this.searcher.on(BI.MultiSelectSearcher.EVENT_CHANGE, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_CHANGE, arguments); - }); - this.numberCounter = BI.createWidget(o.switcher, { - type: "bi.multi_select_check_selected_switcher", - valueFormatter: o.valueFormatter, - itemsCreator: o.itemsCreator, - adapter: o.adapter, - masker: o.masker, - value: o.value - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_COUNTER_CLICK); - }); - this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.SearchMultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW); - }); - - var wrapNumberCounter = BI.createWidget({ - type: "bi.right_vertical_adapt", - hgap: 4, - items: [{ - el: this.numberCounter - }] - }); - - var wrapper = BI.createWidget({ - type: "bi.htape", - element: this, - items: [ - { - el: this.searcher, - width: "fill" - }, { - el: wrapNumberCounter, - width: 0 - }, { - el: BI.createWidget(), - width: 24 - }] - }); - - this.numberCounter.on(BI.Events.VIEW, function (b) { - BI.nextTick(function () {// 自动调整宽度 - wrapper.attr("items")[1].width = (b === true ? self.numberCounter.element.outerWidth() + 8 : 0); - wrapper.resize(); - }); - }); - - this.element.click(function (e) { - if (self.element.find(e.target).length > 0) { - self.numberCounter.hideView(); - } - }); - }, - - getCounter: function () { - return this.numberCounter; - }, - - getSearcher: function () { - return this.searcher; - }, - - stopEditing: function () { - this.searcher.stopSearch(); - this.numberCounter.hideView(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - this.numberCounter.setAdapter(adapter); - }, - - setValue: function (ob) { - this.searcher.setValue(ob); - this.numberCounter.setValue(ob); - }, - - setTipType: function (v) { - this.searcher.setTipType(v); - }, - - getKey: function () { - return this.searcher.getKey(); - }, - - getValue: function () { - return this.searcher.getValue(); - } -}); - -BI.SearchMultiSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.SearchMultiSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; -BI.SearchMultiSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchMultiSelectTrigger.EVENT_START = "EVENT_START"; -BI.SearchMultiSelectTrigger.EVENT_STOP = "EVENT_STOP"; -BI.SearchMultiSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SearchMultiSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.SearchMultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; - -BI.shortcut("bi.search_multi_select_trigger", BI.SearchMultiSelectTrigger); diff --git a/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js b/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js deleted file mode 100644 index 59113111e..000000000 --- a/src/widget/searchmultitextvaluecombo/multitextvalue.loader.search.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * 多选加载数据面板 - * Created by guy on 15/11/2. - * @class BI.SearchMultiSelectLoader - * @extends Widget - */ -BI.SearchMultiSelectLoader = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SearchMultiSelectLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-loader", - logic: { - dynamic: true - }, - el: { - height: 400 - }, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - onLoaded: BI.emptyFn - }); - }, - - _init: function () { - BI.SearchMultiSelectLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - - this.storeValue = opts.value || {}; - this._assertValue(this.storeValue); - - this.button_group = BI.createWidget({ - type: "bi.select_list", - element: this, - logic: opts.logic, - toolbar: { - type: "bi.multi_select_bar", - cls: "bi-list-item-active", - height: this.options.itemHeight, - iconWrapperWidth: 36 - }, - el: BI.extend({ - onLoaded: opts.onLoaded, - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [{ - type: "bi.vertical" - }] - } - } - }, opts.el), - itemsCreator: function (op, callback) { - var startValue = self._startValue; - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: BI.isKey(startValue) && self.storeValue.type === BI.Selection.Multi - ? self.storeValue.value.concat(startValue) : self.storeValue.value - })); - opts.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && self.storeValue) { - var json = BI.map(self.storeValue.value, function (i, v) { - var txt = opts.valueFormatter(v) || v; - return { - text: txt, - value: v, - title: txt, - selected: self.storeValue.type === BI.Selection.Multi - }; - }); - if (BI.isKey(self._startValue) && !BI.contains(self.storeValue.value, self._startValue)) { - var txt = opts.valueFormatter(startValue) || startValue; - json.unshift({ - text: txt, - value: startValue, - title: txt, - selected: true - }); - } - firstItems = self._createItems(json); - } - callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); - if (op.times === 1 && self.storeValue) { - BI.isKey(startValue) && (self.storeValue.type === BI.Selection.All ? BI.remove(self.storeValue.value, startValue) : BI.pushDistinct(self.storeValue.value, startValue)); - self.setValue(self.storeValue); - } - (op.times === 1) && self._scrollToTop(); - }); - }, - hasNext: function () { - return hasNext; - }, - value: this.storeValue - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button_group.on(BI.SelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.SearchMultiSelectLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - return BI.createItems(items, { - type: "bi.multi_select_item", - logic: this.options.logic, - cls: "bi-list-item-active", - height: this.options.itemHeight, - selected: this.isAllSelected(), - iconWrapperWidth: 36 - }); - }, - - _scrollToTop: function () { - var self = this; - BI.delay(function () { - self.button_group.element.scrollTop(0); - }, 30); - }, - - isAllSelected: function () { - return this.button_group.isAllSelected(); - }, - - _assertValue: function (val) { - val || (val = {}); - val.type || (val.type = BI.Selection.Multi); - val.value || (val.value = []); - }, - - setStartValue: function (v) { - this._startValue = v; - }, - - setValue: function (v) { - this.storeValue = v || {}; - this._assertValue(this.storeValue); - this.button_group.setValue(this.storeValue); - }, - - getValue: function () { - return this.button_group.getValue(); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - if (BI.isNotNull(items)) { - arguments[0] = this._createItems(items); - } - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.resetHeight(h); - }, - - resetWidth: function (w) { - this.button_group.resetWidth(w); - } -}); - -BI.SearchMultiSelectLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.search_multi_select_loader", BI.SearchMultiSelectLoader); \ No newline at end of file diff --git a/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js b/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js deleted file mode 100644 index cb8027f0c..000000000 --- a/src/widget/searchmultitextvaluecombo/multitextvalue.popup.view.search.js +++ /dev/null @@ -1,92 +0,0 @@ -BI.SearchMultiSelectPopupView = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SearchMultiSelectPopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-popup-view", - maxWidth: "auto", - minWidth: 135, - maxHeight: 400, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - onLoaded: BI.emptyFn - }); - }, - - _init: function () { - BI.SearchMultiSelectPopupView.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - - this.loader = BI.createWidget({ - type: "bi.search_multi_select_loader", - itemsCreator: opts.itemsCreator, - valueFormatter: opts.valueFormatter, - onLoaded: opts.onLoaded, - value: opts.value - }); - - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - element: this, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_OK")], - el: this.loader, - value: opts.value - }); - - this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { - self.fireEvent(BI.SearchMultiSelectPopupView.EVENT_CHANGE); - }); - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.SearchMultiSelectPopupView.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.SearchMultiSelectPopupView.EVENT_CLICK_CONFIRM); - break; - } - }); - }, - - isAllSelected: function () { - return this.loader.isAllSelected(); - }, - - setStartValue: function (v) { - this.loader.setStartValue(v); - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - populate: function (items) { - this.popupView.populate.apply(this.popupView, arguments); - }, - - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, - - resetWidth: function (w) { - this.popupView.resetWidth(w); - }, - - setDirection: function (direction, position) { - this.popupView.setDirection(direction, position); - }, -}); - -BI.SearchMultiSelectPopupView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchMultiSelectPopupView.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.SearchMultiSelectPopupView.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - - -BI.shortcut("bi.search_multi_select_popup_view", BI.SearchMultiSelectPopupView); diff --git a/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js b/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js deleted file mode 100644 index 506532b3c..000000000 --- a/src/widget/searchmultitextvaluecombo/trigger/searcher.multitextvalue.js +++ /dev/null @@ -1,175 +0,0 @@ -BI.SearchMultiSelectSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SearchMultiSelectSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-select-searcher", - itemsCreator: BI.emptyFn, - el: {}, - popup: {}, - valueFormatter: BI.emptyFn, - adapter: null, - masker: {} - }); - }, - - _init: function () { - BI.SearchMultiSelectSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.multi_select_editor", - height: o.height, - text: o.text, - tipType: o.tipType, - warningTitle: o.warningTitle - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - height: o.height, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - el: this.editor, - - popup: BI.extend({ - type: "bi.multi_select_search_pane", - valueFormatter: o.valueFormatter, - keywordGetter: function () { - return self.editor.getValue(); - }, - itemsCreator: function (op, callback) { - var keyword = self.editor.getValue(); - op.keywords = [keyword]; - o.itemsCreator(op, callback); - }, - value: o.value - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.SearchMultiSelectSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - if (this.hasMatched()) { - - } - self.fireEvent(BI.SearchMultiSelectSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.SearchMultiSelectSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.SearchMultiSelectSearcher.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { - var keywords = this.getKeywords(); - self.fireEvent(BI.SearchMultiSelectSearcher.EVENT_SEARCHING, keywords); - }); - if(BI.isNotNull(o.value)) { - this.setState(o.value); - } - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeyword: function () { - return this.editor.getValue(); - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setState: function (obj) { - var o = this.options; - var ob = {}; - ob.type = obj.type; - ob.value = o.allValueGetter() || []; - ob.assist = obj.assist; - if (ob.type === BI.Selection.All) { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.All); - } else if (BI.size(ob.assist) <= 20) { - var state = ""; - BI.each(ob.assist, function (i, v) { - if (i === 0) { - state += "" + (o.valueFormatter(v + "") || v); - } else { - state += "," + (o.valueFormatter(v + "") || v); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } else { - if (ob.value.length === 0) { - this.editor.setState(BI.Selection.None); - } else if (BI.size(ob.value) <= 20) { - var state = ""; - BI.each(ob.value, function (i, v) { - if (i === 0) { - state += "" + (o.valueFormatter(v + "") || v); - } else { - state += "," + (o.valueFormatter(v + "") || v); - } - }); - this.editor.setState(state); - } else { - this.editor.setState(BI.Selection.Multi); - } - } - }, - - setTipType: function (v) { - this.editor.setTipType(v); - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - } -}); - -BI.SearchMultiSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.SearchMultiSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SearchMultiSelectSearcher.EVENT_START = "EVENT_START"; -BI.SearchMultiSelectSearcher.EVENT_STOP = "EVENT_STOP"; -BI.SearchMultiSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SearchMultiSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.shortcut("bi.search_multi_select_searcher", BI.SearchMultiSelectSearcher); diff --git a/src/widget/selecttree/nodes/node.first.plus.js b/src/widget/selecttree/nodes/node.first.plus.js deleted file mode 100644 index 378eac230..000000000 --- a/src/widget/selecttree/nodes/node.first.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.SelectTreeFirstPlusGroupNode - * @extends BI.NodeButton - */ -BI.SelectTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.SelectTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-select-tree-first-plus-group-node bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.SelectTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.first_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - }, - - setOpened: function (v) { - BI.SelectTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.select_tree_first_plus_group_node", BI.SelectTreeFirstPlusGroupNode); \ No newline at end of file diff --git a/src/widget/selecttree/nodes/node.last.plus.js b/src/widget/selecttree/nodes/node.last.plus.js deleted file mode 100644 index f8e764e10..000000000 --- a/src/widget/selecttree/nodes/node.last.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.SelectTreeLastPlusGroupNode - * @extends BI.NodeButton - */ -BI.SelectTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.SelectTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-select-tree-last-plus-group-node bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.SelectTreeLastPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.last_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - }, - - setOpened: function (v) { - BI.SelectTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.select_tree_last_plus_group_node", BI.SelectTreeLastPlusGroupNode); \ No newline at end of file diff --git a/src/widget/selecttree/nodes/node.mid.plus.js b/src/widget/selecttree/nodes/node.mid.plus.js deleted file mode 100644 index ddafe5704..000000000 --- a/src/widget/selecttree/nodes/node.mid.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.SelectTreeMidPlusGroupNode - * @extends BI.NodeButton - */ -BI.SelectTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.SelectTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-select-tree-mid-plus-group-node bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.SelectTreeMidPlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.mid_tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - }, - - setOpened: function (v) { - BI.SelectTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.select_tree_mid_plus_group_node", BI.SelectTreeMidPlusGroupNode); \ No newline at end of file diff --git a/src/widget/selecttree/nodes/node.plus.js b/src/widget/selecttree/nodes/node.plus.js deleted file mode 100644 index d5cd39c66..000000000 --- a/src/widget/selecttree/nodes/node.plus.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 加号表示的组节点 - * Created by GUY on 2015/9/6. - * @class BI.SelectTreePlusGroupNode - * @extends BI.NodeButton - */ -BI.SelectTreePlusGroupNode = BI.inherit(BI.NodeButton, { - _defaultConfig: function () { - var conf = BI.SelectTreePlusGroupNode.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-select-tree-plus-group-node bi-list-item-active", - logic: { - dynamic: false - }, - id: "", - pId: "", - readonly: true, - open: false, - height: 24 - }); - }, - _init: function () { - BI.SelectTreePlusGroupNode.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.checkbox = BI.createWidget({ - type: "bi.tree_node_checkbox", - stopPropagation: true, - iconHeight: o.height, - iconWidth: o.iconWrapperWidth || o.height - }); - this.text = BI.createWidget({ - type: "bi.label", - textAlign: "left", - whiteSpace: "nowrap", - textHeight: o.height, - height: o.height, - hgap: o.hgap, - text: o.text, - value: o.value, - keyword: o.keyword, - py: o.py - }); - this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.triggerExpand(); - } else { - self.triggerCollapse(); - } - } - }); - var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); - var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { - width: 24, - el: this.checkbox - }, this.text); - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { - items: items - })))); - }, - - isOnce: function () { - return true; - }, - - doRedMark: function () { - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doClick: function () { - BI.NodeButton.superclass.doClick.apply(this, arguments); - }, - - setOpened: function (v) { - BI.SelectTreePlusGroupNode.superclass.setOpened.apply(this, arguments); - if (BI.isNotNull(this.checkbox)) { - this.checkbox.setSelected(v); - } - } -}); - -BI.shortcut("bi.select_tree_plus_group_node", BI.SelectTreePlusGroupNode); \ No newline at end of file diff --git a/src/widget/selecttree/selecttree.combo.js b/src/widget/selecttree/selecttree.combo.js deleted file mode 100644 index 5095c120d..000000000 --- a/src/widget/selecttree/selecttree.combo.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @class BI.SelectTreeCombo - * @extends BI.Widget - */ -BI.SelectTreeCombo = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SelectTreeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-tree-combo bi-border bi-border-radius", - height: 24, - text: "", - items: [], - value: "", - allowClear: false, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.SelectTreeCombo.superclass._init.apply(this, arguments); - - this.trigger = BI.createWidget({ - type: "bi.single_tree_trigger", - text: o.text, - height: BI.toPix(o.height, 2), - items: o.items, - value: o.value, - allowClear: o.allowClear, - warningTitle: o.warningTitle, - }); - - this.trigger.on(BI.SingleTreeTrigger.EVENT_CLEAR, function () { - self._clear(); - }); - - this.popup = BI.createWidget({ - type: "bi.select_level_tree", - items: o.items, - value: o.value - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - container: o.container, - element: this, - adjustLength: 2, - el: this.trigger, - popup: { - el: this.popup - } - }); - - this.combo.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.popup.on(BI.SingleTreePopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - }); - - if (BI.isKey(o.value)) { - this._checkError(o.value); - } - }, - - _checkError: function (v) { - if (BI.isNull(v) || BI.isEmptyArray(v) || BI.isEmptyString(v)) { - this.trigger.options.tipType = "success"; - this.trigger.element.removeClass("error"); - this.element.removeClass("error"); - } else { - v = BI.isArray(v) ? v : [v]; - var result = BI.find(this.options.items, function (idx, item) { - return BI.contains(v, item.value); - }); - if (BI.isNull(result)) { - this.trigger.setTipType("warning"); - this.element.removeClass("error").addClass("error"); - this.trigger.element.removeClass("error").addClass("error"); - } else { - this.trigger.setTipType("success"); - this.trigger.element.removeClass("error"); - this.element.removeClass("error"); - } - } - }, - - _clear: function () { - this.setValue([]); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.trigger.setValue(v); - this.popup.setValue(v); - this._checkError(v); - }, - - getValue: function () { - return this.popup.getValue(); - }, - - populate: function (items) { - this.combo.populate(items); - } -}); - - -BI.shortcut("bi.select_tree_combo", BI.SelectTreeCombo); diff --git a/src/widget/selecttree/selecttree.expander.js b/src/widget/selecttree/selecttree.expander.js deleted file mode 100644 index b708e4bb9..000000000 --- a/src/widget/selecttree/selecttree.expander.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @class BI.SelectTreeExpander - * @extends BI.Widget - */ -BI.SelectTreeExpander = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SelectTreeExpander.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-tree-expander", - trigger: "", - toggle: true, - direction: "bottom", - isDefaultInit: true, - el: {}, - popup: {} - }); - }, - - _init: function () { - BI.SelectTreeExpander.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.trigger = BI.createWidget(o.el); - this.trigger.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - if (this.isSelected()) { - self.expander.setValue([]); - } - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.expander = BI.createWidget({ - type: "bi.expander", - element: this, - trigger: o.trigger, - toggle: o.toggle, - direction: o.direction, - isDefaultInit: o.isDefaultInit, - el: this.trigger, - popup: o.popup - }); - this.expander.on(BI.Controller.EVENT_CHANGE, function (type) { - if (type === BI.Events.CLICK) { - self.trigger.setSelected(false); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - }, - - getAllLeaves: function () { - return this.expander.getAllLeaves(); - }, - - setValue: function (v) { - if (BI.contains(v, this.trigger.getValue())) { - this.trigger.setSelected(true); - this.expander.setValue([]); - } else { - this.trigger.setSelected(false); - this.expander.setValue(v); - } - }, - - getValue: function () { - if (this.trigger.isSelected()) { - return [this.trigger.getValue()]; - } - return this.expander.getValue(); - }, - - populate: function (items) { - this.expander.populate(items); - } -}); - -BI.shortcut("bi.select_tree_expander", BI.SelectTreeExpander); \ No newline at end of file diff --git a/src/widget/selecttree/selecttree.popup.js b/src/widget/selecttree/selecttree.popup.js deleted file mode 100644 index cfce060ef..000000000 --- a/src/widget/selecttree/selecttree.popup.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @class BI.SelectTreePopup - * @extends BI.Pane - */ - -BI.SelectTreePopup = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.SelectTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-level-tree", - tipText: BI.i18nText("BI-No_Selected_Item"), - items: [], - value: "" - }); - }, - - _formatItems: function (nodes, layer, pNode) { - var self = this; - BI.each(nodes, function (i, node) { - var extend = { - layer: layer, - isFirstNode: i === 0, - isLastNode: i === nodes.length - 1, - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - pNode: pNode, - }; - node.id = node.id || BI.UUID(); - - if (node.isParent === true || node.parent === true || BI.isNotEmptyArray(node.children)) { - - extend.type = "bi.tree_node"; - extend.selectable = true; - BI.defaults(node, extend); - self._formatItems(node.children, layer + 1, node); - } else { - extend.type = "bi.tree_item"; - BI.defaults(node, extend); - } - }); - return nodes; - }, - - _init: function () { - BI.SelectTreePopup.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.tree = BI.createWidget({ - type: "bi.level_tree", - expander: { - type: "bi.tree_expander", - // isDefaultInit: true, - selectable: true, - }, - items: this._formatItems(BI.Tree.transformToTreeFormat(o.items), 0), - value: o.value, - chooseType: BI.Selection.Single - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - vgap: 5, - items: [this.tree] - }); - - this.tree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.tree.on(BI.LevelTree.EVENT_CHANGE, function () { - self.fireEvent(BI.SelectTreePopup.EVENT_CHANGE); - }); - - this.check(); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - BI.SelectTreePopup.superclass.populate.apply(this, arguments); - this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(items))); - } -}); - -BI.SelectTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.select_level_tree", BI.SelectTreePopup); diff --git a/src/widget/singleselect/search/singleselect.search.loader.js b/src/widget/singleselect/search/singleselect.search.loader.js deleted file mode 100644 index 5625593dd..000000000 --- a/src/widget/singleselect/search/singleselect.search.loader.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * 单选加载数据搜索loader面板 - * Created by guy on 15/11/4. - * @class BI.SingleSelectSearchLoader - * @extends Widget - */ -BI.SingleSelectSearchLoader = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectSearchLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-search-loader", - allowNoSelect: false, - logic: { - dynamic: false - }, - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn, - valueFormatter: BI.emptyFn - }); - }, - - _init: function () { - BI.SingleSelectSearchLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - - this.button_group = BI.createWidget({ - type: "bi.single_select_list", - allowNoSelect: opts.allowNoSelect, - element: this, - logic: { - dynamic: false - }, - value: opts.value, - el: { - tipText: BI.i18nText("BI-No_Select"), - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [{ - type: "bi.vertical" - }] - } - } - }, - itemsCreator: function (op, callback) { - self.storeValue && (op = BI.extend(op || {}, { - selectedValues: [self.storeValue] - })); - opts.itemsCreator(op, function (ob) { - var keyword = ob.keyword = opts.keywordGetter(); - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && !BI.isUndefined(self.storeValue)) { - var json = self._filterValues(self.storeValue); - firstItems = self._createItems(json); - } - var context = { - tipText: ob.tipText, - }; - callback(firstItems.concat(self._createItems(ob.items)), keyword || "", context); - if (op.times === 1 && self.storeValue) { - self.setValue(self.storeValue); - } - }); - }, - hasNext: function () { - return hasNext; - } - }); - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button_group.on(BI.SingleSelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleSelectSearchLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return BI.extend({ - type: o.allowNoSelect ? "bi.single_select_item" : "bi.single_select_radio_item", - logic: o.logic, - cls: "bi-list-item-active", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - selected: false, - iconWrapperWidth: 26, - hgap: o.allowNoSelect ? 10 : 0, - title: item.title || item.text - }, item); - }); - }, - - _filterValues: function (src) { - var o = this.options; - var keyword = o.keywordGetter(); - var values = src || []; - var newValues = BI.map(BI.isArray(values) ? values : [values], function (i, v) { - return { - text: o.valueFormatter(v) || v, - value: v - }; - }); - if (BI.isKey(keyword)) { - var search = BI.Func.getSearchResult(newValues, keyword); - values = search.match.concat(search.find); - } - return BI.map(values, function (i, v) { - return { - text: v.text, - title: v.text, - value: v.value, - selected: false - }; - }); - }, - - setValue: function (v) { - // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 - this.storeValue = v; - this.button_group.setValue(v); - }, - - getValue: function () { - return this.button_group.getValue(); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.resetHeight(h); - }, - - resetWidth: function (w) { - this.button_group.resetWidth(w); - } -}); - -BI.SingleSelectSearchLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_search_loader", BI.SingleSelectSearchLoader); diff --git a/src/widget/singleselect/search/singleselect.search.pane.insert.js b/src/widget/singleselect/search/singleselect.search.pane.insert.js deleted file mode 100644 index 6c1e49af2..000000000 --- a/src/widget/singleselect/search/singleselect.search.pane.insert.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.SingleSelectSearchInsertPane - * @extends Widget - */ - -BI.SingleSelectSearchInsertPane = BI.inherit(BI.Widget, { - - constants: { - height: 25, - lgap: 10, - tgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectSearchInsertPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-search-pane-insert bi-card", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.SingleSelectSearchInsertPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.addNotMatchTip = BI.createWidget({ - type: "bi.label", - text: BI.i18nText("BI-Basic_Press_Enter_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-keyword-red-mark", - hgap: 5, - }); - - this.loader = BI.createWidget({ - type: "bi.single_select_search_loader", - allowNoSelect: o.allowNoSelect, - keywordGetter: o.keywordGetter, - valueFormatter: o.valueFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator.apply(self, [op, function (res) { - callback(res); - self.setKeyword(o.keywordGetter()); - }]); - }, - value: o.value - }); - this.loader.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.resizer = BI.createWidget({ - type: "bi.vertical_fill", - rowSize: ["", "fill"], - element: this, - items: [{ - type: "bi.vertical", - items: [this.addNotMatchTip], - height: this.constants.height - }, { - el: this.loader - }] - }); - }, - - setKeyword: function (keyword) { - this.addNotMatchTip.setText(BI.i18nText("BI-Basic_Press_Enter_To_Add_Text", keyword)); - }, - - hasMatched: function () { - return false; - }, - - setValue: function (v) { - this.loader.setValue(v); - }, - - getValue: function () { - return this.loader.getValue(); - }, - - empty: function () { - this.loader.empty(); - }, - - populate: function (items) { - this.loader.populate.apply(this.loader, arguments); - } -}); - -BI.SingleSelectSearchInsertPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.single_select_search_insert_pane", BI.SingleSelectSearchInsertPane); diff --git a/src/widget/singleselect/search/singleselect.search.pane.js b/src/widget/singleselect/search/singleselect.search.pane.js deleted file mode 100644 index ea923c5f6..000000000 --- a/src/widget/singleselect/search/singleselect.search.pane.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.SingleSelectSearchPane - * @extends Widget - */ - -BI.SingleSelectSearchPane = BI.inherit(BI.Widget, { - - constants: { - height: 25, - lgap: 10, - tgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-search-pane bi-card", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.SingleSelectSearchPane.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.tooltipClick = BI.createWidget({ - type: "bi.label", - invisible: true, - text: BI.i18nText("BI-Click_Blank_To_Select"), - cls: "single-select-toolbar", - height: this.constants.height - }); - - this.loader = BI.createWidget({ - type: "bi.single_select_search_loader", - allowNoSelect: o.allowNoSelect, - keywordGetter: o.keywordGetter, - valueFormatter: o.valueFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator.apply(self, [op, function (res) { - callback(res); - self.setKeyword(o.keywordGetter()); - }]); - }, - value: o.value - }); - this.loader.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.resizer = BI.createWidget({ - type: "bi.vertical_fill", - rowSize: ["", "fill"], - element: this, - items: [{ - el: this.tooltipClick, - }, { - el: this.loader - }] - }); - this.tooltipClick.setVisible(false); - }, - - setKeyword: function (keyword) { - var btn, o = this.options; - var isVisible = this.loader.getAllButtons().length > 0 && (btn = this.loader.getAllButtons()[0]) && (keyword === (o.valueFormatter(btn.getValue()) || btn.getValue())); - if (isVisible !== this.tooltipClick.isVisible()) { - this.tooltipClick.setVisible(isVisible); - this.resizer.attr("items")[0].height = (isVisible ? this.constants.height : 0); - this.resizer.resize(); - } - }, - - hasMatched: function () { - return this.tooltipClick.isVisible(); - }, - - setValue: function (v) { - this.loader.setValue(v); - }, - - getValue: function () { - return this.loader.getValue(); - }, - - empty: function () { - this.loader.empty(); - }, - - populate: function (items) { - this.loader.populate.apply(this.loader, arguments); - } -}); - -BI.SingleSelectSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.shortcut("bi.single_select_search_pane", BI.SingleSelectSearchPane); diff --git a/src/widget/singleselect/singleselect.combo.js b/src/widget/singleselect/singleselect.combo.js deleted file mode 100644 index cc4d7c261..000000000 --- a/src/widget/singleselect/singleselect.combo.js +++ /dev/null @@ -1,272 +0,0 @@ -/** - * - * @class BI.SingleSelectCombo - * @extends BI.Single - */ -BI.SingleSelectCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-combo", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - itemWrapper: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - allowEdit: true - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.SingleSelectCombo.superclass._init.apply(this, arguments); - - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue = self._startValue); - self.trigger.getSearcher().setState(self.storeValue); - }; - this.storeValue = o.value; - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.single_select_trigger", - height: BI.toPix(o.height, o.simple ? 1 : 2), - // adapter: this.popup, - allowNoSelect: o.allowNoSelect, - allowEdit: o.allowEdit, - valueFormatter: o.valueFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(self.getValue()); - } - callback.apply(self, arguments); - }); - }, - text: o.text, - value: this.storeValue - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.SingleSelectCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.SingleSelectCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_START, function () { - self._setStartValue(); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_STOP, function () { - self._setStartValue(); - self.fireEvent(BI.SingleSelectCombo.EVENT_STOP); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_SEARCHING, function () { - self._dataChange = true; - self.fireEvent(BI.SingleSelectCombo.EVENT_SEARCHING); - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_CHANGE, function (value, obj) { - self.storeValue = this.getValue(); - assertShowValue(); - self._defaultState(); - self._dataChange = true; - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - container: o.container, - toggle: false, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.single_select_popup_view", - allowNoSelect: o.allowNoSelect, - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - }, - listeners: [{ - eventName: BI.SingleSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - self._defaultState(); - }); - self.fireEvent(BI.SingleSelectCombo.EVENT_CLICK_ITEM); - } - }], - itemsCreator: o.itemsCreator, - itemWrapper: o.itemWrapper, - valueFormatter: o.valueFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0; - }, - value: o.value - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self.populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self.trigger.stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "single-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }] - }); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _joinKeywords: function (keywords, callback) { - var self = this, o = this.options; - this._assertValue(this.storeValue); - this.requesting = true; - o.itemsCreator({ - type: BI.SingleSelectCombo.REQ_GET_ALL_DATA, - keywords: keywords - }, function (ob) { - var values = BI.map(ob.items, "value"); - digest(values); - }); - - function digest (items) { - var selectedMap = self._makeMap(items); - BI.each(keywords, function (i, val) { - if (BI.isNotNull(selectedMap[val])) { - BI.remove(self.storeValue.value, val); - } - }); - self._adjust(callback); - } - }, - - _adjust: function (callback) { - var self = this, o = this.options; - if (!this._count) { - o.itemsCreator({ - type: BI.SingleSelectCombo.REQ_GET_DATA_LENGTH - }, function (res) { - self._count = res.count; - adjust(); - callback(); - }); - } else { - adjust(); - callback(); - - } - - function adjust () { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - setValue: function (v) { - this.storeValue = v; - this._assertValue(this.storeValue); - this.combo.setValue(this.storeValue); - }, - - getValue: function () { - return this.storeValue; - }, - - populate: function () { - this._count = null; - this.combo.populate.apply(this.combo, arguments); - } -}); - -BI.extend(BI.SingleSelectCombo, { - REQ_GET_DATA_LENGTH: 0, - REQ_GET_ALL_DATA: -1 -}); - -BI.SingleSelectCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.SingleSelectCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SingleSelectCombo.EVENT_STOP = "EVENT_STOP"; -BI.SingleSelectCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.SingleSelectCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.SingleSelectCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - -BI.shortcut("bi.single_select_combo", BI.SingleSelectCombo); diff --git a/src/widget/singleselect/singleselect.insert.combo.js b/src/widget/singleselect/singleselect.insert.combo.js deleted file mode 100644 index a36bf0bd6..000000000 --- a/src/widget/singleselect/singleselect.insert.combo.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * - * @class BI.SingleSelectInsertCombo - * @extends BI.Single - */ -BI.SingleSelectInsertCombo = BI.inherit(BI.Single, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectInsertCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-combo", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - itemWrapper: BI.emptyFn, - valueFormatter: BI.emptyFn, - height: 24, - allowEdit: true, - watermark: BI.i18nText("BI-Basic_Search_And_Patch_Paste"), - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.SingleSelectInsertCombo.superclass._init.apply(this, arguments); - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue = self._startValue); - self.trigger.getSearcher().setState(self.storeValue); - }; - this.storeValue = o.value; - // 标记正在请求数据 - this.requesting = false; - - this.trigger = BI.createWidget({ - type: "bi.single_select_trigger", - watermark: o.watermark, - height: BI.toPix(o.height, o.simple ? 1 : 2), - allowNoSelect: o.allowNoSelect, - allowEdit: o.allowEdit, - // adapter: this.popup, - valueFormatter: o.valueFormatter, - itemsCreator: function (op, callback) { - o.itemsCreator(op, function (res) { - if (op.times === 1 && BI.isNotNull(op.keywords)) { - // 预防trigger内部把当前的storeValue改掉 - self.trigger.setValue(self.getValue()); - } - callback.apply(self, arguments); - }); - }, - text: o.text, - value: this.storeValue, - searcher: { - popup: { - type: "bi.single_select_search_insert_pane", - } - } - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_FOCUS, function () { - self.fireEvent(BI.SingleSelectInsertCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_BLUR, function () { - self.fireEvent(BI.SingleSelectInsertCombo.EVENT_BLUR); - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_START, function () { - self._setStartValue(); - this.getSearcher().setValue(self.storeValue); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_STOP, function () { - self._setStartValue(); - self.fireEvent(BI.SingleSelectInsertCombo.EVENT_STOP); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_PAUSE, function () { - self.storeValue = self.trigger.getSearcher().getKeyword(); - assertShowValue(); - self._defaultState(); - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_SEARCHING, function () { - self._dataChange = true; - self.fireEvent(BI.SingleSelectInsertCombo.EVENT_SEARCHING); - }); - - this.trigger.on(BI.SingleSelectTrigger.EVENT_CHANGE, function (value, obj) { - self.storeValue = this.getValue(); - assertShowValue(); - self._defaultState(); - self._dataChange = true; - }); - this.trigger.on(BI.SingleSelectTrigger.EVENT_COUNTER_CLICK, function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - container: o.container, - toggle: false, - el: this.trigger, - adjustLength: 1, - popup: { - type: "bi.single_select_popup_view", - allowNoSelect: o.allowNoSelect, - ref: function () { - self.popup = this; - self.trigger.setAdapter(this); - }, - listeners: [{ - eventName: BI.SingleSelectPopupView.EVENT_CHANGE, - action: function () { - self._dataChange = true; - self.storeValue = this.getValue(); - self._adjust(function () { - assertShowValue(); - self._defaultState(); - }); - self.fireEvent(BI.SingleSelectInsertCombo.EVENT_CLICK_ITEM); - } - }], - itemsCreator: o.itemsCreator, - itemWrapper: o.itemWrapper, - valueFormatter: o.valueFormatter, - onLoaded: function () { - BI.nextTick(function () { - self.combo.adjustWidth(); - self.combo.adjustHeight(); - self.trigger.getSearcher().adjustView(); - }); - } - }, - hideChecker: function (e) { - return triggerBtn.element.find(e.target).length === 0; - }, - value: o.value - }); - - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - if (!this.isViewVisible()) { - self._dataChange = false;// 标记数据是否发生变化 - } - this.setValue(self.storeValue); - BI.nextTick(function () { - self.populate(); - }); - }); - // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 - this.wants2Quit = false; - this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { - // important:关闭弹出时又可能没有退出编辑状态 - self.trigger.stopEditing(); - if (self.requesting === true) { - self.wants2Quit = true; - } else { - self._dataChange && self.fireEvent(BI.SingleSelectInsertCombo.EVENT_CONFIRM); - } - }); - - var triggerBtn = BI.createWidget({ - type: "bi.trigger_icon_button", - width: o.height, - height: o.height, - cls: "single-select-trigger-icon-button" - }); - triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } else { - self.combo.showView(); - } - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.combo, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: triggerBtn, - right: 0, - top: 0, - bottom: 0 - }] - }); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - this.combo.hideView(); - }, - - _assertValue: function (val) { - }, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _adjust: function (callback) { - var self = this, o = this.options; - adjust(); - callback(); - - function adjust () { - if (self.wants2Quit === true) { - self._dataChange && self.fireEvent(BI.SingleSelectInsertCombo.EVENT_CONFIRM); - self.wants2Quit = false; - } - self.requesting = false; - } - }, - - _setStartValue: function (value) { - this._startValue = value; - this.popup.setStartValue(value); - }, - - setValue: function (v) { - this.storeValue = v; - this._assertValue(this.storeValue); - this.combo.setValue(this.storeValue); - }, - - getValue: function () { - return this.storeValue; - }, - - populate: function () { - this.combo.populate.apply(this.combo, arguments); - } -}); - -BI.extend(BI.SingleSelectInsertCombo, { - REQ_GET_DATA_LENGTH: 0, - REQ_GET_ALL_DATA: -1 -}); - -BI.SingleSelectInsertCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SingleSelectInsertCombo.EVENT_BLUR = "EVENT_BLUR"; -BI.SingleSelectInsertCombo.EVENT_STOP = "EVENT_STOP"; -BI.SingleSelectInsertCombo.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.SingleSelectInsertCombo.EVENT_CLICK_ITEM = "EVENT_CLICK_ITEM"; -BI.SingleSelectInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - -BI.shortcut("bi.single_select_insert_combo", BI.SingleSelectInsertCombo); diff --git a/src/widget/singleselect/singleselect.list.js b/src/widget/singleselect/singleselect.list.js deleted file mode 100644 index 9842eb3ea..000000000 --- a/src/widget/singleselect/singleselect.list.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * 选择列表 - * - * Created by GUY on 2015/11/1. - * @class BI.SingleSelectList - * @extends BI.Widget - */ -BI.SingleSelectList = BI.inherit(BI.Widget, { - - _constants: { - itemHeight: 24 - }, - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-select-list", - direction: BI.Direction.Top, // toolbar的位置 - logic: { - dynamic: true - }, - items: [], - itemsCreator: BI.emptyFn, - hasNext: BI.emptyFn, - onLoaded: BI.emptyFn, - el: { - type: "bi.list_pane" - }, - allowNoSelect: false - }); - }, - _init: function () { - BI.SingleSelectList.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.list = BI.createWidget(o.el, { - type: "bi.list_pane", - items: o.items, - itemsCreator: function (op, callback) { - op.times === 1 && self.toolbar && self.toolbar.setVisible(false); - o.itemsCreator(op, function (items) { - callback.apply(self, arguments); - if (op.times === 1) { - self.toolbar && self.toolbar.setVisible(items && items.length > 0); - self.toolbar && self.toolbar.setEnable(items && items.length > 0); - } - }); - }, - onLoaded: o.onLoaded, - hasNext: o.hasNext, - value: o.value - }); - - this.list.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { - if (type === BI.Events.CLICK) { - self.fireEvent(BI.SingleSelectList.EVENT_CHANGE, value, obj); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - BI.createWidget(BI.extend({ - element: this - }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ - scrolly: true - }, o.logic, { - items: o.allowNoSelect ? BI.LogicFactory.createLogicItemsByDirection(o.direction, { - type: "bi.single_select_item", - cls: "bi-list-item-active", - height: this._constants.itemHeight, - forceNotSelected: true, - text: BI.i18nText("BI-Basic_No_Select"), - ref: function (_ref) { - self.toolbar = _ref; - }, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function (type) { - if (type === BI.Events.CLICK) { - self.list.setValue(); - self.fireEvent(BI.SingleSelectList.EVENT_CHANGE); - } - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }] - }, this.list) : BI.LogicFactory.createLogicItemsByDirection(o.direction, this.list) - })))); - - }, - - hasPrev: function () { - return this.list.hasPrev(); - }, - - hasNext: function () { - return this.list.hasNext(); - }, - - prependItems: function (items) { - this.list.prependItems.apply(this.list, arguments); - }, - - addItems: function (items) { - this.list.addItems.apply(this.list, arguments); - }, - - setValue: function (v) { - this.list.setValue([v]); - }, - - getValue: function () { - return this.list.getValue()[0]; - }, - - empty: function () { - this.list.empty(); - }, - - populate: function (items) { - this.list.populate.apply(this.list, arguments); - }, - - resetHeight: function (h) { - this.list.resetHeight ? this.list.resetHeight(h) : - this.list.element.css({"max-height": BI.pixFormat(h - (this.options.allowNoSelect ? this._constants.itemHeight : 0))}); - }, - - setNotSelectedValue: function () { - this.list.setNotSelectedValue.apply(this.list, arguments); - }, - - getNotSelectedValue: function () { - return this.list.getNotSelectedValue(); - }, - - getAllButtons: function () { - return this.list.getAllButtons(); - }, - - getAllLeaves: function () { - return this.list.getAllLeaves(); - }, - - getSelectedButtons: function () { - return this.list.getSelectedButtons(); - }, - - getNotSelectedButtons: function () { - return this.list.getNotSelectedButtons(); - }, - - getIndexByValue: function (value) { - return this.list.getIndexByValue(value); - }, - - getNodeById: function (id) { - return this.list.getNodeById(id); - }, - - getNodeByValue: function (value) { - return this.list.getNodeByValue(value); - } -}); -BI.SingleSelectList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_list", BI.SingleSelectList); diff --git a/src/widget/singleselect/singleselect.loader.js b/src/widget/singleselect/singleselect.loader.js deleted file mode 100644 index 645bdad66..000000000 --- a/src/widget/singleselect/singleselect.loader.js +++ /dev/null @@ -1,178 +0,0 @@ -/** - * 单选加载数据面板 - * Created by guy on 15/11/2. - * @class BI.SingleSelectLoader - * @extends Widget - */ -BI.SingleSelectLoader = BI.inherit(BI.Widget, { - - _constants: { - itemVgap: 5 - }, - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectLoader.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-loader", - logic: { - dynamic: true - }, - el: { - height: 400 - }, - allowNoSelect: false, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemWrapper: BI.emptyFn, - onLoaded: BI.emptyFn - }); - }, - - _init: function () { - BI.SingleSelectLoader.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - var hasNext = false; - this.storeValue = opts.value; - this.button_group = BI.createWidget({ - type: "bi.single_select_list", - allowNoSelect: opts.allowNoSelect, - logic: opts.logic, - el: BI.extend({ - onLoaded: opts.onLoaded, - el: { - type: "bi.loader", - isDefaultInit: false, - logic: { - dynamic: true, - scrolly: true - }, - el: { - chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, - behaviors: { - redmark: function () { - return true; - } - }, - layouts: [{ - type: "bi.vertical" - }] - } - } - }, opts.el), - itemsCreator: function (op, callback) { - var startValue = self._startValue; - !BI.isUndefined(self.storeValue) && (op = BI.extend(op || {}, { - selectedValues: [self.storeValue] - })); - opts.itemsCreator(op, function (ob) { - hasNext = ob.hasNext; - var firstItems = []; - if (op.times === 1 && !BI.isUndefined(self.storeValue)) { - var json = BI.map([self.storeValue], function (i, v) { - var txt = opts.valueFormatter(v) || v; - return opts.itemWrapper({ - text: txt, - value: v, - title: txt, - selected: true - }) || { - text: txt, - value: v, - title: txt, - selected: true - }; - }); - firstItems = self._createItems(json); - } - callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); - if (op.times === 1 && self.storeValue) { - BI.isKey(startValue) && (self.storeValue = startValue); - self.setValue(self.storeValue); - } - (op.times === 1) && self._scrollToTop(); - }); - }, - hasNext: function () { - return hasNext; - }, - value: this.storeValue - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - items: [this.button_group], - vgap: this._constants.itemVgap - }); - - this.button_group.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.button_group.on(BI.SingleSelectList.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleSelectLoader.EVENT_CHANGE, arguments); - }); - }, - - _createItems: function (items) { - var o = this.options; - return BI.map(items, function (i, item) { - return BI.extend({ - type: o.allowNoSelect ? "bi.single_select_item" : "bi.single_select_radio_item", - logic: o.logic, - cls: "bi-list-item-active", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - selected: false, - iconWrapperWidth: 26, - textHgap: o.allowNoSelect ? 10 : 0, - title: item.title || item.text - }, item); - }); - }, - - _scrollToTop: function () { - var self = this; - BI.delay(function () { - self.button_group.element.scrollTop(0); - }, 30); - }, - - _assertValue: function (val) { - }, - - setStartValue: function (v) { - this._startValue = v; - }, - - setValue: function (v) { - this.storeValue = v; - this._assertValue(this.storeValue); - this.button_group.setValue(this.storeValue); - }, - - getValue: function () { - return this.button_group.getValue(); - }, - - getAllButtons: function () { - return this.button_group.getAllButtons(); - }, - - empty: function () { - this.button_group.empty(); - }, - - populate: function (items) { - this.button_group.populate.apply(this.button_group, arguments); - }, - - resetHeight: function (h) { - this.button_group.resetHeight(h - this._constants.itemVgap * 2); - }, - - resetWidth: function (w) { - this.button_group.resetWidth(w); - } -}); - -BI.SingleSelectLoader.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_loader", BI.SingleSelectLoader); diff --git a/src/widget/singleselect/singleselect.popup.view.js b/src/widget/singleselect/singleselect.popup.view.js deleted file mode 100644 index ffa8766bd..000000000 --- a/src/widget/singleselect/singleselect.popup.view.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 带加载的单选下拉面板 - * @class BI.SingleSelectPopupView - * @extends Widget - */ -BI.SingleSelectPopupView = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectPopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-popup-view", - allowNoSelect: false, - maxWidth: "auto", - minWidth: 135, - maxHeight: 400, - valueFormatter: BI.emptyFn, - itemsCreator: BI.emptyFn, - itemWrapper: BI.emptyFn, - onLoaded: BI.emptyFn - }); - }, - - _init: function () { - BI.SingleSelectPopupView.superclass._init.apply(this, arguments); - var self = this, opts = this.options; - - this.loader = BI.createWidget({ - type: "bi.single_select_loader", - allowNoSelect: opts.allowNoSelect, - itemsCreator: opts.itemsCreator, - itemWrapper: opts.itemWrapper, - valueFormatter: opts.valueFormatter, - onLoaded: opts.onLoaded, - value: opts.value - }); - - this.popupView = BI.createWidget({ - type: "bi.popup_view", - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - element: this, - el: this.loader, - value: opts.value - }); - - this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleSelectPopupView.EVENT_CHANGE); - }); - }, - - setStartValue: function (v) { - this.loader.setStartValue(v); - }, - - setValue: function (v) { - this.popupView.setValue(v); - }, - - getValue: function () { - return this.popupView.getValue(); - }, - - populate: function (items) { - this.popupView.populate.apply(this.popupView, arguments); - }, - - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, - - resetWidth: function (w) { - this.popupView.resetWidth(w); - }, - - setDirection: function (direction, position) { - this.popupView.setDirection(direction, position); - }, -}); - -BI.SingleSelectPopupView.EVENT_CHANGE = "EVENT_CHANGE"; - - -BI.shortcut("bi.single_select_popup_view", BI.SingleSelectPopupView); diff --git a/src/widget/singleselect/singleselect.trigger.js b/src/widget/singleselect/singleselect.trigger.js deleted file mode 100644 index 35c6c0349..000000000 --- a/src/widget/singleselect/singleselect.trigger.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * - * 单选下拉框 - * @class BI.SingleSelectTrigger - * @extends BI.Trigger - */ - -BI.SingleSelectTrigger = BI.inherit(BI.Trigger, { - - constants: { - height: 14, - rgap: 4, - lgap: 4 - }, - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-trigger", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcher: {}, - switcher: {}, - - adapter: null, - masker: {}, - allowEdit: true - }); - }, - - _init: function () { - BI.SingleSelectTrigger.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.searcher = BI.createWidget(o.searcher, { - type: "bi.single_select_searcher", - watermark: o.watermark, - allowNoSelect: o.allowNoSelect, - text: o.text, - height: o.height, - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - popup: {}, - adapter: o.adapter, - masker: o.masker, - value: o.value - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_START, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_START); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_PAUSE, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_PAUSE); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_SEARCHING, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_SEARCHING, arguments); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_STOP, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_STOP); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_FOCUS, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_FOCUS); - }); - this.searcher.on(BI.SingleSelectSearcher.EVENT_BLUR, function () { - self.fireEvent(BI.SingleSelectTrigger.EVENT_BLUR, arguments); - }); - - var wrapper = BI.createWidget({ - type: "bi.htape", - element: this, - items: [ - { - el: this.searcher, - width: "fill" - }, { - el: BI.createWidget(), - width: 24 - }] - }); - - !o.allowEdit && BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.text", - title: function () { - return self.searcher.getState(); - } - }, - left: 0, - right: 24, - top: 0, - bottom: 0 - }] - }); - }, - - getSearcher: function () { - return this.searcher; - }, - - stopEditing: function () { - this.searcher.stopSearch(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setValue: function (v) { - this.searcher.setValue(v); - }, - - getKey: function () { - return this.searcher.getKey(); - }, - - getValue: function () { - return this.searcher.getValue(); - } -}); - -BI.SingleSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; -BI.SingleSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; -BI.SingleSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SingleSelectTrigger.EVENT_START = "EVENT_START"; -BI.SingleSelectTrigger.EVENT_STOP = "EVENT_STOP"; -BI.SingleSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SingleSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.SingleSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; -BI.SingleSelectTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SingleSelectTrigger.EVENT_BLUR = "EVENT_BLUR"; - -BI.shortcut("bi.single_select_trigger", BI.SingleSelectTrigger); \ No newline at end of file diff --git a/src/widget/singleselect/singleselectlist.insert.js b/src/widget/singleselect/singleselectlist.insert.js deleted file mode 100644 index def836349..000000000 --- a/src/widget/singleselect/singleselectlist.insert.js +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @author: Teller - * @createdAt: 2018/3/28 - * @Description -*/ -BI.SingleSelectInsertList = BI.inherit(BI.Single, { - _defaultConfig: function () { - return BI.extend(BI.SingleSelectInsertList.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-insert-list", - allowNoSelect: false, - itemsCreator: BI.emptyFn, - itemWrapper: BI.emptyFn, - valueFormatter: BI.emptyFn, - searcherHeight: 24, - simple: false, - }); - }, - _init: function () { - BI.SingleSelectInsertList.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - this.storeValue = o.value; - - var assertShowValue = function () { - BI.isKey(self._startValue) && (self.storeValue = self._startValue); - // self.trigger.setValue(self.storeValue); - }; - - this.adapter = BI.createWidget({ - type: "bi.single_select_loader", - allowNoSelect: o.allowNoSelect, - cls: "popup-single-select-list bi-border-left bi-border-right bi-border-bottom", - itemsCreator: o.itemsCreator, - valueFormatter: o.valueFormatter, - itemWrapper: o.itemWrapper, - logic: { - dynamic: true - }, - // onLoaded: o.onLoaded, - el: {}, - value: o.value - }); - this.adapter.on(BI.SingleSelectLoader.EVENT_CHANGE, function () { - self.storeValue = this.getValue(); - assertShowValue(); - self.fireEvent(BI.SingleSelectInsertList.EVENT_CHANGE); - }); - - this.searcherPane = BI.createWidget({ - type: "bi.single_select_search_insert_pane", - allowNoSelect: o.allowNoSelect, - cls: "bi-border-left bi-border-right bi-border-bottom", - valueFormatter: o.valueFormatter, - keywordGetter: function () { - return self.trigger.getKeyword(); - }, - itemsCreator: function (op, callback) { - op.keywords = [self.trigger.getKeyword()]; - if (BI.isNotEmptyString(op.keywords[0])) { - this.setKeyword(op.keywords[0]); - o.itemsCreator(op, callback); - } - }, - }); - this.searcherPane.setVisible(false); - - this.trigger = BI.createWidget({ - type: "bi.searcher", - el: { - type: "bi.select_patch_editor", - el: { - type: "bi.search_editor", - watermark: BI.i18nText("BI-Basic_Search_And_Patch_Paste"), - simple: o.simple, - }, - ref: function (ref) { - self.editor = ref; - }, - height: o.searcherHeight, - }, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - adapter: this.adapter, - popup: this.searcherPane, - masker: false, - value: o.value, - listeners: [{ - eventName: BI.Searcher.EVENT_START, - action: function () { - self._showSearcherPane(); - self._setStartValue(); - this.setValue(BI.deepClone(self.storeValue)); - } - }, { - eventName: BI.Searcher.EVENT_STOP, - action: function () { - self._showAdapter(); - self._setStartValue(); - self.adapter.setValue(self.storeValue); - // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 - self.adapter.populate(); - } - }, { - eventName: BI.Searcher.EVENT_PAUSE, - action: function () { - var keyword = this.getKeyword(); - self.storeValue = keyword; - self._showAdapter(); - self.adapter.setValue(self.storeValue); - self._setStartValue(keyword); - assertShowValue(); - self.adapter.populate(); - self._setStartValue(); - self.fireEvent(BI.SingleSelectInsertList.EVENT_CHANGE); - - } - }, { - eventName: BI.Searcher.EVENT_CHANGE, - action: function () { - self.storeValue = this.getValue(); - self.fireEvent(BI.SingleSelectInsertList.EVENT_CHANGE); - } - }] - }); - - BI.createWidget({ - type: "bi.vertical_fill", - rowSize: ["", "fill"], - element: this, - items: [{ - el: this.trigger, - }, { - el: this.adapter, - }] - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.searcherPane, - top: 24, - bottom: 0, - left: 0, - right: 0 - }] - }); - }, - - _showAdapter: function () { - this.adapter.setVisible(true); - this.searcherPane.setVisible(false); - }, - - _showSearcherPane: function () { - this.searcherPane.setVisible(true); - this.adapter.setVisible(false); - }, - - _defaultState: function () { - this.trigger.stopEditing(); - }, - - _assertValue: function () {}, - - _makeMap: function (values) { - return BI.makeObject(values || []); - }, - - _setStartValue: function (value) { - this._startValue = value; - this.adapter.setStartValue(value); - }, - - isAllSelected: function () { - return this.adapter.isAllSelected(); - }, - - resize: function () { - // this.trigger.getCounter().adjustView(); - // this.trigger.adjustView(); - }, - setValue: function (v) { - this.storeValue = v; - this.adapter.setValue(this.storeValue); - this.trigger.setValue(this.storeValue); - }, - - getValue: function () { - return BI.deepClone(this.storeValue); - }, - - populate: function () { - this._count = null; - this._allData = null; - this.adapter.populate.apply(this.adapter, arguments); - this.trigger.populate.apply(this.trigger, arguments); - } -}); - -BI.extend(BI.SingleSelectInsertList, { - REQ_GET_DATA_LENGTH: 0, - REQ_GET_ALL_DATA: -1 -}); - -BI.SingleSelectInsertList.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_select_insert_list", BI.SingleSelectInsertList); diff --git a/src/widget/singleselect/trigger/editor.singleselect.js b/src/widget/singleselect/trigger/editor.singleselect.js deleted file mode 100644 index 881f60b45..000000000 --- a/src/widget/singleselect/trigger/editor.singleselect.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * 单选输入框 - * Created by guy on 15/11/3. - * @class BI.SingleSelectEditor - * @extends Widget - */ -BI.SingleSelectEditor = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectEditor.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-editor", - el: {}, - text: BI.i18nText("BI-Basic_Please_Select"), - watermark: BI.i18nText("BI-Basic_Search"), - }); - }, - - _init: function () { - BI.SingleSelectEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.select_patch_editor", - element: this, - height: o.height, - watermark: o.watermark, - allowBlank: true, - value: o.value, - defaultText: o.text, - text: o.text, - }); - - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.StateEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.SingleSelectEditor.EVENT_FOCUS); - }); - this.editor.on(BI.StateEditor.EVENT_BLUR, function () { - self.fireEvent(BI.SingleSelectEditor.EVENT_BLUR); - }); - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setState: function (state) { - this.editor.setState(state); - }, - - setValue: function (v) { - this.editor.setValue(v); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getKeywords: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - if (/\u200b\s\u200b$/.test(val)) { - return keywords.concat([BI.BlankSplitChar]); - } - - return keywords; - }, - - getKeyword: function () { - var val = this.editor.getValue(); - var keywords = val.split(/\u200b\s\u200b/); - if (BI.isEmptyString(keywords[keywords.length - 1])) { - keywords = keywords.slice(0, keywords.length - 1); - } - return BI.isEmptyArray(keywords) ? "" : keywords[keywords.length - 1]; - }, - - populate: function (items) { - - } -}); - -BI.SingleSelectEditor.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SingleSelectEditor.EVENT_BLUR = "EVENT_BLUR"; -BI.shortcut("bi.single_select_editor", BI.SingleSelectEditor); \ No newline at end of file diff --git a/src/widget/singleselect/trigger/searcher.singleselect.js b/src/widget/singleselect/trigger/searcher.singleselect.js deleted file mode 100644 index 800fd7560..000000000 --- a/src/widget/singleselect/trigger/searcher.singleselect.js +++ /dev/null @@ -1,162 +0,0 @@ -/** - * searcher - * Created by guy on 15/11/3. - * @class BI.SingleSelectSearcher - * @extends Widget - */ -BI.SingleSelectSearcher = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.SingleSelectSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-select-searcher", - itemsCreator: BI.emptyFn, - el: {}, - popup: {}, - valueFormatter: BI.emptyFn, - adapter: null, - masker: {}, - allowNoSelect: false - }); - }, - - _init: function () { - BI.SingleSelectSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget(o.el, { - type: "bi.single_select_editor", - height: o.height, - watermark: o.watermark, - text: o.text, - listeners: [{ - eventName: BI.SingleSelectEditor.EVENT_FOCUS, - action: function () { - self.fireEvent(BI.SingleSelectSearcher.EVENT_FOCUS); - } - }, { - eventName: BI.SingleSelectEditor.EVENT_BLUR, - action: function () { - self.fireEvent(BI.SingleSelectSearcher.EVENT_BLUR); - } - }] - }); - - this.searcher = BI.createWidget({ - type: "bi.searcher", - element: this, - height: o.height, - isAutoSearch: false, - isAutoSync: false, - onSearch: function (op, callback) { - callback(); - }, - el: this.editor, - - popup: BI.extend({ - type: "bi.single_select_search_pane", - allowNoSelect: o.allowNoSelect, - valueFormatter: o.valueFormatter, - keywordGetter: function () { - return self.editor.getValue(); - }, - itemsCreator: function (op, callback) { - var keyword = self.editor.getValue(); - op.keywords = [keyword]; - this.setKeyword(keyword); - o.itemsCreator(op, callback); - }, - value: o.value - }, o.popup), - - adapter: o.adapter, - masker: o.masker - }); - this.searcher.on(BI.Searcher.EVENT_START, function () { - self.fireEvent(BI.SingleSelectSearcher.EVENT_START); - }); - this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { - if (this.hasMatched()) { - - } - self.fireEvent(BI.SingleSelectSearcher.EVENT_PAUSE); - }); - this.searcher.on(BI.Searcher.EVENT_STOP, function () { - self.fireEvent(BI.SingleSelectSearcher.EVENT_STOP); - }); - this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleSelectSearcher.EVENT_CHANGE, arguments); - }); - this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { - var keywords = this.getKeywords(); - self.fireEvent(BI.SingleSelectSearcher.EVENT_SEARCHING, keywords); - }); - - if(BI.isNotNull(o.value)){ - this.setState(o.value); - } - }, - - adjustView: function () { - this.searcher.adjustView(); - }, - - isSearching: function () { - return this.searcher.isSearching(); - }, - - stopSearch: function () { - this.searcher.stopSearch(); - }, - - getKeyword: function () { - return this.editor.getKeyword(); - }, - - hasMatched: function () { - return this.searcher.hasMatched(); - }, - - hasChecked: function () { - return this.searcher.getView() && this.searcher.getView().hasChecked(); - }, - - setAdapter: function (adapter) { - this.searcher.setAdapter(adapter); - }, - - setState: function (v) { - var o = this.options; - if (BI.isUndefined(v)) { - this.editor.setState(BI.Selection.None); - } else { - v = v ?? ""; - this.editor.setState(o.valueFormatter(v + "") || (v + "")); - } - }, - - setValue: function (ob) { - this.setState(ob); - this.searcher.setValue(ob); - }, - - getKey: function () { - return this.editor.getValue(); - }, - - getValue: function () { - return this.searcher.getValue(); - }, - - populate: function (items) { - this.searcher.populate.apply(this.searcher, arguments); - } -}); - -BI.SingleSelectSearcher.EVENT_FOCUS = "EVENT_FOCUS"; -BI.SingleSelectSearcher.EVENT_BLUR = "EVENT_BLUR"; -BI.SingleSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.SingleSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SingleSelectSearcher.EVENT_START = "EVENT_START"; -BI.SingleSelectSearcher.EVENT_STOP = "EVENT_STOP"; -BI.SingleSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; -BI.SingleSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; -BI.shortcut("bi.single_select_searcher", BI.SingleSelectSearcher); diff --git a/src/widget/singleslider/button/editor.sign.text.js b/src/widget/singleslider/button/editor.sign.text.js deleted file mode 100644 index 281c7b0e1..000000000 --- a/src/widget/singleslider/button/editor.sign.text.js +++ /dev/null @@ -1,196 +0,0 @@ -BI.SignTextEditor = BI.inherit(BI.Widget, { - _defaultConfig: function () { - var conf = BI.SignTextEditor.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - baseCls: (conf.baseCls || "") + " bi-sign-initial-editor", - validationChecker: BI.emptyFn, - text: "", - height: 24 - }); - }, - - _init: function () { - BI.SignTextEditor.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.editor", - simple: o.simple, - height: o.height, - hgap: 4, - vgap: 2, - value: o.value, - validationChecker: o.validationChecker, - allowBlank: false - }); - this.text = BI.createWidget({ - type: "bi.text_button", - cls: "sign-editor-text", - title: function () { - return self.getValue(); - }, - textAlign: o.textAlign, - height: o.height, - hgap: 4, - handler: function () { - self._showInput(); - self.editor.focus(); - self.editor.selectAll(); - } - }); - this.text.on(BI.TextButton.EVENT_CHANGE, function () { - BI.nextTick(function () { - self.fireEvent(BI.SignTextEditor.EVENT_CLICK_LABEL); - }); - }); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: this.text, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }); - this.editor.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.editor.on(BI.Editor.EVENT_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.SignTextEditor.EVENT_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_CHANGE_CONFIRM, function () { - self._showHint(); - self._checkText(); - self.fireEvent(BI.SignTextEditor.EVENT_CHANGE_CONFIRM, arguments); - }); - this.editor.on(BI.Editor.EVENT_ERROR, function () { - self._checkText(); - }); - BI.createWidget({ - type: "bi.vertical", - scrolly: false, - element: this, - items: [this.editor] - }); - this._showHint(); - self._checkText(); - }, - - _checkText: function () { - var o = this.options; - BI.nextTick(BI.bind(function () { - if (this.editor.getValue() === "") { - this.text.setValue(o.watermark || ""); - this.text.element.addClass("bi-water-mark"); - } else { - var v = this.editor.getValue(); - v = (BI.isEmpty(v) || v == o.text) ? o.text : v + o.text; - this.text.setValue(v); - this.text.element.removeClass("bi-water-mark"); - } - }, this)); - }, - - _showInput: function () { - this.editor.visible(); - this.text.invisible(); - }, - - _showHint: function () { - this.editor.invisible(); - this.text.visible(); - }, - - setTitle: function (title) { - this.text.setTitle(title); - }, - - setWarningTitle: function (title) { - this.text.setWarningTitle(title); - }, - - focus: function () { - this._showInput(); - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - this._showHint(); - this._checkText(); - }, - - doRedMark: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doRedMark.apply(this.text, arguments); - }, - - unRedMark: function () { - this.text.unRedMark.apply(this.text, arguments); - }, - - doHighLight: function () { - if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { - return; - } - this.text.doHighLight.apply(this.text, arguments); - }, - - unHighLight: function () { - this.text.unHighLight.apply(this.text, arguments); - }, - - isValid: function () { - return this.editor.isValid(); - }, - - setErrorText: function (text) { - this.editor.setErrorText(text); - }, - - getErrorText: function () { - return this.editor.getErrorText(); - }, - - isEditing: function () { - return this.editor.isEditing(); - }, - - getLastValidValue: function () { - return this.editor.getLastValidValue(); - }, - - getLastChangedValue: function () { - return this.editor.getLastChangedValue(); - }, - - setValue: function (v) { - this.editor.setValue(v); - this._checkText(); - }, - - getValue: function () { - return this.editor.getValue(); - }, - - getState: function () { - return this.text.getValue(); - }, - - setState: function (v) { - var o = this.options; - this._showHint(); - v = (BI.isEmpty(v) || v == o.text) ? o.text : v + o.text; - this.text.setValue(v); - } -}); -BI.SignTextEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.SignTextEditor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; -BI.SignTextEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; - -BI.shortcut("bi.sign_text_editor", BI.SignTextEditor); \ No newline at end of file diff --git a/src/widget/singleslider/button/iconbutton.slider.js b/src/widget/singleslider/button/iconbutton.slider.js deleted file mode 100644 index 3b3432253..000000000 --- a/src/widget/singleslider/button/iconbutton.slider.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Created by zcf on 2016/9/22. - */ -BI.SliderIconButton = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-single-slider-button slider-button bi-high-light-border", - height: 8, - width: 8, - }, - - constants: { - LARGE_SIZE: 16, - NORMAL_SIZE: 12, - LARGE_OFFSET: 4, - NORMAL_OFFSET: 6 - }, - - render: function () { - var self = this; - return { - type: "bi.layout", - }; - } -}); -BI.shortcut("bi.single_slider_button", BI.SliderIconButton); diff --git a/src/widget/singleslider/singleslider.js b/src/widget/singleslider/singleslider.js deleted file mode 100644 index 4eaf0cc0c..000000000 --- a/src/widget/singleslider/singleslider.js +++ /dev/null @@ -1,380 +0,0 @@ -/** - * Created by zcf on 2016/9/22. - */ -BI.SingleSlider = BI.inherit(BI.Single, { - _constant: { - EDITOR_WIDTH: 90, - EDITOR_HEIGHT: 20, - SLIDER_WIDTH_HALF: 15, - SLIDER_WIDTH: 30, - SLIDER_HEIGHT: 30, - TRACK_HEIGHT: 24, - TRACK_GAP_HALF: 7, - TRACK_GAP: 14 - }, - - props: { - baseCls: "bi-single-slider bi-slider-track", - digit: false, - unit: "", - value: "", - min: 0, - max: 100, - }, - - beforeMount: function () { - const { value, min, max } = this.options; - this.setMinAndMax({ - min, - max, - }); - this.setValue(value); - this.populate(); - }, - - render: function () { - var self = this, o = this.options; - var c = this._constant; - this.enable = false; - this.value = ""; - - this.grayTrack = BI.createWidget({ - type: "bi.layout", - cls: "gray-track", - height: 6 - }); - this.blueTrack = BI.createWidget({ - type: "bi.layout", - cls: "blue-track bi-high-light-background", - height: 6 - }); - this.track = this._createTrackWrapper(); - - this.slider = BI.createWidget({ - type: "bi.single_slider_button" - }); - this._draggable(this.slider); - var sliderVertical = BI.createWidget({ - type: "bi.vertical_adapt", - cls: "slider-wrapper", - columnSize: ["fill"], - items: [ - { - type: "bi.absolute", - items: [ - { - el: this.slider, - top: 8, - } - ], - height: c.SLIDER_HEIGHT - } - ], - hgap: c.SLIDER_WIDTH_HALF, - height: c.SLIDER_HEIGHT - }); - // 这边其实是有问题的,拖拽区域是个圆,在圆的边缘拖拽后放开,这边计算出来的蓝条宽度实际上会比放开时长一点或者短一点 - sliderVertical.element.click(function (e) { - if (self.enable && self.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { - var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; - var trackLength = self.track.element[0].scrollWidth - c.TRACK_GAP; - var percent = 0; - if (offset < 0) { - percent = 0; - } - if (offset > 0 && offset < trackLength) { - percent = offset * 100 / self._getGrayTrackLength(); - } - if (offset >= trackLength) { - percent = 100; - } - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setAllPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - v = o.digit === false ? v : v.toFixed(o.digit); - self.label.setValue(v); - self.value = v; - self.fireEvent(BI.SingleSlider.EVENT_CHANGE); - } - }); - this.label = BI.createWidget({ - type: "bi.sign_text_editor", - cls: "slider-editor-button", - text: o.unit, - width: BI.toPix(c.EDITOR_WIDTH, 2), - height: BI.toPix(c.EDITOR_HEIGHT, 2), - allowBlank: false, - textAlign: "center", - validationChecker: function (v) { - return self._checkValidation(v); - } - }); - this.label.element.hover(function () { - self.label.element.removeClass("bi-border").addClass("bi-border"); - }, function () { - self.label.element.removeClass("bi-border"); - }); - this.label.on(BI.SignEditor.EVENT_CONFIRM, function () { - var v = BI.parseFloat(this.getValue()); - var percent = self._getPercentByValue(v); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setAllPosition(significantPercent); - this.setValue(v); - self.value = v; - self.fireEvent(BI.SingleSlider.EVENT_CHANGE); - }); - this._setVisible(false); - return { - type: "bi.absolute", - items: [ - { - el: { - type: "bi.vertical", - items: [ - { - type: "bi.absolute", - items: [ - { - el: this.track, - width: "100%", - height: c.TRACK_HEIGHT - } - ] - } - ], - hgap: c.TRACK_GAP_HALF, - height: c.TRACK_HEIGHT - }, - top: 23, - left: 0, - width: "100%" - }, { - el: sliderVertical, - top: 20, - left: 0, - width: "100%" - }, { - el: { - type: "bi.vertical", - items: [ - { - type: "bi.horizontal_auto", - items: [this.label] - } - ], - // height: c.EDITOR_HEIGHT - }, - top: 0, - left: 0, - width: "100%" - } - ] - }; - }, - - _draggable: function (widget) { - var self = this, o = this.options; - var startDrag = false; - var size = 0, offset = 0, defaultSize = 0; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { - if (mouseMoveTracker.isDragging()) { - startDrag = true; - offset += deltaX; - size = optimizeSize(defaultSize + offset); - widget.element.addClass("dragging"); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 - self._setBlueTrack(significantPercent); - self._setLabelPosition(significantPercent); - self._setSliderPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - v = o.digit === false ? v : v.toFixed(o.digit); - self.label.setValue(v); - self.value = v; - } - }, function () { - if (startDrag === true) { - size = optimizeSize(size); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setSliderPosition(significantPercent); - size = 0; - offset = 0; - defaultSize = size; - startDrag = false; - } - widget.element.removeClass("dragging"); - mouseMoveTracker.releaseMouseMoves(); - self.fireEvent(BI.SingleSlider.EVENT_CHANGE); - }, window); - widget.element.on("mousedown", function (event) { - if (!widget.isEnabled()) { - return; - } - defaultSize = this.offsetLeft; - optimizeSize(defaultSize); - mouseMoveTracker.captureMouseMoves(event); - }); - - function optimizeSize(s) { - return BI.clamp(s, 0, self._getGrayTrackLength()); - } - }, - - _createTrackWrapper: function () { - return BI.createWidget({ - type: "bi.absolute", - items: [ - { - el: { - type: "bi.vertical", - items: [ - { - type: "bi.absolute", - items: [ - { - el: this.grayTrack, - top: 0, - left: 0, - width: "100%" - }, { - el: this.blueTrack, - top: 0, - left: 0, - width: "0%" - } - ] - } - ], - hgap: 8, - height: 8 - }, - top: 8, - left: 0, - width: "100%" - } - ] - }); - }, - - _checkValidation: function (v) { - var o = this.options; - var valid = false; - if (BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max)) { - if (o.digit === false) { - valid = true; - } else { - var dotText = (v + "").split(".")[1] || ""; - valid = (dotText.length === o.digit); - } - } - return valid; - }, - - _setBlueTrack: function (percent) { - this.blueTrack.element.css({ width: percent + "%" }); - }, - - _setLabelPosition: function (percent) { - // this.label.element.css({left: percent + "%"}); - }, - - _setSliderPosition: function (percent) { - this.slider.element.css({ left: percent + "%" }); - }, - - _setAllPosition: function (percent) { - this._setSliderPosition(percent); - this._setLabelPosition(percent); - this._setBlueTrack(percent); - }, - - _setVisible: function (visible) { - this.slider.setVisible(visible); - this.label.setVisible(visible); - }, - - _getGrayTrackLength: function () { - return this.grayTrack.element[0].scrollWidth; - }, - - _getValueByPercent: function (percent) { - var thousandth = BI.parseInt(percent * 10); - return (((this.max - this.min) * thousandth) / 1000 + this.min); - }, - - _getPercentByValue: function (v) { - return (v - this.min) * 100 / (this.max - this.min); - }, - - getValue: function () { - return this.value; - }, - - setValue: function (v) { - var o = this.options; - v = BI.parseFloat(v); - v = o.digit === false ? v : v.toFixed(o.digit); - if ((!isNaN(v))) { - if (this._checkValidation(v)) { - this.value = v; - } - if (v > this.max) { - this.value = this.max; - } - if (v < this.min) { - this.value = this.min; - } - } - }, - - _setEnable: function (b) { - BI.SingleSlider.superclass._setEnable.apply(this, [b]); - if (b) { - this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); - } else { - this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); - } - }, - - setMinAndMax: function (v) { - var minNumber = this.options.min = BI.parseFloat(v.min); - var maxNumber = this.options.max = BI.parseFloat(v.max); - if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber)) { - this.min = minNumber; - this.max = maxNumber; - } - }, - - reset: function () { - this._setVisible(false); - this.enable = false; - this.value = ""; - this.min = 0; - this.max = 0; - this._setBlueTrack(0); - }, - - populate: function () { - var o = this.options; - if (!isNaN(this.min) && !isNaN(this.max)) { - this._setVisible(true); - this.enable = true; - if (o.digit) { - this.label.setErrorText(BI.i18nText("BI-Basic_Please_Enter_Number_Between", this.min, this.max)); - } else { - this.label.setErrorText(BI.i18nText("BI-Basic_Please_Enter_Integer_Number_Between", this.min, this.max)); - } - - if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { - this.label.setValue(this.value); - this._setAllPosition(this._getPercentByValue(this.value)); - } else { - this.label.setValue(this.max); - this._setAllPosition(100); - } - } - } -}); -BI.SingleSlider.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_slider", BI.SingleSlider); diff --git a/src/widget/singleslider/singleslider.label.js b/src/widget/singleslider/singleslider.label.js deleted file mode 100644 index c9ec33998..000000000 --- a/src/widget/singleslider/singleslider.label.js +++ /dev/null @@ -1,328 +0,0 @@ -/** - * Created by Urthur on 2017/9/12. - */ -BI.SingleSliderLabel = BI.inherit(BI.Single, { - _constant: { - EDITOR_WIDTH: 90, - EDITOR_HEIGHT: 20, - HEIGHT: 20, - SLIDER_WIDTH_HALF: 15, - SLIDER_WIDTH: 30, - SLIDER_HEIGHT: 30, - TRACK_HEIGHT: 24, - TRACK_GAP_HALF: 7, - TRACK_GAP: 14 - }, - - props: { - baseCls: "bi-single-slider-label bi-slider-track", - digit: false, - unit: "", - value: "", - min: 0, - max: 100, - }, - - beforeMount: function () { - const { value, min, max } = this.options; - this.setMinAndMax({ - min, - max, - }); - this.setValue(value); - this.populate(); - }, - - render: function () { - var self = this, o = this.options; - var c = this._constant; - this.enable = false; - this.value = ""; - - this.grayTrack = BI.createWidget({ - type: "bi.layout", - cls: "gray-track", - height: 6 - }); - this.blueTrack = BI.createWidget({ - type: "bi.layout", - cls: "blue-track bi-high-light-background", - height: 6 - }); - this.track = this._createTrackWrapper(); - - this.slider = BI.createWidget({ - type: "bi.single_slider_button" - }); - this._draggable(this.slider); - var sliderVertical = BI.createWidget({ - type: "bi.vertical_adapt", - columnSize: ["fill"], - items: [{ - type: "bi.absolute", - items: [ - { - el: this.slider, - top: 8, - } - ], - height: c.SLIDER_HEIGHT - }], - hgap: c.SLIDER_WIDTH_HALF, - height: c.SLIDER_HEIGHT - }); - sliderVertical.element.click(function (e) { - if (self.enable && self.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { - var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; - var trackLength = self.track.element[0].scrollWidth - c.TRACK_GAP; - var percent = 0; - if (offset < 0) { - percent = 0; - } - if (offset > 0 && offset < trackLength) { - percent = offset * 100 / self._getGrayTrackLength(); - } - if (offset >= trackLength) { - percent = 100; - } - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setAllPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - v = o.digit === false ? v : v.toFixed(o.digit); - self.label.setText(v + o.unit); - self.value = v; - self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); - } - }); - this.label = BI.createWidget({ - type: "bi.label", - height: c.HEIGHT, - width: BI.toPix(c.EDITOR_WIDTH, 2) - }); - - this._setVisible(false); - return ({ - type: "bi.absolute", - items: [{ - el: { - type: "bi.vertical", - items: [{ - type: "bi.absolute", - items: [{ - el: this.track, - width: "100%", - height: c.TRACK_HEIGHT - }] - }], - hgap: c.TRACK_GAP_HALF, - height: c.TRACK_HEIGHT - }, - top: 13, - left: 0, - width: "100%" - }, { - el: sliderVertical, - top: 10, - left: 0, - width: "100%" - }, { - el: { - type: "bi.vertical", - items: [{ - type: "bi.horizontal_auto", - items: [this.label] - }], - height: c.EDITOR_HEIGHT - }, - top: 0, - left: 0, - width: "100%" - }] - }); - }, - - _draggable: function (widget) { - var self = this, o = this.options; - var startDrag = false; - var size = 0, offset = 0, defaultSize = 0; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { - if (mouseMoveTracker.isDragging()) { - startDrag = true; - offset += deltaX; - size = optimizeSize(defaultSize + offset); - widget.element.addClass("dragging"); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 - self._setBlueTrack(significantPercent); - self._setLabelPosition(significantPercent); - self._setSliderPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - v = o.digit === false ? v : v.toFixed(o.digit); - self.label.setValue(v + o.unit); - self.value = v; - self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); - } - }, function () { - if (startDrag === true) { - size = optimizeSize(size); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setSliderPosition(significantPercent); - size = 0; - offset = 0; - defaultSize = size; - startDrag = false; - } - widget.element.removeClass("dragging"); - mouseMoveTracker.releaseMouseMoves(); - self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); - }, window); - widget.element.on("mousedown", function (event) { - if (!widget.isEnabled()) { - return; - } - defaultSize = this.offsetLeft; - optimizeSize(defaultSize); - mouseMoveTracker.captureMouseMoves(event); - }); - - function optimizeSize(s) { - return BI.clamp(s, 0, self._getGrayTrackLength()); - } - }, - - _createTrackWrapper: function () { - return BI.createWidget({ - type: "bi.absolute", - items: [{ - el: { - type: "bi.vertical", - items: [{ - type: "bi.absolute", - items: [{ - el: this.grayTrack, - top: 0, - left: 0, - width: "100%" - }, { - el: this.blueTrack, - top: 0, - left: 0, - width: "0%" - }] - }], - hgap: 8, - height: 8 - }, - top: 8, - left: 0, - width: "100%" - }] - }); - }, - - _checkValidation: function (v) { - return BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max); - }, - - _setBlueTrack: function (percent) { - this.blueTrack.element.css({ width: percent + "%" }); - }, - - _setLabelPosition: function (percent) { - // this.label.element.css({left: percent + "%"}); - }, - - _setSliderPosition: function (percent) { - this.slider.element.css({ left: percent + "%" }); - }, - - _setAllPosition: function (percent) { - this._setSliderPosition(percent); - this._setLabelPosition(percent); - this._setBlueTrack(percent); - }, - - _setVisible: function (visible) { - this.slider.setVisible(visible); - this.label.setVisible(visible); - }, - - _getGrayTrackLength: function () { - return this.grayTrack.element[0].scrollWidth; - }, - - _getValueByPercent: function (percent) { - var thousandth = BI.parseInt(percent * 10); - return (((this.max - this.min) * thousandth) / 1000 + this.min); - }, - - _getPercentByValue: function (v) { - return (v - this.min) * 100 / (this.max - this.min); - }, - - _setEnable: function (b) { - BI.SingleSliderLabel.superclass._setEnable.apply(this, [b]); - if (b) { - this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); - } else { - this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); - } - }, - - getValue: function () { - return this.value; - }, - - setValue: function (v) { - var o = this.options; - v = BI.parseFloat(v); - v = o.digit === false ? v : v.toFixed(o.digit); - if ((!isNaN(v))) { - if (this._checkValidation(v)) { - this.value = v; - } - if (v > this.max) { - this.value = this.max; - } - if (v < this.min) { - this.value = this.min; - } - } - }, - - setMinAndMax: function (v) { - var minNumber = BI.parseFloat(v.min); - var maxNumber = BI.parseFloat(v.max); - if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber)) { - this.min = minNumber; - this.max = maxNumber; - } - }, - - reset: function () { - this._setVisible(false); - this.enable = false; - this.value = ""; - this.min = 0; - this.max = 0; - this._setBlueTrack(0); - }, - - populate: function () { - var o = this.options; - if (!isNaN(this.min) && !isNaN(this.max)) { - this._setVisible(true); - this.enable = true; - if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { - this.label.setValue(this.value + o.unit); - this._setAllPosition(this._getPercentByValue(this.value)); - } else { - this.label.setValue(this.max + o.unit); - this._setAllPosition(100); - } - } - } -}); -BI.SingleSliderLabel.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_slider_label", BI.SingleSliderLabel); diff --git a/src/widget/singleslider/singleslider.normal.js b/src/widget/singleslider/singleslider.normal.js deleted file mode 100644 index 1f7338530..000000000 --- a/src/widget/singleslider/singleslider.normal.js +++ /dev/null @@ -1,303 +0,0 @@ -/** - * normal single slider - * Created by Young on 2017/6/21. - */ -BI.SingleSliderNormal = BI.inherit(BI.Single, { - - _constant: { - HEIGHT: 28, - SLIDER_WIDTH_HALF: 15, - SLIDER_WIDTH: 30, - SLIDER_HEIGHT: 30, - TRACK_HEIGHT: 24, - TRACK_GAP_HALF: 7, - TRACK_GAP: 14 - }, - - props: { - baseCls: "bi-single-slider-normal bi-slider-track", - min: 0, - max: 100, - value: "", - // color: "#3f8ce8" - }, - - beforeMount: function () { - const { value, min, max } = this.options; - this.setMinAndMax({ - min, - max, - }); - this.setValue(value); - this.populate(); - }, - - render: function () { - var self = this; - var o = this.options; - var c = this._constant; - - var track = this._createTrack(); - this.slider = BI.createWidget({ - type: "bi.single_slider_button" - }); - this._draggable(this.slider); - - var sliderVertical = BI.createWidget({ - type: "bi.vertical_adapt", - columnSize: ["fill"], - items: [{ - type: "bi.absolute", - items: [ - { - el: this.slider, - top: 8, - } - ], - height: c.SLIDER_HEIGHT - }], - hgap: c.SLIDER_WIDTH_HALF, - height: c.SLIDER_HEIGHT - }); - sliderVertical.element.click(function (e) { - if (self.enable && self.isEnabled() && sliderVertical.element[0] === e.originalEvent.target) { - var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; - var trackLength = self.track.element[0].scrollWidth - c.TRACK_GAP; - var percent = 0; - if (offset < 0) { - percent = 0; - } - if (offset > 0 && offset < trackLength) { - percent = offset * 100 / self._getGrayTrackLength(); - } - if (offset >= trackLength) { - percent = 100; - } - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setAllPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - self.value = v; - self.fireEvent(BI.SingleSlider.EVENT_CHANGE); - } - }); - - return { - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.vertical", - items: [{ - type: "bi.absolute", - items: [{ - el: track, - width: "100%", - height: c.TRACK_HEIGHT - }] - }], - hgap: c.TRACK_GAP_HALF, - height: c.TRACK_HEIGHT - }, - top: 3, - left: 0, - width: "100%" - }, { - el: sliderVertical, - top: 0, - left: 0, - width: "100%" - }] - }; - }, - - _draggable: function (widget) { - var self = this, o = this.options; - var startDrag = false; - var size = 0, offset = 0, defaultSize = 0; - var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { - if (mouseMoveTracker.isDragging()) { - startDrag = true; - offset += deltaX; - size = optimizeSize(defaultSize + offset); - widget.element.addClass("dragging"); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 - self._setBlueTrack(significantPercent); - self._setSliderPosition(significantPercent); - var v = self._getValueByPercent(significantPercent); - v = o.digit === false ? v : v.toFixed(o.digit); - self.value = v; - self.fireEvent(BI.SingleSliderNormal.EVENT_DRAG, v); - } - }, function () { - if (startDrag === true) { - size = optimizeSize(size); - var percent = size * 100 / (self._getGrayTrackLength()); - var significantPercent = BI.parseFloat(percent.toFixed(1)); - self._setSliderPosition(significantPercent); - size = 0; - offset = 0; - defaultSize = size; - startDrag = false; - } - widget.element.removeClass("dragging"); - mouseMoveTracker.releaseMouseMoves(); - self.fireEvent(BI.SingleSlider.EVENT_CHANGE); - }, window); - widget.element.on("mousedown", function (event) { - if(!widget.isEnabled()) { - return; - } - defaultSize = this.offsetLeft; - optimizeSize(defaultSize); - mouseMoveTracker.captureMouseMoves(event); - }); - - function optimizeSize (s) { - return BI.clamp(s, 0, self._getGrayTrackLength()); - } - }, - - _createTrack: function () { - var self = this; - var c = this._constant; - this.grayTrack = BI.createWidget({ - type: "bi.layout", - cls: "gray-track", - height: 6 - }); - this.blueTrack = BI.createWidget({ - type: "bi.layout", - cls: "blue-track bi-high-light-background", - height: 6 - }); - if (this.options.color) { - this.blueTrack.element.css({"background-color": this.options.color}); - } - - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.vertical", - items: [{ - type: "bi.absolute", - items: [{ - el: this.grayTrack, - top: 0, - left: 0, - width: "100%" - }, { - el: this.blueTrack, - top: 0, - left: 0, - width: "0%" - }] - }], - hgap: 8, - height: 8 - }, - top: 8, - left: 0, - width: "100%" - }], - ref: function (ref) { - self.track = ref; - } - }; - }, - - _checkValidation: function (v) { - return !(BI.isNull(v) || v < this.min || v > this.max); - }, - - _setBlueTrack: function (percent) { - this.blueTrack.element.css({width: percent + "%"}); - }, - - _setSliderPosition: function (percent) { - this.slider.element.css({left: percent + "%"}); - }, - - _setAllPosition: function (percent) { - this._setSliderPosition(percent); - this._setBlueTrack(percent); - }, - - _setVisible: function (visible) { - this.slider.setVisible(visible); - }, - - _getGrayTrackLength: function () { - return this.grayTrack.element[0].scrollWidth; - }, - - _getValueByPercent: function (percent) { - var thousandth = BI.parseInt(percent * 10); - return (((this.max - this.min) * thousandth) / 1000 + this.min); - }, - - _getPercentByValue: function (v) { - return (v - this.min) * 100 / (this.max - this.min); - }, - - _setEnable: function (b) { - BI.SingleSliderNormal.superclass._setEnable.apply(this, [b]); - if(b) { - this.blueTrack.element.removeClass("disabled-blue-track").addClass("blue-track"); - } else { - this.blueTrack.element.removeClass("blue-track").addClass("disabled-blue-track"); - } - }, - - getValue: function () { - return this.value; - }, - - setValue: function (v) { - var value = BI.parseFloat(v); - if ((!isNaN(value))) { - if (this._checkValidation(value)) { - this.value = value; - } - if (value > this.max) { - this.value = this.max; - } - if (value < this.min) { - this.value = this.min; - } - } - }, - - setMinAndMax: function (v) { - var minNumber = BI.parseFloat(v.min); - var maxNumber = BI.parseFloat(v.max); - if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber )) { - this.min = minNumber; - this.max = maxNumber; - } - }, - - reset: function () { - this._setVisible(false); - this.enable = false; - this.value = ""; - this.min = 0; - this.max = 0; - this._setBlueTrack(0); - }, - - populate: function () { - if (!isNaN(this.min) && !isNaN(this.max)) { - this._setVisible(true); - this.enable = true; - if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { - this._setAllPosition(this._getPercentByValue(this.value)); - } else { - this._setAllPosition(100); - } - } - } -}); -BI.SingleSliderNormal.EVENT_DRAG = "EVENT_DRAG"; -BI.shortcut("bi.single_slider_normal", BI.SingleSliderNormal); diff --git a/src/widget/singletree/singletree.combo.js b/src/widget/singletree/singletree.combo.js deleted file mode 100644 index 589c205c6..000000000 --- a/src/widget/singletree/singletree.combo.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @class BI.SingleTreeCombo - * @extends BI.Widget - */ -BI.SingleTreeCombo = BI.inherit(BI.Widget, { - - _defaultConfig: function (config) { - return BI.extend(BI.SingleTreeCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-tree-combo " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - trigger: {}, - height: 24, - text: "", - items: [], - value: "", - allowClear: false, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.SingleTreeCombo.superclass._init.apply(this, arguments); - - this.trigger = BI.createWidget(BI.extend({ - type: "bi.single_tree_trigger", - text: o.text, - defaultText: o.defaultText, - height: BI.toPix(o.height, 2), - items: o.items, - value: o.value, - allowClear: o.allowClear, - warningTitle: o.warningTitle, - }, o.trigger)); - - this.trigger.on(BI.SingleTreeTrigger.EVENT_CLEAR, function () { - self._clear(); - }); - - this.popup = BI.createWidget({ - type: "bi.single_level_tree", - items: o.items, - value: o.value - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - container: o.container, - element: this, - adjustLength: 2, - el: this.trigger, - popup: { - el: this.popup - } - }); - - this.combo.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.fireEvent(BI.SingleTreeCombo.EVENT_BEFORE_POPUPVIEW, arguments); - }); - - this.popup.on(BI.SingleTreePopup.EVENT_CHANGE, function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.SingleTreeCombo.EVENT_CHANGE); - }); - - if (BI.isKey(o.value)) { - this._checkError(o.value); - } - }, - - _checkError: function (v) { - if (BI.isNull(v) || BI.isEmptyArray(v) || BI.isEmptyString(v)) { - this.trigger.options.tipType = "success"; - this.trigger.element.removeClass("error"); - this.element.removeClass("error"); - } else { - v = BI.isArray(v) ? v : [v]; - var result = BI.find(this.options.items, function (idx, item) { - return BI.contains(v, item.value); - }); - if (BI.isNull(result)) { - this.trigger.setTipType("warning"); - this.element.removeClass("error").addClass("error"); - this.trigger.element.removeClass("error").addClass("error"); - } else { - this.trigger.setTipType("success"); - this.trigger.element.removeClass("error"); - this.element.removeClass("error"); - } - } - }, - - _clear: function () { - this.setValue([]); - }, - - populate: function (items) { - this.combo.populate(items); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.trigger.setValue(v); - this.popup.setValue(v); - this._checkError(v); - }, - - getValue: function () { - return this.popup.getValue(); - } -}); - -BI.SingleTreeCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.SingleTreeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.single_tree_combo", BI.SingleTreeCombo); diff --git a/src/widget/singletree/singletree.popup.js b/src/widget/singletree/singletree.popup.js deleted file mode 100644 index 6a73680af..000000000 --- a/src/widget/singletree/singletree.popup.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @class BI.SingleTreePopup - * @extends BI.Pane - */ - -BI.SingleTreePopup = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.SingleTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-level-tree", - tipText: BI.i18nText("BI-No_Selected_Item"), - items: [], - value: "" - }); - }, - - _init: function () { - BI.SingleTreePopup.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.tree = BI.createWidget({ - type: "bi.level_tree", - expander: { - isDefaultInit: true - }, - items: o.items, - value: o.value, - chooseType: BI.Selection.Single - }); - - BI.createWidget({ - type: "bi.vertical", - element: this, - vgap: 5, - items: [this.tree] - }); - - this.tree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.tree.on(BI.LevelTree.EVENT_CHANGE, function () { - self.fireEvent(BI.SingleTreePopup.EVENT_CHANGE); - }); - - this.check(); - }, - - getValue: function () { - return this.tree.getValue(); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.tree.setValue(v); - }, - - populate: function (items) { - BI.SingleTreePopup.superclass.populate.apply(this, arguments); - this.tree.populate(items); - } -}); - -BI.SingleTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.single_level_tree", BI.SingleTreePopup); \ No newline at end of file diff --git a/src/widget/singletree/singletree.trigger.js b/src/widget/singletree/singletree.trigger.js deleted file mode 100644 index 221c8b069..000000000 --- a/src/widget/singletree/singletree.trigger.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @class BI.SingleTreeTrigger - * @extends BI.Trigger - */ - -BI.SingleTreeTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.SingleTreeTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-single-tree-trigger", - height: 24, - text: "", - items: [], - value: "", - allowClear: false, - valueFormatter: BI.emptyFn, - }); - }, - - _init: function () { - BI.SingleTreeTrigger.superclass._init.apply(this, arguments); - - var self = this, o = this.options; - - this.trigger = BI.createWidget({ - type: "bi.select_text_trigger", - element: this, - text: o.text, - defaultText: o.defaultText, - items: o.items, - height: o.height, - warningTitle: o.warningTitle, - tipType: o.tipType, - value: o.value, - allowClear: o.allowClear, - valueFormatter: o.valueFormatter, - listeners: [ - { - eventName: BI.SelectTextTrigger.EVENT_CLEAR, - action: function () { - self.fireEvent(BI.SingleTreeTrigger.EVENT_CLEAR); - } - } - ] - }); - }, - - _checkTitle: function () { - var self = this, val = this.getValue(); - BI.any(this.options.items, function (i, item) { - if (BI.contains(val, item.value)) { - self.trigger.setTitle(item.text || item.value); - return true; - } - }); - }, - - setValue: function (v) { - v = BI.isArray(v) ? v : [v]; - this.options.value = v; - this.trigger.setValue(v); - this._checkTitle(); - }, - - setTipType: function (v) { - this.options.tipType = v; - this.trigger.setTipType(v); - }, - - getValue: function () { - return this.options.value || []; - }, - - getTextor: function () { - return this.trigger.getTextor(); - }, - - populate: function (items) { - this.trigger.populate(items); - } - -}); - -BI.SingleTreeTrigger.EVENT_CLEAR = "EVENT_CLEAR"; -BI.shortcut("bi.single_tree_trigger", BI.SingleTreeTrigger); diff --git a/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js b/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js deleted file mode 100644 index 55ff01e49..000000000 --- a/src/widget/textvaluedownlistcombo/combo.textvaluedownlist.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @class BI.TextValueDownListCombo - * @extend BI.Widget - */ -BI.TextValueDownListCombo = BI.inherit(BI.Widget, { - _defaultConfig: function (config) { - return BI.extend(BI.TextValueDownListCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-text-value-down-list-combo " + (config.simple ? "bi-border-bottom" : "bi-border bi-border-radius"), - height: 24, - }); - }, - - _init: function () { - var self = this, o = this.options; - BI.TextValueDownListCombo.superclass._init.apply(this, arguments); - this._createValueMap(); - - var value; - if(BI.isNotNull(o.value)) { - value = this._digest(o.value); - } - - this.combo = BI.createWidget({ - type: "bi.down_list_combo", - element: this, - chooseType: BI.Selection.Single, - adjustLength: 2, - width: BI.toPix(o.width, 2), - height: BI.toPix(o.height, 2), - el: { - type: "bi.down_list_select_text_trigger", - ref: function (_ref) { - self.trigger = _ref; - }, - cls: "text-value-down-list-trigger", - height: BI.toPix(o.height, 2), - items: o.items, - text: o.text, - value: value - }, - value: BI.isNull(value) ? [] : [value], - items: BI.deepClone(o.items) - }); - - this.combo.on(BI.DownListCombo.EVENT_CHANGE, function () { - var currentVal = self.combo.getValue()[0].value; - if (currentVal !== self.value) { - self.setValue(currentVal); - self.fireEvent(BI.TextValueDownListCombo.EVENT_CHANGE); - } - }); - - this.combo.on(BI.DownListCombo.EVENT_SON_VALUE_CHANGE, function () { - var currentVal = self.combo.getValue()[0].childValue; - if (currentVal !== self.value) { - self.setValue(currentVal); - self.fireEvent(BI.TextValueDownListCombo.EVENT_CHANGE); - } - }); - }, - - _createValueMap: function () { - var self = this; - this.valueMap = {}; - BI.each(BI.flatten(this.options.items), function (idx, item) { - if (BI.has(item, "el")) { - BI.each(item.children, function (id, it) { - self.valueMap[it.value] = {value: item.el.value, childValue: it.value}; - }); - } else { - self.valueMap[item.value] = {value: item.value}; - } - }); - }, - - _digest: function (v) { - this.value = v; - return this.valueMap[v]; - }, - - setValue: function (v) { - v = this._digest(v); - this.combo.setValue([v]); - this.trigger?.setValue(v); - }, - - getValue: function () { - var v = this.combo.getValue()[0]; - return [v.childValue || v.value]; - }, - - populate: function (items) { - this.options.items = BI.flatten(items); - this.combo.populate(items); - this._createValueMap(); - } -}); -BI.TextValueDownListCombo.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.text_value_down_list_combo", BI.TextValueDownListCombo); diff --git a/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js b/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js deleted file mode 100644 index b335ce5c1..000000000 --- a/src/widget/textvaluedownlistcombo/trigger.textvaluedownlist.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * 选择字段trigger, downlist专用 - * 显示形式为 父亲值(儿子值) - * - * @class BI.DownListSelectTextTrigger - * @extends BI.Trigger - */ -BI.DownListSelectTextTrigger = BI.inherit(BI.Trigger, { - - _defaultConfig: function () { - return BI.extend(BI.DownListSelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-down-list-select-text-trigger", - height: 24, - text: "" - }); - }, - - _init: function () { - BI.DownListSelectTextTrigger.superclass._init.apply(this, arguments); - var o = this.options; - this.trigger = BI.createWidget({ - type: "bi.select_text_trigger", - element: this, - height: o.height, - items: this._formatItemArray(o.items), - text: o.text, - value: BI.isNull(o.value) ? "" : o.value.childValue || o.value.value - }); - }, - - _formatItemArray: function () { - var sourceArray = BI.flatten(BI.deepClone(this.options.items)); - var targetArray = []; - BI.each(sourceArray, function (idx, item) { - if(BI.has(item, "el")) { - BI.each(item.children, function (id, it) { - it.text = item.el.text + "(" + it.text + ")"; - }); - targetArray = BI.concat(targetArray, item.children); - }else{ - targetArray.push(item); - } - }); - return targetArray; - }, - - setValue: function (vals) { - this.trigger.setValue(vals.childValue || vals.value); - }, - - populate: function (items) { - this.trigger.populate(this._formatItemArray(items)); - } -}); -BI.shortcut("bi.down_list_select_text_trigger", BI.DownListSelectTextTrigger); \ No newline at end of file diff --git a/src/widget/time/datetime.popup.js b/src/widget/time/datetime.popup.js deleted file mode 100644 index 39c5e753d..000000000 --- a/src/widget/time/datetime.popup.js +++ /dev/null @@ -1,94 +0,0 @@ -!(function () { - BI.TimePopup = BI.inherit(BI.Widget, { - props: { - baseCls: "bi-date-time-popup", - height: 68 - }, - render: function () { - var self = this, o = this.options; - - return { - type: "bi.vtape", - items: [{ - el: { - type: "bi.center_adapt", - cls: "bi-split-top", - items: [{ - type: "bi.dynamic_date_time_select", - value: o.value, - ref: function (_ref) { - self.timeSelect = _ref; - } - }] - }, - hgap: 10, - height: 44 - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - shadow: true, - text: BI.i18nText("BI-Basic_Clears"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.TimePopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - shadow: true, - text: BI.i18nText("BI-Basic_Now"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.TimePopup.BUTTON_NOW_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-high-light bi-split-top", - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.TimePopup.BUTTON_OK_EVENT_CHANGE); - } - }] - }]] - }, - height: 24 - }] - }; - }, - - setValue: function (value) { - if (this._checkValueValid(value)) { - this.timeSelect.setValue(); - } else { - this.timeSelect.setValue({ - hour: value.hour, - minute: value.minute, - second: value.second - }); - } - }, - - getValue: function () { - return this.timeSelect.getValue(); - }, - - _checkValueValid: function (value) { - return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); - } - }); - BI.TimePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; - BI.TimePopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; - BI.TimePopup.BUTTON_NOW_EVENT_CHANGE = "BUTTON_NOW_EVENT_CHANGE"; - BI.TimePopup.CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; - BI.shortcut("bi.time_popup", BI.TimePopup); -})(); \ No newline at end of file diff --git a/src/widget/time/time.combo.js b/src/widget/time/time.combo.js deleted file mode 100644 index 6f3f8947d..000000000 --- a/src/widget/time/time.combo.js +++ /dev/null @@ -1,247 +0,0 @@ -/** - * 时间选择 - * qcc - * 2019/2/28 - */ - -!(function () { - BI.TimeCombo = BI.inherit(BI.Single, { - constants: { - popupHeight: 80, - popupWidth: 240, - comboAdjustHeight: 1, - border: 1, - iconWidth: 24 - }, - props: { - baseCls: "bi-time-combo", - height: 24, - format: "", - allowEdit: false, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false - }, - - _init: function () { - var o = this.options; - BI.TimeCombo.superclass._init.apply(this, arguments); - }, - - render: function () { - var self = this, opts = this.options; - this.storeTriggerValue = ""; - this.storeValue = opts.value; - - var popup = { - type: "bi.time_popup", - value: opts.value, - listeners: [{ - eventName: BI.TimePopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.hidePopupView(); - self.fireEvent(BI.TimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.TimePopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.hidePopupView(); - self.fireEvent(BI.TimeCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.TimePopup.BUTTON_NOW_EVENT_CHANGE, - action: function () { - self._setNowTime(); - } - }], - ref: function (_ref) { - self.popup = _ref; - } - }; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.combo", - cls: "bi-border bi-border-radius", - container: opts.container, - toggle: false, - isNeedAdjustHeight: opts.isNeedAdjustHeight, - isNeedAdjustWidth: opts.isNeedAdjustWidth, - el: { - type: "bi.horizontal_fill", - columnSize: ["fill", this.constants.iconWidth], - height: BI.toPix(opts.height, 2), - items: [{ - type: "bi.time_trigger", - height: BI.toPix(opts.height, 2), - allowEdit: opts.allowEdit, - watermark: opts.watermark, - format: opts.format, - value: opts.value, - ref: function (_ref) { - self.trigger = _ref; - }, - listeners: [{ - eventName: "EVENT_KEY_DOWN", - action: function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } - self.fireEvent(BI.TimeCombo.EVENT_KEY_DOWN, arguments); - } - }, { - eventName: "EVENT_STOP", - action: function () { - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - } - }, { - eventName: "EVENT_FOCUS", - action: function () { - self.storeTriggerValue = self.trigger.getKey(); - if (!self.combo.isViewVisible()) { - self.combo.showView(); - } - self.fireEvent("EVENT_FOCUS"); - } - }, { - eventName: "EVENT_BLUR", - action: function () { - self.fireEvent("EVENT_BLUR"); - } - }, { - eventName: "EVENT_ERROR", - action: function () { - var date = BI.getDate(); - self.storeValue = { - hour: date.getHours(), - minute: date.getMinutes(), - second: date.getSeconds() - }; - self.fireEvent("EVENT_ERROR"); - } - }, { - eventName: "EVENT_VALID", - action: function () { - self.fireEvent("EVENT_VALID"); - } - }, { - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_CONFIRM", - action: function () { - if (self.combo.isViewVisible()) { - return; - } - var dateStore = self.storeTriggerValue; - var dateObj = self.trigger.getKey(); - if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.trigger.getValue()); - } else if (BI.isEmptyString(dateObj)) { - self.storeValue = null; - self.trigger.setValue(); - } - self.fireEvent("EVENT_CONFIRM"); - } - }] - }, { - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button time-font", - width: this.constants.iconWidth, - listeners: [{ - eventName: BI.IconButton.EVENT_CHANGE, - action: function () { - if (self.combo.isViewVisible()) { - // self.combo.hideView(); - } else { - self.combo.showView(); - } - } - }], - ref: function (_ref) { - self.triggerBtn = _ref; - } - }, - }], - }, - adjustLength: this.constants.comboAdjustHeight, - popup: { - el: popup, - width: opts.isNeedAdjustWidth ? opts.width : this.constants.popupWidth, - stopPropagation: false - }, - hideChecker: function (e) { - return self.triggerBtn.element.find(e.target).length === 0; - }, - listeners: [{ - eventName: BI.Combo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.popup.setValue(self.storeValue); - self.fireEvent(BI.TimeCombo.EVENT_BEFORE_POPUPVIEW); - } - }], - ref: function (_ref) { - self.combo = _ref; - } - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - }] - }; - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - }, - getValue: function () { - return this.storeValue; - }, - - hidePopupView: function () { - this.combo.hideView(); - }, - - _setNowTime: function () { - var date = BI.getDate(); - var nowTome = { - hour: date.getHours(), - minute: date.getMinutes(), - second: date.getSeconds() - }; - this.setValue(nowTome); - this.hidePopupView(); - this.fireEvent(BI.TimeCombo.EVENT_CONFIRM); - }, - - focus: function () { - this.trigger.focus(); - }, - - blur: function () { - this.trigger.blur(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } - }); - - BI.TimeCombo.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; - BI.TimeCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; - BI.TimeCombo.EVENT_CHANGE = "EVENT_CHANGE"; - BI.TimeCombo.EVENT_VALID = "EVENT_VALID"; - BI.TimeCombo.EVENT_ERROR = "EVENT_ERROR"; - BI.TimeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; - BI.shortcut("bi.time_combo", BI.TimeCombo); -})(); \ No newline at end of file diff --git a/src/widget/time/time.trigger.js b/src/widget/time/time.trigger.js deleted file mode 100644 index a15235cf4..000000000 --- a/src/widget/time/time.trigger.js +++ /dev/null @@ -1,202 +0,0 @@ -!(function () { - BI.TimeTrigger = BI.inherit(BI.Trigger, { - - _const: { - COMPARE_FORMAT: "%H:%M:%S", - COMPLETE_COMPARE_FORMAT: "%Y-%M-%d %H:%M:%S %P", - FORMAT_ARRAY: [ - "%H:%M:%S", // HH:mm:ss - "%I:%M:%S", // hh:mm:ss - "%l:%M:%S", // h:mm:ss - "%k:%M:%S", // H:mm:ss - "%l:%M:%S %p", // h:mm:ss a - "%l:%M:%S %P", // h:mm:ss a - "%H:%M:%S %p", // HH:mm:ss a - "%H:%M:%S %P", // HH:mm:ss a - "%l:%M", // h:mm - "%k:%M", // H:mm - "%I:%M", // hh:mm - "%H:%M", // HH:mm - "%M:%S" // mm:ss - ], - DEFAULT_DATE_STRING: "2000-01-01", - DEFAULT_HOUR: "00" - }, - - props: () => ({ - extraCls: "bi-time-trigger", - value: {}, - format: "", - allowEdit: false, - watermark: BI.i18nText("BI-Basic_Unrestricted"), - }), - - render: function () { - var self = this, o = this.options; - this.storeTriggerValue = ""; - this.storeValue = o.value; - return { - type: "bi.absolute", - items: [{ - el: { - type: "bi.sign_editor", - height: o.height, - validationChecker: function (v) { - return self._dateCheck(v); - }, - quitChecker: function () { - return false; - }, - ref: function (_ref) { - self.editor = _ref; - }, - value: this._formatValue(o.value), - hgap: 4, - allowBlank: true, - watermark: o.watermark, - title: BI.bind(this._getTitle, this), - listeners: [{ - eventName: "EVENT_KEY_DOWN", - action: function () { - self.fireEvent("EVENT_KEY_DOWN", arguments); - } - }, { - eventName: "EVENT_FOCUS", - action: function () { - self.storeTriggerValue = self.getKey(); - self.fireEvent("EVENT_FOCUS"); - } - }, { - eventName: "EVENT_BLUR", - action: function () { - self.fireEvent("EVENT_BLUR"); - } - }, { - eventName: "EVENT_STOP", - action: function () { - self.fireEvent("EVENT_STOP"); - } - }, { - eventName: "EVENT_VALID", - action: function () { - self.fireEvent("EVENT_VALID"); - } - }, { - eventName: "EVENT_ERROR", - action: function () { - self.fireEvent("EVENT_ERROR"); - } - }, { - eventName: "EVENT_CONFIRM", - action: function () { - var value = self.editor.getValue(); - if (BI.isNotNull(value)) { - self.editor.setState(value); - } - if (BI.isNotEmptyString(value) && !BI.isEqual(self.storeTriggerValue, self.getKey())) { - var date = value.match(/\d+/g); - self.storeValue = { - hour: date[0] | 0, - minute: date[1] | 0, - second: date[2] | 0 - }; - } - self.fireEvent("EVENT_CONFIRM"); - } - }, { - eventName: "EVENT_START", - action: function () { - self.fireEvent("EVENT_START"); - } - }, { - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }] - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }, { - el: { - type: "bi.text", - invisible: o.allowEdit, - cls: "show-text", - title: BI.bind(this._getTitle, this), - hgap: 4 - }, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] - }; - }, - - _dateCheck: function (date) { - var c = this._const; - var self = this; - return BI.any(c.FORMAT_ARRAY, function (idx, format) { - return BI.print(BI.parseDateTime(c.DEFAULT_DATE_STRING + " " + self._getCompleteHMS(date, format), c.COMPLETE_COMPARE_FORMAT), format) === date; - }); - }, - - _getCompleteHMS: function (str, format) { - var c = this._const; - switch (format) { - case "%M:%S": - str = c.DEFAULT_HOUR + ":" + str; - break; - default: - break; - } - return str; - }, - - _getTitle: function () { - var storeValue = this.storeValue || {}; - if (BI.isEmptyObject(storeValue)) { - return this.options.watermark; - } - var date = BI.getDate(); - return BI.print(BI.getDate(date.getFullYear(), 0, 1, storeValue.hour, storeValue.minute, storeValue.second), this._getFormatString()); - }, - - _getFormatString: function () { - return this.options.format || this._const.COMPARE_FORMAT; - }, - - _formatValue: function (v) { - var now = BI.getDate(); - return BI.isNotEmptyObject(v) ? BI.print(BI.getDate(now.getFullYear(), now.getMonth(), now.getDay(), v.hour, v.minute, v.second), this._getFormatString()) : ""; - }, - - getKey: function () { - return this.editor.getValue(); - }, - - setValue: function (v) { - this.storeValue = v; - this.editor.setValue(this._formatValue(v)); - }, - - getValue: function () { - return this.storeValue; - }, - - focus: function () { - this.editor.focus(); - }, - - blur: function () { - this.editor.blur(); - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } - }); - BI.shortcut("bi.time_trigger", BI.TimeTrigger); -})(); diff --git a/src/widget/timeinterval/dateinterval.js b/src/widget/timeinterval/dateinterval.js deleted file mode 100644 index 98e27e3ce..000000000 --- a/src/widget/timeinterval/dateinterval.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Created by Baron on 2015/10/19. - */ -BI.DateInterval = BI.inherit(BI.Single, { - constants: { - height: 24, - width: 24, - lgap: 15, - offset: 0, - timeErrorCls: "time-error" - }, - _defaultConfig: function () { - var conf = BI.DateInterval.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-date-interval", - minDate: "1900-01-01", - maxDate: "2099-12-31", - height: 24, - supportDynamic: true, - simple: false, - }); - }, - - render: function () { - var self = this, o = this.options; - o.value = o.value || {}; - this.left = this._createCombo(o.value.start, o.watermark?.start); - this.right = this._createCombo(o.value.end, o.watermark?.end); - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: self.right - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this, o = this.options; - var combo = BI.createWidget({ - type: "bi.dynamic_date_combo", - supportDynamic: o.supportDynamic, - minDate: o.minDate, - maxDate: o.maxDate, - simple: o.simple, - behaviors: o.behaviors, - watermark: watermark, - value: v, - height: o.height, - listeners: [{ - eventName: BI.DynamicDateCombo.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW, - action: function () { - self.fireEvent(BI.DateInterval.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW); - } - }] - }); - combo.on(BI.DynamicDateCombo.EVENT_ERROR, function () { - self._clearTitle(); - BI.Bubbles.hide("error"); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.DateInterval.EVENT_ERROR); - }); - - combo.on(BI.DynamicDateCombo.EVENT_VALID, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.DateInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }); - - combo.on(BI.DynamicDateCombo.EVENT_FOCUS, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.DateInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }); - - // combo.on(BI.DynamicDateCombo.EVENT_BEFORE_POPUPVIEW, function () { - // self.left.hidePopupView(); - // self.right.hidePopupView(); - // }); - - combo.on(BI.DynamicDateCombo.EVENT_CONFIRM, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - self.fireEvent(BI.DateInterval.EVENT_ERROR); - }else{ - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.DateInterval.EVENT_CHANGE); - } - }); - return combo; - }, - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date || - BI.print(BI.parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date; - }, - _checkVoid: function (obj) { - var o = this.options; - return !BI.checkDateVoid(obj.year, obj.month, obj.day, o.minDate, o.maxDate)[0]; - }, - _check: function (smallDate, bigDate) { - var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); - return this._dateCheck(smallDate) && BI.checkDateLegal(smallDate) && this._checkVoid({ - year: smallObj[0], - month: smallObj[1], - day: smallObj[2] - }) && this._dateCheck(bigDate) && BI.checkDateLegal(bigDate) && this._checkVoid({ - year: bigObj[0], - month: bigObj[1], - day: bigObj[2] - }); - }, - _compare: function (smallDate, bigDate) { - smallDate = BI.print(BI.parseDateTime(smallDate, "%Y-%X-%d"), "%Y-%X-%d"); - bigDate = BI.print(BI.parseDateTime(bigDate, "%Y-%X-%d"), "%Y-%X-%d"); - return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; - }, - _setTitle: function (v) { - this.left.setTitle(v); - this.right.setTitle(v); - this.label.setTitle(v); - }, - _clearTitle: function () { - this.left.setTitle(""); - this.right.setTitle(""); - this.label.setTitle(""); - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.left.setMinDate(minDate); - this.right.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.left.setMaxDate(maxDate); - this.right.setMaxDate(maxDate); - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } -}); -BI.DateInterval.EVENT_VALID = "EVENT_VALID"; -BI.DateInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.DateInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.DateInterval.EVENT_BEFORE_YEAR_MONTH_POPUPVIEW = "EVENT_BEFORE_YEAR_MONTH_POPUPVIEW"; -BI.shortcut("bi.date_interval", BI.DateInterval); diff --git a/src/widget/timeinterval/timeinterval.js b/src/widget/timeinterval/timeinterval.js deleted file mode 100644 index c22c8e14e..000000000 --- a/src/widget/timeinterval/timeinterval.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Created by Baron on 2015/10/19. - */ -BI.TimeInterval = BI.inherit(BI.Single, { - constants: { - height: 24, - width: 24, - lgap: 15, - offset: 0, - timeErrorCls: "time-error" - }, - _defaultConfig: function () { - var conf = BI.TimeInterval.superclass._defaultConfig.apply(this, arguments); - return BI.extend(conf, { - extraCls: "bi-time-interval", - minDate: "1900-01-01", - maxDate: "2099-12-31", - height: 24, - supportDynamic: true - }); - }, - - render: function () { - var self = this, o = this.options; - o.value = o.value || {}; - this.left = this._createCombo(o.value.start, o.watermark?.start); - this.right = this._createCombo(o.value.end, o.watermark?.end); - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: self.right - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this, o = this.options; - var combo = BI.createWidget({ - type: "bi.dynamic_date_time_combo", - simple: o.simple, - supportDynamic: o.supportDynamic, - minDate: o.minDate, - maxDate: o.maxDate, - behaviors: o.behaviors, - watermark: watermark, - value: v, - height: o.height, - }); - combo.on(BI.DynamicDateTimeCombo.EVENT_ERROR, function () { - self._clearTitle(); - BI.Bubbles.hide("error"); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.TimeInterval.EVENT_ERROR); - }); - - combo.on(BI.DynamicDateTimeCombo.EVENT_VALID, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.TimeInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }); - - combo.on(BI.DynamicDateTimeCombo.EVENT_FOCUS, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.TimeInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }); - - // 不知道干啥的,先注释掉 - // combo.on(BI.DynamicDateTimeCombo.EVENT_BEFORE_POPUPVIEW, function () { - // self.left.hidePopupView(); - // self.right.hidePopupView(); - // }); - - combo.on(BI.DynamicDateTimeCombo.EVENT_CONFIRM, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - self.fireEvent(BI.TimeInterval.EVENT_ERROR); - }else{ - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.TimeInterval.EVENT_CHANGE); - } - }); - return combo; - }, - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%x-%d %H:%M:%S"), "%Y-%x-%d %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%x-%e %H:%M:%S"), "%Y-%x-%e %H:%M:%S") === date || - BI.print(BI.parseDateTime(date, "%Y-%X-%e %H:%M:%S"), "%Y-%X-%e %H:%M:%S") === date; - }, - _checkVoid: function (obj) { - var o = this.options; - return !BI.checkDateVoid(obj.year, obj.month, obj.day, o.minDate, o.maxDate)[0]; - }, - _check: function (smallDate, bigDate) { - var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); - return this._dateCheck(smallDate) && BI.checkDateLegal(smallDate) && this._checkVoid({ - year: smallObj[0], - month: smallObj[1], - day: smallObj[2] - }) && this._dateCheck(bigDate) && BI.checkDateLegal(bigDate) && this._checkVoid({ - year: bigObj[0], - month: bigObj[1], - day: bigObj[2] - }); - }, - _compare: function (smallDate, bigDate) { - smallDate = BI.print(BI.parseDateTime(smallDate, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S"); - bigDate = BI.print(BI.parseDateTime(bigDate, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S"); - return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; - }, - _setTitle: function (v) { - this.left.setTitle(v); - this.right.setTitle(v); - this.label.setTitle(v); - }, - _clearTitle: function () { - this.left.setTitle(""); - this.right.setTitle(""); - this.label.setTitle(""); - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.left.setMinDate(minDate); - this.right.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.left.setMaxDate(maxDate); - this.right.setMaxDate(maxDate); - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } -}); -BI.TimeInterval.EVENT_VALID = "EVENT_VALID"; -BI.TimeInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.TimeInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.time_interval", BI.TimeInterval); diff --git a/src/widget/timeinterval/timeperiods.js b/src/widget/timeinterval/timeperiods.js deleted file mode 100644 index a8bb9e60b..000000000 --- a/src/widget/timeinterval/timeperiods.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * 时间区间 - * qcc - * 2019/2/28 - */ - -!(function () { - BI.TimePeriods = BI.inherit(BI.Single, { - constants: { - height: 24, - width: 24, - hgap: 15, - offset: -15 - }, - props: { - extraCls: "bi-time-interval", - value: {} - }, - - render: function () { - var self = this, o = this.options; - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: BI.extend({ - ref: function (_ref) { - self.left = _ref; - } - }, this._createCombo(o.value.start, o.watermark?.start)) - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: BI.extend({ - ref: function (_ref) { - self.right = _ref; - } - }, this._createCombo(o.value.end, o.watermark?.end)) - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this; - var o = this.options; - return { - type: "bi.time_combo", - value: v, - height: o.height, - watermark: watermark, - listeners: [{ - eventName: BI.TimeCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.left.hidePopupView(); - self.right.hidePopupView(); - } - }, { - eventName: BI.TimeCombo.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.TimePeriods.EVENT_CHANGE); - } - }, { - eventName: BI.TimeCombo.EVENT_CONFIRM, - action: function () { - self.fireEvent(BI.TimePeriods.EVENT_CONFIRM); - } - }] - }; - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } - }); - BI.TimePeriods.EVENT_CONFIRM = "EVENT_CONFIRM"; - BI.TimePeriods.EVENT_CHANGE = "EVENT_CHANGE"; - BI.shortcut("bi.time_periods", BI.TimePeriods); -})(); diff --git a/src/widget/year/card.dynamic.year.js b/src/widget/year/card.dynamic.year.js deleted file mode 100644 index b38d55119..000000000 --- a/src/widget/year/card.dynamic.year.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * 年份展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.YearCard - * @extends BI.Trigger - */ -BI.DynamicYearCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-year-card" - }, - - render: function () { - var self = this, o = this.options; - return { - type: "bi.vertical", - ref: function (_ref) { - self.wrapper = _ref; - }, - items: [{ - type: "bi.label", - text: BI.i18nText("BI-Multi_Date_Relative_Current_Time"), - textAlign: "left", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }, { - type: "bi.dynamic_date_param_item", - ref: function () { - self.item = this; - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-year-error"); - } - }] - }], - vgap: 10, - hgap: 10 - }; - }, - - _checkDate: function (obj) { - var o = this.options; - var date = BI.DynamicDateHelper.getCalculation(this._getValue()); - - return !BI.checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; - }, - - _createValue: function (type, v) { - return { - dateType: type, - value: Math.abs(v), - offset: v > 0 ? 1 : 0 - }; - }, - - _getErrorText: function () { - var o = this.options; - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - return BI.i18nText("BI-Basic_Year_Range_Error", - start.getFullYear(), - end.getFullYear()); - }, - - setMinDate: function(minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - v = v || {year: 0}; - this.item.setValue(this._createValue(BI.DynamicDateCard.TYPE.YEAR, v.year)); - }, - - _getValue: function () { - var value = this.item.getValue(); - return { - year: (value.offset === 0 ? -value.value : +value.value) - }; - }, - - getInputValue: function () { - return this._getValue(); - }, - - getValue: function () { - return this.checkValidation() ? this._getValue() : {}; - }, - - checkValidation: function (show) { - var errorText; - var invalid = !this.item.checkValidation(); - if (invalid) { - errorText = BI.i18nText("BI-Please_Input_Natural_Number"); - } else { - invalid = !this._checkDate(this._getValue()); - errorText = this._getErrorText(); - } - invalid && show && BI.Bubbles.show("dynamic-year-error", errorText, this.item); - - return !invalid; - }, -}); -BI.DynamicYearCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_card", BI.DynamicYearCard); \ No newline at end of file diff --git a/src/widget/year/card.year.js b/src/widget/year/card.year.js deleted file mode 100644 index b747d104b..000000000 --- a/src/widget/year/card.year.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * 年份展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.StaticYearCard - * @extends BI.Trigger - */ -BI.StaticYearCard = BI.inherit(BI.Widget, { - - _defaultConfig: function () { - return BI.extend(BI.StaticYearCard.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-year-card", - behaviors: {}, - min: "1900-01-01", // 最小日期 - max: "2099-12-31" // 最大日期 - }); - }, - - _createYearCalendar: function (v) { - var o = this.options, y = this._year; - - var calendar = BI.createWidget({ - type: "bi.year_calendar", - behaviors: o.behaviors, - min: o.min, - max: o.max, - logic: { - dynamic: true - }, - year: y + v * 12 - }); - calendar.setValue(this._year); - return calendar; - }, - - _init: function () { - BI.StaticYearCard.superclass._init.apply(this, arguments); - var self = this, o = this.options; - - this.selectedYear = this._year = BI.getDate().getFullYear(); - - this.backBtn = BI.createWidget({ - type: "bi.icon_button", - cls: "pre-page-h-font", - width: 25, - height: 25, - value: -1, - listeners: [{ - eventName: BI.IconButton.EVENT_CHANGE, - action: function () { - self.navigation.setSelect(self.navigation.getSelect() - 1); - self._checkLeftValid(); - self._checkRightValid(); - } - }] - }); - - this.preBtn = BI.createWidget({ - type: "bi.icon_button", - cls: "next-page-h-font", - width: 25, - height: 25, - value: 1, - listeners: [{ - eventName: BI.IconButton.EVENT_CHANGE, - action: function () { - self.navigation.setSelect(self.navigation.getSelect() + 1); - self._checkLeftValid(); - self._checkRightValid(); - } - }] - }); - - this.navigation = BI.createWidget({ - type: "bi.navigation", - direction: "top", - element: this, - single: true, - logic: { - dynamic: true - }, - tab: { - type: "bi.htape", - cls: "bi-split-top bi-split-bottom", - height: 30, - items: [{ - el: { - type: "bi.center_adapt", - items: [self.backBtn] - }, - width: 25 - }, { - type: "bi.layout" - }, { - el: { - type: "bi.center_adapt", - items: [self.preBtn] - }, - width: 25 - }] - }, - cardCreator: BI.bind(this._createYearCalendar, this), - - afterCardShow: function () { - this.setValue(self.selectedYear); - // var calendar = this.getSelectedCard(); - // self.backBtn.setEnable(!calendar.isFrontYear()); - // self.preBtn.setEnable(!calendar.isFinalYear()); - } - }); - - this.navigation.on(BI.Navigation.EVENT_CHANGE, function () { - self.selectedYear = this.getValue(); - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - self.fireEvent(BI.StaticYearCard.EVENT_CHANGE, self.selectedYear); - }); - - if(BI.isKey(o.value)){ - this.setValue(o.value); - } - }, - - _checkLeftValid: function () { - var o = this.options; - var valid = true; - this.backBtn.setEnable(valid); - return valid; - }, - - _checkRightValid: function () { - var o = this.options; - var valid = true; - this.preBtn.setEnable(valid); - return valid; - }, - - _checkMin: function () { - var o = this.options; - BI.each(this.navigation.getAllCard(), function (idx, calendar) { - calendar.setMinDate(o.min); - }); - }, - - _checkMax: function () { - var o = this.options; - BI.each(this.navigation.getAllCard(), function (idx, calendar) { - calendar.setMaxDate(o.max); - }); - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - this._checkLeftValid(); - this._checkRightValid(); - this._checkMin(); - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - this._checkLeftValid(); - this._checkRightValid(); - this._checkMax(); - } - }, - - getValue: function () { - return { - year: this.selectedYear - }; - }, - - setValue: function (obj) { - var o = this.options; - obj = obj || {}; - var v = obj.year; - if (BI.checkDateVoid(v, 1, 1, o.min, o.max)[0]) { - v = BI.getDate().getFullYear(); - this.selectedYear = ""; - this.navigation.setSelect(BI.YearCalendar.getPageByYear(v)); - this.navigation.setValue(""); - } else { - this.selectedYear = BI.parseInt(v); - this.navigation.setSelect(BI.YearCalendar.getPageByYear(v)); - this.navigation.setValue(this.selectedYear); - } - this._checkLeftValid(); - this._checkRightValid(); - } -}); -BI.StaticYearCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.static_year_card", BI.StaticYearCard); \ No newline at end of file diff --git a/src/widget/year/combo.year.js b/src/widget/year/combo.year.js deleted file mode 100644 index d2d68d19b..000000000 --- a/src/widget/year/combo.year.js +++ /dev/null @@ -1,227 +0,0 @@ -BI.DynamicYearCombo = BI.inherit(BI.Widget, { - - _const: { - iconWidth: 24 - }, - - props: { - baseCls: "bi-year-combo", - behaviors: {}, - minDate: "1900-01-01", // 最小日期 - maxDate: "2099-12-31", // 最大日期 - height: 24, - supportDynamic: true - }, - - _init: function () { - var self = this, o = this.options; - BI.DynamicYearCombo.superclass._init.apply(this, arguments); - this.storeValue = o.value; - var border = o.simple ? 1 : 2; - this.trigger = BI.createWidget({ - type: "bi.dynamic_year_trigger", - simple: o.simple, - min: o.minDate, - max: o.maxDate, - height: BI.toPix(o.height, border), - value: o.value || "", - watermark: o.watermark - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_KEY_DOWN, function () { - if (self.combo.isViewVisible()) { - self.combo.hideView(); - } - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_FOCUS, function () { - self.storeTriggerValue = this.getKey(); - self.fireEvent(BI.DynamicYearCombo.EVENT_FOCUS); - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_START, function () { - self.combo.isViewVisible() && self.combo.hideView(); - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_STOP, function () { - self.combo.showView(); - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_ERROR, function () { - self.combo.isViewVisible() && self.combo.hideView(); - self.comboWrapper.element.addClass("error"); - self.fireEvent(BI.DynamicYearCombo.EVENT_ERROR); - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_VALID, function () { - self.comboWrapper.element.removeClass("error"); - self.fireEvent(BI.DynamicYearCombo.EVENT_VALID); - }); - this.trigger.on(BI.DynamicYearTrigger.EVENT_CONFIRM, function () { - if (self.combo.isViewVisible()) { - return; - } - if (this.getKey() && this.getKey() !== self.storeTriggerValue) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.storeValue); - } else if (!this.getKey()) { - self.storeValue = null; - self.setValue(); - } - self._checkDynamicValue(self.storeValue); - self.fireEvent(BI.DynamicYearCombo.EVENT_CONFIRM); - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - container: o.container, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false, - el: this.trigger, - destroyWhenHide: true, - adjustLength: 1, - popup: { - minWidth: 85, - stopPropagation: false, - el: { - type: "bi.dynamic_year_popup", - supportDynamic: o.supportDynamic, - ref: function () { - self.popup = this; - }, - listeners: [{ - eventName: BI.DynamicYearPopup.EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearPopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearPopup.BUTTON_lABEL_EVENT_CHANGE, - action: function () { - var date = BI.getDate(); - self.setValue({ type: BI.DynamicYearCombo.Static, value: { year: date.getFullYear() } }); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearPopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }], - behaviors: o.behaviors, - min: o.minDate, - max: o.maxDate - }, - value: o.value || "" - } - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.popup.setMinDate(o.minDate); - self.popup.setMaxDate(o.maxDate); - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DynamicYearCombo.EVENT_BEFORE_POPUPVIEW); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: { - type: "bi.horizontal_fill", - columnSize: ["", "fill"], - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - ref: function () { - self.comboWrapper = this; - }, - items: [{ - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-change-h-font", - width: this._const.iconWidth, - height: BI.toPix(o.height, border), - ref: function () { - self.changeIcon = this; - } - }, - }, this.combo] - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - }] - }); - this._checkDynamicValue(o.value); - }, - - _checkDynamicValue: function (v) { - var type = null; - if (BI.isNotNull(v)) { - type = v.type; - } - switch (type) { - case BI.DynamicYearCombo.Dynamic: - this.changeIcon.setVisible(true); - break; - default: - this.changeIcon.setVisible(false); - break; - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.trigger.setMinDate(minDate); - this.popup && this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.trigger.setMaxDate(maxDate); - this.popup && this.popup.setMaxDate(maxDate); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getKey: function () { - return this.trigger.getKey() + ""; - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - this._checkDynamicValue(v); - }, - - getValue: function () { - return this.storeValue; - }, - - isStateValid: function () { - return this.trigger.isValid(); - }, - - setWaterMark: function (v) { - this.trigger.setWaterMark(v); - } -}); -BI.DynamicYearCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.DynamicYearCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearCombo.EVENT_VALID = "EVENT_VALID"; -BI.DynamicYearCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.shortcut("bi.dynamic_year_combo", BI.DynamicYearCombo); - -BI.extend(BI.DynamicYearCombo, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/year/popup.year.js b/src/widget/year/popup.year.js deleted file mode 100644 index 2e6d4b952..000000000 --- a/src/widget/year/popup.year.js +++ /dev/null @@ -1,246 +0,0 @@ -/** - * 年份展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.DynamicYearPopup - * @extends BI.Trigger - */ -BI.DynamicYearPopup = BI.inherit(BI.Widget, { - constants: { - tabHeight: 40, - }, - - props: { - baseCls: "bi-dynamic-year-popup", - behaviors: {}, - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期, - width: 180, - supportDynamic: true, - }, - - render: function () { - var self = this, opts = this.options, c = this.constants; - this.storeValue = {type: BI.DynamicYearCombo.Static}; - return { - type: "bi.vertical", - items: [{ - el: this._getTabJson() - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearPopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - shadow: true, - text: BI.i18nText("BI-Basic_Current_Year"), - disabled: this._checkTodayValid(), - ref: function () { - self.yearButton = this; - }, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearPopup.BUTTON_lABEL_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicYearPopup.BUTTON_OK_EVENT_CHANGE); - } - } - }] - }]], - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - }, - }] - }; - }, - - _setInnerValue: function () { - if (this.dateTab.getSelect() === BI.DynamicDateCombo.Static) { - this.yearButton.setValue(BI.i18nText("BI-Basic_Current_Year")); - this.yearButton.setEnable(!this._checkYearValid()); - } else { - var date = BI.DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); - date = BI.print(date, "%Y"); - this.yearButton.setValue(date); - this.yearButton.setEnable(false); - } - }, - - _checkYearValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - _getTabJson: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - logic: { - dynamic: true - }, - ref: function () { - self.dateTab = this; - }, - tab: { - type: "bi.linear_segment", - invisible: !o.supportDynamic, - height: this.constants.tabHeight, - items: BI.createItems([{ - text: BI.i18nText("BI-Basic_Year_Fen"), - value: BI.DynamicYearCombo.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicYearCombo.Dynamic - }], { - textAlign: "center" - }) - }, - cardCreator: function (v) { - switch (v) { - case BI.DynamicYearCombo.Dynamic: - return { - type: "bi.dynamic_year_card", - cls: "dynamic-year-pane", - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self._setInnerValue(self.year, v); - } - }], - ref: function () { - self.dynamicPane = this; - } - }; - case BI.DynamicYearCombo.Static: - default: - return { - type: "bi.static_year_card", - behaviors: o.behaviors, - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: BI.StaticYearCard.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearPopup.EVENT_CHANGE); - } - }], - ref: function () { - self.year = this; - } - }; - } - }, - listeners: [{ - eventName: BI.Tab.EVENT_CHANGE, - action: function () { - var v = self.dateTab.getSelect(); - switch (v) { - case BI.DynamicYearCombo.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.year.setValue({year: date.getFullYear()}); - self._setInnerValue(); - break; - case BI.DynamicYearCombo.Dynamic: - default: - if(self.storeValue && self.storeValue.type === BI.DynamicYearCombo.Dynamic) { - self.dynamicPane.setValue(self.storeValue.value); - }else{ - self.dynamicPane.setValue({ - year: 0 - }); - } - self._setInnerValue(); - break; - } - } - }] - }; - }, - - _checkTodayValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.year && this.year.setMinDate(minDate); - this.dynamicPane && this.dynamicPane.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.year && this.year.setMaxDate(maxDate); - this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - this.storeValue = v; - var self = this; - var type, value; - v = v || {}; - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Static: - default: - this.year.setValue(value); - this.yearButton.setValue(BI.i18nText("BI-Basic_Current_Year")); - this.yearButton.setEnable(!this._checkTodayValid()); - break; - } - }, - - getValue: function () { - return { - type: this.dateTab.getSelect(), - value: this.dateTab.getValue() - }; - } - -}); -BI.DynamicYearPopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; -BI.DynamicYearPopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; -BI.DynamicYearPopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DynamicYearPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_popup", BI.DynamicYearPopup); diff --git a/src/widget/year/trigger.year.js b/src/widget/year/trigger.year.js deleted file mode 100644 index 2a9cb1fde..000000000 --- a/src/widget/year/trigger.year.js +++ /dev/null @@ -1,204 +0,0 @@ -BI.DynamicYearTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - vgap: 2, - iconWidth: 24 - }, - - _defaultConfig: function () { - return BI.extend(BI.DynamicYearTrigger.superclass._defaultConfig.apply(this, arguments), { - extraCls: "bi-year-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - watermark: BI.i18nText("BI-Basic_Unrestricted") - }); - }, - - beforeInit: function (callback) { - var o = this.options; - o.title = BI.bind(this._titleCreator, this); - callback(); - }, - - _init: function () { - BI.DynamicYearTrigger.superclass._init.apply(this, arguments); - var self = this, o = this.options, c = this._const; - this.editor = BI.createWidget({ - type: "bi.sign_editor", - simple: o.simple, - height: o.height, - validationChecker: function (v) { - return v === "" || (BI.isPositiveInteger(v) && !BI.checkDateVoid(v, 1, 1, o.min, o.max)[0]); - }, - quitChecker: function (v) { - return false; - }, - hgap: c.hgap, - vgap: c.vgap, - watermark: o.watermark, - allowBlank: true, - errorText: function (v) { - if (BI.isPositiveInteger(v)) { - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - - return BI.i18nText("BI-Basic_Year_Range_Error", - start.getFullYear(), - end.getFullYear()); - } - - return BI.i18nText("BI-Year_Trigger_Invalid_Text"); - }, - }); - this.editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_KEY_DOWN, arguments); - }); - this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_FOCUS); - }); - this.editor.on(BI.SignEditor.EVENT_STOP, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_STOP); - }); - this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { - var value = self.editor.getValue(); - if (BI.isNotNull(value)) { - self.editor.setValue(value); - } - if (BI.isNotEmptyString(value)) { - self.storeValue = { - type: BI.DynamicDateCombo.Static, - value: { - year: value - } - }; - } - - self.fireEvent(BI.DynamicYearTrigger.EVENT_CONFIRM); - }); - this.editor.on(BI.SignEditor.EVENT_SPACE, function () { - if (self.editor.isValid()) { - self.editor.blur(); - } - }); - this.editor.on(BI.SignEditor.EVENT_START, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_START); - }); - this.editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_ERROR); - }); - this.editor.on(BI.SignEditor.EVENT_VALID, function () { - self.fireEvent(BI.DynamicYearTrigger.EVENT_VALID); - }); - BI.createWidget({ - element: this, - type: "bi.horizontal_fill", - columnSize: ["fill", "", ""], - items: [{ - el: this.editor - }, { - el: { - type: "bi.text_button", - baseCls: "bi-trigger-year-text", - text: BI.i18nText("BI-Multi_Date_Year"), - }, - }, { - el: { - type: "bi.trigger_icon_button", - width: this._const.iconWidth - } - }] - }); - this.setValue(o.value); - }, - - _getText: function (obj) { - var value = ""; - if(BI.isNotNull(obj.year) && BI.parseInt(obj.year) !== 0) { - value += Math.abs(obj.year) + BI.i18nText("BI-Basic_Year") + (obj.year < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - return value; - }, - - _setInnerValue: function (date, text) { - var dateStr = BI.print(date, "%Y"); - this.editor.setState(dateStr); - this.editor.setValue(dateStr); - }, - - _titleCreator: function () { - var storeValue = this.storeValue || {}; - var type = storeValue.type || BI.DynamicDateCombo.Static; - var value = storeValue.value; - if(!this.editor.isValid()) { - return ""; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - var date = BI.getDate(); - date = BI.DynamicDateHelper.getCalculation(value); - var dateStr = BI.print(date, "%Y"); - return BI.isEmptyString(text) ? dateStr : (text + ":" + dateStr); - case BI.DynamicDateCombo.Static: - default: - value = value || {}; - return value.year; - } - }, - - setValue: function (v) { - var type, value; - var date = BI.getDate(); - this.storeValue = v; - if (BI.isNotNull(v)) { - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - date = BI.DynamicDateHelper.getCalculation(value); - this._setInnerValue(date, text); - break; - case BI.DynamicDateCombo.Static: - default: - value = value || {}; - this.editor.setState(value.year); - this.editor.setValue(value.year); - break; - } - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - getValue: function () { - return this.storeValue; - }, - - getKey: function () { - return this.editor.getValue() | 0; - }, - - setWaterMark: function (v) { - this.editor.setWaterMark(v); - } -}); -BI.DynamicYearTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.DynamicYearTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicYearTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearTrigger.EVENT_START = "EVENT_START"; -BI.DynamicYearTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearTrigger.EVENT_STOP = "EVENT_STOP"; -BI.DynamicYearTrigger.EVENT_VALID = "EVENT_VALID"; -BI.shortcut("bi.dynamic_year_trigger", BI.DynamicYearTrigger); \ No newline at end of file diff --git a/src/widget/yearinterval/yearinterval.js b/src/widget/yearinterval/yearinterval.js deleted file mode 100644 index 56756e60c..000000000 --- a/src/widget/yearinterval/yearinterval.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/1/25 - */ -BI.YearInterval = BI.inherit(BI.Single, { - constants: { - height: 24, - width: 25, - lgap: 15, - offset: -15, - timeErrorCls: "time-error" - }, - - props: { - extraCls: "bi-year-interval", - minDate: "1900-01-01", - maxDate: "2099-12-31", - supportDynamic: true, - }, - - render: function () { - var self = this, o = this.options; - - o.value = o.value || {}; - this.left = this._createCombo(o.value.start, o.watermark?.start); - this.right = this._createCombo(o.value.end, o.watermark?.end); - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: self.right - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this, o = this.options; - var combo = BI.createWidget({ - type: "bi.dynamic_year_combo", - supportDynamic: o.supportDynamic, - minDate: o.minDate, - maxDate: o.maxDate, - height: o.height, - behaviors: o.behaviors, - value: v, - watermark: watermark, - listeners: [{ - eventName: BI.DynamicYearCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.YearInterval.EVENT_BEFORE_POPUPVIEW); - } - }] - }); - combo.on(BI.DynamicYearCombo.EVENT_ERROR, function () { - self._clearTitle(); - BI.Bubbles.hide("error"); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearInterval.EVENT_ERROR); - }); - - combo.on(BI.DynamicYearCombo.EVENT_VALID, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearCombo.EVENT_FOCUS, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearCombo.EVENT_CONFIRM, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isStateValid() && self.right.isStateValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearInterval.EVENT_ERROR); - }else{ - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearInterval.EVENT_CHANGE); - } - }); - return combo; - }, - - - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y"), "%Y") === date || BI.print(BI.parseDateTime(date, "%Y"), "%Y") === date; - }, - - - // 判是否在最大最小之间 - _checkVoid: function (obj) { - var o = this.options; - return !BI.checkDateVoid(obj.year, 1, 1, o.minDate, o.maxDate)[0]; - }, - - // 判格式合法 - _check: function (smallDate, bigDate) { - var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); - - var smallDate4Check = ""; - if (BI.isNotNull(smallObj)) { - smallDate4Check = smallObj[0] || ""; - } - - var bigDate4Check = ""; - if (BI.isNotNull(bigObj)) { - bigDate4Check = bigObj[0] || ""; - } - - return this._dateCheck(smallDate4Check) && BI.checkDateLegal(smallDate4Check) && this._checkVoid({ - year: smallObj[0], - month: 1, - day: 1 - }) && this._dateCheck(bigDate4Check) && BI.checkDateLegal(bigDate4Check) && this._checkVoid({ - year: bigObj[0], - month: 12, - day: 1 - }); - }, - - _compare: function (smallDate, bigDate) { - smallDate = BI.print(BI.parseDateTime(smallDate, "%Y"), "%Y"); - bigDate = BI.print(BI.parseDateTime(bigDate, "%Y"), "%Y"); - return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; - }, - _setTitle: function (v) { - this.setTitle(v); - }, - _clearTitle: function () { - this.setTitle(""); - }, - _checkValid: function () { - var self = this; - - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.YearInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.left.setMinDate(minDate); - this.right.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.left.setMaxDate(maxDate); - this.right.setMaxDate(maxDate); - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - - this._checkValid(); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } -}); -BI.YearInterval.EVENT_VALID = "EVENT_VALID"; -BI.YearInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.YearInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.YearInterval.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.year_interval", BI.YearInterval); diff --git a/src/widget/yearmonth/card.dynamic.yearmonth.js b/src/widget/yearmonth/card.dynamic.yearmonth.js deleted file mode 100644 index 786b22a00..000000000 --- a/src/widget/yearmonth/card.dynamic.yearmonth.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 年月展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.YearCard - * @extends BI.Trigger - */ -BI.DynamicYearMonthCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-year-month-card" - }, - - render: function () { - var self = this; - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - text: BI.i18nText("BI-Multi_Date_Relative_Current_Time"), - textAlign: "left", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }, { - type: "bi.vertical", - ref: function (_ref) { - self.wrapper = _ref; - }, - items: [{ - el: { - type: "bi.dynamic_date_param_item", - validationChecker: BI.bind(self._checkDate, self), - ref: function () { - self.year = this; - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-year-month-error"); - } - }] - }, - bgap: 10, - }, { - type: "bi.dynamic_date_param_item", - dateType: BI.DynamicDateCard.TYPE.MONTH, - ref: function () { - self.month = this; - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-year-month-error"); - } - }] - }] - }], - vgap: 10, - hgap: 10 - }; - }, - - _getErrorText: function () { - var o = this.options; - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - return BI.i18nText("BI-Basic_Year_Month_Range_Error", - start.getFullYear(), - start.getMonth() + 1, - end.getFullYear(), - end.getMonth() + 1 - ); - }, - - _checkDate: function (obj) { - var o = this.options; - var date = BI.DynamicDateHelper.getCalculation(BI.extend(this._getValue(), this._digestDateTypeValue(obj))); - - return !BI.checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; - }, - - _digestDateTypeValue: function (value) { - var valueMap = {}; - switch (value.dateType) { - case BI.DynamicDateCard.TYPE.YEAR: - valueMap.year = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.MONTH: - valueMap.month = (value.offset === 0 ? -value.value : +value.value); - break; - default: - break; - } - return valueMap; - }, - - _createValue: function (type, v) { - return { - dateType: type, - value: Math.abs(v), - offset: v > 0 ? 1 : 0 - }; - }, - - setMinDate: function(minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - v = v || {year: 0, month: 0}; - this.year.setValue(this._createValue(BI.DynamicDateCard.TYPE.YEAR, v.year)); - this.month.setValue(this._createValue(BI.DynamicDateCard.TYPE.MONTH, v.month)); - }, - - _getValue: function () { - var year = this.year.getValue(); - var month = this.month.getValue(); - return { - year: (year.offset === 0 ? -year.value : year.value), - month: (month.offset === 0 ? -month.value : month.value) - }; - }, - - getInputValue: function () { - return this._getValue(); - }, - - getValue: function () { - return this.checkValidation() ? this._getValue() : {}; - }, - - checkValidation: function (show) { - var errorText; - var yearInvalid = !this.year.checkValidation(); - var monthInvalid = !this.month.checkValidation(); - var invalid = yearInvalid || monthInvalid; - if (invalid) { - errorText = BI.i18nText("BI-Please_Input_Natural_Number"); - } else { - invalid = !this._checkDate(this._getValue()); - errorText = this._getErrorText(); - } - invalid && show && BI.Bubbles.show("dynamic-year-month-error", errorText, this.wrapper); - - return !invalid; - }, -}); -BI.DynamicYearMonthCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_month_card", BI.DynamicYearMonthCard); \ No newline at end of file diff --git a/src/widget/yearmonth/card.static.yearmonth.js b/src/widget/yearmonth/card.static.yearmonth.js deleted file mode 100644 index 6ba4a94bc..000000000 --- a/src/widget/yearmonth/card.static.yearmonth.js +++ /dev/null @@ -1,171 +0,0 @@ -BI.StaticYearMonthCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-static-year-month-card", - behaviors: {} - }, - - _createMonths: function () { - var self = this; - // 纵向排列月 - var month = [1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12]; - var items = BI.chunk(month, 2); - return BI.map(items, function (i, item) { - return BI.map(item, function (j, td) { - return { - type: "bi.text_item", - cls: "bi-list-item-select", - textAlign: "center", - whiteSpace: "nowrap", - once: false, - forceSelected: true, - height: BI.toPix(BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, 1), - width: 38, - value: td, - text: td, - ref: function (_ref) { - self.monthMap[j === 0 ? i : i + 6] = _ref; - } - }; - }); - }); - }, - - render: function () { - var self = this, o = this.options; - this.monthMap = {}; - return { - type: "bi.vertical", - items: [{ - type: "bi.year_picker", - cls: "bi-split-bottom", - min: o.min, - max: o.max, - ref: function () { - self.yearPicker = this; - }, - behaviors: o.behaviors, - height: 30, - listeners: [{ - eventName: BI.YearPicker.EVENT_CHANGE, - action: function () { - var value = this.getValue(); - self._checkMonthStatus(value); - self._setYear(value); - } - }] - }, { - el: { - type: "bi.button_group", - behaviors: o.behaviors, - ref: function () { - self.month = this; - }, - items: this._createMonths(), - layouts: [BI.LogicFactory.createLogic("table", BI.extend({ - dynamic: true - }, { - columns: 2, - rows: 6, - columnSize: [1 / 2, 1 / 2], - rowSize: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT + 1 - })), { - type: "bi.center_adapt", - vgap: 1, - hgap: 2 - }], - value: o.value, - listeners: [{ - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - self.selectedYear = self.yearPicker.getValue(); - self.selectedMonth = this.getValue()[0]; - self.fireEvent(BI.StaticYearMonthCard.EVENT_CHANGE); - } - }] - }, - vgap: 5 - }] - }; - }, - - created: function() { - this._checkMonthStatus(this.selectedYear); - }, - - _checkMonthStatus: function (year) { - var o = this.options; - var minDate = BI.parseDateTime(o.min, "%Y-%X-%d"), maxDate = BI.parseDateTime(o.max, "%Y-%X-%d"); - var minYear = minDate.getFullYear(), maxYear = maxDate.getFullYear(); - var minMonth = 0; - var maxMonth = 11; - minYear === year && (minMonth = minDate.getMonth()); - maxYear === year && (maxMonth = maxDate.getMonth()); - var yearInvalid = year < minYear || year > maxYear; - BI.each(this.monthMap, function (month, obj) { - var monthInvalid = month < minMonth || month > maxMonth; - obj.setEnable(!yearInvalid && !monthInvalid); - }); - }, - - _setYear: function (year) { - var o = this.options; - - var dateVoid = BI.checkDateVoid(year, this.selectedMonth, 1, o.min, o.max); - - // 在切换年的时候,如果月份不在区间内了,取消选中 - if (BI.contains(["y", "m"], dateVoid[0])) { - this.selectedYear = year; - this.month.setValue(); - return; - } - - this.selectedYear = year; - this.month.setValue(this.selectedMonth); - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.yearPicker.setMinDate(minDate); - this._checkMonthStatus(this.selectedYear); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.yearPicker.setMaxDate(maxDate); - this._checkMonthStatus(this.selectedYear); - } - }, - - getValue: function () { - return { - year: this.selectedYear, - month: this.selectedMonth - }; - }, - - setValue: function (obj) { - var o = this.options; - var newObj = {}; - newObj.year = obj.year || 0; - newObj.month = obj.month || 0; - if (newObj.year === 0 || newObj.month === 0 || BI.checkDateVoid(newObj.year, newObj.month, 1, o.min, o.max)[0]) { - var year = newObj.year || BI.getDate().getFullYear(); - this.selectedYear = year; - this.selectedMonth = ""; - this.yearPicker.setValue(year); - this.month.setValue(); - } else { - this.selectedYear = BI.parseInt(newObj.year); - this.selectedMonth = BI.parseInt(newObj.month); - this.yearPicker.setValue(this.selectedYear); - this.month.setValue(this.selectedMonth); - } - this._checkMonthStatus(this.selectedYear); - } -}); -BI.StaticYearMonthCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.static_year_month_card", BI.StaticYearMonthCard); diff --git a/src/widget/yearmonth/combo.yearmonth.js b/src/widget/yearmonth/combo.yearmonth.js deleted file mode 100644 index 0fc8cab5c..000000000 --- a/src/widget/yearmonth/combo.yearmonth.js +++ /dev/null @@ -1,248 +0,0 @@ -BI.DynamicYearMonthCombo = BI.inherit(BI.Single, { - - props: { - baseCls: "bi-year-month-combo", - behaviors: {}, - minDate: "1900-01-01", // 最小日期 - maxDate: "2099-12-31", // 最大日期 - height: 24, - supportDynamic: true, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false - }, - - _init: function () { - var self = this, o = this.options; - BI.DynamicYearMonthCombo.superclass._init.apply(this, arguments); - this.storeValue = o.value; - this.storeTriggerValue = ""; - var border = o.simple ? 1 : 2; - this.trigger = BI.createWidget({ - type: "bi.dynamic_year_month_trigger", - simple: o.simple, - min: o.minDate, - max: o.maxDate, - height: BI.toPix(o.height, border), - value: o.value || "", - watermark: o.watermark, - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_KEY_DOWN, function () { - self.combo.isViewVisible() && self.combo.hideView(); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_START, function () { - self.combo.isViewVisible() && self.combo.hideView(); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_STOP, function () { - self.combo.showView(); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_ERROR, function () { - self.combo.isViewVisible() && self.combo.hideView(); - self.comboWrapper.element.addClass("error"); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_ERROR); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_VALID, function () { - self.comboWrapper.element.removeClass("error"); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_VALID); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_CONFIRM, function () { - var dateStore = self.storeTriggerValue; - var dateObj = self.trigger.getKey(); - if (BI.isEqual(dateObj, dateStore)) { - return; - } - if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.trigger.getValue()); - } - self._checkDynamicValue(self.storeValue); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_CONFIRM); - }); - this.trigger.on(BI.DynamicYearMonthTrigger.EVENT_FOCUS, function () { - self.storeTriggerValue = self.trigger.getKey(); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_FOCUS); - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - container: o.container, - isNeedAdjustHeight: o.isNeedAdjustHeight, - isNeedAdjustWidth: o.isNeedAdjustWidth, - el: this.trigger, - destroyWhenHide: true, - adjustLength: 1, - popup: { - minWidth: 100, - stopPropagation: false, - el: { - type: "bi.dynamic_year_month_popup", - width: o.isNeedAdjustWidth ? o.width : undefined, - supportDynamic: o.supportDynamic, - ref: function () { - self.popup = this; - }, - listeners: [ - { - eventName: BI.DynamicYearMonthPopup.EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearMonthPopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.comboWrapper.element.removeClass("error"); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearMonthPopup.BUTTON_lABEL_EVENT_CHANGE, - action: function () { - var date = BI.getDate(); - self.setValue({ - type: BI.DynamicYearMonthCombo.Static, - value: { year: date.getFullYear(), month: date.getMonth() + 1 } - }); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - var value = self.popup.getValue(); - if (self._checkValue(value)) { - self.setValue(value); - } - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - } - ], - behaviors: o.behaviors, - min: o.minDate, - max: o.maxDate - }, - value: o.value || "" - } - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.popup.setMinDate(o.minDate); - self.popup.setMaxDate(o.maxDate); - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_BEFORE_POPUPVIEW); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: { - type: "bi.horizontal_fill", - columnSize: ["", "fill"], - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - ref: function () { - self.comboWrapper = this; - }, - items: [ - { - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-change-h-font", - width: BI.toPix(o.height, border), - height: BI.toPix(o.height, border), - ref: function () { - self.changeIcon = this; - } - } - }, this.combo - ] - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - } - ] - }); - this._checkDynamicValue(o.value); - }, - - _checkDynamicValue: function (v) { - var type = null; - if (BI.isNotNull(v)) { - type = v.type; - } - switch (type) { - case BI.DynamicYearMonthCombo.Dynamic: - this.changeIcon.setVisible(true); - break; - default: - this.changeIcon.setVisible(false); - break; - } - }, - - _checkValue: function (v) { - var o = this.options; - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - var value = v.value || {}; - - return !BI.checkDateVoid(value.year, value.month, 1, o.minDate, o.maxDate)[0]; - default: - return true; - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.trigger.setMinDate(minDate); - this.popup && this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.trigger.setMaxDate(maxDate); - this.popup && this.popup.setMaxDate(maxDate); - }, - - hideView: function () { - this.combo.hideView(); - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - this._checkDynamicValue(v); - }, - - getValue: function () { - return this.storeValue; - }, - - getKey: function () { - return this.trigger.getKey(); - }, - - isStateValid: function () { - return this.trigger.isStateValid(); - } - -}); -BI.DynamicYearMonthCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearMonthCombo.EVENT_VALID = "EVENT_VALID"; -BI.DynamicYearMonthCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicYearMonthCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearMonthCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.dynamic_year_month_combo", BI.DynamicYearMonthCombo); - -BI.extend(BI.DynamicYearMonthCombo, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/yearmonth/popup.yearmonth.js b/src/widget/yearmonth/popup.yearmonth.js deleted file mode 100644 index 1b80214d7..000000000 --- a/src/widget/yearmonth/popup.yearmonth.js +++ /dev/null @@ -1,241 +0,0 @@ -/** - * 年月 - * - * Created by GUY on 2015/9/2. - * @class BI.DynamicYearMonthPopup - * @extends BI.Trigger - */ -BI.DynamicYearMonthPopup = BI.inherit(BI.Widget, { - constants: { - tabHeight: 40, - }, - - props: { - baseCls: "bi-year-month-popup", - behaviors: {}, - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期, - width: 180, - supportDynamic: true, - }, - - render: function () { - var self = this, opts = this.options, c = this.constants; - this.storeValue = {type: BI.DynamicYearMonthCombo.Static}; - return { - type: "bi.vertical", - items: [{ - el: this._getTabJson() - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_Clear"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearMonthPopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_Current_Month"), - disabled: this._checkTodayValid(), - ref: function () { - self.textButton = this; - }, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearMonthPopup.BUTTON_lABEL_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE); - } - } - }] - }]], - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT - }, - }] - }; - }, - - _setInnerValue: function () { - if (this.dateTab.getSelect() === BI.DynamicDateCombo.Static) { - this.textButton.setValue(BI.i18nText("BI-Basic_Current_Month")); - this.textButton.setEnable(!this._checkTodayValid()); - } else { - var date = BI.DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); - date = BI.print(date, "%Y-%x"); - this.textButton.setValue(date); - this.textButton.setEnable(false); - } - }, - - _checkTodayValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - _getTabJson: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - logic: { - dynamic: true - }, - ref: function () { - self.dateTab = this; - }, - tab: { - type: "bi.linear_segment", - cls: "bi-split-bottom", - invisible: !o.supportDynamic, - height: this.constants.tabHeight, - items: BI.createItems([{ - text: BI.i18nText("BI-Basic_Year_Month"), - value: BI.DynamicYearCombo.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicYearCombo.Dynamic - }], { - textAlign: "center" - }) - }, - cardCreator: function (v) { - switch (v) { - case BI.DynamicYearCombo.Dynamic: - return { - type: "bi.dynamic_year_month_card", - cls: "dynamic-year-month-pane", - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self._setInnerValue(self.year, v); - } - }], - ref: function () { - self.dynamicPane = this; - } - }; - case BI.DynamicYearCombo.Static: - default: - return { - type: "bi.static_year_month_card", - behaviors: o.behaviors, - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: BI.StaticYearMonthCard.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearMonthPopup.EVENT_CHANGE); - } - }], - ref: function () { - self.year = this; - } - }; - } - }, - listeners: [{ - eventName: BI.Tab.EVENT_CHANGE, - action: function () { - var v = self.dateTab.getSelect(); - switch (v) { - case BI.DynamicYearCombo.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.year.setValue({year: date.getFullYear(), month: date.getMonth() + 1}); - self._setInnerValue(); - break; - case BI.DynamicYearCombo.Dynamic: - default: - if(self.storeValue && self.storeValue.type === BI.DynamicYearCombo.Dynamic) { - self.dynamicPane.setValue(self.storeValue.value); - }else{ - self.dynamicPane.setValue({ - year: 0 - }); - } - self._setInnerValue(); - break; - } - } - }] - }; - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.year && this.year.setMinDate(minDate); - this.dynamicPane && this.dynamicPane.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.year && this.year.setMaxDate(maxDate); - this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - this.storeValue = v; - var self = this; - var type, value; - v = v || {}; - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Static: - default: - this.year.setValue(value); - this.textButton.setValue(BI.i18nText("BI-Basic_Current_Month")); - this.textButton.setEnable(!this._checkTodayValid()); - break; - } - }, - - getValue: function () { - return { - type: this.dateTab.getSelect(), - value: this.dateTab.getValue() - }; - } - -}); -BI.DynamicYearMonthPopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; -BI.DynamicYearMonthPopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; -BI.DynamicYearMonthPopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DynamicYearMonthPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_month_popup", BI.DynamicYearMonthPopup); \ No newline at end of file diff --git a/src/widget/yearmonth/trigger.yearmonth.js b/src/widget/yearmonth/trigger.yearmonth.js deleted file mode 100644 index 7995a007b..000000000 --- a/src/widget/yearmonth/trigger.yearmonth.js +++ /dev/null @@ -1,295 +0,0 @@ -BI.DynamicYearMonthTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - vgap: 2, - iconWidth: 24 - }, - - props: () => ({ - extraCls: "bi-year-month-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - watermark: { - year: BI.i18nText("BI-Basic_Unrestricted"), - month: BI.i18nText("BI-Basic_Unrestricted"), - }, - }), - - beforeInit: function (callback) { - var o = this.options; - o.title = BI.bind(this._titleCreator, this); - callback(); - }, - - _init: function () { - BI.DynamicYearMonthTrigger.superclass._init.apply(this, arguments); - var o = this.options; - this.yearEditor = this._createEditor(true); - this.monthEditor = this._createEditor(false); - - BI.createWidget({ - element: this, - type: "bi.htape", - items: [{ - type: "bi.center", - items: [{ - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [this.yearEditor, { - el: { - type: "bi.text_button", - text: BI.i18nText("BI-Multi_Date_Year"), - }, - }] - }, { - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [this.monthEditor, { - el: { - type: "bi.text_button", - text: BI.i18nText("BI-Multi_Date_Month"), - }, - }] - }] - }, { - el: { - type: "bi.trigger_icon_button", - width: this._const.iconWidth - }, - width: this._const.iconWidth - }] - }); - this.setValue(o.value); - }, - - _createEditor: function (isYear) { - var self = this, o = this.options, c = this._const; - var editor = BI.createWidget({ - type: "bi.sign_editor", - simple: o.simple, - height: o.height, - validationChecker: function (v) { - if (isYear) { - var month = self.monthEditor.getValue(); - if(BI.isEmptyString(month)) { - month = parseInt(v, 10) === BI.parseDateTime(o.min, "%Y-%X-%d").getFullYear() ? (BI.parseDateTime(o.min, "%Y-%X-%d").getMonth() + 1) : 1; - } - return v === "" || (BI.isPositiveInteger(v) && !BI.checkDateVoid(v, month, 1, o.min, o.max)[0]); - } - var year = self.yearEditor.getValue(); - - return v === "" || ((BI.isPositiveInteger(v) && v >= 1 && v <= 12) && (BI.isEmptyString(year) ? true : !BI.checkDateVoid(self.yearEditor.getValue(), v, 1, o.min, o.max)[0])); - }, - quitChecker: function () { - return false; - }, - watermark: isYear ? o.watermark?.year : o.watermark.month, - errorText: function (v) { - var year = isYear ? v : self.yearEditor.getValue(); - var month = isYear ? self.monthEditor.getValue() : v; - if (!BI.isPositiveInteger(year) || !BI.isPositiveInteger(month) || month > 12) { - return BI.i18nText("BI-Year_Trigger_Invalid_Text"); - } - - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - - return BI.i18nText("BI-Basic_Year_Month_Range_Error", - start.getFullYear(), - start.getMonth() + 1, - end.getFullYear(), - end.getMonth() + 1 - ); - }, - hgap: c.hgap, - vgap: c.vgap, - allowBlank: true - }); - editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_KEY_DOWN); - }); - editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_FOCUS); - }); - editor.on(BI.SignEditor.EVENT_STOP, function () { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_STOP); - }); - editor.on(BI.SignEditor.EVENT_CONFIRM, function () { - self._doEditorConfirm(editor); - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_CONFIRM); - }); - editor.on(BI.SignEditor.EVENT_SPACE, function () { - if (editor.isValid()) { - editor.blur(); - } - }); - editor.on(BI.SignEditor.EVENT_START, function () { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_START); - }); - editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_ERROR); - }); - editor.on(BI.SignEditor.EVENT_VALID, function () { - var year = self.yearEditor.getValue(); - var month = self.monthEditor.getValue(); - if(BI.isNotEmptyString(year) && BI.isNotEmptyString(month)) { - if(BI.isPositiveInteger(year) && month >= 1 && month <= 12 && !BI.checkDateVoid(year, month, 1, o.min, o.max)[0]) { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_VALID); - } - } - }); - editor.on(BI.SignEditor.EVENT_CHANGE, function () { - if(isYear) { - self._autoSwitch(editor); - } - }); - - return editor; - }, - - _titleCreator: function () { - var storeValue = this.storeValue || {}; - var type = storeValue.type || BI.DynamicDateCombo.Static; - var value = storeValue.value; - if(!this.monthEditor.isValid() || !this.yearEditor.isValid()) { - return ""; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - var date = BI.getDate(); - date = BI.DynamicDateHelper.getCalculation(value); - var dateStr = BI.print(date, "%Y-%x"); - return BI.isEmptyString(text) ? dateStr : (text + ":" + dateStr); - case BI.DynamicDateCombo.Static: - default: - value = value || {}; - return this._getStaticTitle(value); - } - }, - - _doEditorConfirm: function (editor) { - var value = editor.getValue(); - if (BI.isNotNull(value)) { - editor.setValue(value); - } - var monthValue = this.monthEditor.getValue(); - this.storeValue = { - type: BI.DynamicDateCombo.Static, - value: { - year: this.yearEditor.getValue(), - month: BI.isEmptyString(this.monthEditor.getValue()) ? "" : monthValue - } - }; - }, - - _yearCheck: function (v) { - var date = BI.print(BI.parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); - return BI.print(BI.parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; - }, - - _autoSwitch: function (editor) { - var v = editor.getValue(); - if (BI.isNotEmptyString(v) && BI.checkDateLegal(v)) { - if (v.length === 4 && this._yearCheck(v)) { - this._doEditorConfirm(editor); - this.fireEvent(BI.DynamicYearMonthTrigger.EVENT_CONFIRM); - this.monthEditor.focus(); - } - } - }, - - _getText: function (obj) { - var value = ""; - if(BI.isNotNull(obj.year) && BI.parseInt(obj.year) !== 0) { - value += Math.abs(obj.year) + BI.i18nText("BI-Basic_Year") + (obj.year < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - if(BI.isNotNull(obj.month) && BI.parseInt(obj.month) !== 0) { - value += Math.abs(obj.month) + BI.i18nText("BI-Basic_Month") + (obj.month < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - return value; - }, - - _setInnerValue: function (date, text) { - this.yearEditor.setValue(date.getFullYear()); - this.monthEditor.setValue(date.getMonth() + 1); - }, - - _getStaticTitle: function (value) { - value = value || {}; - var hasYear = !(BI.isNull(value.year) || BI.isEmptyString(value.year)); - var hasMonth = !(BI.isNull(value.month) || BI.isEmptyString(value.month)); - switch ((hasYear << 1) | hasMonth) { - // !hasYear && !hasMonth - case 0: - return ""; - // !hasYear && hasMonth - case 1: - return value.month; - // hasYear && !hasMonth - case 2: - return value.year; - // hasYear && hasMonth - case 3: - default: - return value.year + "-" + value.month; - } - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - var type, value; - var date = BI.getDate(); - this.storeValue = v; - if (BI.isNotNull(v)) { - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - } - switch (type) { - case BI.DynamicDateCombo.Dynamic: - var text = this._getText(value); - date = BI.DynamicDateHelper.getCalculation(value); - this._setInnerValue(date, text); - break; - case BI.DynamicDateCombo.Static: - default: - value = value || {}; - var month = BI.isNull(value.month) ? null : value.month; - this.yearEditor.setValue(value.year); - this.monthEditor.setValue(month); - break; - } - }, - - getValue: function () { - return this.storeValue; - }, - - getKey: function () { - return this.yearEditor.getValue() + "-" + this.monthEditor.getValue(); - }, - - isStateValid: function () { - return this.yearEditor.isValid() && this.monthEditor.isValid(); - } -}); -BI.DynamicYearMonthTrigger.EVENT_VALID = "EVENT_VALID"; -BI.DynamicYearMonthTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicYearMonthTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearMonthTrigger.EVENT_START = "EVENT_START"; -BI.DynamicYearMonthTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearMonthTrigger.EVENT_STOP = "EVENT_STOP"; -BI.DynamicYearMonthTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.shortcut("bi.dynamic_year_month_trigger", BI.DynamicYearMonthTrigger); diff --git a/src/widget/yearmonthinterval/yearmonthinterval.js b/src/widget/yearmonthinterval/yearmonthinterval.js deleted file mode 100644 index 2bec1d88d..000000000 --- a/src/widget/yearmonthinterval/yearmonthinterval.js +++ /dev/null @@ -1,190 +0,0 @@ -BI.YearMonthInterval = BI.inherit(BI.Single, { - constants: { - width: 25, - lgap: 15, - offset: -15, - timeErrorCls: "time-error" - }, - - props: { - extraCls: "bi-year-month-interval", - minDate: "1900-01-01", - maxDate: "2099-12-31", - supportDynamic: true, - height: 24, - simple: false, - }, - - render: function () { - var self = this, o = this.options; - o.value = o.value || {}; - this.left = this._createCombo(o.value.start, o.watermark?.start); - this.right = this._createCombo(o.value.end, o.watermark?.end); - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: self.right - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this, o = this.options; - var combo = BI.createWidget({ - type: "bi.dynamic_year_month_combo", - simple: o.simple, - supportDynamic: o.supportDynamic, - height: o.height, - minDate: o.minDate, - maxDate: o.maxDate, - behaviors: o.behaviors, - value: v, - watermark: watermark, - listeners: [{ - eventName: BI.DynamicYearMonthCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.YearMonthInterval.EVENT_BEFORE_POPUPVIEW); - } - }] - }); - combo.on(BI.DynamicYearMonthCombo.EVENT_ERROR, function () { - self._clearTitle(); - BI.Bubbles.hide("error"); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearMonthInterval.EVENT_ERROR); - }); - - combo.on(BI.DynamicYearMonthCombo.EVENT_VALID, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearMonthCombo.EVENT_FOCUS, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearMonthCombo.EVENT_CONFIRM, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isStateValid() && self.right.isStateValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearMonthInterval.EVENT_ERROR); - }else{ - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearMonthInterval.EVENT_CHANGE); - } - }); - return combo; - }, - - - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%x"), "%Y-%x") === date || BI.print(BI.parseDateTime(date, "%Y-%X"), "%Y-%X") === date; - }, - - - // 判是否在最大最小之间 - _checkVoid: function (obj) { - var o = this.options; - return !BI.checkDateVoid(obj.year, obj.month, 1, o.minDate, o.maxDate)[0]; - }, - - // 判格式合法 - _check: function (smallDate, bigDate) { - var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); - - var smallDate4Check = ""; - if (BI.isNotNull(smallObj)) { - smallDate4Check = (smallObj[0] || "") + "-" + (smallObj[1] || 1); - } - - var bigDate4Check = ""; - if (BI.isNotNull(bigObj)) { - bigDate4Check = (bigObj[0] || "") + "-" + (bigObj[1] || 1); - } - - return this._dateCheck(smallDate4Check) && BI.checkDateLegal(smallDate4Check) && this._checkVoid({ - year: smallObj[0], - month: smallObj[1] || 1, - day: 1 - }) && this._dateCheck(bigDate4Check) && BI.checkDateLegal(bigDate4Check) && this._checkVoid({ - year: bigObj[0], - month: bigObj[1] || 1, - day: 1 - }); - }, - - _compare: function (smallDate, bigDate) { - smallDate = BI.print(BI.parseDateTime(smallDate, "%Y-%X"), "%Y-%X"); - bigDate = BI.print(BI.parseDateTime(bigDate, "%Y-%X"), "%Y-%X"); - return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; - }, - _setTitle: function (v) { - this.setTitle(v); - }, - _clearTitle: function () { - this.setTitle(""); - }, - _checkValid: function () { - var self = this; - - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.YearMonthInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.left.setMinDate(minDate); - this.right.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.left.setMaxDate(maxDate); - this.right.setMaxDate(maxDate); - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - - this._checkValid(); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } -}); -BI.YearMonthInterval.EVENT_VALID = "EVENT_VALID"; -BI.YearMonthInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.YearMonthInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.YearMonthInterval.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.year_month_interval", BI.YearMonthInterval); diff --git a/src/widget/yearquarter/card.dynamic.yearquarter.js b/src/widget/yearquarter/card.dynamic.yearquarter.js deleted file mode 100644 index 9e66e5202..000000000 --- a/src/widget/yearquarter/card.dynamic.yearquarter.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 年季度展示面板 - * - * Created by GUY on 2015/9/2. - * @class BI.YearCard - * @extends BI.Trigger - */ -BI.DynamicYearQuarterCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-year-quarter-card" - }, - - render: function () { - var self = this; - return { - type: "bi.vertical", - items: [{ - type: "bi.label", - text: BI.i18nText("BI-Multi_Date_Relative_Current_Time"), - textAlign: "left", - height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, - }, { - type: "bi.vertical", - ref: function (_ref) { - self.wrapper = _ref; - }, - items: [{ - el: { - type: "bi.dynamic_date_param_item", - validationChecker: BI.bind(self._checkDate, self), - ref: function () { - self.year = this; - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-year-quarter-error"); - } - }] - }, - bgap: 10 - }, { - type: "bi.dynamic_date_param_item", - dateType: BI.DynamicDateCard.TYPE.QUARTER, - ref: function () { - self.quarter = this; - }, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self.fireEvent("EVENT_CHANGE"); - } - }, { - eventName: "EVENT_INPUT_CHANGE", - action: function () { - BI.Bubbles.hide("dynamic-year-quarter-error"); - } - }] - }] - }], - vgap: 10, - hgap: 10 - }; - }, - - _getErrorText: function () { - var o = this.options; - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - return BI.i18nText("BI-Basic_Year_Quarter_Range_Error", - start.getFullYear(), - BI.getQuarter(start), - end.getFullYear(), - BI.getQuarter(end) - ); - }, - - _checkDate: function (obj) { - var o = this.options; - var date = BI.DynamicDateHelper.getCalculation(BI.extend(this._getValue(), this._digestDateTypeValue(obj))); - - return !BI.checkDateVoid(date.getFullYear(), date.getMonth() + 1, date.getDate(), o.min, o.max)[0]; - }, - - _digestDateTypeValue: function (value) { - var valueMap = {}; - switch (value.dateType) { - case BI.DynamicDateCard.TYPE.YEAR: - valueMap.year = (value.offset === 0 ? -value.value : +value.value); - break; - case BI.DynamicDateCard.TYPE.QUARTER: - valueMap.quarter = (value.offset === 0 ? -value.value : +value.value); - break; - default: - break; - } - return valueMap; - }, - - _createValue: function (type, v) { - return { - dateType: type, - value: Math.abs(v), - offset: v > 0 ? 1 : 0 - }; - }, - - setMinDate: function(minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - v = v || {year: 0, quarter: 0}; - this.year.setValue(this._createValue(BI.DynamicDateCard.TYPE.YEAR, v.year)); - this.quarter.setValue(this._createValue(BI.DynamicDateCard.TYPE.QUARTER, v.quarter)); - }, - - _getValue: function () { - var year = this.year.getValue(); - var quarter = this.quarter.getValue(); - return { - year: (year.offset === 0 ? -year.value : year.value), - quarter: (quarter.offset === 0 ? -quarter.value : quarter.value) - }; - }, - - getInputValue: function () { - return this._getValue(); - }, - - getValue: function () { - return this.checkValidation() ? this._getValue() : {}; - }, - - checkValidation: function (show) { - var errorText; - var yearInvalid = !this.year.checkValidation(); - var quarterInvalid = !this.quarter.checkValidation(); - var invalid = yearInvalid || quarterInvalid; - if (invalid) { - errorText = BI.i18nText("BI-Please_Input_Natural_Number"); - } else { - invalid = !this._checkDate(this._getValue()); - errorText = this._getErrorText(); - } - invalid && show && BI.Bubbles.show("dynamic-year-quarter-error", errorText, this.wrapper); - - return !invalid; - }, -}); -BI.DynamicYearQuarterCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_quarter_card", BI.DynamicYearQuarterCard); \ No newline at end of file diff --git a/src/widget/yearquarter/card.static.yearquarter.js b/src/widget/yearquarter/card.static.yearquarter.js deleted file mode 100644 index cf54c6fcf..000000000 --- a/src/widget/yearquarter/card.static.yearquarter.js +++ /dev/null @@ -1,152 +0,0 @@ -BI.StaticYearQuarterCard = BI.inherit(BI.Widget, { - - props: { - baseCls: "bi-static-year-quarter-card", - behaviors: {} - }, - - _createQuarter: function () { - var self = this; - var items = [{ - text: BI.getQuarterName(1), - value: 1 - }, { - text: BI.getQuarterName(2), - value: 2 - }, { - text: BI.getQuarterName(3), - value: 3 - }, { - text: BI.getQuarterName(4), - value: 4 - }]; - return BI.map(items, function (j, item) { - return BI.extend(item, { - type: "bi.text_item", - cls: "bi-border-radius bi-list-item-select", - textAlign: "center", - whiteSpace: "nowrap", - once: false, - forceSelected: true, - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, - ref: function (_ref) { - self.quarterMap[j + 1] = _ref; - } - }); - }); - }, - - render: function () { - var self = this, o = this.options; - this.quarterMap = {}; - return { - type: "bi.vertical", - items: [{ - type: "bi.year_picker", - cls: "bi-split-bottom", - ref: function () { - self.yearPicker = this; - }, - min: o.min, - max: o.max, - behaviors: o.behaviors, - height: 30, - listeners: [{ - eventName: BI.YearPicker.EVENT_CHANGE, - action: function () { - var value = this.getValue(); - self._checkQuarterStatus(value); - self.setValue({ - year: value, - quarter: self.selectedQuarter - }); - } - }] - }, { - el: { - type: "bi.button_group", - behaviors: o.behaviors, - ref: function () { - self.quarter = this; - }, - items: this._createQuarter(), - layouts: [{ - type: "bi.vertical", - vgap: 10, - hgap: 12, - }], - value: o.value, - listeners: [{ - eventName: BI.ButtonGroup.EVENT_CHANGE, - action: function () { - self.selectedYear = self.yearPicker.getValue(); - self.selectedQuarter = this.getValue()[0]; - self.fireEvent(BI.StaticYearQuarterCard.EVENT_CHANGE); - } - }] - }, - vgap: 5 - }] - }; - }, - - _checkQuarterStatus: function (year) { - var o = this.options; - var minDate = BI.parseDateTime(o.min, "%Y-%X-%d"), maxDate = BI.parseDateTime(o.max, "%Y-%X-%d"); - var minYear = minDate.getFullYear(), maxYear = maxDate.getFullYear(); - var minQuarter = 1; var maxQuarter = 4; - minYear === year && (minQuarter = BI.parseInt(BI.getQuarter(minDate))); - maxYear === year && (maxQuarter = BI.parseInt(BI.getQuarter(maxDate))); - var yearInvalid = year < minYear || year > maxYear; - BI.each(this.quarterMap, function (quarter, obj) { - var quarterInvalid = quarter < minQuarter || quarter > maxQuarter; - obj.setEnable(!yearInvalid && !quarterInvalid); - }); - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.yearPicker.setMinDate(minDate); - this._checkQuarterStatus(this.selectedYear); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.yearPicker.setMaxDate(maxDate); - this._checkQuarterStatus(this.selectedYear); - } - }, - - - getValue: function () { - return { - year: this.selectedYear, - quarter: this.selectedQuarter - }; - }, - - setValue: function (obj) { - var o = this.options; - var newObj = {}; - newObj.year = obj.year || 0; - newObj.quarter = obj.quarter || 0; - if (newObj.quarter === 0 || newObj.year === 0 || BI.checkDateVoid(newObj.year, newObj.quarter, 1, o.min, o.max)[0]) { - var year = newObj.year || BI.getDate().getFullYear(); - this.selectedYear = year; - this.selectedQuarter = ""; - this.yearPicker.setValue(year); - this.quarter.setValue(); - } else { - this.selectedYear = BI.parseInt(newObj.year); - this.selectedQuarter = BI.parseInt(newObj.quarter); - this.yearPicker.setValue(this.selectedYear); - this.quarter.setValue(this.selectedQuarter); - } - this._checkQuarterStatus(this.selectedYear); - } -}); -BI.StaticYearQuarterCard.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.static_year_quarter_card", BI.StaticYearQuarterCard); diff --git a/src/widget/yearquarter/combo.yearquarter.js b/src/widget/yearquarter/combo.yearquarter.js deleted file mode 100644 index b7f04c4bd..000000000 --- a/src/widget/yearquarter/combo.yearquarter.js +++ /dev/null @@ -1,251 +0,0 @@ -BI.DynamicYearQuarterCombo = BI.inherit(BI.Widget, { - - _consts: { - iconWidth: 24 - }, - props: { - baseCls: "bi-year-quarter-combo", - behaviors: {}, - minDate: "1900-01-01", // 最小日期 - maxDate: "2099-12-31", // 最大日期 - height: 24, - supportDynamic: true, - isNeedAdjustHeight: false, - isNeedAdjustWidth: false - }, - - _init: function () { - var self = this, o = this.options; - BI.DynamicYearQuarterCombo.superclass._init.apply(this, arguments); - this.storeValue = o.value; - var border = o.simple ? 1 : 2; - self.storeTriggerValue = ""; - this.trigger = BI.createWidget({ - type: "bi.dynamic_year_quarter_trigger", - simple: o.simple, - min: o.minDate, - max: o.maxDate, - height: BI.toPix(o.height, border), - value: o.value || "", - watermark: o.watermark, - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_KEY_DOWN, function () { - self.combo.isViewVisible() && self.combo.hideView(); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_START, function () { - self.combo.isViewVisible() && self.combo.hideView(); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_STOP, function () { - self.combo.showView(); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_ERROR, function () { - self.combo.isViewVisible() && self.combo.hideView(); - self.comboWrapper.element.addClass("error"); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_ERROR); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_VALID, function () { - self.comboWrapper.element.removeClass("error"); - self.fireEvent(BI.DynamicYearMonthCombo.EVENT_VALID); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_CONFIRM, function () { - var dateStore = self.storeTriggerValue; - var dateObj = self.trigger.getKey(); - if (BI.isEqual(dateObj, dateStore)) { - return; - } - if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { - self.storeValue = self.trigger.getValue(); - self.setValue(self.trigger.getValue()); - } - self._checkDynamicValue(self.storeValue); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_CONFIRM); - }); - this.trigger.on(BI.DynamicYearQuarterTrigger.EVENT_FOCUS, function () { - self.storeTriggerValue = self.trigger.getKey(); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_FOCUS); - }); - - this.combo = BI.createWidget({ - type: "bi.combo", - container: o.container, - isNeedAdjustHeight: o.isNeedAdjustHeight, - isNeedAdjustWidth: o.isNeedAdjustWidth, - el: this.trigger, - destroyWhenHide: true, - adjustLength: 1, - popup: { - minWidth: 85, - stopPropagation: false, - el: { - type: "bi.dynamic_year_quarter_popup", - width: o.isNeedAdjustWidth ? o.width : undefined, - supportDynamic: o.supportDynamic, - ref: function () { - self.popup = this; - }, - listeners: [ - { - eventName: BI.DynamicYearQuarterPopup.EVENT_CHANGE, - action: function () { - self.setValue(self.popup.getValue()); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearQuarterPopup.BUTTON_CLEAR_EVENT_CHANGE, - action: function () { - self.setValue(); - self.comboWrapper.element.removeClass("error"); - self.combo.hideView(); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearQuarterPopup.BUTTON_lABEL_EVENT_CHANGE, - action: function () { - var date = BI.getDate(); - self.setValue({ - type: BI.DynamicYearMonthCombo.Static, - value: { year: date.getFullYear(), quarter: BI.getQuarter(date) } - }); - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - }, { - eventName: BI.DynamicYearQuarterPopup.BUTTON_OK_EVENT_CHANGE, - action: function () { - var value = self.popup.getValue(); - if (self._checkValue(value)) { - self.setValue(value); - } - self.combo.hideView(); - self.fireEvent(BI.DynamicDateCombo.EVENT_CONFIRM); - } - } - ], - behaviors: o.behaviors, - min: o.minDate, - max: o.maxDate - }, - value: o.value || "" - } - }); - this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { - self.popup.setMinDate(o.minDate); - self.popup.setMaxDate(o.maxDate); - self.popup.setValue(self.storeValue); - self.fireEvent(BI.DynamicYearQuarterCombo.EVENT_BEFORE_POPUPVIEW); - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [ - { - el: { - type: "bi.horizontal_fill", - columnSize: ["", "fill"], - cls: (o.simple ? "bi-border-bottom" : "bi-border bi-border-radius") + " bi-focus-shadow", - ref: function () { - self.comboWrapper = this; - }, - items: [ - { - el: { - type: "bi.icon_button", - cls: "bi-trigger-icon-button date-change-h-font", - width: this._consts.iconWidth, - height: BI.toPix(o.height, border), - ref: function () { - self.changeIcon = this; - } - } - }, this.combo - ] - }, - top: 0, - left: 0, - right: 0, - bottom: 0 - } - ] - }); - this._checkDynamicValue(o.value); - }, - - _checkDynamicValue: function (v) { - var type = null; - if (BI.isNotNull(v)) { - type = v.type; - } - switch (type) { - case BI.DynamicYearQuarterCombo.Dynamic: - this.changeIcon.setVisible(true); - break; - default: - this.changeIcon.setVisible(false); - break; - } - }, - - _checkValue: function (v) { - var o = this.options; - switch (v.type) { - case BI.DynamicDateCombo.Dynamic: - return BI.isNotEmptyObject(v.value); - case BI.DynamicDateCombo.Static: - var value = v.value || {}; - - return !BI.checkDateVoid(value.year, (value.quarter - 1) * 3 + 1, 1, o.minDate, o.maxDate)[0]; - default: - return true; - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.trigger.setMinDate(minDate); - this.popup && this.popup.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.trigger.setMaxDate(maxDate); - this.popup && this.popup.setMaxDate(maxDate); - }, - - hideView: function () { - this.combo.hideView(); - }, - - getKey: function () { - return this.trigger.getKey(); - }, - - setValue: function (v) { - this.storeValue = v; - this.trigger.setValue(v); - this._checkDynamicValue(v); - }, - - getValue: function () { - return this.storeValue; - }, - - isStateValid: function () { - return this.trigger.isStateValid(); - } - -}); -BI.DynamicYearQuarterCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearQuarterCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.DynamicYearQuarterCombo.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearQuarterCombo.EVENT_VALID = "EVENT_VALID"; -BI.DynamicYearQuarterCombo.EVENT_FOCUS = "EVENT_FOCUS"; -BI.shortcut("bi.dynamic_year_quarter_combo", BI.DynamicYearQuarterCombo); - -BI.extend(BI.DynamicYearQuarterCombo, { - Static: 1, - Dynamic: 2 -}); diff --git a/src/widget/yearquarter/popup.yearquarter.js b/src/widget/yearquarter/popup.yearquarter.js deleted file mode 100644 index 6cfbc519a..000000000 --- a/src/widget/yearquarter/popup.yearquarter.js +++ /dev/null @@ -1,235 +0,0 @@ -BI.DynamicYearQuarterPopup = BI.inherit(BI.Widget, { - constants: { - tabHeight: 40, - buttonHeight: 24 - }, - - props: { - baseCls: "bi-year-quarter-popup", - behaviors: {}, - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期, - width: 180, - supportDynamic: true, - }, - - render: function () { - var self = this, opts = this.options, c = this.constants; - this.storeValue = {type: BI.DynamicYearQuarterCombo.Static}; - return { - type: "bi.vertical", - items: [{ - el: this._getTabJson() - }, { - el: { - type: "bi.grid", - items: [[{ - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - shadow: true, - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - text: BI.i18nText("BI-Basic_Clear"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearQuarterPopup.BUTTON_CLEAR_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-left bi-split-right bi-high-light bi-split-top", - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - shadow: true, - text: BI.i18nText("BI-Basic_Current_Quarter"), - disabled: this._checkTodayValid(), - ref: function () { - self.textButton = this; - }, - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearQuarterPopup.BUTTON_lABEL_EVENT_CHANGE); - } - }] - }, { - type: "bi.text_button", - cls: "bi-split-top bi-high-light", - shadow: true, - textHeight: BI.toPix(BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT, 1), - text: BI.i18nText("BI-Basic_OK"), - listeners: [{ - eventName: BI.TextButton.EVENT_CHANGE, - action: function () { - var type = self.dateTab.getSelect(); - if (type === BI.DynamicDateCombo.Dynamic) { - self.dynamicPane.checkValidation(true) && self.fireEvent(BI.DynamicDatePopup.BUTTON_OK_EVENT_CHANGE); - } else { - self.fireEvent(BI.DynamicYearQuarterPopup.BUTTON_OK_EVENT_CHANGE); - } - } - }] - }]], - height: BI.SIZE_CONSANTS.TOOL_BAR_HEIGHT - }, - }] - }; - }, - - _setInnerValue: function () { - if (this.dateTab.getSelect() === BI.DynamicYearQuarterCombo.Static) { - this.textButton.setValue(BI.i18nText("BI-Basic_Current_Quarter")); - this.textButton.setEnable(!this._checkTodayValid()); - } else { - var date = BI.DynamicDateHelper.getCalculation(this.dynamicPane.getInputValue()); - date = BI.print(date, "%Y-%Q"); - this.textButton.setValue(date); - this.textButton.setEnable(false); - } - }, - - _checkTodayValid: function () { - var o = this.options; - var today = BI.getDate(); - return !!BI.checkDateVoid(today.getFullYear(), today.getMonth() + 1, today.getDate(), o.min, o.max)[0]; - }, - - _getTabJson: function () { - var self = this, o = this.options; - return { - type: "bi.tab", - logic: { - dynamic: true - }, - ref: function () { - self.dateTab = this; - }, - tab: { - type: "bi.linear_segment", - cls: "bi-split-bottom", - invisible: !o.supportDynamic, - height: this.constants.tabHeight, - items: BI.createItems([{ - text: BI.i18nText("BI-Basic_Year_Quarter"), - value: BI.DynamicYearQuarterCombo.Static - }, { - text: BI.i18nText("BI-Basic_Dynamic_Title"), - value: BI.DynamicYearQuarterCombo.Dynamic - }], { - textAlign: "center" - }) - }, - cardCreator: function (v) { - switch (v) { - case BI.DynamicYearQuarterCombo.Dynamic: - return { - type: "bi.dynamic_year_quarter_card", - cls: "dynamic-year-quarter-pane", - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: "EVENT_CHANGE", - action: function () { - self._setInnerValue(self.year, v); - } - }], - ref: function () { - self.dynamicPane = this; - } - }; - case BI.DynamicYearQuarterCombo.Static: - default: - return { - type: "bi.static_year_quarter_card", - behaviors: o.behaviors, - min: self.options.min, - max: self.options.max, - listeners: [{ - eventName: BI.DynamicYearCard.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.DynamicYearQuarterPopup.EVENT_CHANGE); - } - }], - ref: function () { - self.year = this; - } - }; - } - }, - listeners: [{ - eventName: BI.Tab.EVENT_CHANGE, - action: function () { - var v = self.dateTab.getSelect(); - switch (v) { - case BI.DynamicYearQuarterCombo.Static: - var date = BI.DynamicDateHelper.getCalculation(self.dynamicPane.getValue()); - self.year.setValue({year: date.getFullYear(), quarter: BI.getQuarter(date)}); - self._setInnerValue(); - break; - case BI.DynamicYearQuarterCombo.Dynamic: - default: - if(self.storeValue && self.storeValue.type === BI.DynamicYearQuarterCombo.Dynamic) { - self.dynamicPane.setValue(self.storeValue.value); - }else{ - self.dynamicPane.setValue({ - year: 0 - }); - } - self._setInnerValue(); - break; - } - } - }] - }; - }, - - setMinDate: function (minDate) { - if (this.options.min !== minDate) { - this.options.min = minDate; - this.year && this.year.setMinDate(minDate); - this.dynamicPane && this.dynamicPane.setMinDate(minDate); - } - }, - - setMaxDate: function (maxDate) { - if (this.options.max !== maxDate) { - this.options.max = maxDate; - this.year && this.year.setMaxDate(maxDate); - this.dynamicPane && this.dynamicPane.setMaxDate(maxDate); - } - }, - - setValue: function (v) { - this.storeValue = v; - var self = this; - var type, value; - v = v || {}; - type = v.type || BI.DynamicDateCombo.Static; - value = v.value || v; - this.dateTab.setSelect(type); - switch (type) { - case BI.DynamicDateCombo.Dynamic: - this.dynamicPane.setValue(value); - self._setInnerValue(); - break; - case BI.DynamicDateCombo.Static: - default: - this.year.setValue(value); - this.textButton.setValue(BI.i18nText("BI-Basic_Current_Quarter")); - this.textButton.setEnable(!this._checkTodayValid()); - break; - } - }, - - getValue: function () { - return { - type: this.dateTab.getSelect(), - value: this.dateTab.getValue() - }; - } - -}); -BI.DynamicYearQuarterPopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; -BI.DynamicYearQuarterPopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; -BI.DynamicYearQuarterPopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; -BI.DynamicYearQuarterPopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.dynamic_year_quarter_popup", BI.DynamicYearQuarterPopup); \ No newline at end of file diff --git a/src/widget/yearquarter/trigger.yearquarter.js b/src/widget/yearquarter/trigger.yearquarter.js deleted file mode 100644 index 876856379..000000000 --- a/src/widget/yearquarter/trigger.yearquarter.js +++ /dev/null @@ -1,277 +0,0 @@ -BI.DynamicYearQuarterTrigger = BI.inherit(BI.Trigger, { - _const: { - hgap: 4, - vgap: 2, - iconWidth: 24 - }, - - props: () => ({ - extraCls: "bi-year-quarter-trigger", - min: "1900-01-01", // 最小日期 - max: "2099-12-31", // 最大日期 - height: 24, - watermark: { - year: BI.i18nText("BI-Basic_Unrestricted"), - quarter: BI.i18nText("BI-Basic_Unrestricted"), - }, - }), - - _init: function () { - BI.DynamicYearQuarterTrigger.superclass._init.apply(this, arguments); - var o = this.options; - this.yearEditor = this._createEditor(true); - this.quarterEditor = this._createEditor(false); - - // 暂时的解决方法 - var height = o.height + 2; - - BI.createWidget({ - element: this, - type: "bi.htape", - items: [{ - type: "bi.center", - items: [{ - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [this.yearEditor, { - el: { - type: "bi.text_button", - text: BI.i18nText("BI-Multi_Date_Year"), - }, - }] - }, { - type: "bi.horizontal_fill", - columnSize: ["fill", ""], - items: [this.quarterEditor, { - el: { - type: "bi.text_button", - text: BI.i18nText("BI-Multi_Date_Quarter"), - }, - }] - }] - }, { - el: { - type: "bi.trigger_icon_button", - width: this._const.iconWidth, - }, - width: this._const.iconWidth, - }] - }); - this.setValue(o.value); - }, - - _createEditor: function (isYear) { - var self = this, o = this.options, c = this._const; - var editor = BI.createWidget({ - type: "bi.sign_editor", - simple: o.simple, - height: o.height, - validationChecker: function (v) { - if(isYear) { - var month = self.quarterEditor.getValue(); - if(BI.isEmptyString(month)) { - month = parseInt(v, 10) === BI.parseDateTime(o.min, "%Y-%X-%d").getFullYear() ? BI.parseDateTime(o.min, "%Y-%X-%d").getMonth() + 1 : 1; - } else { - month = (parseInt(month, 10) - 1) * 3 + 1; - } - return v === "" || (BI.isPositiveInteger(v) && !BI.checkDateVoid(v, month, 1, o.min, o.max)[0]); - } - var year = self.yearEditor.getValue(); - - return v === "" || ((BI.isPositiveInteger(v) && v >= 1 && v <= 4) && (BI.isEmptyString(year) ? true : !BI.checkDateVoid(self.yearEditor.getValue(), (v - 1) * 3 + 1, 1, o.min, o.max)[0])); - }, - quitChecker: function () { - return false; - }, - errorText: function (v) { - var year = isYear ? v : self.yearEditor.getValue(); - var quarter = isYear ? self.quarterEditor.getValue() : v; - if (!BI.isPositiveInteger(year) || !BI.isPositiveInteger(quarter) || quarter > 4) { - return BI.i18nText("BI-Year_Trigger_Invalid_Text"); - } - - var start = BI.parseDateTime(o.min, "%Y-%X-%d"); - var end = BI.parseDateTime(o.max, "%Y-%X-%d"); - - return BI.i18nText("BI-Basic_Year_Quarter_Range_Error", - start.getFullYear(), - BI.getQuarter(start), - end.getFullYear(), - BI.getQuarter(end) - ); - }, - watermark: isYear ? o.watermark?.year : o.watermark?.quarter, - hgap: c.hgap, - vgap: c.vgap, - allowBlank: true - }); - editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_KEY_DOWN); - }); - editor.on(BI.SignEditor.EVENT_FOCUS, function () { - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_FOCUS); - }); - editor.on(BI.SignEditor.EVENT_STOP, function () { - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_STOP); - }); - editor.on(BI.SignEditor.EVENT_CONFIRM, function () { - self._doEditorConfirm(editor); - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_CONFIRM); - }); - editor.on(BI.SignEditor.EVENT_SPACE, function () { - if (editor.isValid()) { - editor.blur(); - } - }); - editor.on(BI.SignEditor.EVENT_START, function () { - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_START); - }); - editor.on(BI.SignEditor.EVENT_ERROR, function () { - self.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_ERROR); - }); - editor.on(BI.SignEditor.EVENT_VALID, function () { - var year = self.yearEditor.getValue(); - var quarter = self.quarterEditor.getValue(); - if(BI.isNotEmptyString(year) && BI.isNotEmptyString(quarter)) { - if(BI.isPositiveInteger(year) && quarter >= 1 && quarter <= 4 && !BI.checkDateVoid(year, (quarter - 1) * 3 + 1, 1, o.min, o.max)[0]) { - self.fireEvent(BI.DynamicYearMonthTrigger.EVENT_VALID); - } - } - }); - editor.on(BI.SignEditor.EVENT_CHANGE, function () { - if(isYear) { - self._autoSwitch(editor); - } - }); - - return editor; - }, - - _doEditorConfirm: function (editor) { - var value = editor.getValue(); - if (BI.isNotNull(value)) { - editor.setValue(value); - } - var quarterValue = this.quarterEditor.getValue(); - this.storeValue = { - type: BI.DynamicYearQuarterCombo.Static, - value: { - year: this.yearEditor.getValue(), - quarter: BI.isEmptyString(this.quarterEditor.getValue()) ? "" : quarterValue - } - }; - this.setTitle(this._getStaticTitle(this.storeValue.value)); - }, - - _yearCheck: function (v) { - var date = BI.print(BI.parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d"); - return BI.print(BI.parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max; - }, - - _autoSwitch: function (editor) { - var v = editor.getValue(); - if (BI.isNotEmptyString(v) && BI.checkDateLegal(v)) { - if (v.length === 4 && this._yearCheck(v)) { - this._doEditorConfirm(editor); - this.fireEvent(BI.DynamicYearQuarterTrigger.EVENT_CONFIRM); - this.quarterEditor.focus(); - } - } - }, - - _getStaticTitle: function (value) { - value = value || {}; - var hasYear = !(BI.isNull(value.year) || BI.isEmptyString(value.year)); - var hasMonth = !(BI.isNull(value.quarter) || BI.isEmptyString(value.quarter)); - switch ((hasYear << 1) | hasMonth) { - // !hasYear && !hasMonth - case 0: - return ""; - // !hasYear && hasMonth - case 1: - return value.quarter; - // hasYear && !hasMonth - case 2: - return value.year; - // hasYear && hasMonth - case 3: - default: - return value.year + "-" + value.quarter; - } - }, - - _getText: function (obj) { - var value = ""; - if(BI.isNotNull(obj.year) && BI.parseInt(obj.year) !== 0) { - value += Math.abs(obj.year) + BI.i18nText("BI-Basic_Year") + (obj.year < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - if(BI.isNotNull(obj.quarter) && BI.parseInt(obj.quarter) !== 0) { - value += Math.abs(obj.quarter) + BI.i18nText("BI-Basic_Single_Quarter") + (obj.quarter < 0 ? BI.i18nText("BI-Basic_Front") : BI.i18nText("BI-Basic_Behind")); - } - return value; - }, - - _setInnerValue: function (date, text) { - var dateStr = BI.print(date, "%Y-%Q"); - this.yearEditor.setValue(date.getFullYear()); - this.quarterEditor.setValue(BI.getQuarter(date)); - this.setTitle(BI.isEmptyString(text) ? dateStr : (text + ":" + dateStr)); - }, - - setMinDate: function (minDate) { - if (BI.isNotEmptyString(this.options.min)) { - this.options.min = minDate; - } - }, - - setMaxDate: function (maxDate) { - if (BI.isNotEmptyString(this.options.max)) { - this.options.max = maxDate; - } - }, - - setValue: function (v) { - var type, value; - var date = BI.getDate(); - this.storeValue = v; - if (BI.isNotNull(v)) { - type = v.type || BI.DynamicYearQuarterCombo.Static; - value = v.value || v; - } - switch (type) { - case BI.DynamicYearQuarterCombo.Dynamic: - var text = this._getText(value); - date = BI.DynamicDateHelper.getCalculation(value); - this._setInnerValue(date, text); - break; - case BI.DynamicYearQuarterCombo.Static: - default: - value = value || {}; - var quarter = BI.isNull(value.quarter) ? null : value.quarter; - this.yearEditor.setValue(value.year); - this.quarterEditor.setValue(quarter); - this.setTitle(this._getStaticTitle(value)); - break; - } - }, - - getValue: function () { - return this.storeValue; - }, - - getKey: function () { - return this.yearEditor.getValue() + "-" + this.quarterEditor.getValue(); - }, - - isStateValid: function () { - return this.yearEditor.isValid() && this.quarterEditor.isValid(); - } -}); -BI.DynamicYearQuarterTrigger.EVENT_FOCUS = "EVENT_FOCUS"; -BI.DynamicYearQuarterTrigger.EVENT_ERROR = "EVENT_ERROR"; -BI.DynamicYearQuarterTrigger.EVENT_START = "EVENT_START"; -BI.DynamicYearQuarterTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; -BI.DynamicYearQuarterTrigger.EVENT_STOP = "EVENT_STOP"; -BI.DynamicYearQuarterTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; -BI.DynamicYearQuarterTrigger.EVENT_VALID = "EVENT_VALID"; -BI.shortcut("bi.dynamic_year_quarter_trigger", BI.DynamicYearQuarterTrigger); diff --git a/src/widget/yearquarterinterval/yearquarterinterval.js b/src/widget/yearquarterinterval/yearquarterinterval.js deleted file mode 100644 index 02a0c67d7..000000000 --- a/src/widget/yearquarterinterval/yearquarterinterval.js +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @author windy - * @version 2.0 - * Created by windy on 2021/1/25 - */ -BI.YearQuarterInterval = BI.inherit(BI.Single, { - constants: { - height: 24, - width: 25, - lgap: 15, - offset: -15, - timeErrorCls: "time-error" - }, - - props: { - extraCls: "bi-year-quarter-interval", - minDate: "1900-01-01", - maxDate: "2099-12-31", - supportDynamic: true, - }, - - render: function () { - var self = this, o = this.options; - - o.value = o.value || {}; - this.left = this._createCombo(o.value.start, o.watermark?.start); - this.right = this._createCombo(o.value.end, o.watermark?.end); - - - return { - type: "bi.horizontal_fill", - columnSize: ["fill", "", "fill"], - items: [{ - el: self.left - }, { - el: { - type: "bi.label", - height: o.height, - hgap: 5, - text: "-", - ref: function (_ref) { - self.label = _ref; - } - } - }, { - el: self.right - }] - }; - }, - - _createCombo: function (v, watermark) { - var self = this, o = this.options; - var combo = BI.createWidget({ - type: "bi.dynamic_year_quarter_combo", - supportDynamic: o.supportDynamic, - minDate: o.minDate, - maxDate: o.maxDate, - behaviors: o.behaviors, - value: v, - height: o.height, - watermark: watermark, - listeners: [{ - eventName: BI.DynamicYearQuarterCombo.EVENT_BEFORE_POPUPVIEW, - action: function () { - self.fireEvent(BI.YearQuarterInterval.EVENT_BEFORE_POPUPVIEW); - } - }] - }); - combo.on(BI.DynamicYearQuarterCombo.EVENT_ERROR, function () { - self._clearTitle(); - BI.Bubbles.hide("error"); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearQuarterInterval.EVENT_ERROR); - }); - - combo.on(BI.DynamicYearQuarterCombo.EVENT_VALID, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearQuarterCombo.EVENT_FOCUS, function () { - self._checkValid(); - }); - - combo.on(BI.DynamicYearQuarterCombo.EVENT_CONFIRM, function () { - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isStateValid() && self.right.isStateValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearQuarterInterval.EVENT_ERROR); - }else{ - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - self.fireEvent(BI.YearQuarterInterval.EVENT_CHANGE); - } - }); - return combo; - }, - - - _dateCheck: function (date) { - return BI.print(BI.parseDateTime(date, "%Y-%Q"), "%Y-%Q") === date || BI.print(BI.parseDateTime(date, "%Y-%q"), "%Y-%q") === date; - }, - - - // 判是否在最大最小之间 - _checkVoid: function (obj) { - var o = this.options; - return !BI.checkDateVoid(obj.year, (obj.quarter - 1) * 3 + 1, 1, o.minDate, o.maxDate)[0]; - }, - - // 判格式合法 - _check: function (smallDate, bigDate) { - var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); - - var smallDate4Check = ""; - if (BI.isNotNull(smallObj)) { - smallDate4Check = (smallObj[0] || "") + "-" + (smallObj[1] || 1); - } - - var bigDate4Check = ""; - if (BI.isNotNull(bigObj)) { - bigDate4Check = (bigObj[0] || "") + "-" + (bigObj[1] || 1); - } - - return this._dateCheck(smallDate4Check) && BI.checkDateLegal(smallDate4Check) && this._checkVoid({ - year: smallObj[0], - quarter: smallObj[1] || 1 - }) && this._dateCheck(bigDate4Check) && BI.checkDateLegal(bigDate4Check) && this._checkVoid({ - year: bigObj[0], - quarter: bigObj[1] || 1 - }); - }, - - _compare: function (smallDate, bigDate) { - smallDate = BI.print(BI.parseDateTime(smallDate, "%Y-%Q"), "%Y-%Q"); - bigDate = BI.print(BI.parseDateTime(bigDate, "%Y-%Q"), "%Y-%Q"); - return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; - }, - _setTitle: function (v) { - this.setTitle(v); - }, - _clearTitle: function () { - this.setTitle(""); - }, - _checkValid: function () { - var self = this; - - BI.Bubbles.hide("error"); - var smallDate = self.left.getKey(), bigDate = self.right.getKey(); - if (self.left.isValid() && self.right.isValid() && self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { - self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); - self.element.addClass(self.constants.timeErrorCls); - BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { - offsetStyle: "center" - }); - self.fireEvent(BI.YearQuarterInterval.EVENT_ERROR); - } else { - self._clearTitle(); - self.element.removeClass(self.constants.timeErrorCls); - } - }, - - setMinDate: function (minDate) { - var o = this.options; - o.minDate = minDate; - this.left.setMinDate(minDate); - this.right.setMinDate(minDate); - }, - - setMaxDate: function (maxDate) { - var o = this.options; - o.maxDate = maxDate; - this.left.setMaxDate(maxDate); - this.right.setMaxDate(maxDate); - }, - - setValue: function (date) { - date = date || {}; - this.left.setValue(date.start); - this.right.setValue(date.end); - - this._checkValid(); - }, - getValue: function () { - return {start: this.left.getValue(), end: this.right.getValue()}; - } -}); -BI.YearQuarterInterval.EVENT_VALID = "EVENT_VALID"; -BI.YearQuarterInterval.EVENT_ERROR = "EVENT_ERROR"; -BI.YearQuarterInterval.EVENT_CHANGE = "EVENT_CHANGE"; -BI.YearQuarterInterval.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; -BI.shortcut("bi.year_quarter_interval", BI.YearQuarterInterval); diff --git a/template/index.html b/template/index.html deleted file mode 100644 index bcf5ad41a..000000000 --- a/template/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - Demo - - - - - - -
    - - - - diff --git a/test/prepare.js b/test/prepare.js deleted file mode 100644 index 849a7aa0f..000000000 --- a/test/prepare.js +++ /dev/null @@ -1,6 +0,0 @@ -!(function () { - // 先把准备环境准备好 - while(BI.prepares && BI.prepares.length > 0) { - BI.prepares.shift()(); - } -})(); \ No newline at end of file diff --git a/test/utils.js b/test/utils.js deleted file mode 100644 index 8ecf90a72..000000000 --- a/test/utils.js +++ /dev/null @@ -1,47 +0,0 @@ -!(function () { - BI.Test = {}; - BI._.extend(BI.Test, { - createWidget: function (widgetJson) { - var widget = BI.createWidget(BI.extend(widgetJson, { - root: true - })); - widget.element.appendTo("body"); - return widget; - }, - - /** - * 模拟一次输入框的keydown事件 - */ - triggerKeyDown: function (element, value, keyCode, callback) { - // keydown - var e = BI.$.Event("keydown"); - e.keyCode = keyCode; - element.trigger(e); - - // input - BI.isNotNull(value) && element.val(value); - var e1 = BI.$.Event("input"); - e1.originalEvent = {}; - e1.keyCode = keyCode; - element.trigger(e1); - - // keyup 至少等300ms后触发 - var e2 = BI.$.Event("keyup"); - e2.keyCode = keyCode; - element.trigger(e2); - BI.delay(function () { - callback(); - }, 300); - }, - - /** - * 模拟一次鼠标hover - */ - triggerMouseover: function (element, callback) { - // keydown - var e = BI.$.Event("mouseover"); - element.trigger(e); - callback && callback(); - } - }) -})(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5630b275a..580e4fd6c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,34 +1,13 @@ -{ - "compilerOptions": { - "sourceMap": true, - "target": "es2017", - "module": "es2015", - "moduleResolution": "node", - "lib": [ - "es2017", - "dom" - ], - "declaration": true, - "experimentalDecorators": true, - "outDir": "./dist/lib", - "baseUrl": ".", - // "strict": true, - "strictNullChecks": true, - "noImplicitAny": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "emitDeclarationOnly": true - }, - "include": [ - "typescript/*.ts", - "typescript/**/*.ts", - "types/*.d.ts", - "src/*.js", - "src/**/*.js", - "examples/*.js", - "examples/**/*.js", - ] -} \ No newline at end of file +// 帮助别名跳转的,先将就一下 +{ + "compilerOptions": { + "allowJs": true, + "baseUrl": "packages/fineui", + "outDir": "./dist/", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["packages/fineui/src", "packages/fineui/src/*.js"], + "exclude": ["packages/fineui/node_modules"] +} diff --git a/types/globals.d.ts b/types/globals.d.ts deleted file mode 100644 index 0b5805aa0..000000000 --- a/types/globals.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -interface Obj { - [key: string]: any; -} - -declare let BI: Obj & import("../typescript/index").BI; - -// declare let BI: Obj; - -declare const Fix: Obj; - -declare interface String { - replaceAll(regx: string, callback: (str: string) => void): string; -} - -declare const _global: typeof window; diff --git a/typescript/base/base.ts b/typescript/base/base.ts deleted file mode 100644 index b6dfd4240..000000000 --- a/typescript/base/base.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { LayerController } from "../core/controller/controller.layer"; -import { BroadcastController } from "../core/controller/controller.broadcast"; - -export type Layers = LayerController; - -export type Broadcasts = BroadcastController; - diff --git a/typescript/base/foundation/message.ts b/typescript/base/foundation/message.ts deleted file mode 100644 index ad0e7bac0..000000000 --- a/typescript/base/foundation/message.ts +++ /dev/null @@ -1,13 +0,0 @@ -type toastOptions = { - level: "success" | "warning" | "error" | "normal" | "loading" - autoClose?: boolean - callback?: Function - closable?: boolean -} - -export type _msg = { - alert: (title: string, message?: string | { [key: string]: any }, callback?: (result?: boolean) => void) => void - confirm: (title: string, message?: string | { [key: string]: any }, callback?: (result: boolean) => void) => void - prompt: (title: string, message?: string, value?: any, callback?: (result: string) => void, minWidth?: number) => void - toast: (message: string | Obj, options?: toastOptions | string, context?: HTMLElement) => Function -} diff --git a/typescript/base/single/button/buttons/button.text.ts b/typescript/base/single/button/buttons/button.text.ts deleted file mode 100644 index e9c4c2ce3..000000000 --- a/typescript/base/single/button/buttons/button.text.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Label } from "../../../.."; -import { BasicButton } from "../button.basic"; - -export declare class TextButton extends BasicButton { - static xtype: string; - static EVENT_CHANGE: string; - - props: Label['props'] & BasicButton['props']; - - setStyle(style: any): void; - - doRedMark(...args: any[]): void; - - unRedMark(...args: any[]): void; - - doHighLight(...args: any[]): void; - - unHighLight(...args: any[]): void; -} diff --git a/typescript/base/single/button/buttons/button.ts b/typescript/base/single/button/buttons/button.ts deleted file mode 100644 index 102db20cb..000000000 --- a/typescript/base/single/button/buttons/button.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { AbstractLabel, IconLabel, Label } from "../../../.."; -import { BasicButton } from "../button.basic"; - -export declare class Button extends BasicButton { - static xtype: string; - - static EVENT_CHANGE: string; - - props: { - minWidth?: number; - readonly?: boolean; - iconCls?: string; - level?: 'common' | 'success' | 'warning' | 'error' | 'ignore', - block?: boolean; // 是否块状显示,即不显示边框,没有最小宽度的限制 - loading?: boolean, // 是否处于加载中 - light?: boolean, // 是否使用浅色 - plain?: boolean, // 是否是朴素按钮,和 clear 的区别是 plain 有悬浮效果 - clear?: boolean; // 是否去掉边框和背景 - ghost?: boolean; // 是否幽灵显示, 即正常状态无背景 - iconGap?: number; - iconPosition?: string; - textWidth?: number; - } & AbstractLabel['props'] & IconLabel['props'] & BasicButton['props']; - - text: Label; - icon?: IconLabel; - - doRedMark(...args: any[]): void; - - unRedMark(...args: any[]): void; - - doHighLight(...args: any[]): void; - - unHighLight(...args: any[]): void; - - loading(): void; - - loaded(): void; - - setIcon(iconCls: string): void; - - isLoading(): boolean; -} diff --git a/typescript/bundle.ts b/typescript/bundle.ts deleted file mode 100644 index 61cffc88a..000000000 --- a/typescript/bundle.ts +++ /dev/null @@ -1,3 +0,0 @@ -import fineui from "./index"; - -BI.extend(BI, fineui); diff --git a/typescript/core/base.ts b/typescript/core/base.ts deleted file mode 100644 index 5cc0a010c..000000000 --- a/typescript/core/base.ts +++ /dev/null @@ -1,410 +0,0 @@ -import { Widget } from "./widget"; - -export interface _base { - assert: (v: any, is: Function) => Boolean; - - warn: (message: any) => Boolean; - - UUID: () => string; - - isWidget: (widget: any) => widget is Widget; - - createWidgets: (items: any, options: any, context: any) => any; - - createItems: (data: T[], innerAttr?: U, outerAttr?: K) => (U & T & K)[]; - - packageItems: (items: any[], layouts: any[]) => any[]; - - formatEL: (obj: T) => { el: T } | T; - - stripEL: (obj: { el: T } | T) => T; - - trans2Element: (widgets: any[]) => any[]; - - // 集合相关方法 - where: (collection: any[] | object | string, source: object) => any[]; - - findWhere: (collection: any[] | object | string, callback?: Function | object | string, thisArg?: any) => object | undefined; - - invoke: (collection: any[] | object | string, methodName: Function | string, arg?: any) => any[]; - - pluck: (collection: any[] | object | string, property: string) => any[]; - - shuffle: (collection: any[] | object | string) => any[]; - - sample: (collection: any[] | object | string, n?: number) => any[]; - - toArray: (collection: any[] | object | string) => any[]; - - size: (collection: any) => number; - - each(collection: ArrayLike, iteratee?: (index: number, value: T) => void, thisArg?: any): ArrayLike; - each(collection: T, iteratee?: (index: K, value: T[K]) => void, thisArg?: any): T; - each(collection: T, iteratee?: any, thisArg?: any): T; - - map: (collection: T[] | object | string | null | undefined, callback?: ((index: number, value: T) => U) | object | string, thisArg?: any) => U[]; - - reduce: (collection: T[] | object | string, callback?: ((total: U extends T ? U : T, currentValue: T, currentIndex: number) => U extends T ? U : T) | object | string, initialValue?: U | T) => U extends T ? U : T; - - reduceRight: (collection: T[] | object | string, callback?: ((total: U extends T ? U : T, currentValue: T, currentIndex: number) => U extends T ? U : T) | object | string, initialValue?: U | T) => U extends T ? U : T; - - find: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => T | undefined; - - filter: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => T[]; - - reject: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => T[]; - - every: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => boolean; - - all: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => boolean; - - some: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => boolean; - - any: (collection: T[] | object | string, callback?: ((index: number, value: T) => boolean) | object | string, thisArg?: any) => boolean; - - max: (collection: T[]) => T; - - min: (collection: T[]) => T; - - sortBy: (collection: any[] | object | string, callback?: ((index: number, value: T) => number) | object | string, thisArg?: any) => any[]; - - groupBy: (collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any) => object; - - indexBy: (collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any) => object; - - countBy: (collection: any[] | object | string, callback?: ((index: number, value: T) => any) | object | string, thisArg?: any) => object; - - - count: (from: number, to: number, predicate: Function) => number; - - inverse: (from: number, to: number, predicate: Function) => number; - - firstKey: (obj: object) => string; - - lastKey: (obj: object) => string; - - firstObject: (obj: object) => any; - - lastObject: (obj: object) => any; - - concat: (obj1: any, obj2: any, ...args: any[]) => any; - - backEach: (obj: any, predicate: Function, context?: any) => boolean; - - backAny: (obj: any, predicate: Function, context?: any) => boolean; - - backEvery: (obj: any, predicate: Function, context?: any) => boolean; - - backFindKey: (obj: any, predicate: Function, context?: any) => string; - - backFind: (obj: any, predicate: Function, context?: any) => any; - - remove: (obj: any, predicate: any, context?: any) => void; - - removeAt: (obj: any, index: number | number[]) => void; - - string2Array: (str: string) => string[]; - - array2String: (array: any[]) => string; - - abc2Int: (str: string) => number; - - int2Abc: (num: number) => string; - - // 数组相关的方法 - first: (array: T[], callback?: Function | object | number | string, thisArg?: any) => T; - - initial: (array: T[], callback?: Function | object | number | string, thisArg?: any) => T[]; - - last: (array: T[], callback?: Function | object | number | string, thisArg?: any) => T; - - rest: (array: T[], callback?: Function | object | number | string, thisArg?: any) => T[]; - - compact: (array: any[]) => any[]; - - flatten: (array: any[], isShallow?: boolean, callback?: Function | object | string, thisArg?: any) => any[]; - - without: (array: any[], value?: any) => any[]; - - union: (...array: any[]) => any[]; - - intersection: (...array: any[]) => any[]; - - difference: (...array: any[]) => any[]; - - zip: (...array: any[]) => any[]; - - unzip: (...array: any[]) => any[]; - - object: (keys: string[], values?: any[]) => any[]; - - indexOf: (array: any[], value: any, fromIndex?: number) => number; - - lastIndexOf: (array: any[], value: any, fromIndex?: number) => number; - - sortedIndex: (array: any[], value: any, callback?: Function | object | string, thisArg?: any) => number; - - range: (start: number, end: number, step: number) => number[]; - - take: (array: T[], n: number) => T[]; - - takeRight: (array: T[], n: number) => T[]; - - findIndex: (array: T[], predicate?: ((index: number, item: T, array: T[]) => any) | object | string, thisArg?: any) => number; - - findLastIndex: (array: T[], predicate?: ((index: number, item: T, array: T[]) => any) | object | string, thisArg?: any) => number; - - makeArray: (length: number, value?: T) => number[] | T[]; - - makeObject: (array: any[], value: any) => any; - - makeArrayByArray: (array: any[], value: T) => T[]; - - uniq: (array: T[], isSorted?: boolean, iteratee?: any, context?: any) => T[]; - - // 对象相关方法 - keys: (object: object) => string[]; - - allKeys: (object: object) => string[]; - - values: (object: object) => any[]; - - pairs: (object: object) => any[]; - - invert: (object: object, multiValue: boolean) => object; - - create: (prototype: object, properties?: object) => object; - - functions: (object: object) => string[]; - - extend(object: T): T; - extend(object: T, ...sources: U): T & UnionToIntersection>; - - defaults: (object: object, ...sources: any[]) => object; - - clone: (object: T) => T; - - property: (path: any[] | string) => Function; - - propertyOf: (object: object) => Function; - - isEqual: (value: any, other: any, customizer?: Function, thisArg?: any) => boolean; - - isMatch: (object: object, source: object, customizer?: Function, thisArg?: any) => boolean; - - isEmpty: (value: any[] | object | string | null | undefined | number) => boolean; - - isElement: (value: any) => boolean; - - isNumber: (value: any) => value is number; - - isString: (value: any) => value is string; - - isArray: (value: T[] | any) => value is T[]; - - isObject: (value: any) => value is object; - - isPlainObject: (value: any) => value is object; - - isArguments: (value: any) => boolean; - - isFunction: (value: any) => value is Function; - - isFinite: (value: any) => value is number; - - isBoolean: (value: any) => value is boolean; - - isDate: (value: any) => value is Date; - - isRegExp: (value: any) => value is RegExp; - - isError: (value: any) => value is Error; - - isNaN: (value: any) => value is number; - - isUndefined: (value: any) => value is undefined; - - zipObject: (props: any[], values?: any[]) => object; - - cloneDeep: (value: T) => T; - - findKey: (object: object, predicate?: Function | object | string, thisArg?: any) => any; - - pick: (object: object, predicate?: Function | string | string[], thisArg?: any) => object; - - omit: (object: object, predicate?: Function | string | string[], thisArg?: any) => object; - - tap: (value: any, interceptor: Function, thisArg?: any) => any; - - inherit: (sb: any, sp: any, overrides?: any) => any; - - init: () => void; - - has: (obj: object, keys: string | string[]) => boolean; - - freeze: (value: T) => T; - - isKey: (key: any) => key is (number | string); - - isCapitalEqual: (a: string | null | undefined, b: string | null | undefined) => boolean; - - isWidthOrHeight: (w: number | string) => boolean; - - isNotNull: (obj: T) => obj is NonNullable; - - isNull: (obj: any) => obj is (undefined | null); - - isEmptyArray: (arr: T[] | U) => arr is T[] & { length: 0 }; - - isNotEmptyArray: (arr: T[] | U) => arr is [T, ...T[]]; - - isEmptyObject: (obj: any) => boolean; - - isNotEmptyObject: (obj: any) => obj is object; - - isWindow: (obj: any) => obj is Window; - - deepClone: (obj: T) => T; - - deepExtend: merge["deepExtend"]; - - isDeepMatch: (object: any, attrs: any) => boolean; - - contains: (obj: any[], target: any, fromIndex?: number) => boolean; - - deepContains: (obj: any[], copy: any) => boolean; - - deepIndexOf: (obj: any[], target: any) => number; - - deepRemove: (obj: any[], target: any) => boolean; - - deepWithout: (obj: any[], target: any) => any[]; - - deepUnique: (array: any[]) => any[]; - - deepDiff: (object: any, other: any) => string[]; - - uniqueId: (prefix?: string) => string; - - result: (object: any, key: string) => any; - - chain: (value: any) => any; - - iteratee: (func?: Function, thisArg?: any) => Function; - - unescape: (str?: string) => string; - - bind: (func: T, thisArg: any, ...partials: any) => T; - - once: (func: Function) => Function; - - partial: (func: Function, ...partials: any) => Function; - - debounce: (func: T, wait?: number, options?: any) => T; - - throttle: (func: T, wait?: number, options?: any) => T; - - delay: (func: Function, wait: number, ...args: any[]) => number; - - defer: (func: Function, ...args: any[]) => number; - - wrap: (value: any, wrapper: Function) => Function; - - nextTick: (func?: Function) => Promise; - - random: (min?: number, max?: number, floating?: boolean) => number; - - parseInt: (s: string | number) => number; - - parseSafeInt: (s: string) => number; - - parseFloat: (string: string) => number; - - isNaturalNumber: (value: string | number) => boolean; - - isPositiveInteger: (value: string | number) => boolean; - - isNegativeInteger: (value: string | number) => boolean; - - isInteger: (value: string | number) => boolean; - - isNumeric: (value: string | number) => boolean; - - isFloat: (value: string | number) => boolean; - - isOdd: (value: string | number) => boolean; - - isEven: (value: string | number) => boolean; - - sum: (array: any[], iteratee?: Function, context?: any) => number; - - average: (array: any[], iteratee?: Function, context?: any) => number; - - trim: (string?: string, chars?: string) => string; - - toUpperCase: (string: string) => string; - - toLowerCase: (string: string) => string; - - isEndWithBlank: (string: string) => boolean; - - isLiteral: (string: string) => boolean; - - stripQuotes: (string: string) => string; - - camelize: (string: string) => string; - - hyphenate: (string: string) => string; - - isNotEmptyString: (string: any) => boolean; - - isEmptyString: (str: any) => str is ""; - - encrypt: (type: string, text: string, key: string) => string; - - escape: (string: string) => string; - - leftPad: (val: string, size: number, ch: string) => string; - - format: (format: string, ...str: string[]) => string; - - isLeapYear: (year: number) => boolean; - - checkDateVoid: (YY: string | number, MM: string | number, DD: string | number, minDate: string, maxDate: string) => (number | string)[]; - - checkDateLegal: (str: string) => boolean; - - parseDateTime: (str: string, fmt: string) => Date; - - getDate: (...args: (number | string)[]) => Date; - - getTime: (...args: any[]) => number; - - /** - * 判断一个对象是不是promise - * @param obj 对象 - */ - isPromise: (obj: any) => obj is Promise; -} - -type merge = { - deepExtend(object: TObject, source: TSource): TObject & TSource; - - deepExtend(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; - - deepExtend(object: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2; - - deepExtend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3): TObject & TSource1 & TSource2 & TSource3; - - deepExtend(object: TObject, source1: TSource1, source2: TSource2, source3: TSource3, source4: TSource4): TObject & TSource1 & TSource2 & TSource3 & TSource4; - - deepExtend(object: any, ...otherArgs: any[]): any; -} - -type UnionToIntersection = ( - Union extends unknown - ? (x: Union) => void - : never -) extends ((x: infer Intersection) => void) - ? Intersection - : never; diff --git a/typescript/core/decorator/decorator.ts b/typescript/core/decorator/decorator.ts deleted file mode 100644 index bc5db42bf..000000000 --- a/typescript/core/decorator/decorator.ts +++ /dev/null @@ -1,136 +0,0 @@ -export type Constructor = new(...args: any[]) => T; - -/** - * 注册widget - */ -export function shortcut() { - return function decorator(Target: Constructor & {xtype: string}): void { - BI.shortcut(Target.xtype, Target); - }; -} - -/** - * 注册provider - */ -export function provider() { - return function decorator(Target: Constructor & {xtype: string}): void { - BI.provider(Target.xtype, Target); - }; -} - -/** - * 注册model - */ -export function model() { - return function decorator}>(Target: U): void { - BI.model(Target.xtype, Target); - }; -} - -/** - * 类注册_store属性 - * @param Model model类 - * @param opts 额外条件 - */ -export function store(Model: Constructor & {xtype: string}, opts: { props?(this: unknown): { [key: string]: unknown } } = {}) { - return function classDecorator(constructor:U) { - return class extends constructor { - _store() { - const props = opts.props ? opts.props.apply(this) : undefined; - - return BI.Models.getModel(Model.xtype, props); - } - }; - }; -} - -/** - * 注册mixin - * ie8下不能使用 - */ -export function mixin() { - return function decorator(Target: Constructor & { xtype: string }): void { - const mixin: { - [key: string]: Function; - } = {}; - - Object.getOwnPropertyNames(Target.prototype).forEach(name => { - if (name === 'constructor') { - return; - } - - mixin[name] = Target.prototype[name]; - }); - - Fix.mixin(Target.xtype, mixin); - }; -} - -/** - * 类注册mixins属性 - * ie8下不能使用 - * @param Mixins - */ -export function mixins(...Mixins: ({ new (...args: any[]): {} } & { xtype: string })[]) { - return function classDecorator(constructor: U) { - const mixins: string[] = []; - - Mixins.forEach(mixin => { - mixin.xtype && mixins.push(mixin.xtype); - }); - - return class extends constructor { - mixins = mixins; - }; - }; -} - -/** - * Model基类 - */ -export class Model} = {}> extends Fix.Model { - // @ts-ignore this["computed"][key]为空 - model: Pick<{[key in keyof U["types"]]: U["types"][key]}, U["context"][number]> & ReturnType & {[key in keyof this["computed"]]: ReturnType}; - - store: this["actions"]; - - state(): {[key: string]: unknown} | {} { - return {}; - } - - context: U["context"]; - - actions:{[key: string]: (...args: any[]) => any} | {}; - - childContext: ReadonlyArray)>; - - // @ts-ignore this["computed"][key]为空 - TYPE: Pick<{[key in keyof this["computed"]]: ReturnType} & {[key in keyof ReturnType]: ReturnType[key]}, this["childContext"][number]>; - - computed: {[key: string]: () => unknown} | {}; -} - -/* 分享一段很好看的代码 -// union to intersection of functions -type UnionToIoF = - (U extends any ? (k: (x: U) => void) => void : never) extends - ((k: infer I) => void) ? I : never - -// return last element from Union -type UnionPop = UnionToIoF extends { (a: infer A): void; } ? A : never; - -// prepend an element to a tuple. -type Prepend> = - ((a: U, ...r: T) => void) extends (...r: infer R) => void ? R : never; - -type UnionToTupleRecursively> = { - 1: Result; - 0: UnionToTupleRecursively_, Result>; - // 0: UnionToTupleRecursively>, Prepend, Result>> -}[[Union] extends [never] ? 1 : 0]; - -type UnionToTupleRecursively_> = - UnionToTupleRecursively, Prepend>; - -type UnionToTuple = UnionToTupleRecursively; -*/ diff --git a/typescript/core/func/array.ts b/typescript/core/func/array.ts deleted file mode 100644 index e27e400bb..000000000 --- a/typescript/core/func/array.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type _array = { - pushArray: (sArray: any[], array: any[]) => void; - pushDistinct: (sArray: any[], obj: any) => void; - pushDistinctArray: (sArray: any[], array: any[]) => void; -} diff --git a/typescript/core/func/date.ts b/typescript/core/func/date.ts deleted file mode 100644 index 93e004f8c..000000000 --- a/typescript/core/func/date.ts +++ /dev/null @@ -1,93 +0,0 @@ -export type _Date = { - SECOND: number; - MINUTE: number; - HOUR: number; - DAY: number; - WEEK: number; - _DN: string[]; - _SDN: string[]; - _FD: number; - _MN: string[]; - _SMN: number[]; - _QN: string[]; - _MD: number[]; - _OFFSET: number[]; -} - -export type _date = { - - /** - * 获取时区 - */ - getTimezone: (date: Date) => string; - - /** - * 获取指定月共有多少天 - */ - getMonthDays: (date: Date, month: number) => number; - - /** - * 获取指定月的最后一天 - */ - getLastDateOfMonth: (data: Date) => Date; - - /** - * 获取指定时间距离当年已经过了多少天 - */ - getDayOfYear: (data: Date) => number; - - /** - * 获取指定时间距离当年已经过了多少周 - */ - getWeekNumber: (data: Date) => number; - - /** - * 获取指定时间的所处季度 - */ - getQuarter: (date: Date) => number; - - /** - * 离当前时间多少天的时间 - */ - getOffsetDate: (date: Date, offset: number) => Date; - - /** - * 离当前时间多少天季度的时间 - */ - getOffsetQuarter: (date: Date, n: number) => Date; - - /** - * 得到本季度的起始月份 - */ - getQuarterStartMonth: (date: Date) => number; - - /** - * 获得本季度的起始日期 - */ - getQuarterStartDate: (date: Date) => number; - - /** - * 获取本季度的其实日期 - */ - getQuarterEndDate: (date: Date) => number; - - /** - * 指定日期n个月之前或之后的日期 - */ - getOffsetMonth: (date: Date, n: number) => Date; - - /** - * 获取本周的起始日期 - */ - getWeekStartDate: (date: Date) => Date; - - /** - * 获取本周的结束日期 - */ - getWeekEndDate: (date: Date) => Date; - - /** - * 格式化打印日期 - */ - print: (date: Date, str: string) => string; -} diff --git a/typescript/core/func/function.ts b/typescript/core/func/function.ts deleted file mode 100644 index 4da9ab104..000000000 --- a/typescript/core/func/function.ts +++ /dev/null @@ -1,46 +0,0 @@ -export type _function = { - - /** - * 创建唯一的名字 - * @param array 已有的名字集合 - * @param name 待生成的名字 - * @return 生成后的名字 - */ - createDistinctName: (array: any[], name: string) => string; - - /** - * 获取搜索结果 - * @param items 待搜索的数据 - * @param keyword 关键字 - * @param param 搜索哪个属性 - */ - getSearchResult: (items: any, keyword: any, param?: string) => { find: any[], match: any[] }; - - /** - * 获取编码后的url - * @param urlTemplate url模板 - * @param param 参数 - */ - getEncodeURL: (urlTemplate: string, param: any) => string; - - /** - * 获取按GB2312排序的结果 - * @param items - * @param key - */ - getSortedResult: (items: T[], key?: string | Function) => T[]; - - /** - * 在方法A执行之前执行方法B - * @param sFunc 方法A - * @param func 方法B - */ - beforeFunc: (sFunc: Function, func: Function) => Function; - - /** - * 在方法A执行之后执行方法B - * @param sFunc 方法A - * @param func 方法B - */ - afterFunc: (sFunc: Function, func: Function) => Function; -} diff --git a/typescript/core/func/index.ts b/typescript/core/func/index.ts deleted file mode 100644 index 7aca32af5..000000000 --- a/typescript/core/func/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { _array } from "./array"; -import { _string } from "./string"; -import { _number } from "./number"; -import { _function } from "./function"; -import { _Date, _date } from "./date"; - -export interface _func extends _array, _string, _number, _date { - Date: _Date; - Func: _function; -} diff --git a/typescript/core/func/number.ts b/typescript/core/func/number.ts deleted file mode 100644 index 9831185bd..000000000 --- a/typescript/core/func/number.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type _number = { - - /** - * 加法函数,用来得到精确的加法结果 - * @param {Number} num 被加数 - * @param {Number} arg 加数 - * @return {Number} 两个数字相加后的结果 - */ - add: (num: number, arg: number) => number; - - /** - * 减法函数,用来得到精确的减法结果 - * @param {Number} num 被减数 - * @param {Number} arg 减数 - * @return {Number} 两个数字相减后的结果 - */ - sub: (num: number, arg: number) => number; - - /** - * 乘法函数,用来得到精确的乘法结果 - * @param {Number} num 被乘数 - * @param {Number} arg 乘数 - * @return {Number} 两个数字相乘后的结果 - */ - mul: (num: number, arg: number) => number; - - /** - * 除法函数,用来得到精确的除法结果 - * @param {Number} num 被除数 - * @param {Number} arg 除数 - * @return {Number} 两个数字相除后的结果 - */ - div: (num: number, arg: number) => number; -} diff --git a/typescript/core/func/string.ts b/typescript/core/func/string.ts deleted file mode 100644 index 02df541a5..000000000 --- a/typescript/core/func/string.ts +++ /dev/null @@ -1,59 +0,0 @@ -export type _string = { - - /** - * 判断字符串是否已指定的字符串开始 - * @param str source字符串 - * @param {String} startTag 指定的开始字符串 - * @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false - */ - startWith: (str: string, startTag: string) => boolean; - - /** - * 判断字符串是否以指定的字符串结束 - * @param str source字符串 - * @param {String} endTag 指定的字符串 - * @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false - */ - endWith: (str: string, endTag: string) => boolean; - - /** - * 获取url中指定名字的参数 - * @param str source字符串 - * @param {String} name 参数的名字 - * @return {String} 参数的值 - */ - getQuery: (str: string, name: string) => string|null; - - /** - * 给url加上给定的参数 - * @param str source字符串 - * @param {Object} paras 参数对象,是一个键值对对象 - * @return {String} 添加了给定参数的url - */ - appendQuery: (str: string, paras: {[key: string]: string|number}) => string; - - /** - * 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 - * @param str source字符串 - * @param {String} s1 要替换的字符串的正则表达式 - * @param {String} s2 替换的结果字符串 - * @returns {String} 替换后的字符串 - */ - replaceAll: (str: string, s1: string, s2: string) => string; - - /** - * 总是让字符串以指定的字符开头 - * @param str source字符串 - * @param {String} start 指定的字符 - * @returns {String} 以指定字符开头的字符串 - */ - perfectStart: (str: string, start: string) => string; - - /** - * 获取字符串中某字符串的所有项位置数组 - * @param str source字符串 - * @param {String} sub 子字符串 - * @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 - */ - allIndexOf: (str: string, sub: string) => number[]; -} diff --git a/typescript/core/i18n.ts b/typescript/core/i18n.ts deleted file mode 100644 index 79903578a..000000000 --- a/typescript/core/i18n.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type _addI18n = (v: string | object) => string; - -export type _i18nText = (key: string, ..._args: any[]) => string; - -export type _i18n = { - addI18n: _addI18n; - i18nText: _i18nText; -} \ No newline at end of file diff --git a/typescript/core/inject.ts b/typescript/core/inject.ts deleted file mode 100644 index e199b06f5..000000000 --- a/typescript/core/inject.ts +++ /dev/null @@ -1,47 +0,0 @@ -type _module = (xtype: string, cls: any) => void; -type _constant = (xtype: string, cls: T) => (() => T); -type _model = (xtype: string, cls: any) => Function; -type _store = (xtype: string, cls: any) => Function; -type _service = (xtype: string, cls: any) => Function; -type _provider = (xtype: string, cls: any) => Function; - -interface _modules { - getModule: (type: string) => any; - getAllModules: () => any; -} - -interface _constants { - getConstant: (type: string) => any; -} - -interface _models { - getModel: (type: string, options?: any) => any; -} - -interface _stores { - getStore: (type: string, options?: any) => any; -} - -interface _providers { - getProvider: (type: string, options?: any) => any; -} - -interface _services { - getService: (type: string, options?: any) => any; -} - - -export type _inject = { - module: _module; - constant: _constant; - model: _model; - store: _store; - provider: _provider; - service: _service; - Modules: _modules; - Constants: _constants; - Models: _models; - Stores: _stores; - Providers: _providers; - Services: _services; -} diff --git a/typescript/core/platform/web/detectElementResize.ts b/typescript/core/platform/web/detectElementResize.ts deleted file mode 100644 index 8e1566ce9..000000000 --- a/typescript/core/platform/web/detectElementResize.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Widget } from "../../../core/widget"; - -export type _DetectElementResize = { - addResizeListener: (widget: Widget, fn: Function) => Function - removeResizeListener: (widget: Widget, fn?: Function) => void -} diff --git a/typescript/core/platform/web/dom.ts b/typescript/core/platform/web/dom.ts deleted file mode 100644 index fbb7e8cf9..000000000 --- a/typescript/core/platform/web/dom.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Widget } from "../../../core/widget"; - - -export type _DOM = { - ready: (fn: Function) => void - - // TODO: 引入jquery描述后处理 - patchProps: (fromElement: any, toElement: any) => void - - hang: (doms: Widget[]) => DocumentFragment - isExist: (obj: Widget) => boolean - preloadImages: (srcArray: string[], onload: Function) => void - getTextSizeWidth: (text: string, fontSize?: number) => number - getTextSizeHeight: (text: string, fontSize?: number) => number - getScrollWidth: () => number - getImage: (param: string, fillStyle?: string, backgroundColor?: string) => { width: number, height: number, src: string, style: string, param: string } - - isColor: (color: string) => boolean - isRGBColor: (color: string) => boolean - isHexColor: (color: string) => boolean - isDarkColor: (hex: string) => boolean - getContrastColor: (color: string) => string - rgb2hex: (rgbColour: string) => string - rgb2json: (rgbColour: string) => { r: number, g: number, b: number } - rgba2json: (rgbColour: string) => { r: number, g: number, b: number, a:number } - json2rgb: (rgb: { r: number, g: number, b: number }) => string - json2rgba: (rgba: { r: number, g: number, b: number, a:number }) => string - int2hex: (strNum: number) => string - hex2rgb: (color: string) => string - rgba2rgb: (rgbColor: string, bgColor?:string) => string - - getLeftPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getInnerLeftPosition: (combo: Widget, popup?: Widget, extraWidth?: number) => { left: number} - getRightPosition: (combo: Widget, popup?: Widget, extraWidth?: number) => { left: number} - getInnerRightPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getTopPosition: (combo: Widget, popup: Widget, extraHeight?: number) => { top: number} - getBottomPosition: (combo: Widget, popup?: Widget, extraHeight?: number) => { top: number} - isLeftSpaceEnough: (combo: Widget, popup: Widget, extraWidth?: number) => boolean - isInnerLeftSpaceEnough: (combo: Widget, popup: Widget, extraWidth?: number) => boolean - isRightSpaceEnough: (combo: Widget, popup: Widget, extraWidth?: number) => boolean - isInnerRightSpaceEnough: (combo: Widget, popup: Widget, extraWidth?: number) => boolean - isTopSpaceEnough: (combo: Widget, popup?: Widget, extraHeight?: number) => boolean - isBottomSpaceEnough: (combo: Widget, popup?: Widget, extraHeight?: number) => boolean - isRightSpaceLarger: (combo: Widget) => boolean - isBottomSpaceLarger: (combo: Widget) => boolean - getLeftAlignPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getLeftAdaptPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getRightAlignPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getRightAdaptPosition: (combo: Widget, popup: Widget, extraWidth?: number) => { left: number} - getTopAlignPosition: (combo: Widget, popup: Widget, extraHeight?:number, needAdaptHeight?:boolean) => { top: number, adaptHeight?: number} - getTopAdaptPosition: (combo: Widget, popup: Widget, extraHeight?:number, needAdaptHeight?:boolean) => { top: number, adaptHeight?: number} - getBottomAlignPosition: (combo: Widget, popup: Widget, extraHeight?:number, needAdaptHeight?:boolean) => { top: number, adaptHeight?: number} - getBottomAdaptPosition: (combo: Widget, popup: Widget, extraHeight?:number, needAdaptHeight?:boolean) => { top: number, adaptHeight?: number} - getCenterAdaptPosition: (combo: Widget, popup: Widget) => { left: number } - getMiddleAdaptPosition: (combo: Widget, popup: Widget) => { top: number } - getComboPositionByDirections: (combo: Widget, popup: Widget, extraWidth?:number, extraHeight?:number, needAdaptHeight?:number, directions?:number) => { dir: string, left?: number, top?: number, change?: string} - getComboPosition: (combo: Widget, popup: Widget, extraWidth?:number, extraHeight?:number, needAdaptHeight?:number, directions?:number) => { dir: string, left?: number, top?: number, change?: string} -} \ No newline at end of file diff --git a/typescript/core/platform/web/eventListener.ts b/typescript/core/platform/web/eventListener.ts deleted file mode 100644 index d50aa7da1..000000000 --- a/typescript/core/platform/web/eventListener.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type _EventListener = { - listen: (target: EventTarget, eventType: string, callback: Function) => { remove: () => void } - capture: (target: EventTarget, eventType: string, callback: Function) => { remove: () => void } - registerDefault: () => void -} \ No newline at end of file diff --git a/typescript/core/platform/web/function.ts b/typescript/core/platform/web/function.ts deleted file mode 100644 index 406eb95ee..000000000 --- a/typescript/core/platform/web/function.ts +++ /dev/null @@ -1,13 +0,0 @@ -export type _function = { - isIE: () => boolean; - getIEVersion: () => number; - isEdge: () => boolean; - isChrome: () => boolean; - isFireFox: () => boolean; - isOpera: () => boolean; - isSafari: () => boolean; - isMac: () => boolean; - isWindows: () => boolean; - isSupportCss3: (style: any) => boolean; - getSafariVersion: () => number; -} \ No newline at end of file diff --git a/typescript/core/platform/web/index.ts b/typescript/core/platform/web/index.ts deleted file mode 100644 index 79b2a19c5..000000000 --- a/typescript/core/platform/web/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { _function } from "./function"; -import { _EventListener } from './eventListener'; -import { _DetectElementResize } from './detectElementResize'; -import { _load } from './load'; -import { _DOM } from './dom'; - -export interface _web extends _function, _load { - EventListener: _EventListener, - ResizeDetector: _DetectElementResize, - DOM: _DOM -} \ No newline at end of file diff --git a/typescript/core/platform/web/load.ts b/typescript/core/platform/web/load.ts deleted file mode 100644 index 4d49d2aeb..000000000 --- a/typescript/core/platform/web/load.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type _load = { - $import: (src: string, ext?: string, must?: boolean) => void -} \ No newline at end of file diff --git a/typescript/core/plugin.ts b/typescript/core/plugin.ts deleted file mode 100644 index afae32a91..000000000 --- a/typescript/core/plugin.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Widget } from "./widget"; - -type configWidgetFn = (type: string, options: Obj) => void -type configObjectFn = (type: string, widget: Widget) => void - -export type _config = (widgetFunction: configWidgetFn | configWidgetFn[], objectFunction: configObjectFn | configObjectFn[]) => void - -export type _configWidget = (shortcut: string, widgetFunction: configWidgetFn) => void - -export type _registerObject = (shortcut: string, objectFunction: configObjectFn) => void - -export type _Plugin = { - config: _config; - configWidget: _configWidget; - registerObject: _registerObject; -} diff --git a/typescript/core/utils/aes.ts b/typescript/core/utils/aes.ts deleted file mode 100644 index d6e93a497..000000000 --- a/typescript/core/utils/aes.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type _aes = { - aesEncrypt: (text: string, key:string) => string - aesDecrypt: (text: string, key:string) => string -} \ No newline at end of file diff --git a/typescript/core/utils/aspect.ts b/typescript/core/utils/aspect.ts deleted file mode 100644 index 94b4eed10..000000000 --- a/typescript/core/utils/aspect.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type _aspect = { - before: (target: object, methodName: string, advice: Function) => { advice: Function, index: number, remove: () => void} - after: (target: object, methodName: string, advice: Function) => { advice: Function, index: number, remove: () => void} -} \ No newline at end of file diff --git a/typescript/core/utils/base64.ts b/typescript/core/utils/base64.ts deleted file mode 100644 index 3bbfefcf4..000000000 --- a/typescript/core/utils/base64.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type _base64 = { - encode: (input: string) => string - decode: (text: string) => string -} \ No newline at end of file diff --git a/typescript/core/utils/cache.ts b/typescript/core/utils/cache.ts deleted file mode 100644 index 3f1b788e2..000000000 --- a/typescript/core/utils/cache.ts +++ /dev/null @@ -1,14 +0,0 @@ -export type _cache = { - setUsername: (username: string) => void - getUsername: () => string - _getKeyPrefix: () => string - _generateKey: (key?: string) => void - getItem: (key?: string) => string - setItem: (key: string, value: any) => void - removeItem: (key: string) => void - clear: () => void - keys: () => string[] - addCookie: (name: string, value: any, path?: string, expiresHours?: number) => void - getCookie: (name: string) => string - deleteCookie: (name: string, path?: string) => void -} \ No newline at end of file diff --git a/typescript/core/utils/chinesePY.ts b/typescript/core/utils/chinesePY.ts deleted file mode 100644 index 54ba50141..000000000 --- a/typescript/core/utils/chinesePY.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type _chinesePY = { - makeFirstPY: (str: string, options?: { ignoreMulti?: boolean, splitChar?: string }) => string -} diff --git a/typescript/core/utils/index.ts b/typescript/core/utils/index.ts deleted file mode 100644 index 42b340588..000000000 --- a/typescript/core/utils/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { _aes } from './aes'; -import { _aspect } from './aspect'; -import { _base64 } from './base64'; -import { _cache } from './cache'; -import { _chinesePY } from './chinesePY'; -import { MouseMoveTracker } from './events/mousemovetracker'; -import { WheelHandler } from './events/wheelhandler'; -import { CellSizeAndPositionManager, ScalingCellSizeAndPositionManager } from './cellSizeAndPositionManager'; -import { Heap } from './heap'; -import { LinkedHashMap } from './linkedHashMap'; -import { LRU } from './lru'; -import { PrefixIntervalTree } from './prefixIntervalTree'; -import { Queue } from './queue'; -import { Section } from './sectionManager'; -import { Tree } from './tree'; -import { Vector, Region } from './vector'; - -export interface _utils extends _aes, _base64, _chinesePY { - aspect: _aspect - Cache: _cache - MouseMoveTracker: typeof MouseMoveTracker - WheelHandler: typeof WheelHandler - CellSizeAndPositionManager: typeof CellSizeAndPositionManager - ScalingCellSizeAndPositionManager: typeof ScalingCellSizeAndPositionManager - Heap: typeof Heap - LinkedHashMap: typeof LinkedHashMap - LRU: typeof LRU - PrefixIntervalTree: typeof PrefixIntervalTree - Queue: typeof Queue - Section: typeof Section - Tree: typeof Tree - Vector: typeof Vector - Region: typeof Region -} diff --git a/typescript/core/var.ts b/typescript/core/var.ts deleted file mode 100644 index 626c8272b..000000000 --- a/typescript/core/var.ts +++ /dev/null @@ -1,133 +0,0 @@ -export interface _var { - MAX: number; - MIN: number; - EVENT_RESPONSE_TIME: number; - zIndex_layer: number; - zIndex_popover: number; - zIndex_popup: number; - zIndex_masker: number; - zIndex_tip: number; - emptyStr: string; - emptyFn: Function; - empty: null, - Key: { - 48: string; - 49: string; - 50: string; - 51: string; - 52: string; - 53: string; - 54: string; - 55: string; - 56: string; - 57: string; - 65: string; - 66: string; - 67: string; - 68: string; - 69: string; - 70: string; - 71: string; - 72: string; - 73: string; - 74: string; - 75: string; - 76: string; - 77: string; - 78: string; - 79: string; - 80: string; - 81: string; - 82: string; - 83: string; - 84: string; - 85: string; - 86: string; - 87: string; - 88: string; - 89: string; - 90: string; - 96: string; - 97: string; - 98: string; - 99: string; - 100: string; - 101: string; - 102: string; - 103: string; - 104: string; - 105: string; - 106: string; - 107: string; - 109: string; - 110: string; - 111: string; - }, - KeyCode: { - BACKSPACE: number; - COMMA: number; - DELETE: number; - DOWN: number; - END: number; - ENTER: number; - ESCAPE: number; - HOME: number; - LEFT: number; - NUMPAD_ADD: number; - NUMPAD_DECIMAL: number; - NUMPAD_DIVIDE: number; - NUMPAD_ENTER: number; - NUMPAD_MULTIPLY: number; - NUMPAD_SUBTRACT: number; - PAGE_DOWN: number; - PAGE_UP: number; - PERIOD: number; - RIGHT: number; - SPACE: number; - TAB: number; - UP: number; - }, - Status: { - SUCCESS: number; - WRONG: number; - START: number; - END: number; - WAITING: number; - READY: number; - RUNNING: number; - OUTOFBOUNDS: number; - NULL: number; - }, - Direction: { - Top: string; - Bottom: string; - Left: string; - Right: string; - Custom: string; - }, - Axis: { - Vertical: string; - Horizontal: string; - }, - Selection: { - Default: number; - None: number; - Single: number; - Multi: number; - All: number; - }, - HorizontalAlign: { - Left: string; - Right: string; - Center: string; - Stretch: string; - }, - VerticalAlign: { - Middle: string; - Top: string; - Bottom: string; - Stretch: string; - }, - StartOfWeek: number; - BlankSplitChar: string; -} diff --git a/typescript/core/widget.ts b/typescript/core/widget.ts deleted file mode 100644 index 3cd8f175e..000000000 --- a/typescript/core/widget.ts +++ /dev/null @@ -1,418 +0,0 @@ -import { OB, _OB } from "./ob"; - -interface RenderEngine { - // TODO: 完成jquery文件夹后把这块改了 - /** - * 创建元素方法,返回的类jQuery对象 - * @param widget widget对象 - */ - createElement: (widget: any) => any; - - /** - * 创建DocumentFragment对象 - */ - createFragment: () => DocumentFragment; -} - -export declare class Widget extends OB { - /** - * 注册渲染引擎 - * @param engine 引擎 - */ - static registerRenderEngine(engine: RenderEngine): void; - - /** - * 渲染引擎 - */ - static _renderEngine: RenderEngine; - - /** - * 出现loading的锁 - */ - __asking: boolean; - - /** - * 同步锁 - */ - __async: boolean; - - /** - * widget类标识符 - */ - widgetName: string | null; - - /** - * 是否为根节点 - */ - _isRoot: boolean; - - /** - * 父节点 - */ - _parent: Widget | null; - // TODO: 完成jquery文件夹后把这块改了 - /** - * 真实dom的类jQuery对象 - */ - element: { - width(): number; - height(): number; - width(width: number | string): Widget["element"]; - height(height: number | string): Widget["element"]; - [key: string]: any; - }; - - /** - * 子元素 - */ - _children: { - [key: string]: Widget; - }; - - /** - * 是否已挂载 - */ - _isMounted: boolean; - - /** - * 手动设置enable - */ - _manualSetEnable: boolean; - - /** - * 手动设置valid - */ - _manualSetValid: boolean; - - _store(): void; - - // 生命周期函数 - /** - * 初始化前 - */ - beforeInit?(cb: Function): void; - - /** - * 渲染前 - */ - beforeRender?(cb: Function): void; - - /** - * 创建前 - */ - beforeCreate?(): void; - - /** - * 创建 - */ - created?(): void; - - /** - * 渲染 - */ - render?(): any; - - /** - * 挂载前 - */ - beforeMount?(): void; - - /** - * 挂载 - */ - mounted?(): void; - - /** - * 更新前 - */ - shouldUpdate?(): void; - - /** - * 更新 - */ - update?(...args: any[]): void; - - /** - * 销毁前 - */ - beforeDestroy?(): void; - - /** - * 销毁 - */ - destroyed?(): void; - - /** - * 初始化render函数 - */ - _initRender: () => void; - - /** - * 内部主render函数 - */ - _render: () => void; - - /** - * 初始化根节点 - */ - _initRoot: () => void; - - /** - * 初始化元素宽度 - */ - _initElementWidth: () => void; - - /** - * 初始化元素高度 - */ - _initElementHeight: () => void; - - /** - * 初始化元素可见 - */ - _initVisual: () => void; - - /** - * 初始化元素可用不可用 - */ - _initEffects: () => void; - - /** - * 设置mounted锁 - */ - _initState: () => void; - - /** - * 生成真实dom - */ - _initElement: () => void; - - /** - * 设置父节点 - */ - _setParent: () => void; - - /** - * @param force 是否强制挂载子节点 - * @param deep 子节点是否也是按照当前force处理 - * @param lifeHook 生命周期钩子触不触发,默认触发 - * @param predicate 递归每个widget的回调 - */ - _mount(force?: boolean, deep?: boolean, lifeHook?: boolean, predicate?: Function): boolean; - - /** - * 挂载子节点 - */ - _mountChildren?(): void; - - /** - * 是否已挂载 - */ - isMounted(): boolean; - - /** - * 设置宽度 - */ - setWidth(w: number | string): void; - - /** - * 设置高度 - */ - setHeight(h: number | string): void; - - /** - * 设置可用 - */ - _setEnable(enable: boolean): void; - - /** - * 设置合法 - */ - _setValid(valid: boolean): void; - - /** - * 设置可见 - */ - _setVisible(visible: boolean): void; - - /** - * 设置是否可用 - */ - setEnable(enable: boolean): void; - - /** - * 设置是否可见 - */ - setVisible(visible: boolean): void; - - /** - * 设置是否合法 - */ - setValid(valid: boolean): void; - - /** - * 设置反馈效果 - * @param args arguments参数 - */ - doBehavior(...args: any[]): void; - - /** - * 获取宽度 - */ - getWidth(): number; - - /** - * 获取高度 - */ - getHeight(): number; - - /** - * 是否合法 - */ - isValid(): boolean; - - /** - * 新增子元素 - */ - addWidget(widget: Widget): Widget; - addWidget(_name: any, _widget: Widget): Widget; - - /** - * 根据wigetname获取子元素实例 - */ - getWidgetByName(_name: string): Widget | undefined; - - /** - * 移除子元素 - * @param nameOrWidget widgetName或widget实例 - */ - removeWidget(nameOrWidget: string | Widget): void; - - /** - * 是否有某个子元素 - */ - hasWidget(name: string): boolean; - - /** - * 获取widgetName - */ - getName(): string; - - /** - * 设置tag - * @param tag html tag - */ - setTag(tag: string): void; - - /** - * 获取tag - */ - getTag(): string; - - /** - * 设置属性 - * @param key 键 - * @param value 值 - */ - attr(key: string | { [key: string]: any }, value?: any): any; - - /** - * 获取text - */ - getText(): string; - - /** - * 设置text - */ - setText(text: string): void; - - /** - * 获取值 - */ - getValue(): any; - - /** - * 设置值 - */ - setValue(...args: any[]): void; - - /** - * 获取是否enable - */ - isEnabled(): boolean; - - /** - * 是否可见 - */ - isVisible(): boolean; - - /** - * disable元素 - */ - disable(): void; - - /** - * enable元素 - */ - enable(): void; - - /** - * 是widget合法 - */ - valid(): void; - - /** - * 使元素不合法 - */ - invalid(): void; - - /** - * 使不可见 - */ - invisible(..._args: any[]): void; - - /** - * 可见 - */ - visible(..._args: any[]): void; - - /** - * 清除子元素 - */ - __d(): void; - - /** - * 取消挂载 - */ - _unMount(): void; - - /** - * watch响应式数据 - */ - __watch any>(getter: T, handler: Function, options?: Obj): ReturnType - - /** - * hang元素 - */ - isolate(): void; - - /** - * 请除元素 - */ - empty(): void; - - /** - * 刷新控件 - */ - reset(): void; - - /** - * 内部destory方法 - */ - _destroy(): void; - - /** - * destory元素 - */ - destroy(): void; -} diff --git a/typescript/core/worker/controller/worker.controller.ts b/typescript/core/worker/controller/worker.controller.ts deleted file mode 100644 index 123bba98a..000000000 --- a/typescript/core/worker/controller/worker.controller.ts +++ /dev/null @@ -1,131 +0,0 @@ -import type { IWorkerController, IWorkerMessage } from '../worker.core'; -import { WorkerChannel } from '../worker.channel'; - -/** - * 通信控制器 - * - * @class WorkerBaseController - */ -export class WorkerBaseController implements IWorkerController { - /** - * 原生 worker, 在子类中实例化 - */ - protected worker: Worker; - - /** - * 通信 Channel, 在子类中实例化 - */ - protected channel: WorkerChannel; - - /** - * 事务处理器 Map - */ - protected actionHandlerMap: { - [propsName: string]: (payload: any) => any; - }; - - public constructor() { - this.actionHandlerMap = {}; - } - - /** - * 发送事务,不等待结果 - * - * @param actionType 事务类型 - * @param payload 负载 - */ - public request(actionType: string, payload: any): void { - if (this.channel) { - return this.channel.request(actionType, payload); - } - - console.error('No channel.'); - - return; - } - - /** - * 发送 Promise 形式的事务, 在 then 中获取响应 - * - * @param actionType 事务类型 - * @param payload 负载 - * @param [timeout] 响应的超时; Worker 通道是可靠的, 超时后只上报, 不阻止当前请求 - */ - public requestPromise(actionType: string, payload: any = '', timeout?: number): Promise { - // 有 Channel 实例才能进行通信, 此时还没有实例化是浏览器不支持创建 worker - if (this.channel) { - return this.channel.requestPromise(actionType, payload, timeout); - } - - // 兼容上层调用的 .then().catch() - return Promise.reject(new Error('No channel.')); - } - - /** - * 添加事务处理器, 不允许重复添加 - * - * @param actionType 事务类型 - * @param handler 事务处理器 - */ - public addActionHandler(actionType: string, handler: (payload: any) => any): void { - if (this.hasActionHandler(actionType)) { - throw new Error(`Add action \`${actionType}\` handler repeat`); - } - this.actionHandlerMap[actionType] = handler; - } - - /** - * 事务处理器, 提供给通信 Channel 调用 - * - * @param message 会话消息 - * @returns - */ - public actionHandler(message: IWorkerMessage): Promise { - const { actionType, payload } = message; - - if (this.hasActionHandler(actionType)) { - // 执行指定的事务处理器, 并返回 Promise 封装的事务结果 - try { - const actionResult = this.actionHandlerMap[actionType](payload); - - // 对于 Promise 形式的结果, 需要进行 Promise 错误捕获 - if (BI.isPromise(actionResult)) { - return actionResult.catch(error => Promise.reject(error)); - } - - // 对数据结果, 包装为 Promise - return Promise.resolve(actionResult); - } catch (error) { - // 继续抛出给外层 - return Promise.reject(error); - } - } else { - throw new Error(`Not Found Session Handler \`${actionType}\`.`); - } - } - - /** - * 添加 worker onmessage 事件的回调 - * - * @param {(event: any) => void} onmessage 回调函数 - * @returns {() => void} 移除监听函数 - */ - public addOnmessageListener(onmessage: (event: any) => void): () => void { - this.worker.addEventListener('message', onmessage); - - // 返回移除监听函数 - return () => { - this.worker.removeEventListener('message', onmessage); - }; - } - - /** - * 判断是否有指定事务的处理器 - * - * @param actionType 事务类型 - * @returns {boolean} - */ - protected hasActionHandler(actionType: string): boolean { - return !!this.actionHandlerMap[actionType]; - } -} diff --git a/typescript/index.ts b/typescript/index.ts deleted file mode 100644 index cf63c604d..000000000 --- a/typescript/index.ts +++ /dev/null @@ -1,597 +0,0 @@ -import { Combo } from "./base/combination/combo"; -import { ButtonGroup } from "./base/combination/group.button"; -import { Tab } from "./base/combination/tab"; -import { Pane } from "./base/pane"; -import { BasicButton } from "./base/single/button/button.basic"; -import { NodeButton } from "./base/single/button/button.node"; -import { Button } from "./base/single/button/buttons/button"; -import { TextButton } from "./base/single/button/buttons/button.text"; -import { IconTextItem } from "./base/single/button/listitem/icontextitem"; -import { Editor } from "./base/single/editor/editor"; -import { Iframe } from "./base/single/iframe/iframe"; -import { Checkbox } from "./base/single/input/checkbox"; -import { Input } from "./base/single/input/input"; -import { AbstractLabel } from "./base/single/label/abstract.label"; -import { Label } from "./base/single/label/label"; -import { Single } from "./base/single/single"; -import { Text } from "./base/single/text"; -import { Trigger } from "./base/single/trigger/trigger"; -import { IconChangeButton } from "./case/button/icon/icon.change"; -import { MultiSelectItem } from "./case/button/item.multiselect"; -import { BubbleCombo } from "./case/combo/bubblecombo/combo.bubble"; -import { TextValueCombo } from "./case/combo/combo.textvalue"; -import { TextValueComboPopup } from "./case/combo/popup.textvalue"; -import { SmallTextValueCombo } from "./case/combo/combo.textvaluesmall"; -import { SearchTextValueCombo } from "./case/combo/searchtextvaluecombo/combo.searchtextvalue"; -import { SignEditor } from "./case/editor/editor.sign"; -import { StateEditor } from "./case/editor/editor.state"; -import { AllValueMultiTextValueCombo } from "./component/allvaluemultitextvaluecombo/allvalue.multitextvalue.combo"; -import { Form } from "./component/form/form"; -import { AbstractTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser"; -import { AbstractListTreeValueChooser } from "./component/treevaluechooser/abstract.treevaluechooser.list"; -import { Action, ActionFactory } from "./core/action/action"; -import { ShowAction } from "./core/action/action.show"; -import { _base } from "./core/base"; -import { Behavior, BehaviorFactory } from "./core/behavior/behavior"; -import { HighlightBehavior } from "./core/behavior/behavior.highlight"; -import { RedMarkBehavior } from "./core/behavior/behavior.redmark"; -import * as decorator from "./core/decorator/decorator"; -import { _func } from "./core/func"; -import { _i18n } from "./core/i18n"; -import { _Plugin } from "./core/plugin"; -import { _var } from "./core/var"; -import { OB } from "./core/ob"; -import { Widget } from "./core/widget"; -import { _inject } from "./core/inject"; -import { Layout } from "./core/wrapper/layout"; -import { AbsoluteLayout } from "./core/wrapper/layout/layout.absolute"; -import { HTapeLayout, VTapeLayout } from "./core/wrapper/layout/layout.tape"; -import { HorizontalFillLayout } from "./core/wrapper/layout/fill/fill.horizontal"; -import { VerticalFillLayout } from "./core/wrapper/layout/fill/fill.vertical"; -import { VerticalLayout } from "./core/wrapper/layout/layout.vertical"; -import { DefaultLayout } from "./core/wrapper/layout/layout.default"; -import { DownListCombo } from "./widget/downlist/combo.downlist"; -import { DownListPopup } from "./widget/downlist/popup.downlist"; -import { Icon } from "./base/single/icon/icon"; -import { LeftVerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.leftvertical"; -import { - LeftRightVerticalAdaptLayout, - RightVerticalAdaptLayout, -} from "./core/wrapper/layout/adapt/adapt.leftrightvertical"; -import { IconTextIconItem } from "./base/single/button/listitem/icontexticonitem"; -import { HorizontalAutoLayout } from "./core/wrapper/layout/adapt/auto.horizontal"; -import { InlineVerticalAdaptLayout } from "./core/wrapper/layout/adapt/inline.vertical"; -import { TableAdaptLayout } from "./core/wrapper/layout/adapt/adapt.table"; -import { IconButton } from "./base/single/button/buttons/button.icon"; -import { TextEditor } from "./widget/editor/editor.text"; -import { IconLabel } from "./base/single/label/icon.label"; -import { Popover, BarPopover } from "./base/layer/layer.popover"; -import { IconCombo } from "./case/combo/iconcombo/combo.icon"; -import { DynamicDateCombo } from "./widget/dynamicdate/dynamicdate.combo"; -import { CustomTree } from "./base/tree/customtree"; -import { ButtonTree } from "./base/combination/tree.button"; -import { IconArrowNode } from "./case/button/node/node.icon.arrow"; -import { MidTreeLeafItem } from "./case/button/treeitem/item.mid.treeleaf"; -import { FirstTreeLeafItem } from "./case/button/treeitem/item.first.treeleaf"; -import { LastTreeLeafItem } from "./case/button/treeitem/item.last.treeleaf"; -import { SmallTextEditor } from "./widget/editor/editor.text.small"; -import { MultifileEditor } from "./widget/editor/editor.multifile"; -import { AbsoluteCenterLayout } from "./core/wrapper/layout/adapt/absolute.center"; -import { HorizontalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.horizontal"; -import { FloatLeftLayout, FloatRightLayout } from "./core/wrapper/layout/layout.flow"; -import { CenterAdaptLayout } from "./core/wrapper/layout/adapt/adapt.center"; -import { VerticalAdaptLayout } from "./core/wrapper/layout/adapt/adapt.vertical"; -import { MultiSelectInsertCombo } from "./widget/multiselect/multiselect.insert.combo"; -import { MultiSelectCombo } from "./widget/multiselect/multiselect.combo"; -import { SearchEditor } from "./widget/editor/editor.search"; -import { MultiLayerSingleLevelTree } from "./widget/multilayersingletree/multilayersingletree.leveltree"; -import { SimpleColorChooser } from "./case/colorchooser/colorchooser.simple"; -import { ColorChooser } from "./case/colorchooser/colorchooser"; -import { A } from "./base/a/a"; -import { Html } from "./base/single/html/html"; -import { Switcher } from "./base/combination/switcher"; -import { Expander } from "./base/combination/expander"; -import { Loader } from "./base/combination/loader"; -import { ListPane } from "./case/layer/pane.list"; -import { MultiPopupView } from "./case/layer/layer.multipopup"; -import { MultiSelectBar } from "./case/toolbar/toolbar.multiselect"; -import { SelectList } from "./case/list/list.select"; -import { AbstractAllValueChooser } from "./component/allvaluechooser/abstract.allvaluechooser"; -import { AllValueChooserCombo } from "./component/allvaluechooser/combo.allvaluechooser"; -import { TextAreaEditor } from "./base/single/editor/editor.textarea"; -import { SingleSelectItem } from "./case/button/item.singleselect"; -import { DynamicDateTimeCombo } from "./widget/dynamicdatetime/dynamicdatetime.combo"; -import { MultiTreeCombo } from "./widget/multitree/multi.tree.combo"; -import { CenterLayout } from "./core/wrapper/layout/middle/middle.center"; -import { VirtualGroup } from "./base/combination/group.virtual"; -import { GridLayout } from "./core/wrapper/layout/layout.grid"; -import { TriggerIconButton } from "./case/button/icon/icon.trigger"; -import { Searcher } from "./base/combination/searcher"; -import { ListTreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.listtreevaluechooser"; -import { TreeValueChooserCombo } from "./component/treevaluechooser/combo.treevaluechooser"; -import { TreeValueChooserInsertCombo } from "./component/treevaluechooser/combo.treevaluechooser.insert"; -import { Radio } from "./base/single/input/radio/radio"; -import { MultiLayerSelectTreePopup } from "./widget/multilayerselecttree/multilayerselecttree.popup"; -import { MultiLayerSingleTreePopup } from "./widget/multilayersingletree/multilayersingletree.popup"; -import { MultiLayerDownListPopup } from "./widget/multilayerdownlist/multilayerdownlist.popup"; -import { TreeView } from "./base/tree/ztree/treeview"; -import { MultiTreePopup } from "./widget/multitree/multi.tree.popup"; -import { SingleSelectRadioItem } from "./case/button/item.singleselect.radio"; -import { SingleSelectInsertCombo } from "./widget/singleselect/singleselect.insert.combo"; -import { SingleSelectCombo } from "./widget/singleselect/singleselect.combo"; -import { CardLayout } from "./core/wrapper/layout/layout.card"; -import { DynamicYearMonthCombo } from "./widget/yearmonth/combo.yearmonth"; -import { TimeCombo } from "./widget/time/time.combo"; -import { ListTreeView } from "./base/tree/ztree/list/listtreeview"; -import { ListAsyncTree } from "./base/tree/ztree/list/listasynctree"; -import { AsyncTree } from "./base/tree/ztree/asynctree"; -import { MultiLayerSingleTreeCombo } from "./widget/multilayersingletree/multilayersingletree.combo"; -import { MultiLayerSelectTreeCombo } from "./widget/multilayerselecttree/multilayerselecttree.combo"; -import { MultiLayerDownListCombo } from "./widget/multilayerdownlist/multilayerdownlist.combo"; -import { MultiTreeListCombo } from "./widget/multitree/multi.tree.list.combo"; -import { MultiTreeInsertCombo } from "./widget/multitree/multi.tree.insert.combo"; -import { TextValueDownListCombo } from "./widget/textvaluedownlistcombo/combo.textvaluedownlist"; -import { Switch } from "./case/button/switch"; -import { HorizontalLayout } from "./core/wrapper/layout/layout.horizontal"; -import { ShelterEditor } from "./case/editor/editor.shelter"; -import { TextTrigger } from "./case/trigger/trigger.text"; -import { SelectTextTrigger } from "./case/trigger/trigger.text.select"; -import { DateInterval } from "./widget/timeinterval/dateinterval"; -import { DynamicDatePane } from "./widget/datepane/datepane"; -import { AllCountPager } from "./case/pager/pager.all.count"; -import { DirectionPager } from "./case/pager/pager.direction"; -import { PopupView } from "./base/layer/layer.popup"; -import { BubblePopupView, BubblePopupBarView, TextBubblePopupBarView } from "./case/combo/bubblecombo/popup.bubble"; -import { ArrowTreeGroupNodeCheckbox } from "./case/checkbox/check.arrownode"; -import { NumberInterval } from "./widget/numberinterval/numberinterval"; -import { DynamicYearQuarterCombo } from "./widget/yearquarter/combo.yearquarter"; -import { DynamicYearCombo } from "./widget/year/combo.year"; -import { DynamicYearPopup } from "./widget/year/popup.year"; -import { IntervalSlider } from "./widget/intervalslider/intervalslider"; -import { MultiSelectInsertList } from "./widget/multiselectlist/multiselectlist.insert"; -import { YearMonthInterval } from "./widget/yearmonthinterval/yearmonthinterval"; -import { NumberEditor } from "./widget/numbereditor/numbereditor"; -import { TextValueCheckCombo } from "./case/combo/textvaluecheckcombo/combo.textvaluecheck"; -import { Segment } from "./case/segment/segment"; -import { LinearSegment } from "./case/linersegment/linear.segment"; -import { Img } from "./base/single/img/img"; -import { EditorIconCheckCombo } from "./case/combo/editoriconcheckcombo/combo.editiconcheck"; -import { IconTextValueCombo } from "./case/combo/icontextvaluecombo/combo.icontextvalue"; -import { ListView } from "./base/list/listview"; -import { VirtualList } from "./base/list/virtuallist"; -import { VirtualGroupList } from "./base/list/virtualgrouplist"; -import { FloatCenterLayout } from "./core/wrapper/layout/middle/middle.float.center"; -import { _msg } from "./base/foundation/message"; -import { _web } from "./core/platform/web"; -import { DynamicYearMonthPopup } from "./widget/yearmonth/popup.yearmonth"; -import { _utils } from "./core/utils"; -import { Controller } from "./core/controller/controller"; -import { LayerController } from "./core/controller/controller.layer"; -import { DateCalendarPopup } from "./widget/date/calendar/popup.calendar.date"; -import { Tree, Node } from "./core/utils/tree"; -import { TextNode } from "./base/single/button/node/textnode"; -import { TextValueCheckComboPopup } from "./case/combo/textvaluecheckcombo/popup.textvaluecheck"; -import { ImageButton } from "./base/single/button/buttons/button.image"; -import { History, Router } from "./router/router"; -import { DateTimeCombo } from "./widget/datetime/datetime.combo"; -import { FloatHorizontalLayout } from "./core/wrapper/layout/adapt/float.horizontal"; -import { AdaptiveLayout } from "./core/wrapper/layout/layout.adaptive"; -import { HexColorChooserPopup } from "./case/colorchooser/colorchooser.popup.hex"; -import { BlankIconTextItem } from "./base/single/button/listitem/blankicontextitem"; -import { Broadcasts, Layers } from "./base/base"; -import { BroadcastController } from "./core/controller/controller.broadcast"; -import { Pager } from "./base/pager/pager"; -import { TimeInterval } from "./widget/timeinterval/timeinterval"; -import { DynamicDateTimePane } from "./widget/datetimepane/datetimepane"; -import { SingleSelectInsertList } from "./widget/singleselect/singleselectlist.insert"; -import { MultiSelectTree } from "./widget/multiselecttree/multiselecttree"; -import { HtmlLabel } from "./base/single/label/html.label"; -import { TreeValueChooserPane } from "./component/treevaluechooser/pane.treevaluechooser"; -import { TdLayout } from "./core/wrapper/layout/layout.td"; -import { MultiLayerSelectLevelTree } from "./widget/multilayerselecttree/multilayerselecttree.leveltree"; -import { SelectTreeExpander } from "./widget/selecttree/selecttree.expander"; -import { DownListGroupItem } from "./widget/downlist/item.downlistgroup"; -import { VerticalStickyLayout } from "./core/wrapper/layout/sticky/sticky.vertical"; -import { HorizontalStickyLayout } from "./core/wrapper/layout/sticky/sticky.horizontal"; -import { TableLayout } from "./core/wrapper/layout/layout.table"; -import "./shims-tsx"; -import { Workers } from "./core/worker/workers"; - - -export interface BI extends _func, _i18n, _base, _inject, _var, _web, _utils { - OB: typeof OB; - Plugin: _Plugin; - Widget: typeof Widget; - Single: typeof Single; - BasicButton: typeof BasicButton; - NodeButton: typeof NodeButton; - Checkbox: typeof Checkbox; - Button: typeof Button; - TextButton: typeof TextButton; - IconChangeButton: typeof IconChangeButton; - Trigger: typeof Trigger; - Action: typeof Action; - ActionFactory: typeof ActionFactory; - ShowAction: typeof ShowAction; - Controller: typeof Controller; - Layers: Layers; - LayerController: typeof LayerController; - Broadcasts: Broadcasts; - BroadcastController: typeof BroadcastController; - Behavior: typeof Behavior; - BehaviorFactory: typeof BehaviorFactory; - HighlightBehavior: typeof HighlightBehavior; - RedMarkBehavior: typeof RedMarkBehavior; - Pane: typeof Pane; - Tab: typeof Tab; - ButtonGroup: typeof ButtonGroup; - Combo: typeof Combo; - TextValueCombo: typeof TextValueCombo; - TextValueComboPopup: typeof TextValueComboPopup; - SmallTextValueCombo: typeof SmallTextValueCombo; - BubbleCombo: typeof BubbleCombo; - AllValueMultiTextValueCombo: typeof AllValueMultiTextValueCombo; - Form: typeof Form; - IconTextItem: typeof IconTextItem; - MultiSelectItem: typeof MultiSelectItem; - AbstractLabel: typeof AbstractLabel; - Label: typeof Label; - Text: typeof Text; - Editor: typeof Editor; - SignEditor: typeof SignEditor; - StateEditor: typeof StateEditor; - Layout: typeof Layout; - HTapeLayout: typeof HTapeLayout; - VTapeLayout: typeof VTapeLayout; - AbstractTreeValueChooser: typeof AbstractTreeValueChooser; - AbstractListTreeValueChooser: typeof AbstractListTreeValueChooser; - ListTreeValueChooserInsertCombo: typeof ListTreeValueChooserInsertCombo; - TreeValueChooserCombo: typeof TreeValueChooserCombo; - TreeValueChooserInsertCombo: typeof TreeValueChooserInsertCombo; - MultiLayerSelectTreePopup: typeof MultiLayerSelectTreePopup; - MultiLayerSingleTreePopup: typeof MultiLayerSingleTreePopup; - MultiLayerDownListPopup: typeof MultiLayerDownListPopup; - TreeView: typeof TreeView; - ListTreeView: typeof ListTreeView; - ListAsyncTree: typeof ListAsyncTree; - AsyncTree: typeof AsyncTree; - MultiLayerSingleTreeCombo: typeof MultiLayerSingleTreeCombo; - MultiLayerSelectTreeCombo: typeof MultiLayerSelectTreeCombo; - MultiLayerDownListCombo: typeof MultiLayerDownListCombo; - MultiTreeListCombo: typeof MultiTreeListCombo; - MultiTreeInsertCombo: typeof MultiTreeInsertCombo; - Decorators: typeof decorator; - DownListCombo: typeof DownListCombo; - DownListPopup: typeof DownListPopup; - Iframe: typeof Iframe; - AbsoluteLayout: typeof AbsoluteLayout; - HorizontalFillLayout: typeof HorizontalFillLayout; - VerticalFillLayout: typeof VerticalFillLayout; - VerticalLayout: typeof VerticalLayout; - DefaultLayout: typeof DefaultLayout; - Input: typeof Input; - SearchTextValueCombo: typeof SearchTextValueCombo; - Icon: typeof Icon; - LeftVerticalAdaptLayout: typeof LeftVerticalAdaptLayout; - LeftRightVerticalAdaptLayout: typeof LeftRightVerticalAdaptLayout; - IconTextIconItem: typeof IconTextIconItem; - HorizontalAutoLayout: typeof HorizontalAutoLayout; - InlineVerticalAdaptLayout: typeof InlineVerticalAdaptLayout; - RightVerticalAdaptLayout: typeof RightVerticalAdaptLayout; - TableAdaptLayout: typeof TableAdaptLayout; - AbsoluteCenterLayout: typeof AbsoluteCenterLayout; - HorizontalAdaptLayout: typeof HorizontalAdaptLayout; - FloatLeftLayout: typeof FloatLeftLayout; - FloatRightLayout: typeof FloatRightLayout; - CenterAdaptLayout: typeof CenterAdaptLayout; - VerticalAdaptLayout: typeof VerticalAdaptLayout; - IconButton: typeof IconButton; - TriggerIconButton: typeof TriggerIconButton; - Searcher: typeof Searcher; - TextEditor: typeof TextEditor; - Radio: typeof Radio; - A: typeof A; - Html: typeof Html; - Switcher: typeof Switcher; - Expander: typeof Expander; - Loader: typeof Loader; - ListPane: typeof ListPane; - MultiPopupView: typeof MultiPopupView; - MultiSelectBar: typeof MultiSelectBar; - SelectList: typeof SelectList; - IconLabel: typeof IconLabel; - Popover: typeof Popover; - BarPopover: typeof BarPopover; - IconCombo: typeof IconCombo; - DynamicDateCombo: typeof DynamicDateCombo; - CustomTree: typeof CustomTree; - ButtonTree: typeof ButtonTree; - IconArrowNode: typeof IconArrowNode; - MidTreeLeafItem: typeof MidTreeLeafItem; - FirstTreeLeafItem: typeof FirstTreeLeafItem; - LastTreeLeafItem: typeof LastTreeLeafItem; - SmallTextEditor: typeof SmallTextEditor; - MultifileEditor: typeof MultifileEditor; - MultiSelectInsertCombo: typeof MultiSelectInsertCombo; - MultiSelectCombo: typeof MultiSelectCombo; - SearchEditor: typeof SearchEditor; - MultiLayerSingleLevelTree: typeof MultiLayerSingleLevelTree; - SimpleColorChooser: typeof SimpleColorChooser; - ColorChooser: typeof ColorChooser; - AbstractAllValueChooser: typeof AbstractAllValueChooser; - AllValueChooserCombo: typeof AllValueChooserCombo; - TextAreaEditor: typeof TextAreaEditor; - SingleSelectItem: typeof SingleSelectItem; - DynamicDateTimeCombo: typeof DynamicDateTimeCombo; - MultiTreeCombo: typeof MultiTreeCombo; - CenterLayout: typeof CenterLayout; - VirtualGroup: typeof VirtualGroup; - GridLayout: typeof GridLayout; - MultiTreePopup: typeof MultiTreePopup; - SingleSelectRadioItem: typeof SingleSelectRadioItem; - SingleSelectInsertCombo: typeof SingleSelectInsertCombo; - SingleSelectCombo: typeof SingleSelectCombo; - CardLayout: typeof CardLayout; - DynamicYearMonthCombo: typeof DynamicYearMonthCombo; - TimeCombo: typeof TimeCombo; - TextValueDownListCombo: typeof TextValueDownListCombo; - Switch: typeof Switch; - HorizontalLayout: typeof HorizontalLayout; - ShelterEditor: typeof ShelterEditor; - TextTrigger: typeof TextTrigger; - SelectTextTrigger: typeof SelectTextTrigger; - DateInterval: typeof DateInterval; - DynamicDatePane: typeof DynamicDatePane; - AllCountPager: typeof AllCountPager; - DirectionPager: typeof DirectionPager; - Pager: typeof Pager; - PopupView: typeof PopupView; - BubblePopupView: typeof BubblePopupView; - BubblePopupBarView: typeof BubblePopupBarView; - TextBubblePopupBarView: typeof TextBubblePopupBarView; - ArrowTreeGroupNodeCheckbox: typeof ArrowTreeGroupNodeCheckbox; - NumberInterval: typeof NumberInterval; - DynamicYearQuarterCombo: typeof DynamicYearQuarterCombo; - DynamicYearCombo: typeof DynamicYearCombo; - DynamicYearPopup: typeof DynamicYearPopup; - IntervalSlider: typeof IntervalSlider; - MultiSelectInsertList: typeof MultiSelectInsertList; - YearMonthInterval: typeof YearMonthInterval; - TextValueCheckCombo: typeof TextValueCheckCombo; - NumberEditor: typeof NumberEditor; - Segment: typeof Segment; - LinearSegment: typeof LinearSegment; - Img: typeof Img; - EditorIconCheckCombo: typeof EditorIconCheckCombo; - IconTextValueCombo: typeof IconTextValueCombo; - ListView: typeof ListView; - VirtualList: typeof VirtualList; - VirtualGroupList: typeof VirtualGroupList; - FloatCenterLayout: typeof FloatCenterLayout; - Msg: _msg; - DynamicYearMonthPopup: typeof DynamicYearMonthPopup; - DateCalendarPopup: typeof DateCalendarPopup; - TextNode: typeof TextNode; - TextValueCheckComboPopup: typeof TextValueCheckComboPopup; - ImageButton: typeof ImageButton; - Router: typeof Router; - history: History, - DateTimeCombo: typeof DateTimeCombo; - FloatHorizontalLayout: typeof FloatHorizontalLayout; - AdaptiveLayout: typeof AdaptiveLayout; - HexColorChooserPopup: typeof HexColorChooserPopup; - BlankIconTextItem: typeof BlankIconTextItem; - TimeInterval: typeof TimeInterval; - DynamicDateTimePane: typeof DynamicDateTimePane; - SingleSelectInsertList: typeof SingleSelectInsertList; - MultiSelectTree: typeof MultiSelectTree; - HtmlLabel: typeof HtmlLabel; - TreeValueChooserPane: typeof TreeValueChooserPane; - TdLayout: typeof TdLayout; - MultiLayerSelectLevelTree: typeof MultiLayerSelectLevelTree; - SelectTreeExpander: typeof SelectTreeExpander; - DownListGroupItem: typeof DownListGroupItem; - VerticalStickyLayout: typeof VerticalStickyLayout; - HorizontalStickyLayout: typeof HorizontalStickyLayout; - TableLayout: typeof TableLayout; - Workers: typeof Workers; -} - -export default { - Decorators: decorator, - Workers, -}; -export { - OB, - Widget, - Single, - BasicButton, - Checkbox, - Icon, - LeftVerticalAdaptLayout, - LeftRightVerticalAdaptLayout, - SearchTextValueCombo, - Input, - IconTextItem, - AllValueMultiTextValueCombo, - IconTextIconItem, - Layout, - HorizontalAutoLayout, - InlineVerticalAdaptLayout, - RightVerticalAdaptLayout, - TableAdaptLayout, - AbsoluteCenterLayout, - HorizontalAdaptLayout, - FloatLeftLayout, - FloatRightLayout, - HorizontalFillLayout, - VerticalFillLayout, - VerticalLayout, - AbsoluteLayout, - DefaultLayout, - HTapeLayout, - CenterAdaptLayout, - VTapeLayout, - VerticalAdaptLayout, - IconButton, - Trigger, - TriggerIconButton, - Action, - ActionFactory, - ShowAction, - Controller, - LayerController, - BroadcastController, - Behavior, - BehaviorFactory, - RedMarkBehavior, - HighlightBehavior, - Searcher, - AbstractLabel, - Label, - TextButton, - DownListCombo, - DownListPopup, - IconChangeButton, - Button, - TextEditor, - A, - Html, - Switcher, - Expander, - BubbleCombo, - Loader, - ListPane, - MultiPopupView, - MultiSelectBar, - SelectList, - TextValueCombo, - TextValueComboPopup, - SmallTextValueCombo, - Editor, - IconLabel, - Popover, - BarPopover, - Tab, - AbstractTreeValueChooser, - AbstractListTreeValueChooser, - ListTreeValueChooserInsertCombo, - TreeValueChooserCombo, - TreeValueChooserInsertCombo, - MultiLayerSelectTreePopup, - MultiLayerSingleTreePopup, - MultiLayerDownListPopup, - TreeView, - ListTreeView, - ListAsyncTree, - AsyncTree, - MultiLayerSingleTreeCombo, - MultiLayerSelectTreeCombo, - MultiLayerDownListCombo, - MultiTreeListCombo, - MultiTreeInsertCombo, - Combo, - IconCombo, - DynamicDateCombo, - Radio, - MultiSelectItem, - CustomTree, - ButtonGroup, - ButtonTree, - NodeButton, - IconArrowNode, - MidTreeLeafItem, - FirstTreeLeafItem, - LastTreeLeafItem, - SmallTextEditor, - MultifileEditor, - SignEditor, - StateEditor, - MultiSelectInsertCombo, - MultiSelectCombo, - SearchEditor, - Text, - Pane, - MultiLayerSingleLevelTree, - ColorChooser, - SimpleColorChooser, - AbstractAllValueChooser, - AllValueChooserCombo, - TextAreaEditor, - SingleSelectItem, - DynamicDateTimeCombo, - MultiTreeCombo, - CenterLayout, - VirtualGroup, - GridLayout, - MultiTreePopup, - SingleSelectRadioItem, - SingleSelectInsertCombo, - SingleSelectCombo, - CardLayout, - DynamicYearMonthCombo, - TimeCombo, - Iframe, - TextValueDownListCombo, - Switch, - HorizontalLayout, - ShelterEditor, - Form, - TextTrigger, - SelectTextTrigger, - DateInterval, - DynamicDatePane, - AllCountPager, - Pager, - PopupView, - BubblePopupView, - BubblePopupBarView, - TextBubblePopupBarView, - ArrowTreeGroupNodeCheckbox, - NumberInterval, - DynamicYearQuarterCombo, - DynamicYearCombo, - DynamicYearPopup, - IntervalSlider, - MultiSelectInsertList, - YearMonthInterval, - TextValueCheckCombo, - NumberEditor, - Segment, - LinearSegment, - Img, - EditorIconCheckCombo, - IconTextValueCombo, - ListView, - VirtualList, - VirtualGroupList, - FloatCenterLayout, - DynamicYearMonthPopup, - DateCalendarPopup, - Tree, - Node, - TextNode, - TextValueCheckComboPopup, - ImageButton, - Router, - History, - DateTimeCombo, - FloatHorizontalLayout, - AdaptiveLayout, - HexColorChooserPopup, - BlankIconTextItem, - TimeInterval, - DynamicDateTimePane, - SingleSelectInsertList, - MultiSelectTree, - HtmlLabel, - TreeValueChooserPane, - TdLayout, - MultiLayerSelectLevelTree, - SelectTreeExpander, - DirectionPager, - DownListGroupItem, - HorizontalStickyLayout, - VerticalStickyLayout, - TableLayout, -}; diff --git a/typescript/router/router.ts b/typescript/router/router.ts deleted file mode 100644 index 75fded652..000000000 --- a/typescript/router/router.ts +++ /dev/null @@ -1,237 +0,0 @@ -type Component = any -type Dictionary = { [key: string]: T } -type ErrorHandler = (err: Error) => void - -export type RouterMode = "hash" | "history" | "abstract" -export type RawLocation = string | Location -export type RedirectOption = RawLocation | ((to: Route) => RawLocation) -export type NavigationGuardNext = ( - to?: RawLocation | false | void, -) => void - -export type NavigationGuard = ( - to: Route, - from: Route, - next: NavigationGuardNext, -) => any - -interface _History { - current: Route; -} - -export declare class VueRouter { - constructor(options?: Obj) - - mode: RouterMode; - currentRoute: Route; - - history: _History; - - beforeEach(guard: NavigationGuard): Function - - beforeResolve(guard: NavigationGuard): Function - - afterEach(hook: (to: Route, from: Route) => any): Function - - push(location: RawLocation): Promise - - replace(location: RawLocation): Promise - - push( - location: RawLocation, - onComplete?: Function, - onAbort?: ErrorHandler, - ): void - - replace( - location: RawLocation, - onComplete?: Function, - onAbort?: ErrorHandler, - ): void - - go(n: number): void - - back(): void - - forward(): void - - match(raw: RawLocation, current?: Route, redirectedFrom?: Location): Route - - getMatchedComponents(to?: RawLocation | Route): Component[] - - onReady(cb: Function, errorCb?: ErrorHandler): void - - onError(cb: ErrorHandler): void - - addRoutes(routes: RouteConfig[]): void - - addRoute(parent: string, route: RouteConfig): void - addRoute(route: RouteConfig): void - - getRoutes(): RouteRecordPublic[] - - resolve( - to: RawLocation, - current?: Route, - append?: boolean, - ): { - location: Location - route: Route - href: string - // backwards compat - normalizedTo: Location - resolved: Route - } - -} - -type RoutePropsFunction = (route: Route) => Object - -interface _RouteConfigBase { - path: string; - name?: string; - children?: RouteConfig[]; - redirect?: RedirectOption; - alias?: string | string[]; - meta?: RouteMeta; - beforeEnter?: NavigationGuard; - caseSensitive?: boolean; - pathToRegexpOptions?: PathToRegexpOptions; -} - -interface RouteConfigSingleView extends _RouteConfigBase { - component?: Component; - props?: boolean | Object | RoutePropsFunction; -} - -interface RouteConfigMultipleViews extends _RouteConfigBase { - components?: Dictionary; - props?: Dictionary; -} - -type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews - -interface PathToRegexpOptions { - sensitive?: boolean; - strict?: boolean; - end?: boolean; -} - -interface _RouteConfigBase { - path: string; - name?: string; - children?: RouteConfig[]; - redirect?: RedirectOption; - alias?: string | string[]; - meta?: RouteMeta; - beforeEnter?: NavigationGuard; - caseSensitive?: boolean; - pathToRegexpOptions?: PathToRegexpOptions; -} - -interface RouteRecord { - path: string; - regex: RegExp; - components: Dictionary; - name?: string; - parent?: RouteRecord; - redirect?: RedirectOption; - matchAs?: string; - meta: RouteMeta; - beforeEnter?: ( - route: Route, - redirect: (location: RawLocation) => void, - next: () => void, - ) => any; - props: - | boolean - | Object - | RoutePropsFunction - | Dictionary; -} - -interface RouteRecordPublic { - path: string; - components: Dictionary; - name?: string; - redirect?: RedirectOption; - meta: any; - beforeEnter?: ( - route: Route, - redirect: (location: RawLocation) => void, - next: () => void, - ) => any; - props: - | boolean - | Object - | RoutePropsFunction - | Dictionary; -} - - -interface Location { - name?: string; - path?: string; - hash?: string; - query?: Dictionary; - params?: Dictionary; - append?: boolean; - replace?: boolean; -} - -interface Route { - path: string; - name?: string | null; - hash: string; - query: Dictionary; - params: Dictionary; - fullPath: string; - matched: RouteRecord[]; - redirectedFrom?: string; - meta?: RouteMeta; -} - -interface RouteMeta extends Record { -} - - -export declare class Router { - constructor(op: { [key: string]: any }); - - static $router: VueRouter; - - route(route: string, callback: Function): this; - route(route: string, name: string, callback?: Function): this; - - execute(callback?: Function, args?: any[]): void; - - navigate(fragment: string, options?: { [key: string]: any } | boolean): this; -} - -export declare class History { - atRoot(): boolean; - - getSearch(): string; - - getHash(window?: Window): string; - - getPath(): string; - - getFragment(fragment?: string): string; - - start(op?: { [key: string]: any }): void; - - stop(): void; - - route(route: string, callback: Function): void; - - checkRoute(route: string): { route: string, callback: Function }; - - unRoute(route: string): void; - - checkUrl(e?: Event): void; - - loadUrl(fragment: string): boolean; - - navigate(fragment: string, options?: { [key: string]: any } | boolean): void; -} diff --git a/typescript/widget/multiselect/multiselect.combo.ts b/typescript/widget/multiselect/multiselect.combo.ts deleted file mode 100644 index 9ebe8b9fb..000000000 --- a/typescript/widget/multiselect/multiselect.combo.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Single } from "../../base/single/single"; - -export declare class MultiSelectCombo extends Single { - static xtype: string; - static EVENT_BLUR: string; - static EVENT_FOCUS: string; - static EVENT_STOP: string; - static EVENT_SEARCHING: string; - static EVENT_CLICK_ITEM: string; - static EVENT_CONFIRM: string; - static REQ_GET_DATA_LENGTH: 1; - static REQ_GET_ALL_DATA: -1; - - props: { - itemsCreator: (options: any, callback: () => any[]) => void; - itemHeight: number; - text: string; - valueFormatter: (v: string) => string; - allowEdit: boolean; - } & Single['props'] - - _itemsCreator4Trigger(op: any, callback: Function): void; - - _stopEditing(): void; - - _defaultState(): void; - - _assertValue(): void; - - _makeMap(): Obj; - - _joinKeywords(keywords: string[], callback: Function): void; - - _joinAll(res: { - type: number; - value: string[]; - assist: string[]; - }, callback: Function): void; - - _adjust(callback: Function): void; - - _join(): void; - - _setStartValue(value: string): void; - - _populate(...args: any[]): void; - - showView(): void; - - hideView(): void; - - setValue(value: { - type: number; - value: string[]; - assist: string[]; - }): void; - - getValue(): { - type: number; - value: string[]; - assist: string[]; - }; - - populate(...args: any[]): void; -} diff --git a/typescript/widget/multiselect/multiselect.insert.combo.ts b/typescript/widget/multiselect/multiselect.insert.combo.ts deleted file mode 100644 index 98e33d28e..000000000 --- a/typescript/widget/multiselect/multiselect.insert.combo.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Single } from "../../base/single/single"; - -export declare class MultiSelectInsertCombo extends Single { - static xtype: string; - static EVENT_FOCUS: string; - static EVENT_BLUR: string; - static EVENT_STOP: string; - static EVENT_SEARCHING: string; - static EVENT_CLICK_ITEM: string; - static EVENT_CONFIRM: string; - static EVENT_ADD_ITEM: string; - static REQ_GET_DATA_LENGTH: 1; - static REQ_GET_ALL_DATA: -1; - - props: { - itemsCreator?: Function; - valueFormatter?: Function; - itemHeight?: number; - allowEdit?: boolean; - text?: string; - watermark?: string; - container?: any; - } & Single['props']; - - _itemsCreator4Trigger(op: any, callback: Function): void; - - _addItem(assertShowValue: () => void, matched: boolean): void; - - _stopEditing(): void; - - _defaultState(): void; - - _assertValue(): void; - - _makeMap(): Obj; - - _joinKeywords(keywords: string[], callback: Function): void; - - _joinAll(res: { - type: string; - value: string[]; - assist: string[]; - }, callback: Function): void; - - _adjust(callback: Function): void; - - _join(): void; - - _setStartValue(value: string): void; - - _populate(...args: any[]): void; - - showView(): void; - - hideView(): void; - - setValue(value?: { - type: number; - value: string[]; - assist: string[]; - }): void; - - getValue(): { - type: number; - value: string[]; - assist: string[]; - }; - - populate(...args: any[]): void; -} diff --git a/ui/js/index.js b/ui/js/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/ui/less/font.less b/ui/less/font.less deleted file mode 100644 index d7399c46e..000000000 --- a/ui/less/font.less +++ /dev/null @@ -1,2 +0,0 @@ -@import "../../src/less/resource/font.less"; -@import "var.less"; diff --git a/ui/less/icon.less b/ui/less/icon.less deleted file mode 100644 index 8aa44a2ae..000000000 --- a/ui/less/icon.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "../../src/less/resource/icon.less"; -@import "var.less"; - - - diff --git a/webpack/attachments.js b/webpack/attachments.js deleted file mode 100644 index befe73db1..000000000 --- a/webpack/attachments.js +++ /dev/null @@ -1,270 +0,0 @@ -const { sync, uniq } = require("./utils"); - -const fixJs = "./dist/fix/fix.js"; -const fixProxyJs = './dist/fix/fix.proxy.js'; -const fixCompact = "./dist/fix/fix.compact.js"; -const workerCompact = './dist/fix/worker.compact.js'; -const lodashJs = "src/core/1.lodash.js"; -const jqueryJs = "src/core/platform/web/jquery/_jquery.js"; - -const runtimePolyfill = ["core-js/stable"]; - -const basicAttachmentMap = { - polyfill: sync([ - "src/core/0.foundation.js", - "src/polyfill/**/*.js", - ]).concat(runtimePolyfill), - core: sync([ - "src/less/core/**/*.less", - "src/less/theme/**/*.less", - lodashJs, - jqueryJs, - "src/core/**/*.js", - "src/data/**/*.js", - ]), - // 最基础的控件 - base: sync([ - "src/less/base/**/*.less", - "src/third/**/*.js", - "src/base/**/*.js", - ]), - // 实现好的一些基础实例 - case: sync([ - "src/case/**/*.js", - "src/less/case/**/*.less", - ]), - widget: sync([ - "src/less/widget/**/*.less", - "src/less/component/**/*.less", - "src/widget/**/*.js", - "src/component/**/*.js", - ]), - router: sync([ - "src/router/**/*.js", - ]), - core_without_platform: sync([ - "src/core/0.foundation.js", - lodashJs, - "src/core/**/*.js", - "src/data/**/*.js", - ], [ - "src/core/platform/**/*.js", - "src/core/controller/**/*.js", - ]), - core_without_normalize: sync( - ["src/less/core/**/*.less", "src/less/theme/**/*.less"], ["src/less/core/normalize.less", "src/less/core/normalize2.less"] - ), - core_without_conflict: sync([ - "src/less/core/**/*.less", - "src/less/theme/**/*.less", - lodashJs, - "src/core/**/*.js", - "src/data/**/*.js", - ], [ - "src/core/conflict.js", - ]), - resource: sync(["src/less/resource/**/*.less"]), - font: sync(["public/less/font.less"]), - ts: ['./typescript/bundle.ts'], - ui: sync([ - 'ui/less/app.less', - 'ui/less/**/*.less', - 'ui/js/**/*.js', - ]), - config: sync(["demo/version.js", "i18n/i18n.cn.js"]), - utils: sync([ - "src/core/0.foundation.js", - lodashJs, - "src/core/constant/**/*.js", - "src/core/func/**/*.js", - "src/core/2.base.js", - "src/core/3.ob.js", - "src/core/5.inject.js", - "src/core/utils/*.js", - "i18n/i18n.cn.js", - "_mobile/date.i18n.cn.js", - "src/data/**/*.js", - ]), - fix: [fixJs], - fixProxy: [fixProxyJs], - less: sync([ - "src/less/core/**/*.less", - "src/less/theme/**/*.less", - "src/less/base/**/*.less", - "src/less/case/**/*.less", - "src/less/widget/**/*.less", - "src/less/component/**/*.less", - ]), -}; - -const bundle = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core, - basicAttachmentMap.fix, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - sync(["public/less/app.less", "public/less/**/*.less"]), - [fixCompact, workerCompact], - basicAttachmentMap.router, - sync(["public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"]), - basicAttachmentMap.ts, -); - -const bundleCss = [].concat( - basicAttachmentMap.less, - sync(["public/less/app.less", "public/less/**/*.less"]), -); - -// const bundleModern = [].concat( -// sync(["src/less/modern.less"]), -// sync(["public/modern/app.less", "public/modern/**/*.less"]), -// ); - -const coreJs = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core, - basicAttachmentMap.fix, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - ['./dist/fix/fix.compact.js'], - basicAttachmentMap.router, - basicAttachmentMap.ts, -); - -const resource = sync(["private/less/app.less", "private/less/**/*.less"]); - -const config = sync(["public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"]); - -const bundleWithoutNormalize = [].concat( - basicAttachmentMap.core_without_normalize, - sync([ - "src/less/base/**/*.less", - "src/less/case/**/*.less", - "src/less/widget/**/*.less", - "src/less/component/**/*.less", - "public/less/**/*.less", - // ts的less - ], [ - "public/less/app.less", - ]), -); - -const fineuiWithoutNormalize = [].concat( - basicAttachmentMap.core_without_normalize, - sync([ - "src/less/base/**/*.less", - "src/less/case/**/*.less", - "src/less/widget/**/*.less", - "src/less/component/**/*.less", - 'ui/less/app.less', - 'ui/less/**/*.less', - ]), -); - -const fineui = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core, - basicAttachmentMap.fix, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - basicAttachmentMap.router, - [fixCompact, workerCompact], - basicAttachmentMap.ui, - basicAttachmentMap.ts, -); - -const fineuiWithoutConflict = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core_without_conflict, - basicAttachmentMap.fix, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - basicAttachmentMap.router, - [fixCompact, workerCompact], - basicAttachmentMap.ui, - basicAttachmentMap.ts, -); - -// const fineuiModern = [].concat( -// sync(["src/less/modern.less"]), -// sync([ -// 'ui/modern/app.less', -// 'ui/modern/**/*.less', -// ]), -// ); - -const fineuiProxy = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core, - basicAttachmentMap.fixProxy, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - basicAttachmentMap.router, - [fixCompact, workerCompact], - basicAttachmentMap.ui, - basicAttachmentMap.ts, -); - -const fineuiWithoutJqueryAndPolyfillJs = [].concat( - runtimePolyfill, - sync([ - "src/core/0.foundation.js", - lodashJs, - "src/core/**/*.js", - "src/data/**/*.js", - ], [ - "src/core/platform/web/**/*.js", - ]), - basicAttachmentMap.fix, - sync([ - "src/base/**/*.js", - "src/case/**/*.js", - ], [ - "src/base/single/input/file.js", - "src/case/ztree/**/*.js", - ]), - basicAttachmentMap.widget, - sync([fixCompact, workerCompact, "ui/js/**/*.js"]), - basicAttachmentMap.ts, -); - -const demo = [].concat( - basicAttachmentMap.polyfill, - basicAttachmentMap.core, - basicAttachmentMap.fix, - basicAttachmentMap.config, - basicAttachmentMap.base, - basicAttachmentMap.case, - basicAttachmentMap.widget, - basicAttachmentMap.router, - sync(["public/less/app.less", "public/less/**/*.less"]), - [fixCompact, workerCompact], - basicAttachmentMap.ts, - sync(["demo/less/*.less", "demo/less/**/*.less", "demo/app.js", "demo/js/**/*.js", "demo/config.js"]), -); - -module.exports = { - fix: fixJs, - fixProxy: fixProxyJs, - lodash: lodashJs, - font: basicAttachmentMap.font, - bundle: uniq(bundle), - fineuiWithoutNormalize: uniq(fineuiWithoutNormalize), - fineuiWithoutConflict: uniq(fineuiWithoutConflict), - bundleWithoutNormalize: uniq(bundleWithoutNormalize), - fineui: uniq(fineui), - fineuiProxy: uniq(fineuiProxy), - fineuiWithoutJqueryAndPolyfillJs: uniq(fineuiWithoutJqueryAndPolyfillJs), - utils: uniq(basicAttachmentMap.utils), - demo: uniq(demo), - coreWithoutPlatform: uniq(basicAttachmentMap.core_without_platform), - coreJs: uniq(coreJs), - resource: uniq((resource)), - config: uniq(config), - bundleCss: uniq(bundleCss), -}; diff --git a/webpack/components.js b/webpack/components.js deleted file mode 100644 index 0162cfd2a..000000000 --- a/webpack/components.js +++ /dev/null @@ -1,39 +0,0 @@ -const { sync, uniq } = require("./utils"); - -const basicAttachmentMap = { - single: sync(["src/base/single/**/*.js"]), - layer: sync(["src/base/layer/**/*.js"]), - pane: sync(["src/base/1.pane.js"]), - button_group: sync(["src/base/combination/group.button.js"]), - buttons: sync(["src/case/button/**/*.js"]), - checkboxes: sync(["src/case/checkbox/**/*.js"]), - combos: sync(["src/case/combo/**/*.js"]), - editors: sync(["src/case/editor/**/*.js"]), - triggers: sync(["src/case/trigger/**/*.js"]), - calendar: sync(["src/case/calendar/**/*.js"]), - color_chooser: sync(["src/case/colorchooser/**/*.js"]), - segment: sync(["src/case/segment/**/*.js"]), - linear_segment: sync(["src/case/linearsegment/**/*.js"]), - date: sync(["src/widget/date/**/*.js"]), - down_list: sync(["src/widget/downlist/**/*.js"]), - text_value_down_list_combo: sync(["src/widget/textvaluedownlistcombo/**/*.js"]), -}; - -module.exports = { - single: basicAttachmentMap.single, - layer: basicAttachmentMap.layer, - pane: basicAttachmentMap.pane, - button_group: basicAttachmentMap.button_group, - buttons: basicAttachmentMap.buttons, - checkboxes: basicAttachmentMap.checkboxes, - combos: basicAttachmentMap.combos, - editors: basicAttachmentMap.editors, - triggers: basicAttachmentMap.triggers, - calendar: basicAttachmentMap.calendar, - color_chooser: basicAttachmentMap.color_chooser, - segment: basicAttachmentMap.segment, - linear_segment: basicAttachmentMap.linear_segment, - date: basicAttachmentMap.date, - down_list: basicAttachmentMap.down_list, - text_value_down_list_combo: basicAttachmentMap.text_value_down_list_combo, -}; diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js deleted file mode 100644 index e19801a99..000000000 --- a/webpack/webpack.common.js +++ /dev/null @@ -1,116 +0,0 @@ -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const autoprefixer = require('autoprefixer'); -const path = require('path'); -const fs = require('fs'); - -const dirs = require('./dirs'); - -const attachments = require('./attachments'); - -let lessVariables = {}; - -if (process.env.LESS_CONFIG_PATH) { - const lessConfigPath = path.isAbsolute(process.env.LESS_CONFIG_PATH) - ? process.env.LESS_CONFIG_PATH - : path.resolve(__dirname, '../', process.env.LESS_CONFIG_PATH); - - lessVariables = fs.existsSync(lessConfigPath) - ? require(lessConfigPath) || {} - : {}; -} - -module.exports = { - entry: { - demo: attachments.demo, - // 用于启动dev模式时,工程引用调试 - fineui: attachments.fineui, - "fineui.proxy": attachments.fineuiProxy, - }, - externals: { - lodash: '_', - underscore: '_', - }, - resolve: { - mainFields: ['module', 'main'], - extensions: ['.js', '.ts'], - }, - module: { - rules: [ - { - test: /\.(jsx?|tsx?)$/i, - include: [ - dirs.NODE_MODULES, - dirs.PRIVATE, - dirs.PUBLIC, - dirs.MOBILE, - dirs.DEMO, - dirs.I18N, - dirs.UI, - dirs.FIX, - dirs.TYPESCRIPT, - dirs.SRC, - ], - exclude: /node_modules(\/|\\)core-js/, - use: [ - { - loader: 'babel-loader', - options: { - configFile: dirs.BABEL_CONFIG, - }, - }, - ], - }, - { - test: /\.js$/, - include: [path.resolve(__dirname, '../', attachments.lodash)], - use: [ - { - loader: 'script-loader', - }, - ], - }, - { - test: path.resolve(__dirname, '../', attachments.fix), - use: [ - { - loader: 'expose-loader', - options: 'Fix', - }, - ], - }, { - test: path.resolve(__dirname, '../', attachments.fixProxy), - use: [ - { - loader: 'expose-loader', - options: 'Fix', - }, - ], - }, - { - test: /\.(css|less)$/, - use: [ - MiniCssExtractPlugin.loader, - { - loader: 'css-loader', - options: { - url: false, - }, - }, - { - loader: 'postcss-loader', - options: { - plugins: [autoprefixer], - }, - }, - { - loader: 'less-loader', - options: { - relativeUrls: false, - modifyVars: lessVariables, - }, - }, - ], - }, - ], - }, -}; diff --git a/webpack/webpack.css.js b/webpack/webpack.css.js deleted file mode 100644 index 0028f7a26..000000000 --- a/webpack/webpack.css.js +++ /dev/null @@ -1,20 +0,0 @@ -const merge = require("webpack-merge"); - -const dirs = require("./dirs"); - -const common = require("./webpack.prod.js"); -common.entry = {}; - -const attachments = require("./attachments"); - -module.exports = merge.smart(common, { - mode: "production", - entry: { - [`2.0/${process.env.LESS_FILE_NAME}.min`]: attachments.bundleCss, - }, - - output: { - path: dirs.DEST, - filename: "[name].js", - }, -}); diff --git a/webpack/webpack.dev.js b/webpack/webpack.dev.js deleted file mode 100644 index 9e5a21432..000000000 --- a/webpack/webpack.dev.js +++ /dev/null @@ -1,79 +0,0 @@ -const merge = require("webpack-merge"); -const path = require("path"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); -const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); - -const dirs = require("./dirs"); - -const common = require("./webpack.common.js"); - -const ModuleDependencyWarning = require("webpack/lib/ModuleDependencyWarning"); - -class IgnoreNotFoundExportPlugin { - apply(compiler) { - const messageRegExp = /export '.*'( \(reexported as '.*'\))? was not found in/; - function doneHook(stats) { - stats.compilation.warnings = stats.compilation.warnings.filter(warn => { - if (warn instanceof ModuleDependencyWarning && messageRegExp.test(warn.message)) { - return false; - } - - return true; - }); - } - if (compiler.hooks) { - compiler.hooks.done.tap("IgnoreNotFoundExportPlugin", doneHook); - } else { - compiler.plugin("done", doneHook); - } - } -} - -module.exports = merge(common, { - devtool: "inline-source-map", - output: { - path: dirs.DEST, - filename: "[name].js", - publicPath: '/', - }, - devServer: { - contentBase: path.join(__dirname, ".."), - port: 9001, - liveReload: true, - historyApiFallback: { - rewrites: [ - { from: /.*/, to: '/index.html' }, - ], - }, - }, - plugins: [ - new MiniCssExtractPlugin({ - path: dirs.DEST, - filename: "[name].css", - }), - new HtmlWebpackPlugin({ - template: path.resolve(__dirname, "../template/index.html"), - chunks: ["demo"], - chunksSortMode: "manual", - }), - new ForkTsCheckerWebpackPlugin({ - watch: ["./typescript"], - }), - new OptimizeCssAssetsPlugin({ - assetNameRegExp: /\.css$/g, - cssProcessor: require("cssnano"), - cssProcessorPluginOptions: { - preset: ["default", { - discardComments: { - removeAll: true, - }, - normalizeUnicode: false, - }], - }, - canPrint: true, - }), - new IgnoreNotFoundExportPlugin(), - ], -}); diff --git a/webpack/webpack.prod.js b/webpack/webpack.prod.js deleted file mode 100644 index c4bb88e5c..000000000 --- a/webpack/webpack.prod.js +++ /dev/null @@ -1,127 +0,0 @@ -const webpack = require("webpack"); -const merge = require("webpack-merge"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); -const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); -const TerserJsPlugin = require("terser-webpack-plugin"); - -const dirs = require("./dirs"); - -const common = require("./webpack.common.js"); - -const attachments = require("./attachments"); -const components = require("./components"); - -const childProcess = require('child_process'); - -function git(command) { - return childProcess - .execSync(`git ${command}`) - .toString() - .trim(); -} - -module.exports = merge.smart(common, { - mode: "production", - entry: { - font: attachments.font, - "fineui.min": attachments.fineui, - "fineui_without_normalize.min": attachments.fineuiWithoutNormalize, - "fineui_without_conflict.min": attachments.fineuiWithoutConflict, - "fineui.proxy.min": attachments.fineuiProxy, - "core_without_platform": attachments.coreWithoutPlatform, - utils: attachments.utils, - "utils.min": attachments.utils, - "fineui_without_jquery_polyfill": attachments.fineuiWithoutJqueryAndPolyfillJs, - "fineui_without_jquery_polyfill.min": attachments.fineuiWithoutJqueryAndPolyfillJs, - "2.0/fineui": attachments.bundle, - "2.0/fineui.min": attachments.bundle, - "2.0/fineui_without_normalize": attachments.bundleWithoutNormalize, - "2.0/fineui_without_normalize.min": attachments.bundleWithoutNormalize, - "2.0/core_without_platform": attachments.coreWithoutPlatform, - "2.0/core_without_platform.min": attachments.coreWithoutPlatform, - core: attachments.coreJs, - resource: attachments.resource, - "lib/single": components.single, - "lib/layers": components.layer, - "lib/pane": components.pane, - "lib/button_group": components.button_group, - "lib/buttons": components.buttons, - "lib/checkboxes": components.checkboxes, - "lib/combos": components.combos, - "lib/editors": components.editors, - "lib/triggers": components.triggers, - "lib/calendar": components.calendar, - "lib/color_chooser": components.color_chooser, - "lib/segment": components.segment, - "lib/linear_segment": components.linear_segment, - "lib/date": components.date, - "lib/down_list": components.down_list, - "lib/text_value_down_list_combo": components.text_value_down_list_combo, - }, - optimization: { - minimizer: [ - new TerserJsPlugin({ - include: /\.min/, - parallel: true, - sourceMap: true, - terserOptions: { - output: { - comments: false - } - } - }), - new webpack.BannerPlugin({ - banner: `time: ${new Date().toLocaleString("en-US")}; branch: ${git( - 'name-rev --name-only HEAD' - )} commit: ${git( - 'rev-parse HEAD' - )}` - }) - ] - }, - - devtool: "hidden-source-map", - - output: { - path: dirs.DEST, - filename: "[name].js" - }, - - plugins: [ - new MiniCssExtractPlugin({ - path: dirs.DEST, - filename: "[name].css" - }), - new ForkTsCheckerWebpackPlugin({}), - new OptimizeCssAssetsPlugin({ - assetNameRegExp: /\.css$/g, - cssProcessor: require("cssnano"), - cssProcessorPluginOptions: { - preset: ["default", { - discardComments: { - removeAll: true - }, - normalizeUnicode: false - }] - }, - canPrint: true - }) - ], - - module: { - rules: [ - { - test: /\.(css|less)$/, - use: [ - { - loader: "postcss-loader", - options: { - plugins: [] - } - } - ] - } - ] - } -});