Browse Source

KERNEL-14076 refact: es6 脚本识别循环依赖。完成 base 处理。

es6
Treecat 2 years ago
parent
commit
630be6aea0
  1. 59
      es6.js
  2. 12
      src/base/0.base.js
  3. 57
      src/base/1.pane.js
  4. 105
      src/base/collection/collection.js
  5. 201
      src/base/combination/bubble.js
  6. 309
      src/base/combination/combo.js
  7. 116
      src/base/combination/expander.js
  8. 67
      src/base/combination/group.button.js
  9. 53
      src/base/combination/group.combo.js
  10. 49
      src/base/combination/group.virtual.js
  11. 148
      src/base/combination/loader.js
  12. 40
      src/base/combination/navigation.js
  13. 75
      src/base/combination/searcher.js
  14. 111
      src/base/combination/switcher.js
  15. 51
      src/base/combination/tab.js
  16. 5
      src/base/combination/tree.button.js
  17. 57
      src/base/context.js
  18. 48
      src/base/el.js
  19. 91
      src/base/foundation/message.js
  20. 146
      src/base/grid/grid.js
  21. 9
      src/base/index.js
  22. 73
      src/base/layer/layer.drawer.js
  23. 148
      src/base/layer/layer.popover.js
  24. 165
      src/base/layer/layer.popup.js
  25. 71
      src/base/layer/layer.searcher.js
  26. 33
      src/base/list/listview.js
  27. 77
      src/base/list/virtualgrouplist.js
  28. 53
      src/base/list/virtuallist.js
  29. 111
      src/base/pager/pager.js
  30. 35
      src/base/single/0.single.js
  31. 50
      src/base/single/1.text.js
  32. 6
      src/base/single/a/a.js
  33. 19
      src/base/single/bar/bar.loading.js
  34. 121
      src/base/single/button/button.basic.js
  35. 2
      src/base/single/button/button.node.js
  36. 9
      src/base/single/button/buttons/button.icon.js
  37. 10
      src/base/single/button/buttons/button.image.js
  38. 31
      src/base/single/button/buttons/button.js
  39. 5
      src/base/single/button/buttons/button.text.js
  40. 28
      src/base/single/button/listitem/blankiconicontextitem.js
  41. 29
      src/base/single/button/listitem/blankicontexticonitem.js
  42. 23
      src/base/single/button/listitem/blankicontextitem.js
  43. 23
      src/base/single/button/listitem/icontexticonitem.js
  44. 18
      src/base/single/button/listitem/icontextitem.js
  45. 20
      src/base/single/button/listitem/texticonitem.js
  46. 5
      src/base/single/button/listitem/textitem.js
  47. 23
      src/base/single/button/node/icontexticonnode.js
  48. 19
      src/base/single/button/node/icontextnode.js
  49. 19
      src/base/single/button/node/texticonnode.js
  50. 10
      src/base/single/button/node/textnode.js
  51. 55
      src/base/single/editor/editor.js
  52. 19
      src/base/single/editor/editor.multifile.js
  53. 83
      src/base/single/editor/editor.textarea.js
  54. 29
      src/base/single/html/html.js
  55. 7
      src/base/single/icon/icon.js
  56. 17
      src/base/single/iframe/iframe.js
  57. 16
      src/base/single/img/img.js
  58. 7
      src/base/single/input/checkbox/checkbox.image.js
  59. 19
      src/base/single/input/checkbox/checkbox.js
  60. 171
      src/base/single/input/file.js
  61. 69
      src/base/single/input/input.js
  62. 7
      src/base/single/input/radio/radio.image.js
  63. 21
      src/base/single/input/radio/radio.js
  64. 16
      src/base/single/instruction/instruction.js
  65. 109
      src/base/single/label/abstract.label.js
  66. 10
      src/base/single/label/html.label.js
  67. 14
      src/base/single/label/icon.label.js
  68. 7
      src/base/single/label/label.js
  69. 10
      src/base/single/link/link.js
  70. 15
      src/base/single/text.pure.js
  71. 6
      src/base/single/tip/0.tip.js
  72. 31
      src/base/single/tip/tip.toast.js
  73. 16
      src/base/single/tip/tip.tooltip.js
  74. 13
      src/base/single/trigger/trigger.js
  75. 58
      src/base/tree/customtree.js
  76. 3
      src/case/combo/bubblecombo/popup.bubble.js

59
es6.js

@ -8,6 +8,9 @@ const _ = require("lodash");
// const XTYPE_ONLY = false; // const XTYPE_ONLY = false;
// const THIS_REPLACE = false; // const THIS_REPLACE = false;
const ConflictImport = [];
const CircularDependency = [];
function objHaveFunction(obj) { function objHaveFunction(obj) {
return Object.keys(obj).some(key => { return Object.keys(obj).some(key => {
const value = obj[key]; const value = obj[key];
@ -44,6 +47,7 @@ async function saveAndFixCode(path, code) {
const prettierCode = prettier.format(_code, { const prettierCode = prettier.format(_code, {
tabWidth: 4, tabWidth: 4,
parser: 'babel', parser: 'babel',
printWidth: 120,
}); });
fs.writeFileSync(path, prettierCode); fs.writeFileSync(path, prettierCode);
@ -138,7 +142,13 @@ async function handleFile(srcName) {
const result = /BI\.(.*?)\s=\sBI\.inherit\(/.exec(sourceCode); const result = /BI\.(.*?)\s=\sBI\.inherit\(/.exec(sourceCode);
if (!result) { if (!result) {
console.log(`已经es6过,替换 xtype => ${srcName}`); // console.log(`已经es6过,替换 xtype => ${srcName}`);
if (!/export class/.test(sourceCode)) {
console.log("忽略文件", srcName);
return;
}
// 处理 xtype // 处理 xtype
const noXtypeCode = sourceCode.replace(/type:\s?"bi\.(.*?)"/g, v => { const noXtypeCode = sourceCode.replace(/type:\s?"bi\.(.*?)"/g, v => {
const matchedSentence = v.replace(/type:\s?/, ""); const matchedSentence = v.replace(/type:\s?/, "");
@ -182,11 +192,36 @@ async function handleFile(srcName) {
const tmpG = {}; const tmpG = {};
_.forEach(G, (depts, module) => { _.forEach(G, (depts, module) => {
const flag = _.some(crossPackages, crosspackage => module.indexOf(crosspackage) >= 0 && !module.startsWith("@")) const flag = _.some(crossPackages, crosspackage => module.indexOf(crosspackage) >= 0 && !module.startsWith("@"));
if (!flag) { if (!flag) {
tmpG[module] = depts; tmpG[module] = depts;
} }
}); });
// 较验手工 import 错误
const map = {};
let conflict = false;
let circle = false;
_.forEach(tmpG, (imports, fromStr) => {
if (srcName.indexOf("base") >= 0) {
if (fromStr === "@/case" || fromStr === "@/base") {
circle = true;
}
}
_.forEach(imports, (bools, _import) => {
if (map[_import] && map[_import] !== fromStr) {
conflict = true;
}
map[_import] = fromStr;
});
});
conflict && ConflictImport.push(srcName);
circle && CircularDependency.push(srcName);
G = tmpG; G = tmpG;
const noImportCode = noXtypeCode.replace(/import {([\s\S]*?)} from "(.*?)";/g, ""); const noImportCode = noXtypeCode.replace(/import {([\s\S]*?)} from "(.*?)";/g, "");
@ -314,7 +349,7 @@ async function handleFile(srcName) {
// 换 super._defaultConfig // 换 super._defaultConfig
f = f.replace( f = f.replace(
/super\._defaultConfig\.apply\(this,\sarguments\)/g, /super\._defaultConfig\.apply\(this,\sarguments\)/g,
"super._defaultConfig(...arguments)" "super._defaultConfig(...arguments)",
); );
// 换 super.xxx.apply // 换 super.xxx.apply
f = f.replace(/super\.(.*?)\.apply\(this,\sarguments\)/g, a => { f = f.replace(/super\.(.*?)\.apply\(this,\sarguments\)/g, a => {
@ -427,19 +462,27 @@ async function traverse(srcName) {
const srcName = process.argv[2]; const srcName = process.argv[2];
initDepts().then(() => { initDepts().then(async () => {
const content = fs.readFileSync("src/core/2.base.js").toString(); const content = fs.readFileSync("src/core/2.base.js").toString();
let result = content.match(/export function (.*?)\(/g); let result = content.match(/export function (.*?)\(/g);
target.push( target.push(
...result.map(el => ...result.map(el =>
el.replace("export function ", "").replace("(", "") el.replace("export function ", "").replace("(", ""),
) ),
); );
result = content.match(/export const (.*?) =/g); result = content.match(/export const (.*?) =/g);
target.push( target.push(
...result.map(el => el.replace("export const ", "").replace(" =", "")) ...result.map(el => el.replace("export const ", "").replace(" =", "")),
); );
traverse(srcName); await traverse(srcName);
// 对数据处理
ConflictImport.forEach(el => {
console.log(`导入冲突 ${el}`);
});
CircularDependency.forEach(el => {
console.log(`出现循环依赖 ${el}`);
});
}); });

12
src/base/0.base.js

@ -20,14 +20,4 @@ const Drawers = new DrawerController();
const Broadcasts = new BroadcastController(); const Broadcasts = new BroadcastController();
const StyleLoaders = new StyleLoaderManager(); const StyleLoaders = new StyleLoaderManager();
export { export { Resizers, Layers, Maskers, Bubbles, Tooltips, Popovers, Drawers, Broadcasts, StyleLoaders };
Resizers,
Layers,
Maskers,
Bubbles,
Tooltips,
Popovers,
Drawers,
Broadcasts,
StyleLoaders
};

57
src/base/1.pane.js

@ -1,3 +1,19 @@
import { Label, Text } from "./single";
import {
CenterAdaptLayout,
HorizontalAdaptLayout,
VerticalLayout,
Widget,
shortcut,
isNotEmptyString,
extend,
isNull,
isEmpty,
createWidget,
Providers
} from "@/core";
import { Layers } from "@/base";
/** /**
* 当没有元素时有提示信息的view * 当没有元素时有提示信息的view
* *
@ -6,8 +22,6 @@
* @extends BI.Widget * @extends BI.Widget
* @abstract * @abstract
*/ */
import { Widget, shortcut, isNotEmptyString, extend, isNull, isEmpty, createWidget, Providers } from "../core";
import { Layers } from "./0.base";
@shortcut() @shortcut()
export class Pane extends Widget { export class Pane extends Widget {
@ -31,32 +45,36 @@ export class Pane extends Widget {
createWidget({ createWidget({
type: "bi.absolute_center_adapt", type: "bi.absolute_center_adapt",
element: this, element: this,
items: [{ items: [
type: "bi.label", {
type: Label.xtype,
ref: _ref => { ref: _ref => {
this._tipText = _ref; this._tipText = _ref;
}, },
cls: "bi-tips", cls: "bi-tips",
text: this.options.tipText, text: this.options.tipText,
height: 25, height: 25,
}], }
],
}); });
} }
} }
loading() { loading() {
const o = this.options; const o = this.options;
const loadingAnimation = createWidget(Providers.getProvider("bi.provider.system").getLoading({ const loadingAnimation = createWidget(
Providers.getProvider("bi.provider.system").getLoading({
loadingSize: o.loadingSize, loadingSize: o.loadingSize,
context: this, context: this,
})); })
);
// pane在同步方式下由items决定tipText的显示与否 // pane在同步方式下由items决定tipText的显示与否
// loading的异步情况下由loaded后对面板的populate的时机决定 // loading的异步情况下由loaded后对面板的populate的时机决定
this.setTipVisible(false); this.setTipVisible(false);
if (o.overlap === true) { if (o.overlap === true) {
if (!Layers.has(`${this.getName()}-loading`)) { if (!Layers.has(`${this.getName()}-loading`)) {
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
cls: "loading-container", cls: "loading-container",
items: this._getLoadingTipItems(loadingAnimation), items: this._getLoadingTipItems(loadingAnimation),
element: Layers.make(`${this.getName()}-loading`, this), element: Layers.make(`${this.getName()}-loading`, this),
@ -66,7 +84,7 @@ export class Pane extends Widget {
} else if (isNull(this._loading)) { } else if (isNull(this._loading)) {
loadingAnimation.element.css("zIndex", 1); loadingAnimation.element.css("zIndex", 1);
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
element: this, element: this,
cls: "loading-container", cls: "loading-container",
items: this._getLoadingTipItems(loadingAnimation), items: this._getLoadingTipItems(loadingAnimation),
@ -82,23 +100,28 @@ export class Pane extends Widget {
_getLoadingTipItems(loadingTip) { _getLoadingTipItems(loadingTip) {
const o = this.options; const o = this.options;
const loadingTipItems = [{ const loadingTipItems = [
type: "bi.horizontal_adapt", {
type: HorizontalAdaptLayout.xtype,
items: [loadingTip], items: [loadingTip],
}]; }
isNotEmptyString(o.loadingText) && loadingTipItems.push({ ];
type: "bi.text", isNotEmptyString(o.loadingText) &&
loadingTipItems.push({
type: Text.xtype,
text: o.loadingText, text: o.loadingText,
tgap: this._getSize(10), tgap: this._getSize(10),
}); });
return [{ return [
type: "bi.vertical", {
type: VerticalLayout.xtype,
ref: _ref => { ref: _ref => {
this._loading = _ref; this._loading = _ref;
}, },
items: loadingTipItems, items: loadingTipItems,
}]; }
];
} }
loaded() { loaded() {

105
src/base/collection/collection.js

@ -1,3 +1,25 @@
import {
VerticalLayout,
AbsoluteLayout,
Widget,
shortcut,
extend,
emptyFn,
debounce,
_lazyCreateWidget,
isFunction,
SectionManager,
isNull,
each,
clamp,
toArray,
invert,
min,
max,
nextTick
} from "@/core";
import { Label } from "../single";
/** /**
* CollectionView * CollectionView
* *
@ -5,7 +27,7 @@
* @class BI.CollectionView * @class BI.CollectionView
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, emptyFn, debounce, _lazyCreateWidget, isFunction, SectionManager, isNull, each, clamp, toArray, invert, min, max, nextTick } from "../../core";
@shortcut() @shortcut()
export class CollectionView extends Widget { export class CollectionView extends Widget {
_defaultConfig() { _defaultConfig() {
@ -19,7 +41,7 @@ export class CollectionView extends Widget {
overflowX: true, overflowX: true,
overflowY: true, overflowY: true,
el: { el: {
type: "bi.vertical", type: VerticalLayout.xtype,
}, },
cellSizeAndPositionGetter: emptyFn, cellSizeAndPositionGetter: emptyFn,
horizontalOverscanSize: 0, horizontalOverscanSize: 0,
@ -45,7 +67,7 @@ export class CollectionView extends Widget {
this._scrollLock = false; this._scrollLock = false;
}, 1000 / 60); }, 1000 / 60);
this.container = _lazyCreateWidget({ this.container = _lazyCreateWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
}); });
this.element.scroll(() => { this.element.scroll(() => {
if (this._scrollLock === true) { if (this._scrollLock === true) {
@ -61,7 +83,8 @@ export class CollectionView extends Widget {
}); });
// 兼容一下 // 兼容一下
let scrollable = o.scrollable; let scrollable = o.scrollable;
const scrollx = o.scrollx, scrolly = o.scrolly; const scrollx = o.scrollx,
scrolly = o.scrolly;
if (overflowX === false) { if (overflowX === false) {
if (overflowY === false) { if (overflowY === false) {
scrollable = false; scrollable = false;
@ -74,16 +97,18 @@ export class CollectionView extends Widget {
} }
} }
_lazyCreateWidget(el, { _lazyCreateWidget(el, {
type: "bi.vertical", type: VerticalLayout.xtype,
element: this, element: this,
scrollable, scrollable,
scrolly, scrolly,
scrollx, scrollx,
items: [this.container], items: [this.container],
}); });
o.items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { o.items = isFunction(o.items)
? this.__watch(o.items, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : o.items; })
: o.items;
if (o.items.length > 0) { if (o.items.length > 0) {
this._calculateSizeAndPositionData(); this._calculateSizeAndPositionData();
this._populate(); this._populate();
@ -109,10 +134,16 @@ export class CollectionView extends Widget {
for (let index = 0, len = items.length; index < len; index++) { for (let index = 0, len = items.length; index < len; index++) {
const cellMetadatum = cellSizeAndPositionGetter(index); const cellMetadatum = cellSizeAndPositionGetter(index);
if (isNull(cellMetadatum.height) || isNaN(cellMetadatum.height) || if (
isNull(cellMetadatum.width) || isNaN(cellMetadatum.width) || isNull(cellMetadatum.height) ||
isNull(cellMetadatum.x) || isNaN(cellMetadatum.x) || isNaN(cellMetadatum.height) ||
isNull(cellMetadatum.y) || isNaN(cellMetadatum.y)) { isNull(cellMetadatum.width) ||
isNaN(cellMetadatum.width) ||
isNull(cellMetadatum.x) ||
isNaN(cellMetadatum.x) ||
isNull(cellMetadatum.y) ||
isNaN(cellMetadatum.y)
) {
throw Error(); throw Error();
} }
@ -157,13 +188,21 @@ export class CollectionView extends Widget {
const bottom = Math.min(this._height, scrollTop + height + verticalOverscanSize); const bottom = Math.min(this._height, scrollTop + height + verticalOverscanSize);
if (right > 0 && bottom > 0) { if (right > 0 && bottom > 0) {
// 如果滚动的区间并没有超出渲染的范围 // 如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) { if (
top >= this.renderRange.minY &&
bottom <= this.renderRange.maxY &&
left >= this.renderRange.minX &&
right <= this.renderRange.maxX
) {
return; return;
} }
const childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); const childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
const renderedCells = [], renderedKeys = {}, renderedWidgets = {}; const renderedCells = [],
renderedKeys = {},
renderedWidgets = {};
// 存储所有的left和top // 存储所有的left和top
let lefts = {}, tops = {}; let lefts = {},
tops = {};
for (let i = 0, len = childrenToDisplay.length; i < len; i++) { for (let i = 0, len = childrenToDisplay.length; i < len; i++) {
const datum = childrenToDisplay[i]; const datum = childrenToDisplay[i];
lefts[datum.x] = datum.x; lefts[datum.x] = datum.x;
@ -176,7 +215,10 @@ export class CollectionView extends Widget {
const leftMap = invert(lefts); const leftMap = invert(lefts);
const topMap = invert(tops); const topMap = invert(tops);
// 存储上下左右四个边界 // 存储上下左右四个边界
const leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {}; const leftBorder = {},
rightBorder = {},
topBorder = {},
bottomBorder = {};
function assertMinBorder(border, offset) { function assertMinBorder(border, offset) {
if (isNull(border[offset])) { if (isNull(border[offset])) {
border[offset] = Number.MAX_VALUE; border[offset] = Number.MAX_VALUE;
@ -197,18 +239,26 @@ export class CollectionView extends Widget {
// 这里只使用px // 这里只使用px
this.renderedCells[index].el.element.css("left", `${datum.x}px`); this.renderedCells[index].el.element.css("left", `${datum.x}px`);
this.renderedCells[index].el.element.css("top", `${datum.y}px`); this.renderedCells[index].el.element.css("top", `${datum.y}px`);
renderedCells.push(child = this.renderedCells[index]); renderedCells.push((child = this.renderedCells[index]));
} else { } else {
const item = itemFormatter(items[datum.index], datum.index); const item = itemFormatter(items[datum.index], datum.index);
child = _lazyCreateWidget(extend({ child = _lazyCreateWidget(
type: "bi.label", extend(
{
type: Label.xtype,
width: datum.width, width: datum.width,
height: datum.height, height: datum.height,
}, item, { },
cls: `${item.cls || ""} collection-cell${datum.y === 0 ? " first-row" : ""}${datum.x === 0 ? " first-col" : ""}`, item,
{
cls: `${item.cls || ""} collection-cell${datum.y === 0 ? " first-row" : ""}${
datum.x === 0 ? " first-col" : ""
}`,
_left: datum.x, _left: datum.x,
_top: datum.y, _top: datum.y,
})); }
)
);
renderedCells.push({ renderedCells.push({
el: child, el: child,
left: `${datum.x}px`, left: `${datum.x}px`,
@ -242,7 +292,9 @@ export class CollectionView extends Widget {
renderedWidgets[i] = child; renderedWidgets[i] = child;
} }
// 已存在的, 需要添加的和需要删除的 // 已存在的, 需要添加的和需要删除的
const existSet = {}, addSet = {}, deleteArray = []; const existSet = {},
addSet = {},
deleteArray = [];
each(renderedKeys, (i, key) => { each(renderedKeys, (i, key) => {
if (this.renderedKeys[i]) { if (this.renderedKeys[i]) {
existSet[i] = key; existSet[i] = key;
@ -289,7 +341,8 @@ export class CollectionView extends Widget {
const o = this.options; const o = this.options;
const { overflowX } = this.options; const { overflowX } = this.options;
// 兼容一下 // 兼容一下
const scrollable = o.scrollable, scrollx = o.scrollx; const scrollable = o.scrollable,
scrollx = o.scrollx;
if (overflowX === false) { if (overflowX === false) {
return false; return false;
} }
@ -307,7 +360,8 @@ export class CollectionView extends Widget {
const o = this.options; const o = this.options;
const { overflowX } = this.options; const { overflowX } = this.options;
// 兼容一下 // 兼容一下
const scrollable = o.scrollable, scrolly = o.scrolly; const scrollable = o.scrollable,
scrolly = o.scrolly;
if (overflowX === false) { if (overflowX === false) {
return false; return false;
} }
@ -344,8 +398,7 @@ export class CollectionView extends Widget {
try { try {
this.element.scrollTop(scrollTop); this.element.scrollTop(scrollTop);
this.element.scrollLeft(scrollLeft); this.element.scrollLeft(scrollLeft);
} catch (e) { } catch (e) {}
}
this._calculateChildrenToRender(); this._calculateChildrenToRender();
} }
setScrollLeft(scrollLeft) { setScrollLeft(scrollLeft) {

201
src/base/combination/bubble.js

@ -1,8 +1,26 @@
import { BubblePopupView } from "@/case/combo/bubblecombo/popup.bubble";
import {
VerticalLayout,
shortcut,
Widget,
Controller,
extend,
nextTick,
createWidget,
each,
defer,
debounce,
delay,
isNull,
isFunction,
contains,
bind
} from "@/core";
/** /**
* @class BI.Bubble * @class BI.Bubble
* @extends BI.Widget * @extends BI.Widget
*/ */
import { shortcut, Widget, Controller, extend, nextTick, createWidget, each, defer, debounce, delay, isNull, isFunction, contains, bind } from "../../core";
@shortcut() @shortcut()
export class Bubble extends Widget { export class Bubble extends Widget {
@ -23,7 +41,7 @@ export class Bubble extends Widget {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-popper", baseCls: `${conf.baseCls || ""} bi-popper`,
attributes: { attributes: {
tabIndex: -1, tabIndex: -1,
}, },
@ -85,26 +103,32 @@ export class Bubble extends Widget {
} }
}); });
this.element.on("mouseenter." + this.getName(), (e) => { this.element.on(`mouseenter.${this.getName()}`, (e) => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this.element.addClass(hoverClass); this.element.addClass(hoverClass);
} }
}); });
this.element.on("mouseleave." + this.getName(), (e) => { this.element.on(`mouseleave.${this.getName()}`, (e) => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this.element.removeClass(hoverClass); this.element.removeClass(hoverClass);
} }
}); });
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
scrolly: false, scrolly: false,
}, BI.LogicFactory.createLogic("vertical", extend(logic, { },
items: [ BI.LogicFactory.createLogic(
{ el: this.combo } "vertical",
], extend(logic, {
})))); items: [{ el: this.combo }],
isDefaultInit && (this._assertPopupView()); })
)
)
);
isDefaultInit && this._assertPopupView();
} }
_toggle(e) { _toggle(e) {
@ -129,39 +153,46 @@ export class Bubble extends Widget {
if (stopPropagation) { if (stopPropagation) {
e.stopPropagation(); e.stopPropagation();
} }
} };
let enterPopup = false; let enterPopup = false;
const hide = (e) => { const hide = (e) => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid() && toggle === true) { if (
this.isEnabled() &&
this.isValid() &&
this.combo.isEnabled() &&
this.combo.isValid() &&
toggle === true
) {
this._hideView(e); this._hideView(e);
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.combo); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.combo);
this.fireEvent(Bubble.EVENT_COLLAPSE); this.fireEvent(Bubble.EVENT_COLLAPSE);
} }
this.popupView && this.popupView.element.off("mouseenter." + this.getName()).off("mouseleave." + this.getName()); this.popupView &&
this.popupView.element.off(`mouseenter.${this.getName()}`).off(`mouseleave.${this.getName()}`);
enterPopup = false; enterPopup = false;
} };
each(evs, (i, ev) => { each(evs, (i, ev) => {
let debounced; let debounced;
switch (ev) { switch (ev) {
case "hover": case "hover":
this.element.on("mouseenter." + this.getName(), (e) => { this.element.on(`mouseenter.${this.getName()}`, (e) => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this._popupView(e); this._popupView(e);
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.combo); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.combo);
this.fireEvent(Bubble.EVENT_EXPAND); this.fireEvent(Bubble.EVENT_EXPAND);
} }
}); });
this.element.on("mouseleave." + this.getName(), (e) => { this.element.on(`mouseleave.${this.getName()}`, (e) => {
if (this.popupView) { if (this.popupView) {
this.popupView.element.on("mouseenter." + this.getName(), (e) => { this.popupView.element.on(`mouseenter.${this.getName()}`, (e) => {
enterPopup = true; enterPopup = true;
this.popupView.element.on("mouseleave." + this.getName(), (e) => { this.popupView.element.on(`mouseleave.${this.getName()}`, (e) => {
hide(e); hide(e);
}); });
this.popupView.element.off("mouseenter." + this.getName()); this.popupView.element.off(`mouseenter.${this.getName()}`);
}); });
defer(() => { defer(() => {
if (!enterPopup) { if (!enterPopup) {
@ -172,9 +203,15 @@ export class Bubble extends Widget {
}); });
break; break;
case "click": case "click":
debounced = debounce((e) => { debounced = debounce(
(e) => {
if (this.combo.element.__isMouseInBounds__(e)) { if (this.combo.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (
this.isEnabled() &&
this.isValid() &&
this.combo.isEnabled() &&
this.combo.isValid()
) {
// if (!o.toggle && this.isViewVisible()) { // if (!o.toggle && this.isViewVisible()) {
// return; // return;
// } // }
@ -188,19 +225,28 @@ export class Bubble extends Widget {
} }
} }
} }
}, BI.EVENT_RESPONSE_TIME, { },
"leading": true, BI.EVENT_RESPONSE_TIME,
"trailing": false, {
}); leading: true,
this.element.off(ev + "." + this.getName()).on(ev + "." + this.getName(), (e) => { trailing: false,
}
);
this.element.off(`${ev}.${this.getName()}`).on(`${ev}.${this.getName()}`, (e) => {
debounced(e); debounced(e);
st(e); st(e);
}); });
break; break;
case "click-hover": case "click-hover":
debounced = debounce((e) => { debounced = debounce(
(e) => {
if (this.combo.element.__isMouseInBounds__(e)) { if (this.combo.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (
this.isEnabled() &&
this.isValid() &&
this.combo.isEnabled() &&
this.combo.isValid()
) {
// if (this.isViewVisible()) { // if (this.isViewVisible()) {
// return; // return;
// } // }
@ -211,22 +257,25 @@ export class Bubble extends Widget {
} }
} }
} }
}, BI.EVENT_RESPONSE_TIME, { },
"leading": true, BI.EVENT_RESPONSE_TIME,
"trailing": false, {
}); leading: true,
this.element.off("click." + this.getName()).on("click." + this.getName(), (e) => { trailing: false,
}
);
this.element.off(`click.${this.getName()}`).on(`click.${this.getName()}`, (e) => {
debounced(e); debounced(e);
st(e); st(e);
}); });
this.element.on("mouseleave." + this.getName(), (e) => { this.element.on(`mouseleave.${this.getName()}`, (e) => {
if (this.popupView) { if (this.popupView) {
this.popupView.element.on("mouseenter." + this.getName(), (e) => { this.popupView.element.on(`mouseenter.${this.getName()}`, (e) => {
enterPopup = true; enterPopup = true;
this.popupView.element.on("mouseleave." + this.getName(), (e) => { this.popupView.element.on(`mouseleave.${this.getName()}`, (e) => {
hide(e); hide(e);
}); });
this.popupView.element.off("mouseenter." + this.getName()); this.popupView.element.off(`mouseenter.${this.getName()}`);
}); });
delay(() => { delay(() => {
if (!enterPopup) { if (!enterPopup) {
@ -237,7 +286,7 @@ export class Bubble extends Widget {
}); });
break; break;
case "hover-click": case "hover-click":
this.element.on("mouseenter." + this.getName(), (e) => { this.element.on(`mouseenter.${this.getName()}`, (e) => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this._popupView(e); this._popupView(e);
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.combo); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.combo);
@ -260,11 +309,15 @@ export class Bubble extends Widget {
_assertPopupView() { _assertPopupView() {
const { showArrow, value } = this.options; const { showArrow, value } = this.options;
if (isNull(this.popupView)) { if (isNull(this.popupView)) {
this.popupView = createWidget(isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { this.popupView = createWidget(
type: "bi.bubble_popup_view", isFunction(this.options.popup) ? this.options.popup() : this.options.popup,
{
type: BubblePopupView.xtype,
showArrow, showArrow,
value, value,
}, this); },
this
);
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
this.combo.setValue(this.getValue()); this.combo.setValue(this.getValue());
@ -283,12 +336,10 @@ export class Bubble extends Widget {
this._assertPopupView(); this._assertPopupView();
if (!this._rendered) { if (!this._rendered) {
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
element: isFunction(this.options.container) ? this.options.container() : (this.options.container || this), element: isFunction(this.options.container) ? this.options.container() : this.options.container || this,
items: [ items: [{ el: this.popupView }],
{ el: this.popupView }
],
}); });
this._rendered = true; this._rendered = true;
} }
@ -299,9 +350,14 @@ export class Bubble extends Widget {
// return; // return;
// } // }
// BI-10290 公式combo双击公式内容会收起 // BI-10290 公式combo双击公式内容会收起
if (e && ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) if (
|| (this.popupView && this.popupView.element.find(e.target).length > 0) e &&
|| e.target.className === "CodeMirror-cursor" || Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0)) {// BI-9887 CodeMirror的公式弹框需要特殊处理下 ((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(","); const directions = this.options.direction.split(",");
if (contains(directions, "innerLeft") || contains(directions, "innerRight")) { if (contains(directions, "innerLeft") || contains(directions, "innerRight")) {
// popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置 // popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置
@ -344,13 +400,17 @@ export class Bubble extends Widget {
this.element.removeClass(this.options.comboClass); this.element.removeClass(this.options.comboClass);
Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); Widget._renderEngine
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); .createElement(document)
.unbind(`mousedown.${this.getName()}`)
.unbind(`mousewheel.${this.getName()}`);
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`);
this.fireEvent(Bubble.EVENT_AFTER_HIDEVIEW); this.fireEvent(Bubble.EVENT_AFTER_HIDEVIEW);
} }
_popupView(e) { _popupView(e) {
const { adjustXOffset, showArrow, adjustYOffset, adjustLength, placement, hideWhenClickOutside, hideWhenBlur } = this.options; const { adjustXOffset, showArrow, adjustYOffset, adjustLength, placement, hideWhenClickOutside, hideWhenBlur } =
this.options;
this._assertPopupViewRender(); this._assertPopupViewRender();
this.fireEvent(Bubble.EVENT_BEFORE_POPUPVIEW); this.fireEvent(Bubble.EVENT_BEFORE_POPUPVIEW);
// popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下 // popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下
@ -365,11 +425,9 @@ export class Bubble extends Widget {
{ {
name: "offset", name: "offset",
options: { options: {
offset: () => { offset: () => [adjustXOffset, (showArrow ? 12 : 0) + (adjustYOffset + adjustLength)],
return [adjustXOffset, (showArrow ? 12 : 0) + (adjustYOffset + adjustLength)];
}, },
}, },
}
]; ];
if (this.options.showArrow) { if (this.options.showArrow) {
modifiers.push({ modifiers.push({
@ -389,11 +447,14 @@ export class Bubble extends Widget {
// this.adjustHeight(e); // this.adjustHeight(e);
this.element.addClass(this.options.comboClass); this.element.addClass(this.options.comboClass);
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()); hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`);
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`);
hideWhenClickOutside && Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), bind(this._hideIf, this)); hideWhenClickOutside &&
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).bind("blur." + this.getName(), bind(this._hideIf, this)); Widget._renderEngine.createElement(document).bind(`mousedown.${this.getName()}`, bind(this._hideIf, this));
BI.EVENT_BLUR &&
hideWhenBlur &&
Widget._renderEngine.createElement(window).bind(`blur.${this.getName()}`, bind(this._hideIf, this));
this.fireEvent(Bubble.EVENT_AFTER_POPUPVIEW); this.fireEvent(Bubble.EVENT_AFTER_POPUPVIEW);
} }
@ -425,9 +486,7 @@ export class Bubble extends Widget {
} }
} }
adjustHeight() { adjustHeight() {}
}
resetListHeight(h) { resetListHeight(h) {
this._assertPopupView(); this._assertPopupView();
@ -501,13 +560,13 @@ export class Bubble extends Widget {
} }
destroyed() { destroyed() {
Widget._renderEngine.createElement(document) Widget._renderEngine
.unbind("click." + this.getName()) .createElement(document)
.unbind("mousedown." + this.getName()) .unbind(`click.${this.getName()}`)
.unbind("mouseenter." + this.getName()) .unbind(`mousedown.${this.getName()}`)
.unbind("mouseleave." + this.getName()); .unbind(`mouseenter.${this.getName()}`)
Widget._renderEngine.createElement(window) .unbind(`mouseleave.${this.getName()}`);
.unbind("blur." + this.getName()); Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`);
this.popper && this.popper.destroy(); this.popper && this.popper.destroy();
this.popper = null; this.popper = null;
this.popupView && this.popupView._destroy(); this.popupView && this.popupView._destroy();

309
src/base/combination/combo.js

@ -1,12 +1,25 @@
import { PopupView } from "../layer";
import { Bubble } from "./bubble";
import {
shortcut,
Widget,
Controller,
extend,
createWidget,
nextTick,
bind,
isNotNull,
isNull,
isFunction,
each
} from "@/core";
import { Resizers } from "@/base/0.base";
/** /**
* @class BI.Combo * @class BI.Combo
* @extends BI.Widget * @extends BI.Widget
*/ */
import { shortcut, Widget, Controller, extend, createWidget, nextTick, bind, isNotNull, isNull, isFunction, each } from "../../core";
import { Bubble } from "./bubble";
import { Resizers } from "../0.base";
let needHideWhenAnotherComboOpen = {}; let needHideWhenAnotherComboOpen = {};
let currentOpenedCombos = {}; let currentOpenedCombos = {};
@ -29,7 +42,7 @@ export class Combo extends Bubble {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), baseCls: `${conf.baseCls || ""} bi-combo${BI.isIE() ? " hack" : ""}`,
attributes: { attributes: {
tabIndex: -1, tabIndex: -1,
}, },
@ -96,42 +109,55 @@ export class Combo extends Bubble {
} }
}); });
this.element.on("mouseenter." + this.getName(), (e) => { this.element.on(`mouseenter.${this.getName()}`, e => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this.element.addClass(hoverClass); this.element.addClass(hoverClass);
} }
}); });
this.element.on("mouseleave." + this.getName(), (e) => { this.element.on(`mouseleave.${this.getName()}`, e => {
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) {
this.element.removeClass(hoverClass); this.element.removeClass(hoverClass);
} }
}); });
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
scrolly: false, scrolly: false,
}, BI.LogicFactory.createLogic("vertical", extend(logic, { },
items: [ BI.LogicFactory.createLogic(
{ el: this.combo } "vertical",
], extend(logic, {
})))); items: [{ el: this.combo }],
isDefaultInit && (this._assertPopupView()); })
Resizers.add(this.getName(), bind((e) => { )
)
);
isDefaultInit && this._assertPopupView();
Resizers.add(
this.getName(),
bind(e => {
// 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理 // 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理
if (this.isViewVisible()) { if (this.isViewVisible()) {
isNotNull(e) ? this._hideIf(e) : this._hideView(); isNotNull(e) ? this._hideIf(e) : this._hideView();
} }
}, this)); }, this)
);
} }
_assertPopupView() { _assertPopupView() {
const { showArrow, value, hideWhenClickOutside, hideWhenBlur } = this.options; const { showArrow, value, hideWhenClickOutside, hideWhenBlur } = this.options;
if (isNull(this.popupView)) { if (isNull(this.popupView)) {
this.popupView = createWidget(isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { this.popupView = createWidget(
type: "bi.popup_view", isFunction(this.options.popup) ? this.options.popup() : this.options.popup,
{
type: PopupView.xtype,
showArrow, showArrow,
value, value,
}, this); },
this
);
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
this.combo.setValue(this.getValue()); this.combo.setValue(this.getValue());
@ -167,8 +193,12 @@ export class Combo extends Bubble {
delete needHideWhenAnotherComboOpen[this.getName()]; delete needHideWhenAnotherComboOpen[this.getName()];
delete currentOpenedCombos[this.getName()]; delete currentOpenedCombos[this.getName()];
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); hideWhenClickOutside &&
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); Widget._renderEngine
.createElement(document)
.unbind(`mousedown.${this.getName()}`)
.unbind(`mousewheel.${this.getName()}`);
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`);
this.fireEvent(Combo.EVENT_AFTER_HIDEVIEW, e); this.fireEvent(Combo.EVENT_AFTER_HIDEVIEW, e);
} }
@ -192,25 +222,49 @@ export class Combo extends Bubble {
this.adjustHeight(e); this.adjustHeight(e);
this.element.addClass(this.options.comboClass); this.element.addClass(this.options.comboClass);
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); hideWhenClickOutside &&
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousewheel." + this.getName()); Widget._renderEngine
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); .createElement(document)
.unbind(`mousedown.${this.getName()}`)
.unbind(`mousewheel.${this.getName()}`);
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind(`mousewheel.${this.getName()}`);
BI.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 &&
hideWhenClickOutside && Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), bind(this._hideIf, this)).bind("mousewheel." + this.getName(), bind(this._hideIf, this)); Widget._renderEngine.createElement(document).bind(`mousewheel.${this.getName()}`, bind(this._hideIf, this));
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).bind("blur." + 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));
BI.EVENT_BLUR &&
hideWhenBlur &&
Widget._renderEngine.createElement(window).bind(`blur.${this.getName()}`, bind(this._hideIf, this));
this.fireEvent(Combo.EVENT_AFTER_POPUPVIEW); this.fireEvent(Combo.EVENT_AFTER_POPUPVIEW);
} }
adjustHeight(e) { adjustHeight(e) {
const { belowMouse, supportCSSTransform, container, direction, adjustXOffset, adjustYOffset, adjustLength, showArrow, isNeedAdjustHeight, offsetStyle } = this.options; const {
belowMouse,
supportCSSTransform,
container,
direction,
adjustXOffset,
adjustYOffset,
adjustLength,
showArrow,
isNeedAdjustHeight,
offsetStyle,
} = this.options;
let p = {}; let p = {};
if (!this.popupView) { if (!this.popupView) {
return; return;
} }
const isVisible = this.popupView.isVisible(); const isVisible = this.popupView.isVisible();
this.popupView.visible(); this.popupView.visible();
const combo = (belowMouse && isNotNull(e)) ? { const combo =
belowMouse && isNotNull(e)
? {
element: { element: {
0: e.target, 0: e.target,
offset: () => { offset: () => {
@ -228,77 +282,206 @@ export class Combo extends Bubble {
height: 24, height: 24,
}; };
}, },
outerWidth: () => { outerWidth: () => 0,
return 0; outerHeight: () => 24,
}, },
outerHeight: () => { }
return 24; : this.combo;
}, const positionRelativeElement = supportCSSTransform
}, ? BI.DOM.getPositionRelativeContainingBlock(
} : this.combo; isNull(container)
const positionRelativeElement = supportCSSTransform ? BI.DOM.getPositionRelativeContainingBlock(isNull(container) ? this.element[0] : Widget._renderEngine.createElement(isFunction(container) ? container() : container)[0]) : null; ? this.element[0]
: Widget._renderEngine.createElement(isFunction(container) ? container() : container)[0]
)
: null;
const TRIANGLE_LENGTH = 12; const TRIANGLE_LENGTH = 12;
switch (direction) { switch (direction) {
case "bottom": case "bottom":
case "bottom,right": case "bottom,right":
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["bottom", "top", "right", "left"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight,
["bottom", "top", "right", "left"],
offsetStyle,
positionRelativeElement
);
break; break;
case "top": case "top":
case "top,right": case "top,right":
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["top", "bottom", "right", "left"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight,
["top", "bottom", "right", "left"],
offsetStyle,
positionRelativeElement
);
break; break;
case "left": case "left":
case "left,bottom": case "left,bottom":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["left", "right", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["left", "right", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "right": case "right":
case "right,bottom": case "right,bottom":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["right", "left", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "top,left": case "top,left":
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["top", "bottom", "left", "right"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight,
["top", "bottom", "left", "right"],
offsetStyle,
positionRelativeElement
);
break; break;
case "bottom,left": case "bottom,left":
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["bottom", "top", "left", "right"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight,
["bottom", "top", "left", "right"],
offsetStyle,
positionRelativeElement
);
break; break;
case "left,top": case "left,top":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["left", "right", "top", "bottom"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["left", "right", "top", "bottom"],
offsetStyle,
positionRelativeElement
);
break; break;
case "right,top": case "right,top":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "top", "bottom"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["right", "left", "top", "bottom"],
offsetStyle,
positionRelativeElement
);
break; break;
case "right,innerRight": case "right,innerRight":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["right", "left", "innerRight", "innerLeft", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "right,innerLeft": case "right,innerLeft":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["right", "left", "innerLeft", "innerRight", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "innerRight": case "innerRight":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["innerRight", "innerLeft", "right", "left", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "innerLeft": case "innerLeft":
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], offsetStyle, positionRelativeElement); p = BI.DOM.getComboPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
adjustYOffset,
isNeedAdjustHeight,
["innerLeft", "innerRight", "left", "right", "bottom", "top"],
offsetStyle,
positionRelativeElement
);
break; break;
case "top,custom": case "top,custom":
case "custom,top": case "custom,top":
p = BI.DOM.getTopAdaptPosition(combo, this.popupView, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight); p = BI.DOM.getTopAdaptPosition(
combo,
this.popupView,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight
);
p.dir = "top"; p.dir = "top";
break; break;
case "custom,bottom": case "custom,bottom":
case "bottom,custom": case "bottom,custom":
p = BI.DOM.getBottomAdaptPosition(combo, this.popupView, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight); p = BI.DOM.getBottomAdaptPosition(
combo,
this.popupView,
adjustYOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0),
isNeedAdjustHeight
);
p.dir = "bottom"; p.dir = "bottom";
break; break;
case "left,custom": case "left,custom":
case "custom,left": case "custom,left":
p = BI.DOM.getLeftAdaptPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0)); p = BI.DOM.getLeftAdaptPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0)
);
delete p.top; delete p.top;
delete p.adaptHeight; delete p.adaptHeight;
p.dir = "left"; p.dir = "left";
break; break;
case "custom,right": case "custom,right":
case "right,custom": case "right,custom":
p = BI.DOM.getRightAdaptPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0)); p = BI.DOM.getRightAdaptPosition(
combo,
this.popupView,
adjustXOffset + adjustLength + (showArrow ? TRIANGLE_LENGTH : 0)
);
delete p.top; delete p.top;
delete p.adaptHeight; delete p.adaptHeight;
p.dir = "right"; p.dir = "right";
@ -313,7 +496,8 @@ export class Combo extends Bubble {
const width = this.combo.element.outerWidth(); const width = this.combo.element.outerWidth();
const height = this.combo.element.outerHeight(); const height = this.combo.element.outerHeight();
this.popupView.setDirection && this.popupView.setDirection(p.dir, { this.popupView.setDirection &&
this.popupView.setDirection(p.dir, {
width, width,
height, height,
offsetStyle, offsetStyle,
@ -323,7 +507,6 @@ export class Combo extends Bubble {
}); });
if (supportCSSTransform) { if (supportCSSTransform) {
const positonedRect = positionRelativeElement.getBoundingClientRect(); const positonedRect = positionRelativeElement.getBoundingClientRect();
const scaleX = positonedRect.width / positionRelativeElement.offsetWidth; const scaleX = positonedRect.width / positionRelativeElement.offsetWidth;
@ -348,14 +531,14 @@ export class Combo extends Bubble {
} }
destroyed() { destroyed() {
Widget._renderEngine.createElement(document) Widget._renderEngine
.unbind("click." + this.getName()) .createElement(document)
.unbind("mousedown." + this.getName()) .unbind(`click.${this.getName()}`)
.unbind("mousewheel." + this.getName()) .unbind(`mousedown.${this.getName()}`)
.unbind("mouseenter." + this.getName()) .unbind(`mousewheel.${this.getName()}`)
.unbind("mouseleave." + this.getName()); .unbind(`mouseenter.${this.getName()}`)
Widget._renderEngine.createElement(window) .unbind(`mouseleave.${this.getName()}`);
.unbind("blur." + this.getName()); Widget._renderEngine.createElement(window).unbind(`blur.${this.getName()}`);
Resizers.remove(this.getName()); Resizers.remove(this.getName());
this.popupView && this.popupView._destroy(); this.popupView && this.popupView._destroy();
delete needHideWhenAnotherComboOpen[this.getName()]; delete needHideWhenAnotherComboOpen[this.getName()];

116
src/base/combination/expander.js

@ -1,3 +1,17 @@
import {
VerticalLayout,
shortcut,
Widget,
Controller,
extend,
nextTick,
each,
debounce,
isNull,
createWidget
} from "@/core";
import { ButtonGroup } from "./group.button";
/** /**
* *
* 某个可以展开的节点 * 某个可以展开的节点
@ -6,7 +20,6 @@
* @class BI.Expander * @class BI.Expander
* @extends BI.Widget * @extends BI.Widget
*/ */
import { shortcut, Widget, Controller, extend, nextTick, each, debounce, isNull, createWidget } from "../../core";
@shortcut() @shortcut()
export class Expander extends Widget { export class Expander extends Widget {
@ -67,22 +80,23 @@ export class Expander extends Widget {
} }
}); });
this.element.hover(() => { this.element.hover(
() => {
if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) {
this.element.addClass(hoverClass); this.element.addClass(hoverClass);
} }
}, () => { },
() => {
if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) {
this.element.removeClass(hoverClass); this.element.removeClass(hoverClass);
} }
}); }
);
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
element: this, element: this,
items: [ items: [{ el: this.expander }],
{ el: this.expander }
],
}); });
isDefaultInit && this._assertPopupView(); isDefaultInit && this._assertPopupView();
if (this.expander.isOpened() === true) { if (this.expander.isOpened() === true) {
@ -107,39 +121,75 @@ export class Expander extends Widget {
each(evs, (i, e) => { each(evs, (i, e) => {
switch (e) { switch (e) {
case "hover": case "hover":
this.element[e]((e) => { this.element[e](
if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { e => {
if (
this.isEnabled() &&
this.isValid() &&
this.expander.isEnabled() &&
this.expander.isValid()
) {
this._popupView(); this._popupView();
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.expander); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.expander);
this.fireEvent(Expander.EVENT_EXPAND); this.fireEvent(Expander.EVENT_EXPAND);
} }
}, () => { },
if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid() && toggle) { () => {
if (
this.isEnabled() &&
this.isValid() &&
this.expander.isEnabled() &&
this.expander.isValid() &&
toggle
) {
this._hideView(); this._hideView();
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.expander); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.expander);
this.fireEvent(Expander.EVENT_COLLAPSE); this.fireEvent(Expander.EVENT_COLLAPSE);
} }
}); }
);
break; break;
case "click": case "click":
if (e) { if (e) {
this.element.off(e + "." + this.getName()).on(e + "." + this.getName(), debounce((e) => { this.element.off(`${e}.${this.getName()}`).on(
`${e}.${this.getName()}`,
debounce(
e => {
if (this.expander.element.__isMouseInBounds__(e)) { if (this.expander.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && this.isValid() && this.expander.isEnabled() && this.expander.isValid()) { if (
this.isEnabled() &&
this.isValid() &&
this.expander.isEnabled() &&
this.expander.isValid()
) {
toggle ? this._toggle() : this._popupView(); toggle ? this._toggle() : this._popupView();
if (this.isExpanded()) { if (this.isExpanded()) {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.expander); this.fireEvent(
Controller.EVENT_CHANGE,
BI.Events.EXPAND,
"",
this.expander
);
this.fireEvent(Expander.EVENT_EXPAND); this.fireEvent(Expander.EVENT_EXPAND);
} else { } else {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.expander); this.fireEvent(
Controller.EVENT_CHANGE,
BI.Events.COLLAPSE,
"",
this.expander
);
this.fireEvent(Expander.EVENT_COLLAPSE); this.fireEvent(Expander.EVENT_COLLAPSE);
} }
} }
} }
}, BI.EVENT_RESPONSE_TIME, { },
"leading": true, BI.EVENT_RESPONSE_TIME,
"trailing": false, {
})); leading: true,
trailing: false,
}
)
);
} }
break; break;
default: default:
@ -155,16 +205,22 @@ export class Expander extends Widget {
_assertPopupView() { _assertPopupView() {
const { value } = this.options; const { value } = this.options;
if (isNull(this.popupView)) { if (isNull(this.popupView)) {
this.popupView = createWidget(this.options.popup, { this.popupView = createWidget(
type: "bi.button_group", this.options.popup,
{
type: ButtonGroup.xtype,
cls: "expander-popup", cls: "expander-popup",
layouts: [{ layouts: [
type: "bi.vertical", {
type: VerticalLayout.xtype,
hgap: 0, hgap: 0,
vgap: 0, vgap: 0,
}], }
],
value, value,
}, this); },
this
);
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args);
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
@ -183,12 +239,10 @@ export class Expander extends Widget {
this._assertPopupView(); this._assertPopupView();
if (!this._rendered) { if (!this._rendered) {
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
element: this, element: this,
items: [ items: [{ el: this.popupView }],
{ el: this.popupView }
],
}); });
this._rendered = true; this._rendered = true;
} }

67
src/base/combination/group.button.js

@ -1,9 +1,38 @@
import {
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
} from "@/core";
import { TextButton } from "../single";
/** /**
* Created by GUY on 2015/6/26. * Created by GUY on 2015/6/26.
* @class BI.ButtonGroup * @class BI.ButtonGroup
* @extends BI.Widget * @extends BI.Widget
*/ */
import { 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 } from "../../core";
@shortcut() @shortcut()
export class ButtonGroup extends Widget { export class ButtonGroup extends Widget {
@ -18,11 +47,13 @@ export class ButtonGroup extends Widget {
items: [], items: [],
value: "", value: "",
chooseType: BI.Selection.Single, chooseType: BI.Selection.Single,
layouts: [{ layouts: [
type: "bi.center", {
type: CenterLayout.xtype,
hgap: 0, hgap: 0,
vgap: 0, vgap: 0,
}], }
],
}); });
} }
@ -35,13 +66,17 @@ export class ButtonGroup extends Widget {
}); });
}); });
this.behaviors = behaviors; this.behaviors = behaviors;
const items = isFunction(optionsItems) ? this.__watch(optionsItems, (context, newValue) => { const items = isFunction(optionsItems)
? this.__watch(optionsItems, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : optionsItems; })
: optionsItems;
this.populate(items); this.populate(items);
this.options.value = isFunction(value) ? this.__watch(value, (context, newValue) => { this.options.value = isFunction(value)
? this.__watch(value, (context, newValue) => {
this.setValue(newValue); this.setValue(newValue);
}) : value; })
: value;
if (isKey(value) || isNotEmptyArray(value)) { if (isKey(value) || isNotEmptyArray(value)) {
this.setValue(value); this.setValue(value);
} }
@ -50,9 +85,11 @@ export class ButtonGroup extends Widget {
_createBtns(items) { _createBtns(items) {
let btns; let btns;
Widget.execWithContext(this, () => { Widget.execWithContext(this, () => {
btns = createWidgets(createItems(items, { btns = createWidgets(
type: "bi.text_button", createItems(items, {
})); type: TextButton.xtype,
})
);
}); });
return btns; return btns;
@ -99,13 +136,15 @@ export class ButtonGroup extends Widget {
const { layouts: optionsLayouts } = this.options; const { layouts: optionsLayouts } = this.options;
const layouts = isArray(optionsLayouts) ? optionsLayouts : [optionsLayouts]; const layouts = isArray(optionsLayouts) ? optionsLayouts : [optionsLayouts];
for (let i = layouts.length - 1; i > 0; i--) { for (let i = layouts.length - 1; i > 0; i--) {
btns = map(btns, (k, it) => extend({}, layouts[i], { btns = map(btns, (k, it) =>
extend({}, layouts[i], {
items: [ items: [
extend({}, layouts[i].el, { extend({}, layouts[i].el, {
el: it, el: it,
}) })
], ],
})); })
);
} }
return btns; return btns;
@ -146,7 +185,7 @@ export class ButtonGroup extends Widget {
_isSimpleLayout() { _isSimpleLayout() {
const { layouts, items } = this.options; const { layouts, items } = this.options;
return isArray(layouts) ? (layouts.length === 1 && !isArray(items[0])) : true; return isArray(layouts) ? layouts.length === 1 && !isArray(items[0]) : true;
} }
doBehavior() { doBehavior() {

53
src/base/combination/group.combo.js

@ -1,9 +1,23 @@
import { TextButton } from "../single";
import { ButtonTree } from "./tree.button";
import {
VerticalLayout,
shortcut,
Widget,
Controller,
extend,
isEmpty,
each,
formatEL,
clone,
createWidget
} from "@/core";
import { Combo } from "./combo";
/** /**
* Created by GUY on 2015/8/10. * Created by GUY on 2015/8/10.
*/ */
import { shortcut, Widget, Controller, extend, isEmpty, each, formatEL, clone, createWidget } from "../../core";
@shortcut() @shortcut()
export class ComboGroup extends Widget { export class ComboGroup extends Widget {
static xtype = "bi.combo_group"; static xtype = "bi.combo_group";
@ -22,16 +36,18 @@ export class ComboGroup extends Widget {
isNeedAdjustHeight: false, isNeedAdjustHeight: false,
isNeedAdjustWidth: false, isNeedAdjustWidth: false,
el: { type: "bi.text_button", text: "", value: "" }, el: { type: TextButton.xtype, text: "", value: "" },
items: [], items: [],
popup: { popup: {
el: { el: {
type: "bi.button_tree", type: ButtonTree.xtype,
chooseType: 0, chooseType: 0,
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
}, },
}, },
}); });
@ -42,7 +58,19 @@ export class ComboGroup extends Widget {
} }
_populate(item) { _populate(item) {
const { items, action, height, direction, isDefaultInit, isNeedAdjustHeight, isNeedAdjustWidth, adjustLength, popup, container, trigger } = this.options; const {
items,
action,
height,
direction,
isDefaultInit,
isNeedAdjustHeight,
isNeedAdjustWidth,
adjustLength,
popup,
container,
trigger,
} = this.options;
const children = items; const children = items;
if (isEmpty(children)) { if (isEmpty(children)) {
throw new Error("ComboGroup构造错误"); throw new Error("ComboGroup构造错误");
@ -65,7 +93,7 @@ export class ComboGroup extends Widget {
} }
}); });
this.combo = createWidget({ this.combo = createWidget({
type: "bi.combo", type: Combo.xtype,
element: this, element: this,
container, container,
height, height,
@ -77,9 +105,12 @@ export class ComboGroup extends Widget {
adjustLength, adjustLength,
el: item, el: item,
popup: extend({}, popup, { popup: extend({}, popup, {
el: extend({ el: extend(
{
items: children, items: children,
}, popup.el), },
popup.el
),
}), }),
}); });
this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {

49
src/base/combination/group.virtual.js

@ -1,4 +1,20 @@
import { shortcut, Widget, Controller, extend, isFunction, isKey, isArray, map, stripEL, deepClone, formatEL, isEmpty, each, createWidget } from "../../core"; import {
CenterLayout,
shortcut,
Widget,
Controller,
extend,
isFunction,
isKey,
isArray,
map,
stripEL,
deepClone,
formatEL,
isEmpty,
each,
createWidget
} from "@/core";
@shortcut() @shortcut()
export class VirtualGroup extends Widget { export class VirtualGroup extends Widget {
@ -10,23 +26,29 @@ export class VirtualGroup extends Widget {
return extend(super._defaultConfig(...arguments), { return extend(super._defaultConfig(...arguments), {
baseCls: "bi-virtual-group", baseCls: "bi-virtual-group",
items: [], items: [],
layouts: [{ layouts: [
type: "bi.center", {
type: CenterLayout.xtype,
hgap: 0, hgap: 0,
vgap: 0, vgap: 0,
}], }
],
}); });
} }
render() { render() {
const { items: optionsItems, value } = this.options; const { items: optionsItems, value } = this.options;
const items = isFunction(optionsItems) ? this.__watch(optionsItems, (context, newValue) => { const items = isFunction(optionsItems)
? this.__watch(optionsItems, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : optionsItems; })
: optionsItems;
this.populate(items); this.populate(items);
this.options.value = isFunction(value) ? this.__watch(value, (context, newValue) => { this.options.value = isFunction(value)
? this.__watch(value, (context, newValue) => {
this.setValue(newValue); this.setValue(newValue);
}) : value; })
: value;
if (isKey(value)) { if (isKey(value)) {
this.setValue(value); this.setValue(value);
} }
@ -34,7 +56,7 @@ export class VirtualGroup extends Widget {
_packageBtns(items) { _packageBtns(items) {
const o = this.options; const o = this.options;
const map = this.buttonMap = {}; const map = (this.buttonMap = {});
const layouts = isArray(o.layouts) ? o.layouts : [o.layouts]; const layouts = isArray(o.layouts) ? o.layouts : [o.layouts];
for (let i = layouts.length - 1; i > 0; i--) { for (let i = layouts.length - 1; i > 0; i--) {
items = map(items, (k, it) => { items = map(items, (k, it) => {
@ -43,13 +65,16 @@ export class VirtualGroup extends Widget {
return extend({}, layouts[i], { return extend({}, layouts[i], {
items: [ items: [
extend({}, layouts[i].el, { extend({}, layouts[i].el, {
el: extend({ el: extend(
ref: (_ref) => { {
ref: _ref => {
if (isKey(map[el.value])) { if (isKey(map[el.value])) {
map[el.value] = _ref; map[el.value] = _ref;
} }
}, },
}, el), },
el
),
}) })
], ],
}); });

148
src/base/combination/loader.js

@ -1,3 +1,22 @@
import { ButtonGroup } from "./group.button";
import { LoadingBar } from "../single";
import {
VerticalLayout,
shortcut,
Widget,
Controller,
extend,
createWidget,
isEmpty,
nextTick,
bind,
isFunction,
isNotEmptyArray,
isNumber,
isObject,
each
} from "@/core";
/** /**
* 加载控件 * 加载控件
* *
@ -5,7 +24,6 @@
* @class BI.Loader * @class BI.Loader
* @extends BI.Widget * @extends BI.Widget
*/ */
import { shortcut, Widget, Controller, extend, createWidget, isEmpty, nextTick, bind, isFunction, isNotEmptyArray, isNumber, isObject, each } from "../../core";
@shortcut() @shortcut()
export class Loader extends Widget { export class Loader extends Widget {
@ -26,7 +44,7 @@ export class Loader extends Widget {
// 下面是button_group的属性 // 下面是button_group的属性
el: { el: {
type: "bi.button_group", type: ButtonGroup.xtype,
}, },
items: [], items: [],
@ -45,32 +63,53 @@ export class Loader extends Widget {
_prevLoad() { _prevLoad() {
const o = this.options; const o = this.options;
this.prev.setLoading(); this.prev.setLoading();
o.itemsCreator.apply(this, [{ times: --this.times }, (...args) => { o.itemsCreator.apply(this, [
{ times: --this.times },
(...args) => {
this.prev.setLoaded(); this.prev.setLoaded();
this.prependItems.apply(this, args); this.prependItems.apply(this, args);
}]); }
]);
} }
_nextLoad() { _nextLoad() {
const o = this.options; const o = this.options;
this.next.setLoading(); this.next.setLoading();
o.itemsCreator.apply(this, [{ times: ++this.times }, (...args) => { o.itemsCreator.apply(this, [
{ times: ++this.times },
(...args) => {
this.next.setLoaded(); this.next.setLoaded();
this.addItems.apply(this, args); this.addItems.apply(this, args);
}]); }
]);
} }
render() { render() {
const { itemsCreator, prev, next, el, items: optionsItems, value, direction, logic, isDefaultInit } = this.options; const {
itemsCreator,
prev,
next,
el,
items: optionsItems,
value,
direction,
logic,
isDefaultInit,
} = this.options;
if (itemsCreator === false) { if (itemsCreator === false) {
prev = false; prev = false;
next = false; next = false;
} }
if (prev !== false) { if (prev !== false) {
this.prev = createWidget(extend({ this.prev = createWidget(
type: "bi.loading_bar", extend(
}, prev)); {
this.prev.on(Controller.EVENT_CHANGE, (type) => { type: LoadingBar.xtype,
},
prev
)
);
this.prev.on(Controller.EVENT_CHANGE, type => {
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
this._prevLoad(); this._prevLoad();
} }
@ -78,13 +117,15 @@ export class Loader extends Widget {
} }
this.button_group = createWidget(el, { this.button_group = createWidget(el, {
type: "bi.button_group", type: ButtonGroup.xtype,
chooseType: 0, chooseType: 0,
items: optionsItems, items: optionsItems,
behaviors: {}, behaviors: {},
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
value, value,
}); });
this.button_group.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.button_group.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
@ -95,30 +136,58 @@ export class Loader extends Widget {
}); });
if (next !== false) { if (next !== false) {
this.next = createWidget(extend({ this.next = createWidget(
type: "bi.loading_bar", extend(
}, next)); {
this.next.on(Controller.EVENT_CHANGE, (type) => { type: LoadingBar.xtype,
},
next
)
);
this.next.on(Controller.EVENT_CHANGE, type => {
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
this._nextLoad(); this._nextLoad();
} }
}); });
} }
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(direction), extend({ },
BI.LogicFactory.createLogic(
BI.LogicFactory.createLogicTypeByDirection(direction),
extend(
{
scrolly: true, scrolly: true,
}, logic, { },
items: BI.LogicFactory.createLogicItemsByDirection(direction, this.prev, this.button_group, this.next), logic,
})))); {
items: BI.LogicFactory.createLogicItemsByDirection(
isDefaultInit && isEmpty(optionsItems) && nextTick(bind(() => { direction,
this.prev,
this.button_group,
this.next
),
}
)
)
)
);
isDefaultInit &&
isEmpty(optionsItems) &&
nextTick(
bind(() => {
isDefaultInit && isEmpty(optionsItems) && this._populate(); isDefaultInit && isEmpty(optionsItems) && this._populate();
}, this)); }, this)
const items = isFunction(optionsItems) ? this.__watch(optionsItems, (context, newValue) => { );
const items = isFunction(optionsItems)
? this.__watch(optionsItems, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : optionsItems; })
: optionsItems;
if (isNotEmptyArray(items)) { if (isNotEmptyArray(items)) {
this._populate(items); this._populate(items);
} }
@ -130,10 +199,12 @@ export class Loader extends Widget {
return this.count < count; return this.count < count;
} }
return !!hasPrev.apply(this, [{ return !!hasPrev.apply(this, [
{
times: this.times, times: this.times,
count: this.count, count: this.count,
}]); }
]);
} }
hasNext() { hasNext() {
@ -142,10 +213,12 @@ export class Loader extends Widget {
return this.count < count; return this.count < count;
} }
return !!hasNext.apply(this, [{ return !!hasNext.apply(this, [
{
times: this.times, times: this.times,
count: this.count, count: this.count,
}]); }
]);
} }
prependItems(items) { prependItems(items) {
@ -176,14 +249,17 @@ export class Loader extends Widget {
_populate(items) { _populate(items) {
const o = this.options; const o = this.options;
if (arguments.length === 0 && (isFunction(o.itemsCreator))) { if (arguments.length === 0 && isFunction(o.itemsCreator)) {
o.itemsCreator.apply(this, [{ times: 1 }, (...args) => { o.itemsCreator.apply(this, [
{ times: 1 },
(...args) => {
if (args.length === 0) { if (args.length === 0) {
throw new Error("参数不能为空"); throw new Error("参数不能为空");
} }
this.populate.apply(this, args); this.populate.apply(this, args);
o.onLoaded(); o.onLoaded();
}]); }
]);
return false; return false;
} }

40
src/base/combination/navigation.js

@ -1,7 +1,23 @@
import { ButtonGroup } from "./group.button";
import {
CardLayout,
shortcut,
Widget,
Controller,
extend,
createWidget,
bind,
ShowListener,
isFunction,
each,
nextTick,
isKey,
values
} from "@/core";
/** /**
* Created by GUY on 2015/6/26. * Created by GUY on 2015/6/26.
*/ */
import { shortcut, Widget, Controller, extend, createWidget, bind, ShowListener, isFunction, each, nextTick, isKey, values } from "../../core";
@shortcut() @shortcut()
export class Navigation extends Widget { export class Navigation extends Widget {
@ -27,18 +43,25 @@ export class Navigation extends Widget {
render() { render() {
const { direction, logic, cardCreator, showIndex } = this.options; const { direction, logic, cardCreator, showIndex } = this.options;
this.tab = createWidget(this.options.tab, { type: "bi.button_group" }); this.tab = createWidget(this.options.tab, { type: ButtonGroup.xtype });
this.cardMap = {}; this.cardMap = {};
this.showIndex = 0; this.showIndex = 0;
this.layout = createWidget({ this.layout = createWidget({
type: "bi.card", type: CardLayout.xtype,
}); });
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(direction), extend({}, logic, { },
BI.LogicFactory.createLogic(
BI.LogicFactory.createLogicTypeByDirection(direction),
extend({}, logic, {
items: BI.LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout), items: BI.LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout),
})))); })
)
)
);
new ShowListener({ new ShowListener({
eventObj: this.tab, eventObj: this.tab,
@ -73,7 +96,7 @@ export class Navigation extends Widget {
const { single } = this.options; const { single } = this.options;
if (single === true) { if (single === true) {
each(this.cardMap, (name, card) => { each(this.cardMap, (name, card) => {
if (name !== (`${currCardName}`)) { if (name !== `${currCardName}`) {
this.layout.deleteCardByName(name); this.layout.deleteCardByName(name);
delete this.cardMap[name]; delete this.cardMap[name];
} }
@ -168,4 +191,3 @@ export class Navigation extends Widget {
super.destroy(arguments); super.destroy(arguments);
} }
} }

75
src/base/combination/searcher.js

@ -1,11 +1,7 @@
/** import { SearchEditor } from "@/widget/editor/editor.search.js";
* 搜索逻辑控件 import { SearcherView } from "../layer";
*
* Created by GUY on 2015/9/28.
* @class BI.Searcher
* @extends BI.Widget
*/
import { import {
VerticalLayout,
shortcut, shortcut,
Widget, Widget,
Controller, Controller,
@ -18,9 +14,17 @@ import {
nextTick, nextTick,
isEmptyString, isEmptyString,
isNull isNull
} from "../../core"; } from "@/core";
import { ButtonGroup } from "./group.button"; import { ButtonGroup } from "./group.button";
import { Maskers } from "../0.base"; import { Maskers } from "@/base/0.base";
/**
* 搜索逻辑控件
*
* Created by GUY on 2015/9/28.
* @class BI.Searcher
* @extends BI.Widget
*/
@shortcut() @shortcut()
export class Searcher extends Widget { export class Searcher extends Widget {
@ -54,15 +58,16 @@ export class Searcher extends Widget {
}, },
el: { el: {
type: "bi.search_editor", type: SearchEditor.xtype,
}, },
popup: { popup: {
type: "bi.searcher_view", type: SearcherView.xtype,
}, },
adapter: null, adapter: null,
masker: { // masker层 masker: {
// masker层
offset: {}, offset: {},
}, },
}); });
@ -72,11 +77,11 @@ export class Searcher extends Widget {
const { el, lgap, rgap, tgap, bgap, vgap, hgap, isDefaultInit } = this.options; const { el, lgap, rgap, tgap, bgap, vgap, hgap, isDefaultInit } = this.options;
this.editor = createWidget(el, { this.editor = createWidget(el, {
type: "bi.search_editor", type: SearchEditor.xtype,
}); });
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
element: this, element: this,
lgap, lgap,
rgap, rgap,
@ -86,13 +91,13 @@ export class Searcher extends Widget {
hgap, hgap,
items: [this.editor], items: [this.editor],
}); });
isDefaultInit && (this._assertPopupView()); isDefaultInit && this._assertPopupView();
const search = debounce(bind(this._search, this), BI.EVENT_RESPONSE_TIME, { const search = debounce(bind(this._search, this), BI.EVENT_RESPONSE_TIME, {
"leading": true, leading: true,
"trailing": false, trailing: false,
}); });
this.editor.on(Controller.EVENT_CHANGE, (type) => { this.editor.on(Controller.EVENT_CHANGE, type => {
switch (type) { switch (type) {
case BI.Events.STARTEDIT: case BI.Events.STARTEDIT:
this._startSearch(); this._startSearch();
@ -118,8 +123,8 @@ export class Searcher extends Widget {
const { masker, popup, chooseType, isAutoSync, adapter } = this.options; const { masker, popup, chooseType, isAutoSync, adapter } = this.options;
if ((masker && !Maskers.has(this.getName())) || (masker === false && !this.popupView)) { if ((masker && !Maskers.has(this.getName())) || (masker === false && !this.popupView)) {
this.popupView = createWidget(popup, { this.popupView = createWidget(popup, {
type: "bi.searcher_view", type: SearcherView.xtype,
chooseType: chooseType, chooseType,
}); });
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args);
@ -149,10 +154,18 @@ export class Searcher extends Widget {
}); });
} }
if (masker && !Maskers.has(this.getName())) { if (masker && !Maskers.has(this.getName())) {
Maskers.create(this.getName(), adapter, extend({ Maskers.create(
this.getName(),
adapter,
extend(
{
container: this, container: this,
render: this.popupView, render: this.popupView,
}, masker), this); },
masker
),
this
);
} }
} }
@ -164,14 +177,14 @@ export class Searcher extends Widget {
this.popupView.startSearch && this.popupView.startSearch(); this.popupView.startSearch && this.popupView.startSearch();
// 搜索前先清空dom // 搜索前先清空dom
// BI.Maskers.get(this.getName()).empty(); // BI.Maskers.get(this.getName()).empty();
nextTick((name) => { nextTick(name => {
Maskers.show(name); Maskers.show(name);
}, this.getName()); }, this.getName());
} }
_pauseSearch() { _pauseSearch() {
this._stop = true; this._stop = true;
nextTick((name) => { nextTick(name => {
Maskers.hide(name); Maskers.hide(name);
}, this.getName()); }, this.getName());
if (this._isSearching === true) { if (this._isSearching === true) {
@ -201,7 +214,8 @@ export class Searcher extends Widget {
if (isAutoSearch) { if (isAutoSearch) {
const items = (adapter && ((adapter.getItems && adapter.getItems()) || adapter.attr("items"))) || []; const items = (adapter && ((adapter.getItems && adapter.getItems()) || adapter.attr("items"))) || [];
const finding = BI.Func.getSearchResult(items, keyword); const finding = BI.Func.getSearchResult(items, keyword);
const match = finding.match, find = finding.find; const match = finding.match,
find = finding.find;
this.popupView.populate(find, match, keyword); this.popupView.populate(find, match, keyword);
isAutoSync && adapter && adapter.getValue && this.popupView.setValue(adapter.getValue()); isAutoSync && adapter && adapter.getValue && this.popupView.setValue(adapter.getValue());
this.fireEvent(Searcher.EVENT_SEARCHING); this.fireEvent(Searcher.EVENT_SEARCHING);
@ -209,11 +223,13 @@ export class Searcher extends Widget {
return; return;
} }
this.popupView.loading && this.popupView.loading(); this.popupView.loading && this.popupView.loading();
onSearch({ onSearch(
{
times: 1, times: 1,
keyword: keyword, keyword,
selectedValues: adapter && adapter.getValue(), selectedValues: adapter && adapter.getValue(),
}, (searchResult, matchResult, ...arg) => { },
(searchResult, matchResult, ...arg) => {
if (!this._stop && keyword === this.editor.getValue()) { if (!this._stop && keyword === this.editor.getValue()) {
const args = [searchResult, matchResult, ...arg]; const args = [searchResult, matchResult, ...arg];
if (args.length > 0) { if (args.length > 0) {
@ -225,7 +241,8 @@ export class Searcher extends Widget {
this.popupView.loaded && this.popupView.loaded(); this.popupView.loaded && this.popupView.loaded();
this.fireEvent(Searcher.EVENT_SEARCHING); this.fireEvent(Searcher.EVENT_SEARCHING);
} }
}); }
);
} }
_getLastSearchKeyword() { _getLastSearchKeyword() {

111
src/base/combination/switcher.js

@ -1,3 +1,18 @@
import {
VerticalLayout,
shortcut,
Widget,
Controller,
extend,
nextTick,
createWidget,
each,
debounce,
isNull
} from "@/core";
import { ButtonGroup } from "./group.button";
import { Maskers } from "@/base/0.base";
/** /**
* *
* 切换显示或隐藏面板 * 切换显示或隐藏面板
@ -6,8 +21,6 @@
* @class BI.Switcher * @class BI.Switcher
* @extends BI.Widget * @extends BI.Widget
*/ */
import { shortcut, Widget, Controller, extend, nextTick, createWidget, each, debounce, isNull } from "../../core";
import { Maskers } from "../0.base";
@shortcut() @shortcut()
export class Switcher extends Widget { export class Switcher extends Widget {
@ -68,24 +81,25 @@ export class Switcher extends Widget {
} }
}); });
this.element.hover(() => { this.element.hover(
() => {
if (this.isEnabled() && this.switcher.isEnabled()) { if (this.isEnabled() && this.switcher.isEnabled()) {
this.element.addClass(hoverClass); this.element.addClass(hoverClass);
} }
}, () => { },
() => {
if (this.isEnabled() && this.switcher.isEnabled()) { if (this.isEnabled() && this.switcher.isEnabled()) {
this.element.removeClass(hoverClass); this.element.removeClass(hoverClass);
} }
}); }
);
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
element: this, element: this,
items: [ items: [{ el: this.switcher }],
{ el: this.switcher }
],
}); });
isDefaultInit && (this._assertPopupView()); isDefaultInit && this._assertPopupView();
} }
_toggle() { _toggle() {
@ -105,39 +119,59 @@ export class Switcher extends Widget {
each(evs, (i, e) => { each(evs, (i, e) => {
switch (e) { switch (e) {
case "hover": case "hover":
this.element[e]((e) => { this.element[e](
e => {
if (this.isEnabled() && this.switcher.isEnabled()) { if (this.isEnabled() && this.switcher.isEnabled()) {
this._popupView(); this._popupView();
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.switcher); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.switcher);
this.fireEvent(Switcher.EVENT_EXPAND); this.fireEvent(Switcher.EVENT_EXPAND);
} }
}, () => { },
() => {
if (this.isEnabled() && this.switcher.isEnabled() && toggle) { if (this.isEnabled() && this.switcher.isEnabled() && toggle) {
this._hideView(); this._hideView();
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.switcher); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.switcher);
this.fireEvent(Switcher.EVENT_COLLAPSE); this.fireEvent(Switcher.EVENT_COLLAPSE);
} }
}); }
);
break; break;
default: default:
if (e) { if (e) {
this.element.off(e + "." + this.getName()).on(e + "." + this.getName(), debounce((e) => { this.element.off(`${e}.${this.getName()}`).on(
`${e}.${this.getName()}`,
debounce(
e => {
if (this.switcher.element.__isMouseInBounds__(e)) { if (this.switcher.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && this.switcher.isEnabled()) { if (this.isEnabled() && this.switcher.isEnabled()) {
toggle ? this._toggle() : this._popupView(); toggle ? this._toggle() : this._popupView();
if (this.isExpanded()) { if (this.isExpanded()) {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.EXPAND, "", this.switcher); this.fireEvent(
Controller.EVENT_CHANGE,
BI.Events.EXPAND,
"",
this.switcher
);
this.fireEvent(Switcher.EVENT_EXPAND); this.fireEvent(Switcher.EVENT_EXPAND);
} else { } else {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", this.switcher); this.fireEvent(
Controller.EVENT_CHANGE,
BI.Events.COLLAPSE,
"",
this.switcher
);
this.fireEvent(Switcher.EVENT_COLLAPSE); this.fireEvent(Switcher.EVENT_COLLAPSE);
} }
} }
} }
}, BI.EVENT_RESPONSE_TIME, { },
"leading": true, BI.EVENT_RESPONSE_TIME,
"trailing": false, {
})); leading: true,
trailing: false,
}
)
);
} }
break; break;
} }
@ -153,17 +187,23 @@ export class Switcher extends Widget {
_assertPopupView() { _assertPopupView() {
const { popup, adapter, masker, value, direction } = this.options; const { popup, adapter, masker, value, direction } = this.options;
if (!this._created) { if (!this._created) {
this.popupView = createWidget(popup, { this.popupView = createWidget(
type: "bi.button_group", popup,
{
type: ButtonGroup.xtype,
element: adapter && Maskers.create(this.getName(), adapter, extend({ container: this }, masker)), element: adapter && Maskers.create(this.getName(), adapter, extend({ container: this }, masker)),
cls: "switcher-popup", cls: "switcher-popup",
layouts: [{ layouts: [
type: "bi.vertical", {
type: VerticalLayout.xtype,
hgap: 0, hgap: 0,
vgap: 0, vgap: 0,
}], }
],
value, value,
}, this); },
this
);
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args);
if (type === BI.Events.CLICK) { if (type === BI.Events.CLICK) {
@ -172,12 +212,10 @@ export class Switcher extends Widget {
}); });
if (direction !== BI.Direction.Custom && !adapter) { if (direction !== BI.Direction.Custom && !adapter) {
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
element: this, element: this,
items: [ items: [{ el: this.popupView }],
{ el: this.popupView }
],
}); });
} }
this._created = true; this._created = true;
@ -190,9 +228,9 @@ export class Switcher extends Widget {
_hideView() { _hideView() {
this.fireEvent(Switcher.EVENT_BEFORE_HIDEVIEW); this.fireEvent(Switcher.EVENT_BEFORE_HIDEVIEW);
const { adapter, switcherClass } = this.options; const { adapter, switcherClass } = this.options;
adapter ? Maskers.hide(this.getName()) : (this.popupView && this.popupView.setVisible(false)); adapter ? Maskers.hide(this.getName()) : this.popupView && this.popupView.setVisible(false);
nextTick(() => { nextTick(() => {
adapter ? Maskers.hide(this.getName()) : (this.popupView && this.popupView.setVisible(false)); adapter ? Maskers.hide(this.getName()) : this.popupView && this.popupView.setVisible(false);
this.element.removeClass(switcherClass); this.element.removeClass(switcherClass);
this.fireEvent(Switcher.EVENT_AFTER_HIDEVIEW); this.fireEvent(Switcher.EVENT_AFTER_HIDEVIEW);
}); });
@ -203,7 +241,7 @@ export class Switcher extends Widget {
this._assertPopupView(); this._assertPopupView();
this.fireEvent(Switcher.EVENT_BEFORE_POPUPVIEW); this.fireEvent(Switcher.EVENT_BEFORE_POPUPVIEW);
adapter ? Maskers.show(this.getName()) : this.popupView.setVisible(true); adapter ? Maskers.show(this.getName()) : this.popupView.setVisible(true);
nextTick((name) => { nextTick(name => {
adapter ? Maskers.show(name) : this.popupView.setVisible(true); adapter ? Maskers.show(name) : this.popupView.setVisible(true);
this.element.addClass(switcherClass); this.element.addClass(switcherClass);
this.fireEvent(Switcher.EVENT_AFTER_POPUPVIEW); this.fireEvent(Switcher.EVENT_AFTER_POPUPVIEW);
@ -248,8 +286,11 @@ export class Switcher extends Widget {
} }
isViewVisible() { isViewVisible() {
return this.isEnabled() && this.switcher.isEnabled() && return (
(this.options.adapter ? Maskers.isVisible(this.getName()) : (this.popupView && this.popupView.isVisible())); this.isEnabled() &&
this.switcher.isEnabled() &&
(this.options.adapter ? Maskers.isVisible(this.getName()) : this.popupView && this.popupView.isVisible())
);
} }
isExpanded() { isExpanded() {

51
src/base/combination/tab.js

@ -1,7 +1,23 @@
import { ButtonGroup } from "./group.button";
import {
CardLayout,
shortcut,
Widget,
Controller,
ShowListener,
extend,
createWidget,
isObject,
each,
isFunction,
contains,
any,
isEqual
} from "@/core";
/** /**
* Created by GUY on 2015/6/26. * Created by GUY on 2015/6/26.
*/ */
import { shortcut, Widget, Controller, ShowListener, extend, createWidget, isObject, each, isFunction, contains, any, isEqual } from "../../core";
@shortcut() @shortcut()
export class Tab extends Widget { export class Tab extends Widget {
@ -19,9 +35,7 @@ export class Tab extends Widget {
}, },
showIndex: false, showIndex: false,
tab: false, tab: false,
cardCreator: (v) => { cardCreator: v => createWidget(),
return createWidget();
},
keepAlives: [], keepAlives: [],
}); });
} }
@ -29,38 +43,46 @@ export class Tab extends Widget {
render() { render() {
const { tab, direction, logic, cardCreator } = this.options; const { tab, direction, logic, cardCreator } = this.options;
if (isObject(tab)) { if (isObject(tab)) {
this.tab = createWidget(this.options.tab, { type: "bi.button_group" }); this.tab = createWidget(this.options.tab, { type: ButtonGroup.xtype });
this.tab.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { this.tab.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => {
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args);
}); });
} }
this.cardMap = {}; this.cardMap = {};
this.layout = createWidget({ this.layout = createWidget({
type: "bi.card", type: CardLayout.xtype,
}); });
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(direction), extend({}, logic, { },
BI.LogicFactory.createLogic(
BI.LogicFactory.createLogicTypeByDirection(direction),
extend({}, logic, {
items: BI.LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout), items: BI.LogicFactory.createLogicItemsByDirection(direction, this.tab, this.layout),
})))); })
)
)
);
const listener = new ShowListener({ const listener = new ShowListener({
eventObj: this.tab, eventObj: this.tab,
cardLayout: this.layout, cardLayout: this.layout,
cardCreator: (v) => { cardCreator: v => {
Widget.execWithContext(this, () => { Widget.execWithContext(this, () => {
this.cardMap[v] = cardCreator(v); this.cardMap[v] = cardCreator(v);
}); });
return this.cardMap[v]; return this.cardMap[v];
}, },
afterCardShow: (v) => { afterCardShow: v => {
this._deleteOtherCards(v); this._deleteOtherCards(v);
this.curr = v; this.curr = v;
}, },
}); });
listener.on(ShowListener.EVENT_CHANGE, (value) => { listener.on(ShowListener.EVENT_CHANGE, value => {
this.fireEvent(Tab.EVENT_CHANGE, value, this); this.fireEvent(Tab.EVENT_CHANGE, value, this);
}); });
} }
@ -69,7 +91,7 @@ export class Tab extends Widget {
const { single } = this.options; const { single } = this.options;
if (single === true) { if (single === true) {
each(this.cardMap, (name, card) => { each(this.cardMap, (name, card) => {
if (name !== (currCardName + "") && this._keepAlive(name) !== true) { if (name !== `${currCardName}` && this._keepAlive(name) !== true) {
this.layout.deleteCardByName(name); this.layout.deleteCardByName(name);
delete this.cardMap[name]; delete this.cardMap[name];
} }
@ -122,7 +144,7 @@ export class Tab extends Widget {
removeTab(cardname) { removeTab(cardname) {
any(this.cardMap, (name, card) => { any(this.cardMap, (name, card) => {
if (isEqual(name, (cardname + ""))) { if (isEqual(name, `${cardname}`)) {
this.layout.deleteCardByName(name); this.layout.deleteCardByName(name);
delete this.cardMap[name]; delete this.cardMap[name];
@ -179,5 +201,4 @@ export class Tab extends Widget {
this.cardMap = {}; this.cardMap = {};
super.destroy(arguments); super.destroy(arguments);
} }
} }

5
src/base/combination/tree.button.js

@ -1,10 +1,11 @@
import { ButtonGroup } from "./group.button";
import { shortcut, Widget, extend, isArray, each, isFunction, deepContains, concat, any, contains } from "@/core";
/** /**
* Created by GUY on 2015/8/10. * Created by GUY on 2015/8/10.
* @class BI.ButtonTree * @class BI.ButtonTree
* @extends BI.ButtonGroup * @extends BI.ButtonGroup
*/ */
import { shortcut, Widget, extend, isArray, each, isFunction, deepContains, concat, any, contains } from "../../core";
import { ButtonGroup } from "./group.button";
@shortcut() @shortcut()
export class ButtonTree extends ButtonGroup { export class ButtonTree extends ButtonGroup {

57
src/base/context.js

@ -1,47 +1,40 @@
/** import { shortcut, Widget, createWidget, Controller } from "@/core";
* 表示当前对象
*
* 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 () { @shortcut()
var self = this, o = this.options; export class Context extends Widget {
static xtype = "bi.context";
props = { context: "", watch: {}, el: {}, items: [] };
render() {
const self = this,
o = this.options;
if (o.context) { if (o.context) {
this.context = BI.useContext(o.context); this.context = BI.useContext(o.context);
} }
this.widget = BI.createWidget((o.items[0] || o.el)(this.context), { this.widget = createWidget((o.items[0] || o.el)(this.context), {
element: this, element: this,
}); });
this.widget.on(BI.Controller.EVENT_CHANGE, function () { this.widget.on(Controller.EVENT_CHANGE, function () {
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); self.fireEvent(Controller.EVENT_CHANGE, arguments);
}); });
}, }
__initWatch: function () { __initWatch() {
BI.Context.superclass.__initWatch.call(this); super.__initWatch.call(this);
var o = this.options; const o = this.options;
BI.watch(this.context, o.context, o.watch); BI.watch(this.context, o.context, o.watch);
}, }
setValue: function (v) { setValue(v) {
this.widget.setValue(v); this.widget.setValue(v);
}, }
getValue: function () { getValue() {
return this.widget.getValue(); return this.widget.getValue();
}, }
populate: function () { populate() {
this.widget.populate.apply(this, arguments); this.widget.populate.apply(this, arguments);
}, }
}); }
BI.shortcut("bi.context", BI.Context);

48
src/base/el.js

@ -1,38 +1,36 @@
/** import { shortcut, Widget, extend, createWidget, Controller } from "@/core";
* 表示当前对象
* @shortcut()
* Created by GUY on 2015/9/7. export class EL extends Widget {
* @class BI.EL static xtype = "bi.el";
* @extends BI.Widget
*/ _defaultConfig() {
BI.EL = BI.inherit(BI.Widget, { return extend(super._defaultConfig(...arguments), {
_defaultConfig: function () {
return BI.extend(BI.EL.superclass._defaultConfig.apply(this, arguments), {
baseCls: "bi-el", baseCls: "bi-el",
el: {}, el: {},
}); });
}, }
render: function () { render() {
var self = this, o = this.options; const self = this,
this.ele = BI.createWidget(o.el, { o = this.options;
this.ele = createWidget(o.el, {
element: this, element: this,
}); });
this.ele.on(BI.Controller.EVENT_CHANGE, function () { this.ele.on(Controller.EVENT_CHANGE, function () {
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); self.fireEvent(Controller.EVENT_CHANGE, arguments);
}); });
}, }
setValue: function (v) { setValue(v) {
this.ele.setValue(v); this.ele.setValue(v);
}, }
getValue: function () { getValue() {
return this.ele.getValue(); return this.ele.getValue();
}, }
populate: function () { populate() {
this.ele.populate.apply(this, arguments); this.ele.populate.apply(this, arguments);
}, }
}); }
BI.shortcut("bi.el", BI.EL);

91
src/base/foundation/message.js

@ -3,26 +3,26 @@
* 弹出提示消息框用于模拟阻塞操作通过回调函数实现 * 弹出提示消息框用于模拟阻塞操作通过回调函数实现
* @class BI.Msg * @class BI.Msg
*/ */
import { Widget, isString, isNull, isFunction, createWidget, remove, each } from "../../core" import { Widget, isString, isNull, isFunction, createWidget, remove, each } from "../../core";
export const Msg = ((() => { export const Msg = (() => {
let $mask, $pop; let $mask, $pop;
let messageShows = []; const messageShows = [];
let toastStack = []; const toastStack = [];
return { return {
alert: function (title, message, callback) { alert (title, message, callback) {
this._show(false, title, message, callback); this._show(false, title, message, callback);
}, },
confirm: function (title, message, callback) { confirm (title, message, callback) {
this._show(true, title, message, callback); this._show(true, title, message, callback);
}, },
prompt: function (title, message, value, callback, min_width) { prompt (title, message, value, callback, min_width) {
// BI.Msg.prompt(title, message, value, callback, min_width); // BI.Msg.prompt(title, message, value, callback, min_width);
}, },
toast: function (message, options, context) { toast (message, options, context) {
isString(options) && (options = { level: options }); isString(options) && (options = { level: options });
options = options || {}; options = options || {};
context = context || Widget._renderEngine.createElement("body"); context = context || Widget._renderEngine.createElement("body");
@ -32,41 +32,46 @@ export const Msg = ((() => {
const toast = createWidget({ const toast = createWidget({
type: "bi.toast", type: "bi.toast",
cls: "bi-message-animate bi-message-leave", cls: "bi-message-animate bi-message-leave",
level: level, level,
autoClose: autoClose, autoClose,
closable: options.closable, closable: options.closable,
text: message, text: message,
listeners: [{ listeners: [
{
eventName: BI.Toast.EVENT_DESTORY, eventName: BI.Toast.EVENT_DESTORY,
action: function () { action () {
remove(toastStack, toast.element); remove(toastStack, toast.element);
let _height = BI.SIZE_CONSANTS.TOAST_TOP; let _height = BI.SIZE_CONSANTS.TOAST_TOP;
each(toastStack, function (i, element) { each(toastStack, (i, element) => {
element.css({ "top": _height }); element.css({ top: _height });
_height += element.outerHeight() + 10; _height += element.outerHeight() + 10;
}); });
callback(); callback();
}, },
}], }
],
}); });
let height = BI.SIZE_CONSANTS.TOAST_TOP; let height = BI.SIZE_CONSANTS.TOAST_TOP;
each(toastStack, function (i, element) { each(toastStack, (i, element) => {
height += element.outerHeight() + 10; height += element.outerHeight() + 10;
}); });
createWidget({ createWidget({
type: "bi.absolute", type: "bi.absolute",
element: context, element: context,
items: [{ items: [
{
el: toast, el: toast,
left: "50%", left: "50%",
top: height, top: height,
}], }
],
}); });
toastStack.push(toast.element); toastStack.push(toast.element);
toast.element.css({ "margin-left": -1 * toast.element.outerWidth() / 2 }); toast.element.css({ "margin-left": (-1 * toast.element.outerWidth()) / 2 });
toast.element.removeClass("bi-message-leave").addClass("bi-message-enter"); toast.element.removeClass("bi-message-leave").addClass("bi-message-enter");
autoClose && BI.delay(function () { autoClose &&
BI.delay(() => {
toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); toast.element.removeClass("bi-message-enter").addClass("bi-message-leave");
toast.destroy?.(); toast.destroy?.();
}, 5000); }, 5000);
@ -76,8 +81,11 @@ export const Msg = ((() => {
toast.destroy?.(); toast.destroy?.();
}; };
}, },
_show: function (hasCancel, title, message, callback) { _show (hasCancel, title, message, callback) {
isNull($mask) && ($mask = Widget._renderEngine.createElement("<div class=\"bi-z-index-mask\">").css({ isNull($mask) &&
($mask = Widget._renderEngine
.createElement("<div class=\"bi-z-index-mask\">")
.css({
position: "absolute", position: "absolute",
zIndex: BI.zIndex_tip - 2, zIndex: BI.zIndex_tip - 2,
top: 0, top: 0,
@ -85,15 +93,19 @@ export const Msg = ((() => {
right: 0, right: 0,
bottom: 0, bottom: 0,
opacity: 0.5, opacity: 0.5,
}).appendTo("body")); })
$pop = Widget._renderEngine.createElement("<div class=\"bi-message-depend\">").css({ .appendTo("body"));
$pop = Widget._renderEngine
.createElement("<div class=\"bi-message-depend\">")
.css({
position: "absolute", position: "absolute",
zIndex: BI.zIndex_tip - 1, zIndex: BI.zIndex_tip - 1,
top: 0, top: 0,
left: 0, left: 0,
right: 0, right: 0,
bottom: 0, bottom: 0,
}).appendTo("body"); })
.appendTo("body");
function close() { function close() {
messageShows[messageShows.length - 1].destroy(); messageShows[messageShows.length - 1].destroy();
messageShows.pop(); messageShows.pop();
@ -102,14 +114,14 @@ export const Msg = ((() => {
$mask = null; $mask = null;
} }
} }
let controlItems = []; const controlItems = [];
if (hasCancel === true) { if (hasCancel === true) {
controlItems.push({ controlItems.push({
el: { el: {
type: "bi.button", type: "bi.button",
text: BI.i18nText("BI-Basic_Cancel"), text: BI.i18nText("BI-Basic_Cancel"),
level: "ignore", level: "ignore",
handler: function () { handler () {
close(); close();
if (isFunction(callback)) { if (isFunction(callback)) {
callback.apply(null, [false]); callback.apply(null, [false]);
@ -122,7 +134,7 @@ export const Msg = ((() => {
el: { el: {
type: "bi.button", type: "bi.button",
text: BI.i18nText("BI-Basic_OK"), text: BI.i18nText("BI-Basic_OK"),
handler: function () { handler () {
close(); close();
if (isFunction(callback)) { if (isFunction(callback)) {
callback.apply(null, [true]); callback.apply(null, [true]);
@ -139,8 +151,8 @@ export const Msg = ((() => {
attributes: { attributes: {
tabIndex: 1, tabIndex: 1,
}, },
mounted: function () { mounted () {
this.element.keyup(function (e) { this.element.keyup(e => {
if (e.keyCode === BI.KeyCode.ENTER) { if (e.keyCode === BI.KeyCode.ENTER) {
close(); close();
if (isFunction(callback)) { if (isFunction(callback)) {
@ -157,9 +169,7 @@ export const Msg = ((() => {
}); });
try { try {
this.element.focus(); this.element.focus();
} catch (e) { } catch (e) {}
}
}, },
cls: "bi-card", cls: "bi-card",
items: { items: {
@ -183,7 +193,7 @@ export const Msg = ((() => {
type: "bi.icon_button", type: "bi.icon_button",
cls: "bi-message-close close-font", cls: "bi-message-close close-font",
// height: 50, // height: 50,
handler: function () { handler () {
close(); close();
if (isFunction(callback)) { if (isFunction(callback)) {
callback.apply(null, [false]); callback.apply(null, [false]);
@ -197,7 +207,9 @@ export const Msg = ((() => {
height: 40, height: 40,
}, },
center: { center: {
el: BI.isPlainObject(message) ? message : { el: BI.isPlainObject(message)
? message
: {
type: "bi.label", type: "bi.label",
vgap: 10, vgap: 10,
hgap: 20, hgap: 20,
@ -208,7 +220,8 @@ export const Msg = ((() => {
south: { south: {
el: { el: {
type: "bi.absolute", type: "bi.absolute",
items: [{ items: [
{
el: { el: {
type: "bi.right_vertical_adapt", type: "bi.right_vertical_adapt",
lgap: 10, lgap: 10,
@ -218,8 +231,8 @@ export const Msg = ((() => {
left: 20, left: 20,
right: 20, right: 20,
bottom: 0, bottom: 0,
}], }
],
}, },
height: 44, height: 44,
}, },
@ -233,4 +246,4 @@ export const Msg = ((() => {
messageShows[messageShows.length] = createWidget(conf); messageShows[messageShows.length] = createWidget(conf);
}, },
}; };
})()); })();

146
src/base/grid/grid.js

@ -1,3 +1,22 @@
import {
VerticalLayout,
AbsoluteLayout,
Widget,
shortcut,
extend,
emptyFn,
debounce,
_lazyCreateWidget,
isFunction,
each,
isNumber,
ScalingCellSizeAndPositionManager,
clamp,
isEmpty,
nextTick
} from "@/core";
import { Label } from "../single";
/** /**
* GridView * GridView
* *
@ -5,7 +24,7 @@
* @class BI.GridView * @class BI.GridView
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, emptyFn, debounce, _lazyCreateWidget, isFunction, each, isNumber, ScalingCellSizeAndPositionManager, clamp, isEmpty, nextTick } from "../../core";
@shortcut() @shortcut()
export class GridView extends Widget { export class GridView extends Widget {
_defaultConfig() { _defaultConfig() {
@ -19,7 +38,7 @@ export class GridView extends Widget {
overflowX: true, overflowX: true,
overflowY: true, overflowY: true,
el: { el: {
type: "bi.vertical", type: VerticalLayout.xtype,
}, },
overscanColumnCount: 0, overscanColumnCount: 0,
overscanRowCount: 0, overscanRowCount: 0,
@ -48,7 +67,7 @@ export class GridView extends Widget {
this._scrollLock = false; this._scrollLock = false;
}, 1000 / 60); }, 1000 / 60);
this.container = _lazyCreateWidget({ this.container = _lazyCreateWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
}); });
this.element.scroll(() => { this.element.scroll(() => {
if (this._scrollLock === true) { if (this._scrollLock === true) {
@ -64,7 +83,8 @@ export class GridView extends Widget {
}); });
// 兼容一下 // 兼容一下
let scrollable = o.scrollable; let scrollable = o.scrollable;
const scrollx = o.scrollx, scrolly = o.scrolly; const scrollx = o.scrollx,
scrolly = o.scrolly;
if (overflowX === false) { if (overflowX === false) {
if (overflowY === false) { if (overflowY === false) {
scrollable = false; scrollable = false;
@ -77,16 +97,18 @@ export class GridView extends Widget {
} }
} }
_lazyCreateWidget(el, { _lazyCreateWidget(el, {
type: "bi.vertical", type: VerticalLayout.xtype,
element: this, element: this,
scrollable, scrollable,
scrolly, scrolly,
scrollx, scrollx,
items: [this.container], items: [this.container],
}); });
o.items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { o.items = isFunction(o.items)
? this.__watch(o.items, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : o.items; })
: o.items;
if (o.items.length > 0) { if (o.items.length > 0) {
this._calculateSizeAndPositionData(); this._calculateSizeAndPositionData();
this._populate(); this._populate();
@ -109,7 +131,15 @@ export class GridView extends Widget {
} }
_calculateSizeAndPositionData() { _calculateSizeAndPositionData() {
const { columnCount, items, rowCount, columnWidthGetter, estimatedColumnSize, rowHeightGetter, estimatedRowSize } = this.options; const {
columnCount,
items,
rowCount,
columnWidthGetter,
estimatedColumnSize,
rowHeightGetter,
estimatedRowSize,
} = this.options;
this.rowCount = 0; this.rowCount = 0;
this.columnCount = 0; this.columnCount = 0;
if (isNumber(columnCount)) { if (isNumber(columnCount)) {
@ -122,8 +152,16 @@ export class GridView extends Widget {
} else { } else {
this.rowCount = items.length; this.rowCount = items.length;
} }
this._columnSizeAndPositionManager = new ScalingCellSizeAndPositionManager(this.columnCount, columnWidthGetter, estimatedColumnSize); this._columnSizeAndPositionManager = new ScalingCellSizeAndPositionManager(
this._rowSizeAndPositionManager = new ScalingCellSizeAndPositionManager(this.rowCount, rowHeightGetter, estimatedRowSize); this.columnCount,
columnWidthGetter,
estimatedColumnSize
);
this._rowSizeAndPositionManager = new ScalingCellSizeAndPositionManager(
this.rowCount,
rowHeightGetter,
estimatedRowSize
);
} }
_getOverscanIndices(cellCount, overscanCellsCount, startIndex, stopIndex) { _getOverscanIndices(cellCount, overscanCellsCount, startIndex, stopIndex) {
@ -138,19 +176,30 @@ export class GridView extends Widget {
const { itemFormatter, items } = this.options; const { itemFormatter, items } = this.options;
const width = o.width, height = o.height, scrollLeft = clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), const width = o.width,
height = o.height,
scrollLeft = clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
scrollTop = clamp(o.scrollTop, 0, this._getMaxScrollTop()), scrollTop = clamp(o.scrollTop, 0, this._getMaxScrollTop()),
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount; overscanColumnCount = o.overscanColumnCount,
overscanRowCount = o.overscanRowCount;
if (height > 0 && width > 0) { if (height > 0 && width > 0) {
const visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); const visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
const visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); const visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
const renderedCells = [], renderedKeys = {}, renderedWidgets = {}; const renderedCells = [],
let minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0; renderedKeys = {},
renderedWidgets = {};
let minX = this._getMaxScrollLeft(),
minY = this._getMaxScrollTop(),
maxX = 0,
maxY = 0;
// 没有可见的单元格就干掉所有渲染过的 // 没有可见的单元格就干掉所有渲染过的
if (!isEmpty(visibleColumnIndices) && !isEmpty(visibleRowIndices)) { if (!isEmpty(visibleColumnIndices) && !isEmpty(visibleRowIndices)) {
const horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft); const horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(
width,
scrollLeft
);
const verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); const verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
this._renderedColumnStartIndex = visibleColumnIndices.start; this._renderedColumnStartIndex = visibleColumnIndices.start;
@ -158,9 +207,19 @@ export class GridView extends Widget {
this._renderedRowStartIndex = visibleRowIndices.start; this._renderedRowStartIndex = visibleRowIndices.start;
this._renderedRowStopIndex = visibleRowIndices.stop; this._renderedRowStopIndex = visibleRowIndices.stop;
const overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex); const overscanColumnIndices = this._getOverscanIndices(
this.columnCount,
overscanColumnCount,
this._renderedColumnStartIndex,
this._renderedColumnStopIndex
);
const overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex); const overscanRowIndices = this._getOverscanIndices(
this.rowCount,
overscanRowCount,
this._renderedRowStartIndex,
this._renderedRowStopIndex
);
const columnStartIndex = overscanColumnIndices.overscanStartIndex; const columnStartIndex = overscanColumnIndices.overscanStartIndex;
const columnStopIndex = overscanColumnIndices.overscanStopIndex; const columnStopIndex = overscanColumnIndices.overscanStopIndex;
@ -177,7 +236,12 @@ export class GridView extends Widget {
const bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size; const bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
const right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.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) { if (
top >= this.renderRange.minY &&
bottom <= this.renderRange.maxY &&
left >= this.renderRange.minX &&
right <= this.renderRange.maxX
) {
return; return;
} }
@ -195,23 +259,38 @@ export class GridView extends Widget {
this.renderedCells[index].el.setWidth(columnDatum.size); this.renderedCells[index].el.setWidth(columnDatum.size);
this.renderedCells[index].el.setHeight(rowDatum.size); this.renderedCells[index].el.setHeight(rowDatum.size);
// 这里只使用px // 这里只使用px
this.renderedCells[index].el.element.css("left", `${columnDatum.offset + horizontalOffsetAdjustment}px`); this.renderedCells[index].el.element.css(
this.renderedCells[index].el.element.css("top", `${rowDatum.offset + verticalOffsetAdjustment}px`); "left",
`${columnDatum.offset + horizontalOffsetAdjustment}px`
);
this.renderedCells[index].el.element.css(
"top",
`${rowDatum.offset + verticalOffsetAdjustment}px`
);
child = this.renderedCells[index].el; child = this.renderedCells[index].el;
renderedCells.push(this.renderedCells[index]); renderedCells.push(this.renderedCells[index]);
} else { } else {
const item = itemFormatter(items[rowIndex][columnIndex], rowIndex, columnIndex); const item = itemFormatter(items[rowIndex][columnIndex], rowIndex, columnIndex);
child = _lazyCreateWidget(extend({ child = _lazyCreateWidget(
type: "bi.label", extend(
{
type: Label.xtype,
width: columnDatum.size, width: columnDatum.size,
height: rowDatum.size, height: rowDatum.size,
}, item, { },
cls: `${item.cls || ""} grid-cell${rowIndex === 0 ? " first-row" : ""}${columnIndex === 0 ? " first-col" : ""}`, item,
{
cls: `${item.cls || ""} grid-cell${rowIndex === 0 ? " first-row" : ""}${
columnIndex === 0 ? " first-col" : ""
}`,
_rowIndex: rowIndex, _rowIndex: rowIndex,
_columnIndex: columnIndex, _columnIndex: columnIndex,
_left: columnDatum.offset + horizontalOffsetAdjustment, _left: columnDatum.offset + horizontalOffsetAdjustment,
_top: rowDatum.offset + verticalOffsetAdjustment, _top: rowDatum.offset + verticalOffsetAdjustment,
}), this); }
),
this
);
renderedCells.push({ renderedCells.push({
el: child, el: child,
left: `${columnDatum.offset + horizontalOffsetAdjustment}px`, left: `${columnDatum.offset + horizontalOffsetAdjustment}px`,
@ -233,7 +312,9 @@ export class GridView extends Widget {
} }
} }
// 已存在的, 需要添加的和需要删除的 // 已存在的, 需要添加的和需要删除的
const existSet = {}, addSet = {}, deleteArray = []; const existSet = {},
addSet = {},
deleteArray = [];
each(renderedKeys, (i, key) => { each(renderedKeys, (i, key) => {
if (this.renderedKeys[i]) { if (this.renderedKeys[i]) {
existSet[i] = key; existSet[i] = key;
@ -303,11 +384,17 @@ export class GridView extends Widget {
} }
_getMaxScrollLeft() { _getMaxScrollLeft() {
return Math.max(0, this._getContainerWidth() - this.options.width + (this._isOverflowX() ? BI.DOM.getScrollWidth() : 0)); return Math.max(
0,
this._getContainerWidth() - this.options.width + (this._isOverflowX() ? BI.DOM.getScrollWidth() : 0)
);
} }
_getMaxScrollTop() { _getMaxScrollTop() {
return Math.max(0, this._getContainerHeight() - this.options.height + (this._isOverflowY() ? BI.DOM.getScrollWidth() : 0)); return Math.max(
0,
this._getContainerHeight() - this.options.height + (this._isOverflowY() ? BI.DOM.getScrollWidth() : 0)
);
} }
_getContainerWidth() { _getContainerWidth() {
@ -333,8 +420,7 @@ export class GridView extends Widget {
try { try {
this.element.scrollTop(scrollTop); this.element.scrollTop(scrollTop);
this.element.scrollLeft(scrollLeft); this.element.scrollLeft(scrollLeft);
} catch (e) { } catch (e) {}
}
this._calculateChildrenToRender(); this._calculateChildrenToRender();
} }

9
src/base/index.js

@ -29,11 +29,4 @@ export * from "./combination";
export * from "./layer"; export * from "./layer";
export * from "./list"; export * from "./list";
export * from "./single"; export * from "./single";
export { export { Pane, GridView, Pager, Msg, CollectionView, CustomTree };
Pane,
GridView,
Pager,
Msg,
CollectionView,
CustomTree
};

73
src/base/layer/layer.drawer.js

@ -1,17 +1,19 @@
import { HTapeLayout, AbsoluteLayout, Layout, VerticalLayout, Widget, shortcut, isPlainObject, extend } from "@/core";
import { Label, IconButton } from "../single";
/** /**
* Popover弹出层 * Popover弹出层
* @class BI.Popover * @class BI.Popover
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, isPlainObject, extend } from "../../core";
@shortcut() @shortcut()
export class Drawer extends Widget { export class Drawer extends Widget {
SIZE = { SIZE = {
SMALL: "small", SMALL: "small",
NORMAL: "normal", NORMAL: "normal",
BIG: "big", BIG: "big",
} };
props = { props = {
baseCls: "bi-drawer bi-card", baseCls: "bi-drawer bi-card",
size: "normal", size: "normal",
@ -23,7 +25,7 @@ export class Drawer extends Widget {
bodyHgap: 20, bodyHgap: 20,
bodyTgap: 10, bodyTgap: 10,
bodyBgap: 10, bodyBgap: 10,
} };
static xtype = "bi.drawer"; static xtype = "bi.drawer";
static EVENT_CLOSE = "EVENT_CLOSE"; static EVENT_CLOSE = "EVENT_CLOSE";
static EVENT_OPEN = "EVENT_OPEN"; static EVENT_OPEN = "EVENT_OPEN";
@ -55,17 +57,22 @@ export class Drawer extends Widget {
} }
render() { render() {
const { header, headerHeight, closable, body, bodyHgap, bodyTgap, bodyBgap } = this.options; const { header, headerHeight, closable, body, bodyHgap, bodyTgap, bodyBgap } = this.options;
const items = [{ const items = [
{
el: { el: {
type: "bi.htape", type: HTapeLayout.xtype,
cls: "bi-message-title bi-header-background", cls: "bi-message-title bi-header-background",
items: [{ items: [
type: "bi.absolute", {
items: [{ type: AbsoluteLayout.xtype,
el: isPlainObject(header) ? extend({}, header, { items: [
{
el: isPlainObject(header)
? extend({}, header, {
extraCls: "bi-font-bold", extraCls: "bi-font-bold",
}) : { })
type: "bi.label", : {
type: Label.xtype,
cls: "bi-font-bold", cls: "bi-font-bold",
height: headerHeight, height: headerHeight,
text: header, text: header,
@ -76,44 +83,56 @@ export class Drawer extends Widget {
top: 0, top: 0,
right: 0, right: 0,
bottom: 0, bottom: 0,
}], }
}, { ],
el: closable ? { },
type: "bi.icon_button", {
el: closable
? {
type: IconButton.xtype,
cls: "bi-message-close close-font", cls: "bi-message-close close-font",
height: headerHeight, height: headerHeight,
handler: () => { handler: () => {
this.close(); this.close();
}, },
} : { }
type: "bi.layout", : {
type: Layout.xtype,
}, },
width: 56, width: 56,
}], }
],
height: headerHeight, height: headerHeight,
}, },
height: headerHeight, height: headerHeight,
}, { },
{
el: { el: {
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: true, scrolly: true,
cls: "drawer-body", cls: "drawer-body",
ref: _ref => { ref: _ref => {
this.body = _ref; this.body = _ref;
}, },
items: [{ items: [
{
el: body, el: body,
}], }
],
}, },
hgap: bodyHgap, hgap: bodyHgap,
tgap: bodyTgap, tgap: bodyTgap,
bgap: bodyBgap, bgap: bodyBgap,
}]; }
];
return extend({ return extend(
{
type: "bi.vtape", type: "bi.vtape",
items, items,
}, this._getSuitableSize()); },
this._getSuitableSize()
);
} }
mounted() { mounted() {
const { placement } = this.options; const { placement } = this.options;
@ -230,7 +249,5 @@ export class Drawer extends Widget {
this.element.css({ "z-index": zindex }); this.element.css({ "z-index": zindex });
} }
destroyed() { destroyed() {}
}
} }

148
src/base/layer/layer.popover.js

@ -1,10 +1,22 @@
import {
HTapeLayout,
AbsoluteLayout,
VerticalLayout,
Widget,
shortcut,
clamp,
isPlainObject,
extend,
isNotNull
} from "@/core";
import { Label, IconButton, Button } from "../single";
/** /**
* Popover弹出层 * Popover弹出层
* @class BI.Popover * @class BI.Popover
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, clamp, isPlainObject, extend, isNotNull } from "../../core";
@shortcut() @shortcut()
export class Popover extends Widget { export class Popover extends Widget {
_constant = { _constant = {
@ -14,7 +26,7 @@ export class Popover extends Widget {
BIG: "big", BIG: "big",
}, },
MAX_HEIGHT: 600, MAX_HEIGHT: 600,
} };
props() { props() {
return { return {
@ -47,7 +59,8 @@ export class Popover extends Widget {
this.startX = 0; this.startX = 0;
this.startY = 0; this.startY = 0;
const size = this._calculateSize(); const size = this._calculateSize();
this.tracker = new BI.MouseMoveTracker((deltaX, deltaY) => { this.tracker = new BI.MouseMoveTracker(
(deltaX, deltaY) => {
const W = Widget._renderEngine.createElement("body").width(); const W = Widget._renderEngine.createElement("body").width();
const H = Widget._renderEngine.createElement("body").height(); const H = Widget._renderEngine.createElement("body").height();
this.startX += deltaX; this.startX += deltaX;
@ -60,24 +73,32 @@ export class Popover extends Widget {
BI.Resizers._resize({ BI.Resizers._resize({
target: this.element[0], target: this.element[0],
}); });
}, () => { },
() => {
this.tracker.releaseMouseMoves(); this.tracker.releaseMouseMoves();
}, _global); },
const items = [{ _global
);
const items = [
{
el: { el: {
type: "bi.htape", type: HTapeLayout.xtype,
cls: "bi-message-title bi-header-background", cls: "bi-message-title bi-header-background",
items: [{ items: [
{
el: { el: {
type: "bi.absolute", type: AbsoluteLayout.xtype,
ref: _ref => { ref: _ref => {
this.dragger = _ref; this.dragger = _ref;
}, },
items: [{ items: [
el: isPlainObject(header) ? extend({}, header, { {
el: isPlainObject(header)
? extend({}, header, {
extraCls: "bi-font-bold", extraCls: "bi-font-bold",
}) : { })
type: "bi.label", : {
type: Label.xtype,
cls: "bi-font-bold", cls: "bi-font-bold",
height: headerHeight, height: headerHeight,
text: header, text: header,
@ -88,11 +109,14 @@ export class Popover extends Widget {
bottom: 0, bottom: 0,
left: BI.SIZE_CONSANTS.H_GAP_SIZE, left: BI.SIZE_CONSANTS.H_GAP_SIZE,
right: closable ? 0 : BI.SIZE_CONSANTS.H_GAP_SIZE, right: closable ? 0 : BI.SIZE_CONSANTS.H_GAP_SIZE,
}], }
],
}, },
}, closable ? { },
closable
? {
el: { el: {
type: "bi.icon_button", type: IconButton.xtype,
cls: "bi-message-close close-font", cls: "bi-message-close close-font",
height: headerHeight, height: headerHeight,
handler: () => { handler: () => {
@ -100,67 +124,88 @@ export class Popover extends Widget {
}, },
}, },
width: 56, width: 56,
} : null], }
: null
],
height: headerHeight, height: headerHeight,
}, },
height: headerHeight, height: headerHeight,
}, logic.dynamic ? { },
logic.dynamic
? {
el: { el: {
type: "bi.vertical", type: VerticalLayout.xtype,
scrolly: true, scrolly: true,
cls: "popover-body", cls: "popover-body",
ref: _ref => { ref: _ref => {
this.body = _ref; this.body = _ref;
}, },
css: { css: {
"max-height": this._getSuitableBodyHeight(c.MAX_HEIGHT - headerHeight - (footer ? footerHeight : 0) - bodyTgap), "max-height": this._getSuitableBodyHeight(
"min-height": this._getSuitableBodyHeight(size.height - headerHeight - (footer ? footerHeight : 0) - bodyTgap), c.MAX_HEIGHT - headerHeight - (footer ? footerHeight : 0) - bodyTgap
),
"min-height": this._getSuitableBodyHeight(
size.height - headerHeight - (footer ? footerHeight : 0) - bodyTgap
),
}, },
items: [{ items: [
{
el: body, el: body,
}], }
],
hgap: bodyHgap, hgap: bodyHgap,
tgap: bodyTgap, tgap: bodyTgap,
}, },
} : { }
: {
el: { el: {
type: "bi.absolute", type: AbsoluteLayout.xtype,
items: [{ items: [
{
el: body, el: body,
left: bodyHgap, left: bodyHgap,
top: bodyTgap, top: bodyTgap,
right: bodyHgap, right: bodyHgap,
bottom: 0, bottom: 0,
}], }
],
}, },
}]; }
];
if (footer) { if (footer) {
items.push({ items.push({
el: { el: {
type: "bi.absolute", type: AbsoluteLayout.xtype,
items: [{ items: [
{
el: footer, el: footer,
left: BI.SIZE_CONSANTS.H_GAP_SIZE, left: BI.SIZE_CONSANTS.H_GAP_SIZE,
top: 0, top: 0,
right: BI.SIZE_CONSANTS.H_GAP_SIZE, right: BI.SIZE_CONSANTS.H_GAP_SIZE,
bottom: 0, bottom: 0,
}], }
],
height: footerHeight, height: footerHeight,
}, },
height: footerHeight, height: footerHeight,
}); });
} }
return extend({ return extend(
{
items, items,
width: this._getSuitableWidth(size.width), width: this._getSuitableWidth(size.width),
}, logic.dynamic ? { },
type: "bi.vertical", logic.dynamic
? {
type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
} : { }
: {
type: "bi.vtape", type: "bi.vtape",
height: this._getSuitableHeight(size.height), height: this._getSuitableHeight(size.height),
}); }
);
} }
// mounted之后绑定事件 // mounted之后绑定事件
mounted() { mounted() {
@ -176,7 +221,14 @@ export class Popover extends Widget {
_getSuitableBodyHeight(height) { _getSuitableBodyHeight(height) {
const { headerHeight, footer, footerHeight, bodyTgap } = this.options; const { headerHeight, footer, footerHeight, bodyTgap } = this.options;
return clamp(height, 0, Widget._renderEngine.createElement("body")[0].clientHeight - headerHeight - (footer ? footerHeight : 0) - bodyTgap); return clamp(
height,
0,
Widget._renderEngine.createElement("body")[0].clientHeight -
headerHeight -
(footer ? footerHeight : 0) -
bodyTgap
);
} }
_getSuitableHeight(height) { _getSuitableHeight(height) {
@ -219,9 +271,7 @@ export class Popover extends Widget {
this.options.draggable = b; this.options.draggable = b;
} }
hide() { hide() {}
}
open() { open() {
this.show(); this.show();
@ -250,11 +300,13 @@ export class BarPopover extends Popover {
beforeCreate() { beforeCreate() {
const { footer, warningTitle } = this.options; const { footer, warningTitle } = this.options;
footer || (this.options.footer = { footer ||
(this.options.footer = {
type: "bi.right_vertical_adapt", type: "bi.right_vertical_adapt",
lgap: 10, lgap: 10,
items: [{ items: [
type: "bi.button", {
type: Button.xtype,
text: this.options.btns[1], text: this.options.btns[1],
value: 1, value: 1,
level: "ignore", level: "ignore",
@ -262,8 +314,9 @@ export class BarPopover extends Popover {
this.fireEvent(Popover.EVENT_CANCEL, v); this.fireEvent(Popover.EVENT_CANCEL, v);
this.close(v); this.close(v);
}, },
}, { },
type: "bi.button", {
type: Button.xtype,
text: this.options.btns[0], text: this.options.btns[0],
warningTitle, warningTitle,
value: 0, value: 0,
@ -271,9 +324,8 @@ export class BarPopover extends Popover {
this.fireEvent(Popover.EVENT_CONFIRM, v); this.fireEvent(Popover.EVENT_CONFIRM, v);
this.close(v); this.close(v);
}, },
}], }
],
}); });
} }
} }

165
src/base/layer/layer.popup.js

@ -1,15 +1,29 @@
import { ButtonGroup } from "../combination/group.button";
import {
VerticalLayout,
AbsoluteLayout,
Layout,
CenterLayout,
Widget,
shortcut,
extend,
Controller,
createWidget,
createItems,
clamp
} from "@/core";
/** /**
* 下拉框弹出层, zIndex在1000w * 下拉框弹出层, zIndex在1000w
* @class BI.PopupView * @class BI.PopupView
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, Controller, createWidget, createItems, clamp } from "../../core";
@shortcut() @shortcut()
export class PopupView extends Widget { export class PopupView extends Widget {
_const = { _const = {
TRIANGLE_LENGTH: 12, TRIANGLE_LENGTH: 12,
} };
static xtype = "bi.popup_view"; static xtype = "bi.popup_view";
static EVENT_CHANGE = "EVENT_CHANGE"; static EVENT_CHANGE = "EVENT_CHANGE";
@ -44,19 +58,35 @@ export class PopupView extends Widget {
buttons: [], // toolbar栏 buttons: [], // toolbar栏
el: { el: {
type: "bi.button_group", type: ButtonGroup.xtype,
items: [], items: [],
chooseType: 0, chooseType: 0,
behaviors: {}, behaviors: {},
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
}, },
}); });
} }
render() { render() {
const { minWidth, maxWidth, stopPropagation, stopEvent, const {
direction, logic, lgap, rgap, tgap, bgap, vgap, hgap, primary, showArrow } = this.options; minWidth,
maxWidth,
stopPropagation,
stopEvent,
direction,
logic,
lgap,
rgap,
tgap,
bgap,
vgap,
hgap,
primary,
showArrow,
} = this.options;
function fn(e) { function fn(e) {
e.stopPropagation(); e.stopPropagation();
} }
@ -65,11 +95,13 @@ export class PopupView extends Widget {
return false; return false;
} }
this.element.css({ this.element
.css({
"z-index": BI.zIndex_popup, "z-index": BI.zIndex_popup,
"min-width": BI.pixFormat(minWidth), "min-width": BI.pixFormat(minWidth),
"max-width": BI.pixFormat(maxWidth), "max-width": BI.pixFormat(maxWidth),
}).bind({ click: fn }); })
.bind({ click: fn });
this.element.bind("mousewheel", fn); this.element.bind("mousewheel", fn);
@ -87,9 +119,14 @@ export class PopupView extends Widget {
} }
}); });
createWidget(extend({ createWidget(
extend(
{
element: this, element: this,
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(direction), extend({}, logic, { },
BI.LogicFactory.createLogic(
BI.LogicFactory.createLogicTypeByDirection(direction),
extend({}, logic, {
scrolly: false, scrolly: false,
lgap, lgap,
rgap, rgap,
@ -97,49 +134,73 @@ export class PopupView extends Widget {
bgap, bgap,
vgap, vgap,
hgap, hgap,
items: BI.LogicFactory.createLogicItemsByDirection(direction, extend({ items: BI.LogicFactory.createLogicItemsByDirection(
direction,
extend(
{
cls: `list-view-outer bi-card list-view-shadow${primary ? " bi-primary" : ""}`, cls: `list-view-outer bi-card list-view-shadow${primary ? " bi-primary" : ""}`,
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(direction), extend({}, logic, { },
items: BI.LogicFactory.createLogicItemsByDirection(direction, this.tool, this.tab, this.view, this.toolbar), BI.LogicFactory.createLogic(
}))) BI.LogicFactory.createLogicTypeByDirection(direction),
extend({}, logic, {
items: BI.LogicFactory.createLogicItemsByDirection(
direction,
this.tool,
this.tab,
this.view,
this.toolbar
),
})
)
)
), ),
})))); })
)
)
);
if (showArrow) { if (showArrow) {
this.arrow = createWidget({ this.arrow = createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
cls: "bi-bubble-arrow", cls: "bi-bubble-arrow",
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
cls: "bubble-arrow", cls: "bubble-arrow",
}], }
],
}); });
this.arrowWrapper = createWidget({ this.arrowWrapper = createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
cls: "bi-bubble-arrow-wrapper", cls: "bi-bubble-arrow-wrapper",
items: [{ items: [
{
el: this.arrow, el: this.arrow,
}], }
],
}); });
// 因为三角符号的原因位置变大了,需要占位 // 因为三角符号的原因位置变大了,需要占位
this.placeholder = createWidget({ this.placeholder = createWidget({
type: "bi.layout", type: Layout.xtype,
}); });
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: this.arrowWrapper, el: this.arrowWrapper,
left: 0, left: 0,
top: 0, top: 0,
}, { },
{
el: this.placeholder, el: this.placeholder,
}], }
],
}); });
} }
} }
_createView() { _createView() {
const { el, value, minHeight, innerVgap, innerHgap } = this.options; const { el, value, minHeight, innerVgap, innerHgap } = this.options;
this.button_group = createWidget(el, { type: "bi.button_group", value }); this.button_group = createWidget(el, { type: ButtonGroup.xtype, value });
this.button_group.element.css({ this.button_group.element.css({
"min-height": BI.pixFormat(minHeight), "min-height": BI.pixFormat(minHeight),
"padding-top": BI.pixFormat(innerVgap), "padding-top": BI.pixFormat(innerVgap),
@ -167,7 +228,7 @@ export class PopupView extends Widget {
} }
return createWidget({ return createWidget({
type: "bi.center", type: CenterLayout.xtype,
cls: "list-view-tab", cls: "list-view-tab",
height: 25, height: 25,
items: tabs, items: tabs,
@ -182,7 +243,7 @@ export class PopupView extends Widget {
} }
return createWidget({ return createWidget({
type: "bi.center", type: CenterLayout.xtype,
cls: "list-view-toolbar bi-high-light bi-split-top", cls: "list-view-toolbar bi-high-light bi-split-top",
height: 24, height: 24,
items: createItems(buttons, { items: createItems(buttons, {
@ -196,7 +257,9 @@ export class PopupView extends Widget {
setDirection(direction, position) { setDirection(direction, position) {
const { showArrow, tgap, vgap, bgap, rgap, hgap, lgap } = this.options; const { showArrow, tgap, vgap, bgap, rgap, hgap, lgap } = this.options;
if (showArrow) { if (showArrow) {
let style = {}, wrapperStyle = {}, placeholderStyle = {}; let style = {},
wrapperStyle = {},
placeholderStyle = {};
const adjustXOffset = position.adjustXOffset || 0; const adjustXOffset = position.adjustXOffset || 0;
const adjustYOffset = position.adjustYOffset || 0; const adjustYOffset = position.adjustYOffset || 0;
const bodyBounds = Widget._renderEngine.createElement("body").bounds(); const bodyBounds = Widget._renderEngine.createElement("body").bounds();
@ -242,7 +305,11 @@ export class PopupView extends Widget {
case "bottom,left": case "bottom,left":
direction = "bottom"; direction = "bottom";
style = { style = {
right: clamp(((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, minRight, maxRight), right: clamp(
((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8,
minRight,
maxRight
),
}; };
wrapperStyle = { wrapperStyle = {
top: bgap + vgap, top: bgap + vgap,
@ -281,7 +348,11 @@ export class PopupView extends Widget {
case "top,left": case "top,left":
direction = "top"; direction = "top";
style = { style = {
right: clamp(((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8, minRight, maxRight), right: clamp(
((middle ? popupWidth : position.width) + adjustXOffset) / 2 - 8,
minRight,
maxRight
),
}; };
wrapperStyle = { wrapperStyle = {
bottom: bgap + vgap, bottom: bgap + vgap,
@ -320,7 +391,11 @@ export class PopupView extends Widget {
case "left,top": case "left,top":
direction = "left"; direction = "left";
style = { style = {
bottom: clamp(((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, minBottom, maxBottom), bottom: clamp(
((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8,
minBottom,
maxBottom
),
}; };
wrapperStyle = { wrapperStyle = {
right: rgap + hgap, right: rgap + hgap,
@ -359,7 +434,11 @@ export class PopupView extends Widget {
case "right,top": case "right,top":
direction = "right"; direction = "right";
style = { style = {
bottom: clamp(((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8, minBottom, maxBottom), bottom: clamp(
((middle ? popupHeight : position.height) + adjustYOffset) / 2 - 8,
minBottom,
maxBottom
),
}; };
wrapperStyle = { wrapperStyle = {
left: lgap + hgap, left: lgap + hgap,
@ -412,12 +491,13 @@ export class PopupView extends Widget {
} }
resetHeight(h) { resetHeight(h) {
const tbHeight = this.toolbar ? (this.toolbar.attr("height") || 24) : 0, const tbHeight = this.toolbar ? this.toolbar.attr("height") || 24 : 0,
tabHeight = this.tab ? (this.tab.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); 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; const resetHeight = h - tbHeight - tabHeight - toolHeight - 2 * this.options.innerVgap;
this.view.resetHeight ? this.view.resetHeight(resetHeight) : this.view.resetHeight
this.view.element.css({ "max-height": BI.pixFormat(resetHeight) }); ? this.view.resetHeight(resetHeight)
: this.view.element.css({ "max-height": BI.pixFormat(resetHeight) });
} }
setValue(selectedValues) { setValue(selectedValues) {
@ -429,4 +509,3 @@ export class PopupView extends Widget {
return this.view.getValue(); return this.view.getValue();
} }
} }

71
src/base/layer/layer.searcher.js

@ -1,3 +1,7 @@
import { ButtonGroup } from "../combination";
import { VerticalLayout, Layout, shortcut, extend, createWidget, Controller, isNotEmptyArray } from "@/core";
import { Pane } from "../1.pane";
/** /**
* 搜索面板 * 搜索面板
* *
@ -6,9 +10,6 @@
* @extends BI.Pane * @extends BI.Pane
*/ */
import { shortcut, extend, createWidget, Controller, isNotEmptyArray } from "../../core";
import { Pane } from "../1.pane";
@shortcut() @shortcut()
export class SearcherView extends Pane { export class SearcherView extends Pane {
static xtype = "bi.searcher_view"; static xtype = "bi.searcher_view";
@ -22,25 +23,30 @@ export class SearcherView extends Pane {
tipText: BI.i18nText("BI-No_Select"), tipText: BI.i18nText("BI-No_Select"),
chooseType: BI.Selection.Single, chooseType: BI.Selection.Single,
matcher: { // 完全匹配的构造器 matcher: {
type: "bi.button_group", // 完全匹配的构造器
type: ButtonGroup.xtype,
behaviors: { behaviors: {
redmark: () => true, redmark: () => true,
}, },
items: [], items: [],
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
}, },
searcher: { searcher: {
type: "bi.button_group", type: ButtonGroup.xtype,
behaviors: { behaviors: {
redmark: () => true, redmark: () => true,
}, },
items: [], items: [],
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
}, },
}); });
} }
@ -48,14 +54,16 @@ export class SearcherView extends Pane {
const { matcher, chooseType, value, searcher } = this.options; const { matcher, chooseType, value, searcher } = this.options;
this.matcher = createWidget(matcher, { this.matcher = createWidget(matcher, {
type: "bi.button_group", type: ButtonGroup.xtype,
chooseType, chooseType,
behaviors: { behaviors: {
redmark: () => true, redmark: () => true,
}, },
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
value, value,
}); });
this.matcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => { this.matcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => {
@ -65,24 +73,28 @@ export class SearcherView extends Pane {
} }
}); });
this.spliter = createWidget({ this.spliter = createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
height: 1, height: 1,
hgap: 10, hgap: 10,
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
height: 1, height: 1,
cls: "searcher-view-spliter bi-background", cls: "searcher-view-spliter bi-background",
}], }
],
}); });
this.searcher = createWidget(searcher, { this.searcher = createWidget(searcher, {
type: "bi.button_group", type: ButtonGroup.xtype,
chooseType, chooseType,
behaviors: { behaviors: {
redmark: () => true, redmark: () => true,
}, },
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
value, value,
}); });
this.searcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => { this.searcher.on(Controller.EVENT_CHANGE, (type, val, ob, ...args) => {
@ -93,19 +105,15 @@ export class SearcherView extends Pane {
}); });
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
element: this, element: this,
items: [this.matcher, this.spliter, this.searcher], items: [this.matcher, this.spliter, this.searcher],
}); });
} }
startSearch() { startSearch() {}
}
stopSearch() { stopSearch() {}
}
setValue(v) { setValue(v) {
this.matcher.setValue(v); this.matcher.setValue(v);
@ -134,4 +142,3 @@ export class SearcherView extends Pane {
return this.matcher.getAllButtons().length > 0; return this.matcher.getAllButtons().length > 0;
} }
} }

33
src/base/list/listview.js

@ -1,3 +1,5 @@
import { VerticalLayout, Widget, shortcut, extend, isFunction } from "@/core";
/** /**
* 边滚动边加载的列表控件 * 边滚动边加载的列表控件
* *
@ -5,7 +7,7 @@
* @class BI.ListView * @class BI.ListView
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, isFunction } from "../../core";
@shortcut() @shortcut()
export class ListView extends Widget { export class ListView extends Widget {
props() { props() {
@ -31,14 +33,19 @@ export class ListView extends Widget {
const { el } = this.options; const { el } = this.options;
return { return {
type: "bi.vertical", type: VerticalLayout.xtype,
items: [extend({ items: [
type: "bi.vertical", extend(
{
type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
ref: _ref => { ref: _ref => {
this.container = _ref; this.container = _ref;
}, },
}, el)], },
el
)
],
element: this, element: this,
}; };
} }
@ -47,9 +54,11 @@ export class ListView extends Widget {
mounted() { mounted() {
const o = this.options; const o = this.options;
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
o.items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { o.items = isFunction(o.items)
? this.__watch(o.items, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : o.items; })
: o.items;
this._populate(); this._populate();
this.element.scroll(e => { this.element.scroll(e => {
o.scrollTop = this.element.scrollTop(); o.scrollTop = this.element.scrollTop();
@ -75,17 +84,20 @@ export class ListView extends Widget {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height(); const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight; const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + blockSize)) || 0; let index = (this.cache[this.renderedIndex] && this.cache[this.renderedIndex].index + blockSize) || 0;
let cnt = this.renderedIndex + 1; let cnt = this.renderedIndex + 1;
let lastHeight; let lastHeight;
const getElementHeight = () => this.container.element.height(); const getElementHeight = () => this.container.element.height();
lastHeight = getElementHeight(); lastHeight = getElementHeight();
while ((lastHeight) < minContentHeight && index < items.length) { while (lastHeight < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize); const itemsArr = items.slice(index, index + blockSize);
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
this.container.addItems(itemsArr.map((item, i) => itemFormatter(item, index + i)), this); this.container.addItems(
itemsArr.map((item, i) => itemFormatter(item, index + i)),
this
);
const addedHeight = getElementHeight() - lastHeight; const addedHeight = getElementHeight() - lastHeight;
this.cache[cnt] = { this.cache[cnt] = {
index, index,
@ -140,4 +152,3 @@ export class ListView extends Widget {
this.restore(); this.restore();
} }
} }

77
src/base/list/virtualgrouplist.js

@ -1,3 +1,6 @@
import { VerticalLayout, Layout, Widget, shortcut, extend, isFunction, isNumber, PrefixIntervalTree } from "@/core";
import { VirtualGroup } from "../combination";
/** /**
* 同时用于virtualGroup和virtualList特性的虚拟列表 * 同时用于virtualGroup和virtualList特性的虚拟列表
* *
@ -6,7 +9,6 @@
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, isFunction, isNumber, PrefixIntervalTree } from "../../core";
@shortcut() @shortcut()
export class VirtualGroupList extends Widget { export class VirtualGroupList extends Widget {
props() { props() {
@ -32,28 +34,37 @@ export class VirtualGroupList extends Widget {
const { rowHeight, items, el } = this.options; const { rowHeight, items, el } = this.options;
return { return {
type: "bi.vertical", type: VerticalLayout.xtype,
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
ref: () => { ref: () => {
this.topBlank = this; this.topBlank = this;
}, },
}, { },
type: "bi.virtual_group", {
type: VirtualGroup.xtype,
height: rowHeight * items.length, height: rowHeight * items.length,
ref: () => { ref: () => {
this.container = this; this.container = this;
}, },
layouts: [extend({ layouts: [
type: "bi.vertical", extend(
{
type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
}, el)], },
}, { el
type: "bi.layout", )
],
},
{
type: Layout.xtype,
ref: () => { ref: () => {
this.bottomBlank = this; this.bottomBlank = this;
}, },
}], }
],
element: this, element: this,
}; };
} }
@ -61,9 +72,11 @@ export class VirtualGroupList extends Widget {
mounted() { mounted() {
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
const o = this.options; const o = this.options;
o.items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { o.items = isFunction(o.items)
? this.__watch(o.items, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : o.items; })
: o.items;
this._populate(); this._populate();
this.ticking = false; this.ticking = false;
this.element.scroll(() => { this.element.scroll(() => {
@ -91,14 +104,19 @@ export class VirtualGroupList extends Widget {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height(); const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight; const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.renderedIndex + 1) * blockSize, cnt = this.renderedIndex + 1; let index = (this.renderedIndex + 1) * blockSize,
cnt = this.renderedIndex + 1;
let lastHeight; let lastHeight;
const getElementHeight = () => this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height(); const getElementHeight = () =>
this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height();
lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight(); lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight();
while (lastHeight < minContentHeight && index < items.length) { while (lastHeight < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize); const itemsArr = items.slice(index, index + blockSize);
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
this.container[this.renderedIndex === -1 ? "populate" : "addItems"](itemsArr.map((item, i) => itemFormatter(item, index + i)), this); this.container[this.renderedIndex === -1 ? "populate" : "addItems"](
itemsArr.map((item, i) => itemFormatter(item, index + i)),
this
);
const elementHeight = getElementHeight(); const elementHeight = getElementHeight();
const addedHeight = elementHeight - lastHeight; const addedHeight = elementHeight - lastHeight;
this.tree.set(cnt, addedHeight); this.tree.set(cnt, addedHeight);
@ -126,23 +144,29 @@ export class VirtualGroupList extends Widget {
const topHeight = this.tree.sumTo(Math.max(-1, start - 1)); const topHeight = this.tree.sumTo(Math.max(-1, start - 1));
this.topBlank.setHeight(`${topHeight}px`); this.topBlank.setHeight(`${topHeight}px`);
if (this._isAutoHeight()) { if (this._isAutoHeight()) {
for (let i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { for (let i = start < 0 ? 0 : start; i <= end && i <= this.renderedIndex; i++) {
const index = i * blockSize; const index = i * blockSize;
for (let j = index; j < index + blockSize && j < items.length; j++) { for (let j = index; j < index + blockSize && j < items.length; j++) {
itemsArr.push(items[j]); itemsArr.push(items[j]);
} }
} }
this.bottomBlank.setHeight(`${this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))}px`); this.bottomBlank.setHeight(
this.container.populate(itemsArr.map((item, i) => itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i))); `${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 { } else {
for (let i = (start < 0 ? 0 : start); i <= end; i++) { for (let i = start < 0 ? 0 : start; i <= end; i++) {
const index = i * blockSize; const index = i * blockSize;
for (let j = index; j < index + blockSize && j < items.length; j++) { for (let j = index; j < index + blockSize && j < items.length; j++) {
itemsArr.push(items[j]); itemsArr.push(items[j]);
} }
} }
this.container.element.height(rowHeight * items.length - topHeight); this.container.element.height(rowHeight * items.length - topHeight);
this.container.populate(itemsArr.map((item, i) => itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i))); this.container.populate(
itemsArr.map((item, i) => itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i))
);
} }
} }
_populate(items) { _populate(items) {
@ -152,13 +176,15 @@ export class VirtualGroupList extends Widget {
this.options.items = items; this.options.items = items;
this._restore(); this._restore();
} }
this.tree = PrefixIntervalTree.uniform(Math.ceil(this.options.items.length / blockSize), this._isAutoHeight() ? 0 : rowHeight * blockSize); this.tree = PrefixIntervalTree.uniform(
Math.ceil(this.options.items.length / blockSize),
this._isAutoHeight() ? 0 : rowHeight * blockSize
);
this._calculateBlocksToRender(); this._calculateBlocksToRender();
try { try {
this.element.scrollTop(scrollTop); this.element.scrollTop(scrollTop);
} catch (e) { } catch (e) {}
}
} }
_restore() { _restore() {
@ -189,4 +215,3 @@ export class VirtualGroupList extends Widget {
this.restore(); this.restore();
} }
} }

53
src/base/list/virtuallist.js

@ -1,3 +1,5 @@
import { VerticalLayout, Layout, Widget, shortcut, isFunction, each, PrefixIntervalTree } from "@/core";
/** /**
* 虚拟列表 * 虚拟列表
* *
@ -6,7 +8,6 @@
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, isFunction, each, PrefixIntervalTree } from "../../core";
@shortcut() @shortcut()
export class VirtualList extends Widget { export class VirtualList extends Widget {
props() { props() {
@ -29,33 +30,39 @@ export class VirtualList extends Widget {
render() { render() {
return { return {
type: "bi.vertical", type: VerticalLayout.xtype,
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
ref: _ref => { ref: _ref => {
this.topBlank = _ref; this.topBlank = _ref;
}, },
}, { },
type: "bi.vertical", {
type: VerticalLayout.xtype,
scrolly: false, scrolly: false,
ref: _ref => { ref: _ref => {
this.container = _ref; this.container = _ref;
}, },
}, { },
type: "bi.layout", {
type: Layout.xtype,
ref: _ref => { ref: _ref => {
this.bottomBlank = _ref; this.bottomBlank = _ref;
}, },
}], }
],
}; };
} }
// mounted之后绑定事件 // mounted之后绑定事件
mounted() { mounted() {
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化 // 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
const o = this.options; const o = this.options;
o.items = isFunction(o.items) ? this.__watch(o.items, (context, newValue) => { o.items = isFunction(o.items)
? this.__watch(o.items, (context, newValue) => {
this.populate(newValue); this.populate(newValue);
}) : o.items; })
: o.items;
this._populate(); this._populate();
this.element.scroll(e => { this.element.scroll(e => {
o.scrollTop = this.element.scrollTop(); o.scrollTop = this.element.scrollTop();
@ -72,14 +79,19 @@ export class VirtualList extends Widget {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options; const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height(); const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight; const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.renderedIndex + 1) * blockSize, cnt = this.renderedIndex + 1; let index = (this.renderedIndex + 1) * blockSize,
cnt = this.renderedIndex + 1;
let lastHeight; let lastHeight;
const getElementHeight = () => this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height(); const getElementHeight = () =>
this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height();
lastHeight = getElementHeight(); lastHeight = getElementHeight();
while (lastHeight < minContentHeight && index < items.length) { while (lastHeight < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize); const itemsArr = items.slice(index, index + blockSize);
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
this.container.addItems(itemsArr.map((item, i) => itemFormatter(item, index + i)), this); this.container.addItems(
itemsArr.map((item, i) => itemFormatter(item, index + i)),
this
);
const addedHeight = getElementHeight() - lastHeight; const addedHeight = getElementHeight() - lastHeight;
this.tree.set(cnt, addedHeight); this.tree.set(cnt, addedHeight);
this.renderedIndex = cnt; this.renderedIndex = cnt;
@ -102,7 +114,8 @@ export class VirtualList extends Widget {
const minContentHeightTo = scrollTop + height + overscanHeight; const minContentHeightTo = scrollTop + height + overscanHeight;
const start = this.tree.greatestLowerBound(minContentHeightFrom); const start = this.tree.greatestLowerBound(minContentHeightFrom);
const end = this.tree.leastUpperBound(minContentHeightTo); const end = this.tree.leastUpperBound(minContentHeightTo);
const needDestroyed = [], needMount = []; const needDestroyed = [],
needMount = [];
for (let i = 0; i < start; i++) { for (let i = 0; i < start; i++) {
const index = i * blockSize; const index = i * blockSize;
if (!this.cache[i]) { if (!this.cache[i]) {
@ -132,7 +145,7 @@ export class VirtualList extends Widget {
const firstFragment = Widget._renderEngine.createFragment(), const firstFragment = Widget._renderEngine.createFragment(),
lastFragment = Widget._renderEngine.createFragment(); lastFragment = Widget._renderEngine.createFragment();
let currentFragment = firstFragment; let currentFragment = firstFragment;
for (let i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { for (let i = start < 0 ? 0 : start; i <= end && i <= this.renderedIndex; i++) {
const index = i * blockSize; const index = i * blockSize;
if (!this.cache[i]) { if (!this.cache[i]) {
this.cache[i] = {}; this.cache[i] = {};
@ -152,7 +165,9 @@ export class VirtualList extends Widget {
this.container.element.prepend(firstFragment); this.container.element.prepend(firstFragment);
this.container.element.append(lastFragment); this.container.element.append(lastFragment);
this.topBlank.setHeight(`${this.tree.sumTo(Math.max(-1, start - 1))}px`); 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`); this.bottomBlank.setHeight(
`${this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))}px`
);
each(needMount, (i, child) => { each(needMount, (i, child) => {
child && child._mount(); child && child._mount();
}); });
@ -170,8 +185,7 @@ export class VirtualList extends Widget {
this._calculateBlocksToRender(); this._calculateBlocksToRender();
try { try {
this.element.scrollTop(scrollTop); this.element.scrollTop(scrollTop);
} catch (e) { } catch (e) {}
}
} }
_clearChildren() { _clearChildren() {
@ -210,4 +224,3 @@ export class VirtualList extends Widget {
this.restore(); this.restore();
} }
} }

111
src/base/pager/pager.js

@ -1,3 +1,20 @@
import {
HorizontalLayout,
Widget,
shortcut,
extend,
emptyFn,
result,
isKey,
createWidget,
map,
stripEL,
formatEL,
Controller
} from "@/core";
import { Label } from "../single";
import { ButtonGroup } from "../combination";
/** /**
* 分页控件 * 分页控件
* *
@ -5,18 +22,20 @@
* @class BI.Pager * @class BI.Pager
* @extends BI.Widget * @extends BI.Widget
*/ */
import { Widget, shortcut, extend, emptyFn, result, isKey, createWidget, map, stripEL, formatEL, Controller } from "../../core";
@shortcut() @shortcut()
export class Pager extends Widget { export class Pager extends Widget {
_defaultConfig() { _defaultConfig() {
return extend(super._defaultConfig(...arguments), { return extend(super._defaultConfig(...arguments), {
baseCls: "bi-pager", baseCls: "bi-pager",
behaviors: {}, behaviors: {},
layouts: [{ layouts: [
type: "bi.horizontal", {
type: HorizontalLayout.xtype,
hgap: 10, hgap: 10,
vgap: 0, vgap: 0,
}], }
],
dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态
// dynamicShow为false时以下两个有用 // dynamicShow为false时以下两个有用
@ -32,7 +51,8 @@ export class Pager extends Widget {
next: "下一页", next: "下一页",
firstPage: 1, firstPage: 1,
lastPage: () => // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 lastPage: () =>
// 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法
1, 1,
hasPrev: emptyFn, // pages不可用时有效 hasPrev: emptyFn, // pages不可用时有效
hasNext: emptyFn, // pages不可用时有效 hasNext: emptyFn, // pages不可用时有效
@ -53,8 +73,11 @@ export class Pager extends Widget {
} }
_populate() { _populate() {
const o = this.options, view = [], dict = {}; const o = this.options,
const { dynamicShow, dynamicShowPrevNext, hasPrev, dynamicShowFirstLast, hasNext, behaviors, layouts, jump } = this.options; view = [],
dict = {};
const { dynamicShow, dynamicShowPrevNext, hasPrev, dynamicShowFirstLast, hasNext, behaviors, layouts, jump } =
this.options;
this.empty(); this.empty();
const pages = result(o, "pages"); const pages = result(o, "pages");
const curr = result(this, "currPage"); const curr = result(this, "currPage");
@ -73,7 +96,7 @@ export class Pager extends Widget {
} }
// 计算当前组 // 计算当前组
dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); dict.index = Math.ceil((curr + (groups > 1 && groups !== pages ? 1 : 0)) / (groups === 0 ? 1 : groups));
// 当前页非首页,则输出上一页 // 当前页非首页,则输出上一页
if (((!dynamicShow && !dynamicShowPrevNext) || curr > 1) && prev !== false) { if (((!dynamicShow && !dynamicShowPrevNext) || curr > 1) && prev !== false) {
@ -85,9 +108,12 @@ export class Pager extends Widget {
}); });
} else { } else {
view.push({ view.push({
el: extend({ el: extend(
{
disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false), disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false),
}, prev), },
prev
),
}); });
} }
} }
@ -101,7 +127,7 @@ export class Pager extends Widget {
}); });
if (dict.index > 1 && groups !== 0 && groups !== pages - 1) { if (dict.index > 1 && groups !== 0 && groups !== pages - 1) {
view.push({ view.push({
type: "bi.label", type: Label.xtype,
cls: "page-ellipsis", cls: "page-ellipsis",
text: "\u2026", text: "\u2026",
}); });
@ -111,16 +137,21 @@ export class Pager extends Widget {
// 输出当前页组 // 输出当前页组
dict.poor = Math.floor((groups - 1) / 2); dict.poor = Math.floor((groups - 1) / 2);
dict.start = dict.index > 1 ? curr - dict.poor : 1; dict.start = dict.index > 1 ? curr - dict.poor : 1;
dict.end = dict.index > 1 ? (function () { dict.end =
dict.index > 1
? (function () {
const max = curr + (groups - dict.poor - 1); const max = curr + (groups - dict.poor - 1);
return max > pages ? pages : max; return max > pages ? pages : max;
}()) : groups; }())
if (dict.end - dict.start < groups - 1) { // 最后一组状态 : groups;
if (dict.end - dict.start < groups - 1) {
// 最后一组状态
dict.start = dict.end - groups + 1; dict.start = dict.end - groups + 1;
} }
let s = dict.start, e = dict.end; let s = dict.start,
if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { e = dict.end;
if (first && last && dict.index > 1 && groups !== 0 && pages > groups && dict.end < pages && groups !== 0) {
s++; s++;
e--; e--;
} }
@ -143,7 +174,7 @@ export class Pager extends Widget {
if (((!dynamicShow && !dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { if (((!dynamicShow && !dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) {
if (pages > groups && dict.end < pages && groups !== 0 && groups !== pages - 1) { if (pages > groups && dict.end < pages && groups !== 0 && groups !== pages - 1) {
view.push({ view.push({
type: "bi.label", type: Label.xtype,
cls: "page-ellipsis", cls: "page-ellipsis",
text: "\u2026", text: "\u2026",
}); });
@ -157,38 +188,47 @@ export class Pager extends Widget {
// 当前页不为尾页时,输出下一页 // 当前页不为尾页时,输出下一页
dict.flow = !prev && groups === 0; dict.flow = !prev && groups === 0;
if (((!dynamicShow && !dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { if ((!dynamicShow && !dynamicShowPrevNext && next) || (curr !== pages && next) || dict.flow) {
view.push((function () { view.push(
(function () {
if (isKey(next)) { if (isKey(next)) {
if (pages === false) { if (pages === false) {
return { text: next, value: "next", disabled: hasNext(curr) === false }; return { text: next, value: "next", disabled: hasNext(curr) === false };
} }
return (dict.flow && curr === pages) return dict.flow && curr === pages
? ? { text: next, value: "next", disabled: true }
{ text: next, value: "next", disabled: true } : { text: next, value: "next", disabled: !((curr !== pages && next) || dict.flow) };
:
{ text: next, value: "next", disabled: !(curr !== pages && next || dict.flow) };
} }
return { return {
el: extend({ el: extend(
disabled: pages === false ? hasNext(curr) === false : !(curr !== pages && next || dict.flow), {
}, next), disabled:
pages === false
? hasNext(curr) === false
: !((curr !== pages && next) || dict.flow),
},
next
),
}; };
}())); })()
);
} }
this.button_group = createWidget({ this.button_group = createWidget({
type: "bi.button_group", type: ButtonGroup.xtype,
element: this, element: this,
items: map(view, (idx, v) => { items: map(view, (idx, v) => {
v = extend({ v = extend(
{
cls: "bi-list-item-select bi-border-radius", cls: "bi-list-item-select bi-border-radius",
height: 23, height: 23,
hgap: v.el ? 0 : 10, hgap: v.el ? 0 : 10,
stopPropagation: true, stopPropagation: true,
}, stripEL(v)); },
stripEL(v)
);
return formatEL(v); return formatEL(v);
}), }),
@ -220,10 +260,12 @@ export class Pager extends Widget {
this.currPage = v; this.currPage = v;
break; break;
} }
jump.apply(this, [{ jump.apply(this, [
{
pages, pages,
curr: this.currPage, curr: this.currPage,
}]); }
]);
this._populate(); this._populate();
this.fireEvent(Pager.EVENT_CHANGE, obj); this.fireEvent(Pager.EVENT_CHANGE, obj);
} }
@ -263,7 +305,8 @@ export class Pager extends Widget {
if (pages === false) { if (pages === false) {
const lastPage = result(o, "lastPage"); const lastPage = result(o, "lastPage");
let firstPage = 1; let firstPage = 1;
this.currPage = v > lastPage ? lastPage : ((firstPage = result(o, "firstPage")), (v < firstPage ? firstPage : v)); this.currPage =
v > lastPage ? lastPage : ((firstPage = result(o, "firstPage")), v < firstPage ? firstPage : v);
} else { } else {
v = v > pages ? pages : v; v = v > pages ? pages : v;
this.currPage = v; this.currPage = v;

35
src/base/single/0.single.js

@ -1,3 +1,6 @@
import { Widget, shortcut, Actions, extend, isKey, isNotNull, isFunction, isPlainObject, isNull, delay } from "@/core";
import { Tooltips } from "@/base";
/** /**
* guy * guy
* 这仅仅只是一个超类, 所有简单控件的基类 * 这仅仅只是一个超类, 所有简单控件的基类
@ -10,9 +13,6 @@
* @abstract * @abstract
*/ */
import { Widget, shortcut, Actions, extend, isKey, isNotNull, isFunction, isPlainObject, isNull, delay } from "../../core";
import { Tooltips } from "../0.base";
@shortcut() @shortcut()
export class Single extends Widget { export class Single extends Widget {
static xtype = "bi.single"; static xtype = "bi.single";
@ -35,7 +35,7 @@ export class Single extends Widget {
const { action } = this.options; const { action } = this.options;
const title = this.getTitle(); const title = this.getTitle();
const showToolTip = (tooltipOpt) => { const showToolTip = tooltipOpt => {
if (isKey(tooltipOpt.text) && !Tooltips.has(this.getName())) { if (isKey(tooltipOpt.text) && !Tooltips.has(this.getName())) {
Tooltips.show(e, this.getName(), tooltipOpt, this, opt); Tooltips.show(e, this.getName(), tooltipOpt, this, opt);
if (action) { if (action) {
@ -43,7 +43,7 @@ export class Single extends Widget {
} }
Actions.runGlobalAction("hover", this.options, this); Actions.runGlobalAction("hover", this.options, this);
} }
} };
if (title instanceof Promise) { if (title instanceof Promise) {
this.requestingTitle = title; this.requestingTitle = title;
@ -54,7 +54,6 @@ export class Single extends Widget {
} else { } else {
showToolTip(this._getTooltipOptions(title)); showToolTip(this._getTooltipOptions(title));
} }
} }
_hideTooltip() { _hideTooltip() {
@ -68,16 +67,17 @@ export class Single extends Widget {
_init() { _init() {
const { value } = this.options; const { value } = this.options;
this.options.value = isFunction(value) ? this.__watch(value, (context, newValue) => { this.options.value = isFunction(value)
? this.__watch(value, (context, newValue) => {
this.setValue(newValue); this.setValue(newValue);
}) : value; })
: value;
super._init(arguments); super._init(arguments);
} }
_mounted() { _mounted() {
const { enableHover, title, warningTitle, belowMouse, container } = this.options; const { enableHover, title, warningTitle, belowMouse, container } = this.options;
if (enableHover || isKey(title) || isKey(warningTitle) if (enableHover || isKey(title) || isKey(warningTitle) || isFunction(title) || isFunction(warningTitle)) {
|| isFunction(title) || isFunction(warningTitle)) {
this.enableHover({ this.enableHover({
belowMouse, belowMouse,
container, container,
@ -105,11 +105,12 @@ export class Single extends Widget {
tooltipOpt.level = this.getTipType() || "success"; tooltipOpt.level = this.getTipType() || "success";
// 由于以前的用法,存在大量disabled:true搭配warningTitle的情况,所以这里做一个兼容,disabled:true的情况下,依然优先显示warningTitle,避免只设置了warningTitle而没有设置title的情况 // 由于以前的用法,存在大量disabled:true搭配warningTitle的情况,所以这里做一个兼容,disabled:true的情况下,依然优先显示warningTitle,避免只设置了warningTitle而没有设置title的情况
if (isNull(tipType) && !this.isEnabled()) { if (isNull(tipType) && !this.isEnabled()) {
tooltipOpt.text = (this.getWarningTitle() || title); tooltipOpt.text = this.getWarningTitle() || title;
} else { } else {
tooltipOpt.text = tooltipOpt.level === "success" ? title : (this.getWarningTitle() || title); tooltipOpt.text = tooltipOpt.level === "success" ? title : this.getWarningTitle() || title;
} }
} }
return tooltipOpt; return tooltipOpt;
} }
@ -117,7 +118,7 @@ export class Single extends Widget {
opt || (opt = {}); opt || (opt = {});
let delayingTooltips; let delayingTooltips;
if (!this._hoverBinded) { if (!this._hoverBinded) {
this.element.unbind("mouseenter.title").on("mouseenter.title", (e) => { this.element.unbind("mouseenter.title").on("mouseenter.title", e => {
this._e = e; this._e = e;
this.mouseOver = true; this.mouseOver = true;
if (this.getTipType() === "warning" || (isKey(this.getWarningTitle()) && !this.isEnabled())) { if (this.getTipType() === "warning" || (isKey(this.getWarningTitle()) && !this.isEnabled())) {
@ -136,7 +137,7 @@ export class Single extends Widget {
}, 500); }, 500);
} }
}); });
this.element.unbind("mousemove.title").on("mousemove.title", (e) => { this.element.unbind("mousemove.title").on("mousemove.title", e => {
this._e = e; this._e = e;
if (isNotNull(this.showTimeout)) { if (isNotNull(this.showTimeout)) {
clearTimeout(this.showTimeout); clearTimeout(this.showTimeout);
@ -165,7 +166,7 @@ export class Single extends Widget {
} }
}, 500); }, 500);
}); });
this.element.unbind("mouseleave.title").on("mouseleave.title", (e) => { this.element.unbind("mouseleave.title").on("mouseleave.title", e => {
this._e = null; this._e = null;
this.mouseOver = false; this.mouseOver = false;
this._clearTimeOut(); this._clearTimeOut();
@ -179,9 +180,7 @@ export class Single extends Widget {
// 取消hover事件 // 取消hover事件
this._clearTimeOut(); this._clearTimeOut();
this._hideTooltip(); this._hideTooltip();
this.element.unbind("mouseenter.title") this.element.unbind("mouseenter.title").unbind("mousemove.title").unbind("mouseleave.title");
.unbind("mousemove.title")
.unbind("mouseleave.title");
this._hoverBinded = false; this._hoverBinded = false;
} }

50
src/base/single/1.text.js

@ -1,10 +1,11 @@
import { Layout, DefaultLayout, shortcut } from "@/core";
import { Single } from "./0.single";
/** /**
* guy 表示一行数据通过position来定位位置的数据 * guy 表示一行数据通过position来定位位置的数据
* @class BI.Text * @class BI.Text
* @extends BI.Single * @extends BI.Single
*/ */
import { shortcut } from "../../core";
import { Single } from "./0.single";
@shortcut() @shortcut()
export class Text extends Single { export class Text extends Single {
@ -24,10 +25,29 @@ export class Text extends Single {
bgap: 0, bgap: 0,
py: "", py: "",
highLight: false, highLight: false,
} };
render() { render() {
const { vgap, hgap, lgap, rgap, tgap, bgap, height, lineHeight, maxWidth, textAlign, whiteSpace, handler, disabled, invalid, text: optionsText, value, keyword, highLight } = this.options; 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) { if (hgap + lgap > 0) {
this.element.css({ this.element.css({
"padding-left": BI.pixFormat(hgap + lgap), "padding-left": BI.pixFormat(hgap + lgap),
@ -58,21 +78,21 @@ export class Text extends Single {
this.element.css({ maxWidth: BI.pixFormat(maxWidth) }); this.element.css({ maxWidth: BI.pixFormat(maxWidth) });
} }
this.element.css({ this.element.css({
textAlign: textAlign, textAlign,
whiteSpace: this._getTextWrap(), whiteSpace: this._getTextWrap(),
textOverflow: whiteSpace === "nowrap" ? "ellipsis" : "", textOverflow: whiteSpace === "nowrap" ? "ellipsis" : "",
overflow: whiteSpace === "nowrap" ? "" : (BI.isWidthOrHeight(height) ? "auto" : ""), overflow: whiteSpace === "nowrap" ? "" : BI.isWidthOrHeight(height) ? "auto" : "",
}); });
if (handler && handler !== BI.emptyFn) { if (handler && handler !== BI.emptyFn) {
this.text = BI.createWidget({ this.text = BI.createWidget({
type: "bi.layout", type: Layout.xtype,
tagName: "span", tagName: "span",
}); });
this.text.element.click((e) => { this.text.element.click(e => {
!disabled && !invalid && handler.call(this, this.getValue(), this, e); !disabled && !invalid && handler.call(this, this.getValue(), this, e);
}); });
BI.createWidget({ BI.createWidget({
type: "bi.default", type: DefaultLayout.xtype,
element: this, element: this,
items: [this.text], items: [this.text],
}); });
@ -80,9 +100,11 @@ export class Text extends Single {
this.text = this; this.text = this;
} }
const text = BI.isFunction(optionsText) ? this.__watch(optionsText, (context, newValue) => { const text = BI.isFunction(optionsText)
? this.__watch(optionsText, (context, newValue) => {
this.setText(newValue); this.setText(newValue);
}) : optionsText; })
: optionsText;
// 只要不是undefined就可以显示text值,否则显示value // 只要不是undefined就可以显示text值,否则显示value
if (!BI.isUndefined(text)) { if (!BI.isUndefined(text)) {
this.setText(text); this.setText(text);
@ -113,7 +135,7 @@ export class Text extends Single {
const { text: optionsText } = this.options; const { text: optionsText } = this.options;
const text = BI.isFunction(optionsText) ? optionsText() : optionsText; const text = BI.isFunction(optionsText) ? optionsText() : optionsText;
return BI.isKey(text) ? Text.formatText(text + "") : text; return BI.isKey(text) ? Text.formatText(`${text}`) : text;
} }
_doRedMark(keyword) { _doRedMark(keyword) {
@ -162,10 +184,10 @@ export class Text extends Single {
} }
const formatters = []; const formatters = [];
Text.addTextFormatter = (formatter) => { Text.addTextFormatter = formatter => {
formatters.push(formatter); formatters.push(formatter);
}; };
Text.formatText = (text) => { Text.formatText = text => {
if (formatters.length > 0) { if (formatters.length > 0) {
for (let i = 0; i < formatters.length; i++) { for (let i = 0; i < formatters.length; i++) {
text = formatters[i](text); text = formatters[i](text);

6
src/base/single/a/a.js

@ -1,3 +1,6 @@
import { Text } from "../1.text";
import { shortcut, extend, createWidget } from "@/core";
/** /**
* 超链接 * 超链接
* *
@ -6,8 +9,7 @@
* @extends BI.Text * @extends BI.Text
* @abstract * @abstract
*/ */
import { shortcut, extend, createWidget } from "../../../core";
import { Text } from "../1.text";
@shortcut() @shortcut()
export class A extends Text { export class A extends Text {
static xtype = "bi.a"; static xtype = "bi.a";

19
src/base/single/bar/bar.loading.js

@ -1,8 +1,9 @@
import { shortcut, emptyFn } from "@/core"; import { TextButton } from "../button";
import { Layout, CenterAdaptLayout, CardLayout, shortcut, emptyFn } from "@/core";
import { Single } from "../0.single"; import { Single } from "../0.single";
@shortcut() @shortcut()
class LoadingBar extends Single { export class LoadingBar extends Single {
static xtype = "bi.loading_bar"; static xtype = "bi.loading_bar";
_defaultConfig() { _defaultConfig() {
@ -18,7 +19,7 @@ class LoadingBar extends Single {
render() { render() {
this.loaded = BI.createWidget({ this.loaded = BI.createWidget({
type: "bi.text_button", type: TextButton.xtype,
cls: "loading-text bi-list-item-simple", cls: "loading-text bi-list-item-simple",
text: BI.i18nText("BI-Load_More"), text: BI.i18nText("BI-Load_More"),
width: 120, width: 120,
@ -29,27 +30,28 @@ class LoadingBar extends Single {
}); });
this.loading = BI.createWidget({ this.loading = BI.createWidget({
type: "bi.layout", type: Layout.xtype,
width: this.options.height, width: this.options.height,
height: this.options.height, height: this.options.height,
cls: "loading-background cursor-default", cls: "loading-background cursor-default",
}); });
const loaded = BI.createWidget({ const loaded = BI.createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
items: [this.loaded], items: [this.loaded],
}); });
const loading = BI.createWidget({ const loading = BI.createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
items: [this.loading], items: [this.loading],
}); });
this.cardLayout = BI.createWidget({ this.cardLayout = BI.createWidget({
type: "bi.card", type: CardLayout.xtype,
element: this, element: this,
items: [ items: [
{ {
el: loaded, el: loaded,
cardName: "loaded", cardName: "loaded",
}, { },
{
el: loading, el: loading,
cardName: "loading", cardName: "loading",
} }
@ -80,4 +82,3 @@ class LoadingBar extends Single {
this.cardLayout.showCardByName("loading"); this.cardLayout.showCardByName("loading");
} }
} }

121
src/base/single/button/button.basic.js

@ -1,5 +1,17 @@
import {
Layout,
AbsoluteLayout,
emptyFn,
shortcut,
extend,
isFunction,
createWidget,
Widget,
isObject,
Controller
} from "@/core";
import { BubbleCombo } from "@/case/combo/bubblecombo/combo.bubble";
import { Single } from "../0.single"; import { Single } from "../0.single";
import { emptyFn, shortcut, extend, isFunction, createWidget, Widget, isObject, Controller } from "../../../core";
/** /**
* guy * guy
@ -18,7 +30,9 @@ export class BasicButton extends Single {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
_baseCls: `${conf._baseCls || ""} bi-basic-button${conf.invalid ? "" : " cursor-pointer"}${(BI.isIE() && BI.getIEVersion() < 10) ? " hack" : ""}`, _baseCls: `${conf._baseCls || ""} bi-basic-button${conf.invalid ? "" : " cursor-pointer"}${
BI.isIE() && BI.getIEVersion() < 10 ? " hack" : ""
}`,
// el: {} // 可以通过el来创建button元素 // el: {} // 可以通过el来创建button元素
value: "", value: "",
stopEvent: false, stopEvent: false,
@ -40,9 +54,11 @@ export class BasicButton extends Single {
_init() { _init() {
const opts = this.options; const opts = this.options;
opts.selected = isFunction(opts.selected) ? this.__watch(opts.selected, (context, newValue) => { opts.selected = isFunction(opts.selected)
? this.__watch(opts.selected, (context, newValue) => {
this.setSelected(newValue); this.setSelected(newValue);
}) : opts.selected; })
: opts.selected;
super._init(arguments); super._init(arguments);
if (opts.shadow) { if (opts.shadow) {
@ -75,20 +91,22 @@ export class BasicButton extends Single {
const assertMask = () => { const assertMask = () => {
if (!this.$mask) { if (!this.$mask) {
this.$mask = createWidget(isObject(o.shadow) ? o.shadow : {}, { this.$mask = createWidget(isObject(o.shadow) ? o.shadow : {}, {
type: "bi.layout", type: Layout.xtype,
cls: "bi-button-mask", cls: "bi-button-mask",
}); });
this.$mask.invisible(); this.$mask.invisible();
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: this.$mask, el: this.$mask,
left: 0, left: 0,
right: 0, right: 0,
top: 0, top: 0,
bottom: 0, bottom: 0,
}], },
],
}); });
} }
}; };
@ -99,7 +117,7 @@ export class BasicButton extends Single {
this.$mask.invisible(); this.$mask.invisible();
} }
}); });
this.element.on(`mouseenter.${this.getName()}`, e => { this.element.on(`mouseenter.${this.getName()}`, (e) => {
if (this.element.__isMouseInBounds__(e)) { if (this.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && !this._hover && (o.isShadowShowingOnSelected || !this.isSelected())) { if (this.isEnabled() && !this._hover && (o.isShadowShowingOnSelected || !this.isSelected())) {
assertMask(); assertMask();
@ -107,7 +125,7 @@ export class BasicButton extends Single {
} }
} }
}); });
this.element.on(`mousemove.${this.getName()}`, e => { this.element.on(`mousemove.${this.getName()}`, (e) => {
if (!this.element.__isMouseInBounds__(e)) { if (!this.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && !this._hover) { if (this.isEnabled() && !this._hover) {
assertMask(); assertMask();
@ -140,7 +158,7 @@ export class BasicButton extends Single {
return bubble; return bubble;
}; };
const clk = e => { const clk = (e) => {
ev(e); ev(e);
if (!this.isEnabled() || !this.isValid()) { if (!this.isEnabled() || !this.isValid()) {
return; return;
@ -152,28 +170,30 @@ export class BasicButton extends Single {
if (BI.isNull(this.combo)) { if (BI.isNull(this.combo)) {
let popup; let popup;
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: { el: {
type: "bi.bubble_combo", type: BubbleCombo.xtype,
trigger: "", trigger: "",
// bubble的提示不需要一直存在在界面上 // bubble的提示不需要一直存在在界面上
destroyWhenHide: true, destroyWhenHide: true,
ref: _ref => { ref: (_ref) => {
this.combo = _ref; this.combo = _ref;
}, },
el: { el: {
type: "bi.layout", type: Layout.xtype,
height: "100%", height: "100%",
}, },
popup: { popup: {
type: "bi.text_bubble_bar_popup_view", type: "bi.text_bubble_bar_popup_view",
text: getBubble(), text: getBubble(),
ref: _ref => { ref: (_ref) => {
popup = _ref; popup = _ref;
}, },
listeners: [{ listeners: [
{
eventName: BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, eventName: BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON,
action: (...args) => { action: (...args) => {
const [v] = args; const [v] = args;
@ -182,20 +202,24 @@ export class BasicButton extends Single {
onClick.apply(this, args); onClick.apply(this, args);
} }
}, },
}],
}, },
listeners: [{ ],
eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, },
listeners: [
{
eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW,
action() { action() {
popup.populate(getBubble()); popup.populate(getBubble());
}, },
}], },
],
}, },
left: 0, left: 0,
right: 0, right: 0,
bottom: 0, bottom: 0,
top: 0, top: 0,
}], },
],
}); });
} }
if (this.combo.isViewVisible()) { if (this.combo.isViewVisible()) {
@ -209,10 +233,8 @@ export class BasicButton extends Single {
onClick.apply(this, arguments); onClick.apply(this, arguments);
}; };
const triggerArr = (o.trigger || "").split(","); const triggerArr = (o.trigger || "").split(",");
triggerArr.forEach(trigger => { triggerArr.forEach((trigger) => {
let mouseDown = false; let mouseDown = false;
let selected = false; let selected = false;
let interval; let interval;
@ -221,7 +243,7 @@ export class BasicButton extends Single {
hand.mousedown(() => { hand.mousedown(() => {
mouseDown = true; mouseDown = true;
}); });
hand.mouseup(e => { hand.mouseup((e) => {
if (mouseDown === true) { if (mouseDown === true) {
clk(e); clk(e);
} }
@ -231,11 +253,16 @@ export class BasicButton extends Single {
break; break;
case "mousedown": case "mousedown":
// let mouseDown = false; // let mouseDown = false;
hand.mousedown(e => { hand.mousedown((e) => {
// if (e.button === 0) { // if (e.button === 0) {
Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, e => { Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, (e) => {
// if (e.button === 0) { // if (e.button === 0) {
if (BI.DOM.isExist(this) && !hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { if (
BI.DOM.isExist(this) &&
!hand.__isMouseInBounds__(e) &&
mouseDown === true &&
!selected
) {
// self.setSelected(!self.isSelected()); // self.setSelected(!self.isSelected());
this._trigger(); this._trigger();
} }
@ -255,7 +282,7 @@ export class BasicButton extends Single {
ev(e); ev(e);
// } // }
}); });
hand.mouseup(e => { hand.mouseup((e) => {
// if (e.button === 0) { // if (e.button === 0) {
if (BI.DOM.isExist(this) && mouseDown === true && selected === true) { if (BI.DOM.isExist(this) && mouseDown === true && selected === true) {
clk(e); clk(e);
@ -270,7 +297,7 @@ export class BasicButton extends Single {
hand.dblclick(clk); hand.dblclick(clk);
break; break;
case "lclick": case "lclick":
hand.mousedown(e => { hand.mousedown((e) => {
Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, () => { Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, () => {
interval && clearInterval(interval); interval && clearInterval(interval);
interval = null; interval = null;
@ -295,13 +322,15 @@ export class BasicButton extends Single {
break; break;
default: default:
if (o.stopEvent || o.stopPropagation) { if (o.stopEvent || o.stopPropagation) {
hand.mousedown(e => { hand.mousedown((e) => {
ev(e); ev(e);
}); });
} }
hand.click(clk); hand.click(clk);
// enter键等同于点击 // enter键等同于点击
o.attributes && o.attributes.zIndex >= 0 && hand.keyup(e => { o.attributes &&
o.attributes.zIndex >= 0 &&
hand.keyup((e) => {
if (e.keyCode === BI.KeyCode.ENTER) { if (e.keyCode === BI.KeyCode.ENTER) {
clk(e); clk(e);
} }
@ -311,10 +340,12 @@ export class BasicButton extends Single {
}); });
// 之后的300ms点击无效 // 之后的300ms点击无效
const onClick = o.debounce ? BI.debounce(this._doClick, BI.EVENT_RESPONSE_TIME, { const onClick = o.debounce
? BI.debounce(this._doClick, BI.EVENT_RESPONSE_TIME, {
leading: true, leading: true,
trailing: false, trailing: false,
}) : this._doClick; })
: this._doClick;
function ev(e) { function ev(e) {
if (o.stopEvent) { if (o.stopEvent) {
@ -332,9 +363,11 @@ export class BasicButton extends Single {
return; return;
} }
if (!this.isDisableSelected()) { if (!this.isDisableSelected()) {
this.isForceSelected() ? this.setSelected(true) : this.isForceSelected()
(this.isForceNotSelected() ? this.setSelected(false) : ? this.setSelected(true)
this.setSelected(!this.isSelected())); : this.isForceNotSelected()
? this.setSelected(false)
: this.setSelected(!this.isSelected());
} }
if (this.isValid()) { if (this.isValid()) {
const v = this.getValue(); const v = this.getValue();
@ -367,13 +400,9 @@ export class BasicButton extends Single {
/** /**
* 子类可以得写这个方法如果返回为 true则可以阻止 handler 的触发 * 子类可以得写这个方法如果返回为 true则可以阻止 handler 的触发
*/ */
beforeClick() { beforeClick() {}
} doClick() {}
doClick() {
}
handle() { handle() {
return this; return this;
@ -457,5 +486,3 @@ export class BasicButton extends Single {
super.empty(...arguments); super.empty(...arguments);
} }
} }

2
src/base/single/button/button.node.js

@ -1,5 +1,5 @@
import { BasicButton } from "./button.basic"; import { BasicButton } from "./button.basic";
import { shortcut, extend, Controller } from "../../../core"; import { shortcut, extend, Controller } from "@/core";
/** /**
* 表示一个可以展开的节点, 不仅有选中状态而且有展开状态 * 表示一个可以展开的节点, 不仅有选中状态而且有展开状态

9
src/base/single/button/buttons/button.icon.js

@ -1,5 +1,6 @@
import { Icon } from "../../icon/icon";
import { DefaultLayout, CenterAdaptLayout, shortcut, extend, isNumber, createWidget, isNull } from "@/core";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { shortcut, extend, isNumber, createWidget, isNull } from "../../../../core";
/** /**
* @class IconButton * @class IconButton
@ -33,14 +34,14 @@ export class IconButton extends BasicButton {
textAlign: "center", textAlign: "center",
}); });
this.icon = createWidget({ this.icon = createWidget({
type: "bi.icon", type: Icon.xtype,
width: o.iconWidth, width: o.iconWidth,
height: o.iconHeight, height: o.iconHeight,
}); });
if (isNumber(o.height) && o.height > 0 && isNull(o.iconWidth) && isNull(o.iconHeight)) { if (isNumber(o.height) && o.height > 0 && isNull(o.iconWidth) && isNull(o.iconHeight)) {
this.element.css("lineHeight", BI.pixFormat(o.height)); this.element.css("lineHeight", BI.pixFormat(o.height));
createWidget({ createWidget({
type: "bi.default", type: DefaultLayout.xtype,
element: this, element: this,
hgap: o.hgap, hgap: o.hgap,
vgap: o.vgap, vgap: o.vgap,
@ -54,7 +55,7 @@ export class IconButton extends BasicButton {
this.element.css("lineHeight", "1"); this.element.css("lineHeight", "1");
createWidget({ createWidget({
element: this, element: this,
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
hgap: o.hgap, hgap: o.hgap,
vgap: o.vgap, vgap: o.vgap,
lgap: o.lgap, lgap: o.lgap,

10
src/base/single/button/buttons/button.image.js

@ -1,6 +1,6 @@
import { Img } from "../../img/img";
import { CenterAdaptLayout, AdaptiveLayout, shortcut, extend, isNumber, createWidget } from "@/core";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { shortcut, extend, isNumber, createWidget } from "../../../../core";
/** /**
* 图片的button * 图片的button
@ -28,20 +28,20 @@ export class ImageButton extends BasicButton {
render() { render() {
const o = this.options; const o = this.options;
this.image = createWidget({ this.image = createWidget({
type: "bi.img", type: Img.xtype,
width: o.iconWidth, width: o.iconWidth,
height: o.iconHeight, height: o.iconHeight,
src: o.src, src: o.src,
}); });
if (isNumber(o.iconWidth) || isNumber(o.iconHeight)) { if (isNumber(o.iconWidth) || isNumber(o.iconHeight)) {
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
element: this, element: this,
items: [this.image], items: [this.image],
}); });
} else { } else {
createWidget({ createWidget({
type: "bi.adaptive", type: AdaptiveLayout.xtype,
element: this, element: this,
items: [this.image], items: [this.image],
scrollable: false, scrollable: false,

31
src/base/single/button/buttons/button.js

@ -1,5 +1,6 @@
import { CenterAdaptLayout, isNumber, shortcut, isPlainObject, createWidget } from "@/core";
import { Label, IconLabel } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { isNumber, shortcut, isPlainObject, createWidget } from "../../../../core";
function isVertical(position) { function isVertical(position) {
return position === "top" || position === "bottom"; return position === "top" || position === "bottom";
@ -19,7 +20,7 @@ const loadingCls = "button-loading-font anim-rotate";
export class Button extends BasicButton { export class Button extends BasicButton {
_const = { _const = {
iconWidth: 18, iconWidth: 18,
} };
static xtype = "bi.button"; static xtype = "bi.button";
static EVENT_CHANGE = "EVENT_CHANGE"; static EVENT_CHANGE = "EVENT_CHANGE";
@ -34,14 +35,14 @@ export class Button extends BasicButton {
adaptiveHeight += props.iconGap || 0; adaptiveHeight += props.iconGap || 0;
const tGap = props.tgap || props.vgap || 2; const tGap = props.tgap || props.vgap || 2;
const bGap = props.bgap || props.vgap || 2; const bGap = props.bgap || props.vgap || 2;
adaptiveHeight += (tGap + bGap); adaptiveHeight += tGap + bGap;
} }
const clearMinWidth = props.block === true || props.clear === true || props.plain; const clearMinWidth = props.block === true || props.clear === true || props.plain;
return { return {
...conf, ...conf,
baseCls: `${conf.baseCls || ""} bi-button${(BI.isIE() && BI.isIE9Below()) ? " hack" : ""}`, baseCls: `${conf.baseCls || ""} bi-button${BI.isIE() && BI.isIE9Below() ? " hack" : ""}`,
attributes: { attributes: {
tabIndex: 1, tabIndex: 1,
}, },
@ -62,7 +63,7 @@ export class Button extends BasicButton {
whiteSpace: "nowrap", whiteSpace: "nowrap",
textWidth: null, textWidth: null,
textHeight: null, textHeight: null,
hgap: props.clear ? 0 : (props.plain && !props.text ? 4 : 10), hgap: props.clear ? 0 : props.plain && !props.text ? 4 : 10,
vgap: 0, vgap: 0,
tgap: 0, tgap: 0,
bgap: 0, bgap: 0,
@ -79,7 +80,7 @@ export class Button extends BasicButton {
// bi.center_adapt 作用:让 hgap 不影响 iconGap。 // bi.center_adapt 作用:让 hgap 不影响 iconGap。
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
horizontalAlign: o.textAlign, horizontalAlign: o.textAlign,
element: this, element: this,
ref: ref => { ref: ref => {
@ -107,7 +108,8 @@ export class Button extends BasicButton {
const o = this.options; const o = this.options;
// 由于button默认情况下有个边框,所以要主动算行高 // 由于button默认情况下有个边框,所以要主动算行高
let lineHeight, textHeight = o.textHeight; let lineHeight,
textHeight = o.textHeight;
let hasBorder = false; let hasBorder = false;
if (isNumber(o.height)) { if (isNumber(o.height)) {
if (!isVertical(o.iconPosition)) { if (!isVertical(o.iconPosition)) {
@ -128,13 +130,13 @@ export class Button extends BasicButton {
const iconInvisible = !(o.loading || o.iconCls || o.icon || defaultRenderIcon); const iconInvisible = !(o.loading || o.iconCls || o.icon || defaultRenderIcon);
let maxTextWidth = Math.max(o.minWidth, o.width); let maxTextWidth = Math.max(o.minWidth, o.width);
maxTextWidth -= (o.hgap * 2 + o.iconGap); maxTextWidth -= o.hgap * 2 + o.iconGap;
// 减去图标水平占位宽度 // 减去图标水平占位宽度
maxTextWidth -= iconInvisible || isVertical(o.iconPosition) ? 0 : this._const.iconWidth; maxTextWidth -= iconInvisible || isVertical(o.iconPosition) ? 0 : this._const.iconWidth;
const textWidth = BI.isNull(o.textWidth) ? maxTextWidth : Math.min(o.textWidth, maxTextWidth); const textWidth = BI.isNull(o.textWidth) ? maxTextWidth : Math.min(o.textWidth, maxTextWidth);
this.text = createWidget({ this.text = createWidget({
type: "bi.label", type: Label.xtype,
text: o.text, text: o.text,
whiteSpace: o.whiteSpace, whiteSpace: o.whiteSpace,
textAlign: o.textAlign, textAlign: o.textAlign,
@ -155,8 +157,8 @@ export class Button extends BasicButton {
this.icon = createWidget(o.icon); this.icon = createWidget(o.icon);
} else { } else {
this.icon = createWidget({ this.icon = createWidget({
type: "bi.icon_label", type: IconLabel.xtype,
cls: o.loading ? loadingCls : (o.iconCls || o.icon), cls: o.loading ? loadingCls : o.iconCls || o.icon,
width: this._const.iconWidth, width: this._const.iconWidth,
height: BI.toPix(lineHeight, hasBorder ? 2 : 0), height: BI.toPix(lineHeight, hasBorder ? 2 : 0),
lineHeight: BI.toPix(lineHeight, hasBorder ? 2 : 0), lineHeight: BI.toPix(lineHeight, hasBorder ? 2 : 0),
@ -179,12 +181,14 @@ export class Button extends BasicButton {
items.reverse(); items.reverse();
} }
return [{ return [
{
type: isVertical(o.iconPosition) ? "bi.vertical" : "bi.horizontal", type: isVertical(o.iconPosition) ? "bi.vertical" : "bi.horizontal",
horizontalAlign: "center", horizontalAlign: "center",
verticalAlign: "middle", verticalAlign: "middle",
items, items,
}]; }
];
} }
doClick() { doClick() {
@ -272,4 +276,3 @@ export class Button extends BasicButton {
this.text.unHighLight(...arguments); this.text.unHighLight(...arguments);
} }
} }

5
src/base/single/button/buttons/button.text.js

@ -1,5 +1,6 @@
import { Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { shortcut, extend, createWidget, isArray } from "../../../../core"; import { shortcut, extend, createWidget, isArray } from "@/core";
/** /**
* guy * guy
@ -33,7 +34,7 @@ export class TextButton extends BasicButton {
render() { render() {
const o = this.options; const o = this.options;
this.text = createWidget({ this.text = createWidget({
type: "bi.label", type: Label.xtype,
element: this, element: this,
textAlign: o.textAlign, textAlign: o.textAlign,
whiteSpace: o.whiteSpace, whiteSpace: o.whiteSpace,

28
src/base/single/button/listitem/blankiconicontextitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, Layout, shortcut, extend } from "@/core";
import { IconLabel, Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { shortcut, extend } from "../../../../core";
/** /**
* 带有一个占位 * 带有一个占位
@ -34,28 +35,32 @@ export class BlankIconIconTextItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, o.rightIconWrapperWidth || o.height, "fill"], columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, o.rightIconWrapperWidth || o.height, "fill"],
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
width: o.blankWidth, width: o.blankWidth,
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls1, cls: o.iconCls1,
width: o.leftIconWrapperWidth || o.height, width: o.leftIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls2, cls: o.iconCls2,
width: o.rightIconWrapperWidth || o.height, width: o.rightIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -69,7 +74,8 @@ export class BlankIconIconTextItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}], }
],
}; };
} }

29
src/base/single/button/listitem/blankicontexticonitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, Layout, shortcut, extend } from "@/core";
import { IconLabel, Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { shortcut, extend } from "../../../../core";
/** /**
* guy * guy
@ -35,21 +36,24 @@ export class BlankIconTextIconItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], columnSize: [o.blankWidth, o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height],
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
width: o.blankWidth, width: o.blankWidth,
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls1, cls: o.iconCls1,
width: o.leftIconWrapperWidth || o.height, width: o.leftIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -63,14 +67,16 @@ export class BlankIconTextIconItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls2, cls: o.iconCls2,
width: o.rightIconWrapperWidth || o.height, width: o.rightIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}], }
],
}; };
} }
@ -115,4 +121,3 @@ export class BlankIconTextIconItem extends BasicButton {
return this.text.getText(); return this.text.getText();
} }
} }

23
src/base/single/button/listitem/blankicontextitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, Layout, extend, shortcut } from "@/core";
import { IconLabel, Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { extend, shortcut } from "../../../../core";
/** /**
* 带有一个占位 * 带有一个占位
@ -33,21 +34,24 @@ export class BlankIconTextItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.blankWidth, o.iconWrapperWidth || o.height, "fill"], columnSize: [o.blankWidth, o.iconWrapperWidth || o.height, "fill"],
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
width: o.blankWidth, width: o.blankWidth,
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls, cls: o.iconCls,
width: o.iconWrapperWidth || o.height, width: o.iconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -62,7 +66,8 @@ export class BlankIconTextItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}], }
],
}; };
} }

23
src/base/single/button/listitem/icontexticonitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { IconLabel, Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { extend, shortcut } from "../../../../core";
/** /**
* guy * guy
@ -35,18 +36,20 @@ export class IconTextIconItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height],
items: [{ items: [
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls1, cls: o.iconCls1,
width: o.leftIconWrapperWidth || o.height, width: o.leftIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -60,14 +63,16 @@ export class IconTextIconItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls2, cls: o.iconCls2,
width: o.rightIconWrapperWidth || o.height, width: o.rightIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}], }
],
}; };
} }

18
src/base/single/button/listitem/icontextitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { IconLabel, Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { extend, shortcut } from "../../../../core";
/** /**
* guy * guy
@ -34,18 +35,20 @@ export class IconTextItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.iconWrapperWidth || o.height, "fill"], columnSize: [o.iconWrapperWidth || o.height, "fill"],
items: [{ items: [
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls, cls: o.iconCls,
width: o.iconWrapperWidth || o.height, width: o.iconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -60,7 +63,8 @@ export class IconTextItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}], }
],
}; };
} }

20
src/base/single/button/listitem/texticonitem.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { Label, IconLabel } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { extend, shortcut } from "../../../../core";
/** /**
* *
@ -12,7 +13,7 @@ import { extend, shortcut } from "../../../../core";
@shortcut() @shortcut()
export class TextIconItem extends BasicButton { export class TextIconItem extends BasicButton {
static xtype = "bi.text_icon_item"; static xtype = "bi.text_icon_item";
static EVENT_CHANGE = "EVENT_CHANGE" static EVENT_CHANGE = "EVENT_CHANGE";
_defaultConfig() { _defaultConfig() {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
@ -34,11 +35,12 @@ export class TextIconItem extends BasicButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: ["fill", o.iconWrapperWidth || o.height], columnSize: ["fill", o.iconWrapperWidth || o.height],
items: [{ items: [
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -53,14 +55,16 @@ export class TextIconItem extends BasicButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls, cls: o.iconCls,
width: o.iconWrapperWidth || o.height, width: o.iconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}], }
],
}; };
} }

5
src/base/single/button/listitem/textitem.js

@ -1,5 +1,6 @@
import { Label } from "../../label";
import { BasicButton } from "../button.basic"; import { BasicButton } from "../button.basic";
import { extend, shortcut, createWidget } from "../../../../core"; import { extend, shortcut, createWidget } from "@/core";
/** /**
* guy * guy
@ -31,7 +32,7 @@ export class TextItem extends BasicButton {
render() { render() {
const o = this.options; const o = this.options;
this.text = createWidget({ this.text = createWidget({
type: "bi.label", type: Label.xtype,
element: this, element: this,
textAlign: o.textAlign, textAlign: o.textAlign,
whiteSpace: o.whiteSpace, whiteSpace: o.whiteSpace,

23
src/base/single/button/node/icontexticonnode.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { IconLabel, Label } from "../../label";
import { NodeButton } from "../button.node"; import { NodeButton } from "../button.node";
import { extend, shortcut } from "../../../../core";
/** /**
* guy * guy
@ -32,18 +33,20 @@ export class IconTextIconNode extends NodeButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height], columnSize: [o.leftIconWrapperWidth || o.height, "fill", o.rightIconWrapperWidth || o.height],
items: [{ items: [
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls1, cls: o.iconCls1,
width: o.leftIconWrapperWidth || o.height, width: o.leftIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -57,14 +60,16 @@ export class IconTextIconNode extends NodeButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls2, cls: o.iconCls2,
width: o.rightIconWrapperWidth || o.height, width: o.rightIconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}], }
],
}; };
} }

19
src/base/single/button/node/icontextnode.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { IconLabel, Label } from "../../label";
import { NodeButton } from "../button.node"; import { NodeButton } from "../button.node";
import { extend, shortcut } from "../../../../core";
/** /**
* guy * guy
@ -31,18 +32,20 @@ export class IconTextNode extends NodeButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: [o.iconWrapperWidth || o.height, "fill"], columnSize: [o.iconWrapperWidth || o.height, "fill"],
items: [{ items: [
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls, cls: o.iconCls,
width: o.iconWrapperWidth || o.height, width: o.iconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}, { },
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -57,7 +60,8 @@ export class IconTextNode extends NodeButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}], }
],
}; };
} }
@ -94,4 +98,3 @@ export class IconTextNode extends NodeButton {
this.text.unRedMark(...arguments); this.text.unRedMark(...arguments);
} }
} }

19
src/base/single/button/node/texticonnode.js

@ -1,5 +1,6 @@
import { VerticalAdaptLayout, extend, shortcut } from "@/core";
import { Label, IconLabel } from "../../label";
import { NodeButton } from "../button.node"; import { NodeButton } from "../button.node";
import { extend, shortcut } from "../../../../core";
/** /**
* Created by GUY on 2015/9/9. * Created by GUY on 2015/9/9.
@ -8,7 +9,6 @@ import { extend, shortcut } from "../../../../core";
*/ */
@shortcut() @shortcut()
export class TextIconNode extends NodeButton { export class TextIconNode extends NodeButton {
static EVENT_CHANGE = "EVENT_CHANGE"; static EVENT_CHANGE = "EVENT_CHANGE";
static xtype = "bi.text_icon_node"; static xtype = "bi.text_icon_node";
@ -31,11 +31,12 @@ export class TextIconNode extends NodeButton {
const o = this.options; const o = this.options;
return { return {
type: "bi.vertical_adapt", type: VerticalAdaptLayout.xtype,
columnSize: ["fill", o.iconWrapperWidth || o.height], columnSize: ["fill", o.iconWrapperWidth || o.height],
items: [{ items: [
{
el: { el: {
type: "bi.label", type: Label.xtype,
ref: _ref => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
@ -50,14 +51,16 @@ export class TextIconNode extends NodeButton {
keyword: o.keyword, keyword: o.keyword,
height: o.height, height: o.height,
}, },
}, { },
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: o.iconCls, cls: o.iconCls,
width: o.iconWrapperWidth || o.height, width: o.iconWrapperWidth || o.height,
height: o.height, height: o.height,
iconWidth: o.iconWidth, iconWidth: o.iconWidth,
iconHeight: o.iconHeight, iconHeight: o.iconHeight,
}], }
],
}; };
} }

10
src/base/single/button/node/textnode.js

@ -1,5 +1,6 @@
import { Label } from "../../label";
import { NodeButton } from "../button.node"; import { NodeButton } from "../button.node";
import { extend, shortcut, createWidget } from "../../../../core"; import { extend, shortcut, createWidget } from "@/core";
/** /**
* guy * guy
@ -10,10 +11,9 @@ import { extend, shortcut, createWidget } from "../../../../core";
*/ */
@shortcut() @shortcut()
export class TextNode extends NodeButton { export class TextNode extends NodeButton {
static xtype = "bi.text_node" static xtype = "bi.text_node";
static EVENT_CHANGE = "EVENT_CHANGE"
static EVENT_CHANGE = "EVENT_CHANGE";
_defaultConfig() { _defaultConfig() {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
@ -32,7 +32,7 @@ export class TextNode extends NodeButton {
render() { render() {
const o = this.options; const o = this.options;
this.text = createWidget({ this.text = createWidget({
type: "bi.label", type: Label.xtype,
element: this, element: this,
textAlign: o.textAlign, textAlign: o.textAlign,
whiteSpace: o.whiteSpace, whiteSpace: o.whiteSpace,

55
src/base/single/editor/editor.js

@ -1,12 +1,25 @@
import { Input } from "../input";
import {
AbsoluteLayout,
shortcut,
Controller,
extend,
createWidget,
isKey,
isEmptyString,
isFunction,
isNull,
trim
} from "@/core";
import { Label } from "../label";
import { Single } from "../0.single";
import { Bubbles } from "@/base";
/** /**
* Created by GUY on 2015/4/15. * Created by GUY on 2015/4/15.
* @class BI.Editor * @class BI.Editor
* @extends BI.Single * @extends BI.Single
*/ */
import { shortcut, Controller, extend, createWidget, isKey, isEmptyString, isFunction, isNull, trim } from "../../../core";
import { Single } from "../0.single";
import { Input } from "../input/input";
import { Bubbles } from "../../0.base";
@shortcut() @shortcut()
export class Editor extends Single { export class Editor extends Single {
@ -57,11 +70,25 @@ export class Editor extends Single {
} }
render() { render() {
const { value, watermark, validationChecker, quitChecker, allowBlank, inputType, hgap, vgap, lgap, rgap, tgap, bgap } = this.options; const {
value,
watermark,
validationChecker,
quitChecker,
allowBlank,
inputType,
hgap,
vgap,
lgap,
rgap,
tgap,
bgap,
} = this.options;
// 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码 // 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码
const autocomplete = this.options.autocomplete ? ` autocomplete=${this.options.autocomplete}` : ""; const autocomplete = this.options.autocomplete ? ` autocomplete=${this.options.autocomplete}` : "";
this.editor = this.addWidget(createWidget({ this.editor = this.addWidget(
type: "bi.input", createWidget({
type: Input.xtype,
element: `<input type='${inputType}'${autocomplete} />`, element: `<input type='${inputType}'${autocomplete} />`,
root: true, root: true,
value, value,
@ -69,7 +96,8 @@ export class Editor extends Single {
validationChecker, validationChecker,
quitChecker, quitChecker,
allowBlank, allowBlank,
})); })
);
this.editor.element.css({ this.editor.element.css({
width: "100%", width: "100%",
height: "100%", height: "100%",
@ -82,7 +110,7 @@ export class Editor extends Single {
const items = [ const items = [
{ {
el: { el: {
type: "bi.absolute", type: AbsoluteLayout.xtype,
ref: _ref => { ref: _ref => {
this.contentWrapper = _ref; this.contentWrapper = _ref;
}, },
@ -104,7 +132,7 @@ export class Editor extends Single {
]; ];
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items, items,
}); });
@ -157,7 +185,8 @@ export class Editor extends Single {
this.editor.on(Input.EVENT_RESTRICT, (...args) => { this.editor.on(Input.EVENT_RESTRICT, (...args) => {
this._checkWaterMark(); this._checkWaterMark();
const tip = this._setErrorVisible(true); const tip = this._setErrorVisible(true);
tip && tip.element.fadeOut(100, () => { tip &&
tip.element.fadeOut(100, () => {
tip.element.fadeIn(100); tip.element.fadeIn(100);
}); });
this.fireEvent(Editor.EVENT_RESTRICT, ...args); this.fireEvent(Editor.EVENT_RESTRICT, ...args);
@ -224,7 +253,7 @@ export class Editor extends Single {
const { height, vgap, tgap } = this.options; const { height, vgap, tgap } = this.options;
if (isNull(this.watermark)) { if (isNull(this.watermark)) {
this.watermark = createWidget({ this.watermark = createWidget({
type: "bi.label", type: Label.xtype,
cls: "bi-water-mark", cls: "bi-water-mark",
text: this.options.watermark, text: this.options.watermark,
height: height - 2 * vgap - tgap, height: height - 2 * vgap - tgap,
@ -281,7 +310,7 @@ export class Editor extends Single {
if (isNull(this.watermark)) { if (isNull(this.watermark)) {
this._assertWaterMark(); this._assertWaterMark();
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this.contentWrapper, element: this.contentWrapper,
items: [ items: [
{ {

19
src/base/single/editor/editor.multifile.js

@ -1,3 +1,6 @@
import { File } from "../input";
import { AbsoluteLayout, AdaptiveLayout, shortcut, Widget, createWidget, extend } from "@/core";
/** /**
* 多文件 * 多文件
* *
@ -6,8 +9,6 @@
* @extends BI.Single * @extends BI.Single
* @abstract * @abstract
*/ */
import { shortcut, Widget, createWidget, extend } from "../../../core";
import { File } from "../input/file";
@shortcut() @shortcut()
export class MultifileEditor extends Widget { export class MultifileEditor extends Widget {
@ -23,7 +24,7 @@ export class MultifileEditor extends Widget {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-multifile-editor", baseCls: `${conf.baseCls || ""} bi-multifile-editor`,
multiple: false, multiple: false,
maxSize: -1, // 1024 * 1024 maxSize: -1, // 1024 * 1024
accept: "", accept: "",
@ -34,7 +35,7 @@ export class MultifileEditor extends Widget {
render() { render() {
const { name, url, multiple, accept, maxSize, maxLength, title, errorText } = this.options; const { name, url, multiple, accept, maxSize, maxLength, title, errorText } = this.options;
this.file = createWidget({ this.file = createWidget({
type: "bi.file", type: File.xtype,
cls: "multifile-editor", cls: "multifile-editor",
width: "100%", width: "100%",
height: "100%", height: "100%",
@ -64,11 +65,12 @@ export class MultifileEditor extends Widget {
}); });
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: { el: {
type: "bi.adaptive", type: AdaptiveLayout.xtype,
scrollable: false, scrollable: false,
items: [this.file], items: [this.file],
}, },
@ -76,7 +78,8 @@ export class MultifileEditor extends Widget {
right: 0, right: 0,
left: 0, left: 0,
bottom: 0, bottom: 0,
}], }
],
}); });
} }

83
src/base/single/editor/editor.textarea.js

@ -1,12 +1,29 @@
import {
Layout,
AbsoluteLayout,
AdaptiveLayout,
shortcut,
Widget,
Controller,
createWidget,
extend,
isEmptyString,
isKey,
isNotEmptyString,
isNotNull,
trim,
isFunction
} from "@/core";
import { Label } from "../label";
import { Single } from "../0.single";
import { Bubbles } from "@/base";
/** /**
* *
* Created by GUY on 2016/1/18. * Created by GUY on 2016/1/18.
* @class BI.TextAreaEditor * @class BI.TextAreaEditor
* @extends BI.Single * @extends BI.Single
*/ */
import { shortcut, Widget, Controller, createWidget, extend, isEmptyString, isKey, isNotEmptyString, isNotNull, trim, isFunction } from "../../../core";
import { Single } from "../0.single";
import { Bubbles } from "../../0.base";
@shortcut() @shortcut()
export class TextAreaEditor extends Single { export class TextAreaEditor extends Single {
@ -27,9 +44,7 @@ export class TextAreaEditor extends Single {
adjustYOffset: conf.simple ? 0 : 2, adjustYOffset: conf.simple ? 0 : 2,
adjustXOffset: 0, adjustXOffset: 0,
offsetStyle: "left", offsetStyle: "left",
validationChecker: () => { validationChecker: () => true,
return true;
},
scrolly: true, scrolly: true,
}); });
} }
@ -37,32 +52,36 @@ export class TextAreaEditor extends Single {
render() { render() {
const { scrolly, value, style } = this.options; const { scrolly, value, style } = this.options;
this.content = createWidget({ this.content = createWidget({
type: "bi.layout", type: Layout.xtype,
tagName: "textarea", tagName: "textarea",
width: "100%", width: "100%",
height: "100%", height: "100%",
cls: "bi-textarea textarea-editor-content display-block", cls: "bi-textarea textarea-editor-content display-block",
css: scrolly ? null : { css: scrolly
? null
: {
overflowY: "hidden", overflowY: "hidden",
}, },
}); });
this.content.element.css({ resize: "none" }); this.content.element.css({ resize: "none" });
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: { el: {
type: "bi.adaptive", type: AdaptiveLayout.xtype,
items: [this.content], items: [this.content],
}, },
left: 4, left: 4,
right: 4, right: 4,
top: 2, top: 2,
bottom: 2, bottom: 2,
}], }
],
}); });
this.content.element.on("input propertychange", (e) => { this.content.element.on("input propertychange", e => {
this._checkError(); this._checkError();
this._checkWaterMark(); this._checkWaterMark();
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this);
@ -76,9 +95,9 @@ export class TextAreaEditor extends Single {
this._checkError(); this._checkError();
this._focus(); this._focus();
this.fireEvent(TextAreaEditor.EVENT_FOCUS); this.fireEvent(TextAreaEditor.EVENT_FOCUS);
Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), (e) => { Widget._renderEngine.createElement(document).bind(`mousedown.${this.getName()}`, e => {
if (BI.DOM.isExist(this) && !this.element.__isMouseInBounds__(e)) { if (BI.DOM.isExist(this) && !this.element.__isMouseInBounds__(e)) {
Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()); Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`);
this.content.element.blur(); this.content.element.blur();
} }
}); });
@ -90,16 +109,16 @@ export class TextAreaEditor extends Single {
this.fireEvent(TextAreaEditor.EVENT_CONFIRM); this.fireEvent(TextAreaEditor.EVENT_CONFIRM);
} }
this.fireEvent(TextAreaEditor.EVENT_BLUR); this.fireEvent(TextAreaEditor.EVENT_BLUR);
Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()); Widget._renderEngine.createElement(document).unbind(`mousedown.${this.getName()}`);
}); });
this.content.element.keydown(() => { this.content.element.keydown(() => {
// 水印快速消失 // 水印快速消失
this._checkWaterMark(); this._checkWaterMark();
}); });
this.content.element.keyup((e) => { this.content.element.keyup(e => {
this.fireEvent(TextAreaEditor.EVENT_KEY_DOWN, e.keyCode); this.fireEvent(TextAreaEditor.EVENT_KEY_DOWN, e.keyCode);
}); });
this.content.element.click((e) => { this.content.element.click(e => {
e.stopPropagation(); e.stopPropagation();
}); });
if (isKey(value)) { if (isKey(value)) {
@ -121,7 +140,7 @@ export class TextAreaEditor extends Single {
if (isNotEmptyString(watermark)) { if (isNotEmptyString(watermark)) {
if (!this.watermark) { if (!this.watermark) {
this.watermark = createWidget({ this.watermark = createWidget({
type: "bi.label", type: Label.xtype,
cls: "bi-water-mark textarea-watermark", cls: "bi-water-mark textarea-watermark",
textAlign: "left", textAlign: "left",
whiteSpace: scrolly ? "normal" : "nowrap", whiteSpace: scrolly ? "normal" : "nowrap",
@ -133,7 +152,7 @@ export class TextAreaEditor extends Single {
height: height > 24 ? "" : height, height: height > 24 ? "" : height,
}); });
this.watermark.element.bind({ this.watermark.element.bind({
mousedown: (e) => { mousedown: e => {
if (this.isEnabled()) { if (this.isEnabled()) {
this.focus(); this.focus();
} else { } else {
@ -141,19 +160,21 @@ export class TextAreaEditor extends Single {
} }
e.stopEvent(); e.stopEvent();
}, },
click: (e) => { click: e => {
e.stopPropagation(); e.stopPropagation();
}, },
}); });
createWidget({ createWidget({
type: "bi.absolute", type: AbsoluteLayout.xtype,
element: this, element: this,
items: [{ items: [
{
el: this.watermark, el: this.watermark,
left: 0, left: 0,
top: 0, top: 0,
right: 0, right: 0,
}], }
],
}); });
} else { } else {
this.watermark.setText(watermark); this.watermark.setText(watermark);
@ -232,9 +253,17 @@ export class TextAreaEditor extends Single {
setStyle(style) { setStyle(style) {
this.style = style; this.style = style;
this.element.css(style); this.element.css(style);
this.content.element.css(extend({}, style, { this.content.element.css(
color: style.color || BI.DOM.getContrastColor(BI.DOM.isRGBColor(style.backgroundColor) ? BI.DOM.rgb2hex(style.backgroundColor) : style.backgroundColor), extend({}, style, {
})); color:
style.color ||
BI.DOM.getContrastColor(
BI.DOM.isRGBColor(style.backgroundColor)
? BI.DOM.rgb2hex(style.backgroundColor)
: style.backgroundColor
),
})
);
} }
getStyle() { getStyle() {

29
src/base/single/html/html.js

@ -1,10 +1,11 @@
import { Layout, DefaultLayout, shortcut, isNumber, createWidget, isWidthOrHeight, isKey } from "@/core";
import { Single } from "../0.single";
/** /**
* guy 表示一行数据通过position来定位位置的数据 * guy 表示一行数据通过position来定位位置的数据
* @class BI.Html * @class BI.Html
* @extends BI.Single * @extends BI.Single
*/ */
import { shortcut, isNumber, createWidget, isWidthOrHeight, isKey } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class Html extends Single { export class Html extends Single {
@ -24,10 +25,26 @@ export class Html extends Single {
bgap: 0, bgap: 0,
text: "", text: "",
highLight: false, highLight: false,
} };
render() { render() {
const { vgap, hgap, lgap, rgap, tgap, bgap, height, lineHeight, maxWidth, textAlign, whiteSpace, handler, text, value, highLight } = this.options; const {
vgap,
hgap,
lgap,
rgap,
tgap,
bgap,
height,
lineHeight,
maxWidth,
textAlign,
whiteSpace,
handler,
text,
value,
highLight,
} = this.options;
if (hgap + lgap > 0) { if (hgap + lgap > 0) {
this.element.css({ this.element.css({
"padding-left": BI.pixFormat(hgap + lgap), "padding-left": BI.pixFormat(hgap + lgap),
@ -68,14 +85,14 @@ export class Html extends Single {
}); });
if (handler) { if (handler) {
this.text = createWidget({ this.text = createWidget({
type: "bi.layout", type: Layout.xtype,
tagName: "span", tagName: "span",
}); });
this.text.element.click(() => { this.text.element.click(() => {
handler(this.getValue()); handler(this.getValue());
}); });
createWidget({ createWidget({
type: "bi.default", type: DefaultLayout.xtype,
element: this, element: this,
items: [this.text], items: [this.text],
}); });

7
src/base/single/icon/icon.js

@ -1,10 +1,11 @@
import { Single } from "../0.single";
import { shortcut, extend } from "@/core";
/** /**
* guy 图标 * guy 图标
* @class BI.Icon * @class BI.Icon
* @extends BI.Single * @extends BI.Single
*/ */
import { shortcut, extend } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class Icon extends Single { export class Icon extends Single {
@ -15,7 +16,7 @@ export class Icon extends Single {
return extend(conf, { return extend(conf, {
tagName: "i", tagName: "i",
baseCls: (conf.baseCls || "") + " x-icon b-font horizon-center display-block", baseCls: `${conf.baseCls || ""} x-icon b-font horizon-center display-block`,
}); });
} }

17
src/base/single/iframe/iframe.js

@ -1,11 +1,12 @@
import { Single } from "../0.single";
import { shortcut, extend } from "@/core";
/** /**
* @class Iframe * @class Iframe
* @extends Single * @extends Single
* @abstract * @abstract
* Created by GameJian on 2016/3/2. * Created by GameJian on 2016/3/2.
*/ */
import { shortcut, extend } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class Iframe extends Single { export class Iframe extends Single {
@ -13,9 +14,10 @@ export class Iframe extends Single {
_defaultConfig(config) { _defaultConfig(config) {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
tagName: "iframe", tagName: "iframe",
baseCls: (conf.baseCls || "") + " bi-iframe", baseCls: `${conf.baseCls || ""} bi-iframe`,
src: "", src: "",
name: "", name: "",
attributes: {}, attributes: {},
@ -31,13 +33,16 @@ export class Iframe extends Single {
} }
_initProps() { _initProps() {
super._initProps(...arguments) super._initProps(...arguments);
const { src, name } = this.options; const { src, name } = this.options;
this.options.attributes = extend({ this.options.attributes = extend(
{
frameborder: 0, frameborder: 0,
src, src,
name, name,
}, this.options.attributes); },
this.options.attributes
);
} }
setSrc(src) { setSrc(src) {

16
src/base/single/img/img.js

@ -1,3 +1,6 @@
import { Single } from "../0.single";
import { shortcut, extend } from "@/core";
/** /**
* ͼƬ * ͼƬ
* *
@ -6,8 +9,6 @@
* @extends BI.Single * @extends BI.Single
* @abstract * @abstract
*/ */
import { shortcut, extend } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class Img extends Single { export class Img extends Single {
@ -18,7 +19,7 @@ export class Img extends Single {
return extend(conf, { return extend(conf, {
tagName: "img", tagName: "img",
baseCls: (conf.baseCls || "") + " bi-img display-block", baseCls: `${conf.baseCls || ""} bi-img display-block`,
src: "", src: "",
attributes: config.src ? { src: config.src } : {}, attributes: config.src ? { src: config.src } : {},
width: "100%", width: "100%",
@ -27,11 +28,14 @@ export class Img extends Single {
} }
_initProps() { _initProps() {
super._initProps(...arguments) super._initProps(...arguments);
const { src } = this.options; const { src } = this.options;
this.options.attributes = extend({ this.options.attributes = extend(
{
src, src,
}, this.options.attributes); },
this.options.attributes
);
} }
setSrc(src) { setSrc(src) {

7
src/base/single/input/checkbox/checkbox.image.js

@ -1,10 +1,11 @@
import { IconButton } from "../../button";
import { shortcut, extend } from "@/core";
/** /**
* guy * guy
* @extends Single * @extends Single
* @type {*|void|Object} * @type {*|void|Object}
*/ */
import { shortcut, extend } from "../../../../core";
import { IconButton } from "../../button";
@shortcut() @shortcut()
export class ImageCheckbox extends IconButton { export class ImageCheckbox extends IconButton {
@ -16,7 +17,7 @@ export class ImageCheckbox extends IconButton {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-image-checkbox check-box-icon", baseCls: `${conf.baseCls || ""} bi-image-checkbox check-box-icon`,
selected: false, selected: false,
handler: BI.emptyFn, handler: BI.emptyFn,
width: 16, width: 16,

19
src/base/single/input/checkbox/checkbox.js

@ -1,10 +1,11 @@
import { CenterAdaptLayout, DefaultLayout, shortcut } from "@/core";
import { BasicButton } from "../../button";
/** /**
* guy * guy
* @extends Single * @extends Single
* @type {*|void|Object} * @type {*|void|Object}
*/ */
import { shortcut } from "../../../../core";
import { BasicButton } from "../../button";
@shortcut() @shortcut()
export class Checkbox extends BasicButton { export class Checkbox extends BasicButton {
@ -20,22 +21,24 @@ export class Checkbox extends BasicButton {
height: 14, height: 14,
iconWidth: 14, iconWidth: 14,
iconHeight: 14, iconHeight: 14,
} };
render() { render() {
const { iconWidth, iconHeight } = this.options; const { iconWidth, iconHeight } = this.options;
return { return {
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
items: [{ items: [
type: "bi.default", {
ref: (_ref) => { type: DefaultLayout.xtype,
ref: _ref => {
this.checkbox = _ref; this.checkbox = _ref;
}, },
cls: "checkbox-content", cls: "checkbox-content",
width: iconWidth, width: iconWidth,
height: iconHeight, height: iconHeight,
}], }
],
}; };
} }

171
src/base/single/input/file.js

@ -1,3 +1,6 @@
import { Msg } from "../../foundation/message";
import { shortcut, Widget, some, extend } from "@/core";
/** /**
* 文件 * 文件
* *
@ -6,27 +9,22 @@
* @extends BI.Single * @extends BI.Single
* @abstract * @abstract
*/ */
import { shortcut, Widget, some, extend } from "../../../core";
import { Msg } from "../../foundation/message";
const document = _global.document || {}; const document = _global.document || {};
/** /**
* @description normalize input.files. create if not present, add item method if not present * @description normalize input.files. create if not present, add item method if not present
* @param Object generated wrap object * @param Object generated wrap object
* @return Object the wrap object itself * @return Object the wrap object itself
*/ */
const F = (((item) => { const F = (item => input => {
return (input) => {
const files = input.files || [input]; const files = input.files || [input];
if (!files.item) { if (!files.item) {
files.item = item; files.item = item;
} }
return files; return files;
}; })(i => this[i]);
})((i) => {
return this[i];
}));
const event = { const event = {
@ -37,14 +35,14 @@ const event = {
* @param Function the callback to associate as event * @param Function the callback to associate as event
* @return Object noswfupload.event * @return Object noswfupload.event
*/ */
add: document.addEventListener ? add: document.addEventListener
(node, name, callback) => { ? (node, name, callback) => {
node.addEventListener(name, callback, false); node.addEventListener(name, callback, false);
return this; return this;
} : }
(node, name, callback) => { : (node, name, callback) => {
node.attachEvent("on" + name, callback); node.attachEvent(`on${name}`, callback);
return this; return this;
}, },
@ -56,14 +54,14 @@ const event = {
* @param Function the callback associated as event * @param Function the callback associated as event
* @return Object noswfupload.event * @return Object noswfupload.event
*/ */
del: document.removeEventListener ? del: document.removeEventListener
(node, name, callback) => { ? (node, name, callback) => {
node.removeEventListener(name, callback, false); node.removeEventListener(name, callback, false);
return this; return this;
} : }
(node, name, callback) => { : (node, name, callback) => {
node.detachEvent("on" + name, callback); node.detachEvent(`on${name}`, callback);
return this; return this;
}, },
@ -79,34 +77,41 @@ const event = {
event.returnValue = !(event.cancelBubble = true); event.returnValue = !(event.cancelBubble = true);
} }
} else { } else {
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
e.preventDefault ? e.preventDefault() : e.returnValue = false; e.preventDefault ? e.preventDefault() : (e.returnValue = false);
} }
return false; return false;
}, },
}; };
const sendFile = (((toString) => { const sendFile = (toString => {
const split = "onabort.onerror.onloadstart.onprogress".split("."), const split = "onabort.onerror.onloadstart.onprogress".split("."),
length = split.length, length = split.length,
CRLF = "\r\n"; CRLF = "\r\n";
let xhr = new XMLHttpRequest, let xhr = new XMLHttpRequest(),
sendFile; sendFile;
const multipart = (boundary, name, file) => { const multipart = (boundary, name, file) =>
return "--".concat( "--".concat(
boundary, CRLF, boundary,
"Content-Disposition: form-data; name=\"", name, "\"; filename=\"", _global.encodeURIComponent(file.fileName), "\"", CRLF, CRLF,
"Content-Type: application/octet-stream", CRLF, "Content-Disposition: form-data; name=\"",
name,
"\"; filename=\"",
_global.encodeURIComponent(file.fileName),
"\"",
CRLF, CRLF,
file.getAsBinary(), CRLF, "Content-Type: application/octet-stream",
"--", boundary, "--", CRLF CRLF,
CRLF,
file.getAsBinary(),
CRLF,
"--",
boundary,
"--",
CRLF
); );
} const isFunction = Function => toString.call(Function) === "[object Function]";
const isFunction = (Function) => {
return toString.call(Function) === "[object Function]";
}
// FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work) // FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work)
if (xhr.upload || xhr.sendAsBinary) { if (xhr.upload || xhr.sendAsBinary) {
@ -119,29 +124,27 @@ const sendFile = (((toString) => {
return; return;
} }
const xhr = new XMLHttpRequest, const xhr = new XMLHttpRequest(),
upload = xhr.upload || { upload = xhr.upload || {
addEventListener(event, callback) { addEventListener(event, callback) {
this["on" + event] = callback; this[`on${event}`] = callback;
}, },
}; };
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
upload.addEventListener( upload.addEventListener(
split[i].substring(2), split[i].substring(2),
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
(((event) => { (event => rpe => {
return (rpe) => {
if (isFunction(handler[event])) { if (isFunction(handler[event])) {
handler[event](rpe, xhr); handler[event](rpe, xhr);
} }
}; })(split[i]),
})(split[i])),
false false
); );
} }
upload.addEventListener( upload.addEventListener(
"load", "load",
(rpe) => { rpe => {
if (handler.onreadystatechange === false) { if (handler.onreadystatechange === false) {
if (isFunction(handler.onload)) { if (isFunction(handler.onload)) {
handler.onload(rpe, xhr); handler.onload(rpe, xhr);
@ -155,15 +158,19 @@ const sendFile = (((toString) => {
} else { } else {
setTimeout(callback, 15); setTimeout(callback, 15);
} }
} };
setTimeout(callback, 15); setTimeout(callback, 15);
} }
}, },
false false
); );
xhr.open("post", BI.appendQuery(handler.url, { xhr.open(
"post",
BI.appendQuery(handler.url, {
filename: _global.encodeURIComponent(handler.file.fileName), filename: _global.encodeURIComponent(handler.file.fileName),
}), true); }),
true
);
if (!xhr.upload) { if (!xhr.upload) {
const rpe = { loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true }; const rpe = { loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true };
rpe.interval = setInterval(() => { rpe.interval = setInterval(() => {
@ -234,8 +241,8 @@ const sendFile = (((toString) => {
upload.onloadstart(); upload.onloadstart();
} }
} }
const boundary = "AjaxUploadBoundary" + (new Date).getTime(); const boundary = `AjaxUploadBoundary${new Date().getTime()}`;
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); xhr.setRequestHeader("Content-Type", `multipart/form-data; boundary=${boundary}`);
if (handler.file.getAsBinary) { if (handler.file.getAsBinary) {
xhr[xhr.sendAsBinary ? "sendAsBinary" : "send"](multipart(boundary, handler.name, handler.file)); xhr[xhr.sendAsBinary ? "sendAsBinary" : "send"](multipart(boundary, handler.name, handler.file));
} else { } else {
@ -256,7 +263,10 @@ const sendFile = (((toString) => {
let iframe, form; let iframe, form;
const url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"), const url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"),
rpe = { rpe = {
loaded: 1, total: 100, simulation: true, interval: setInterval(() => { loaded: 1,
total: 100,
simulation: true,
interval: setInterval(() => {
if (rpe.loaded < rpe.total) { if (rpe.loaded < rpe.total) {
++rpe.loaded; ++rpe.loaded;
} }
@ -265,14 +275,15 @@ const sendFile = (((toString) => {
} }
}, 100), }, 100),
}, },
target = ["AjaxUpload", (new Date).getTime(), String(Math.random()).substring(2)].join("_"); target = ["AjaxUpload", new Date().getTime(), String(Math.random()).substring(2)].join("_");
const onload = () => { const onload = () => {
iframe.onreadystatechange = iframe.onload = iframe.onerror = null; iframe.onreadystatechange = iframe.onload = iframe.onerror = null;
form.parentNode.removeChild(form); form.parentNode.removeChild(form);
form = null; form = null;
clearInterval(rpe.interval); clearInterval(rpe.interval);
// rpe.loaded = rpe.total; // rpe.loaded = rpe.total;
const responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; const responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body
.innerHTML;
try { try {
const attachO = BI.jsonDecode(responseText); const attachO = BI.jsonDecode(responseText);
if (handler.file.type.indexOf("image") !== -1) { if (handler.file.type.indexOf("image") !== -1) {
@ -297,24 +308,29 @@ const sendFile = (((toString) => {
} }
} }
if (isFunction(handler.onload)) { if (isFunction(handler.onload)) {
handler.onload(rpe, { responseText: responseText }); handler.onload(rpe, { responseText });
}
} }
};
try { // IE < 8 does not accept enctype attribute ... try {
// IE < 8 does not accept enctype attribute ...
const form = document.createElement("<form enctype=\"multipart/form-data\"></form>"), const form = document.createElement("<form enctype=\"multipart/form-data\"></form>"),
iframe = handler.iframe || (handler.iframe = document.createElement("<iframe id=\"" + target + "\" name=\"" + target + "\" src=\"" + url + "\"></iframe>")); iframe =
handler.iframe ||
(handler.iframe = document.createElement(
`<iframe id="${target}" name="${target}" src="${url}"></iframe>`
));
} catch (e) { } catch (e) {
const form = document.createElement("form"), const form = document.createElement("form"),
iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); iframe = handler.iframe || (handler.iframe = document.createElement("iframe"));
form.setAttribute("enctype", "multipart/form-data"); form.setAttribute("enctype", "multipart/form-data");
iframe.setAttribute("name", iframe.id = target); iframe.setAttribute("name", (iframe.id = target));
iframe.setAttribute("src", url); iframe.setAttribute("src", url);
} }
iframe.style.position = "absolute"; iframe.style.position = "absolute";
iframe.style.left = iframe.style.top = "-10000px"; iframe.style.left = iframe.style.top = "-10000px";
iframe.onload = onload; iframe.onload = onload;
iframe.onerror = (event) => { iframe.onerror = event => {
if (isFunction(handler.onerror)) { if (isFunction(handler.onerror)) {
handler.onerror(rpe, event || _global.event); handler.onerror(rpe, event || _global.event);
} }
@ -329,7 +345,8 @@ const sendFile = (((toString) => {
++rpe.loaded; ++rpe.loaded;
} }
handler.onloadprogress(rpe, { handler.onloadprogress(rpe, {
readyState: { readyState:
{
loading: 2, loading: 2,
interactive: 3, interactive: 3,
loaded: 4, loaded: 4,
@ -338,7 +355,7 @@ const sendFile = (((toString) => {
}); });
} }
}; };
form.setAttribute("action", handler.url + "&filename=" + _global.encodeURIComponent(handler.file.fileName)); form.setAttribute("action", `${handler.url}&filename=${_global.encodeURIComponent(handler.file.fileName)}`);
form.setAttribute("target", iframe.id); form.setAttribute("target", iframe.id);
form.setAttribute("method", "post"); form.setAttribute("method", "post");
form.appendChild(handler.file); form.appendChild(handler.file);
@ -357,7 +374,7 @@ const sendFile = (((toString) => {
xhr = null; xhr = null;
return sendFile; return sendFile;
})(Object.prototype.toString)); })(Object.prototype.toString);
const sendFiles = (handler, maxSize, width, height) => { const sendFiles = (handler, maxSize, width, height) => {
const length = handler.files.length, const length = handler.files.length,
@ -367,7 +384,7 @@ const sendFiles = (handler, maxSize, width, height) => {
handler.total = 0; handler.total = 0;
handler.sent = 0; handler.sent = 0;
while (handler.current < length) { while (handler.current < length) {
handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); handler.total += handler.files[handler.current].fileSize || handler.files[handler.current].size;
handler.current++; handler.current++;
} }
handler.current = 0; handler.current = 0;
@ -375,7 +392,7 @@ const sendFiles = (handler, maxSize, width, height) => {
handler.file = handler.files[handler.current]; handler.file = handler.files[handler.current];
const callback = (rpe, xhr) => { const callback = (rpe, xhr) => {
handler.onloadstart = null; handler.onloadstart = null;
handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); handler.sent += handler.files[handler.current].fileSize || handler.files[handler.current].size;
if (++handler.current < length) { if (++handler.current < length) {
handler.file = handler.files[handler.current]; handler.file = handler.files[handler.current];
sendFile(handler, maxSize, width, height).onload = callback; sendFile(handler, maxSize, width, height).onload = callback;
@ -415,7 +432,7 @@ const sendFiles = (handler, maxSize, width, height) => {
} }
return handler; return handler;
} };
const r1 = /\.([^.]+)$/; // .png const r1 = /\.([^.]+)$/; // .png
const r2 = /\/([^/]+)$/; // image/png const r2 = /\/([^/]+)$/; // image/png
@ -432,7 +449,7 @@ const fileTypeValidate = (fileName, fileType) => {
} }
const mimes = fileType.split(","); const mimes = fileType.split(",");
if (mimes[0] === fileType) { if (mimes[0] === fileType) {
mimes = (fileType + "").split(";"); mimes = `${fileType}`.split(";");
} }
return some(mimes, (index, mime) => { return some(mimes, (index, mime) => {
@ -446,7 +463,7 @@ const fileTypeValidate = (fileName, fileType) => {
return matches[1] === "*" ? true : fileName.toLowerCase().indexOf(matches[1]) > -1; return matches[1] === "*" ? true : fileName.toLowerCase().indexOf(matches[1]) > -1;
} }
}); });
} };
@shortcut() @shortcut()
export class File extends Widget { export class File extends Widget {
@ -462,7 +479,7 @@ export class File extends Widget {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-file display-block", baseCls: `${conf.baseCls || ""} bi-file display-block`,
tagName: "input", tagName: "input",
attributes: { attributes: {
type: "file", type: "file",
@ -492,7 +509,7 @@ export class File extends Widget {
// create the noswfupload.wrap Object // create the noswfupload.wrap Object
// wrap.maxSize 文件大小限制 // wrap.maxSize 文件大小限制
// wrap.maxLength 文件个数限制 // wrap.maxLength 文件个数限制
const _wrap = this.wrap = this._wrap(this.element[0], maxSize); const _wrap = (this.wrap = this._wrap(this.element[0], maxSize));
// fileType could contain whatever text but filter checks *.{extension} // fileType could contain whatever text but filter checks *.{extension}
// if present // if present
@ -586,20 +603,26 @@ export class File extends Widget {
const validateFileType = fileTypeValidate(value, wrap.fileType); const validateFileType = fileTypeValidate(value, wrap.fileType);
if (!validateFileType) { if (!validateFileType) {
// 文件类型不支持 // 文件类型不支持
Msg.toast(errorText({ Msg.toast(
errorText({
errorType: 0, errorType: 0,
file: item, file: item,
}) || BI.i18nText("BI-Upload_File_Type_Error", wrap.fileType), { level: "error" }); }) || BI.i18nText("BI-Upload_File_Type_Error", wrap.fileType),
{ level: "error" }
);
this.fireEvent(File.EVENT_ERROR, { this.fireEvent(File.EVENT_ERROR, {
errorType: 0, errorType: 0,
file: item, file: item,
}); });
} else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) {
// 文件大小不支持 // 文件大小不支持
Msg.toast(errorText({ Msg.toast(
errorText({
errorType: 1, errorType: 1,
file: item, file: item,
}) || BI.i18nText("BI-Upload_File_Size_Error", Math.ceil(wrap.maxSize / 1024 / 1024)), { level: "error" }); }) || BI.i18nText("BI-Upload_File_Size_Error", Math.ceil(wrap.maxSize / 1024 / 1024)),
{ level: "error" }
);
this.fireEvent(File.EVENT_ERROR, { this.fireEvent(File.EVENT_ERROR, {
errorType: 1, errorType: 1,
file: item, file: item,
@ -609,14 +632,15 @@ export class File extends Widget {
} }
} }
} }
wrap.files.length > 0 && this.fireEvent(File.EVENT_CHANGE, { wrap.files.length > 0 &&
this.fireEvent(File.EVENT_CHANGE, {
files: wrap.files, files: wrap.files,
}); });
input.value = ""; input.value = "";
wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input);
wrap.dom.input = input; wrap.dom.input = input;
event.add(wrap.dom.input, "change", callback); event.add(wrap.dom.input, "change", callback);
} };
event.add(wrap.dom.input, "change", callback); event.add(wrap.dom.input, "change", callback);
return wrap; return wrap;
@ -633,10 +657,9 @@ export class File extends Widget {
// wrap Object // wrap Object
return this._events({ return this._events({
// DOM namespace // DOM namespace
dom: { dom: {
input: input, // input file input, // input file
disabled: false, // internal use, checks input file state disabled: false, // internal use, checks input file state
}, },
name: input.name, // name to send for each file ($_FILES[{name}] in the server) name: input.name, // name to send for each file ($_FILES[{name}] in the server)
@ -655,7 +678,7 @@ export class File extends Widget {
// something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...}
upload(handler) { upload(handler) {
if (handler) { if (handler) {
for (let key in handler) { for (const key in handler) {
this[key] = handler[key]; this[key] = handler[key];
} }
} }

69
src/base/single/input/input.js

@ -1,11 +1,26 @@
import { Single } from "../0.single";
import {
shortcut,
Controller,
extend,
debounce,
bind,
isNull,
isEmptyString,
isKey,
delay,
trim,
isEqual,
nextTick,
isEndWithBlank
} from "@/core";
/** /**
* guy * guy
* @class BI.Input 一个button和一行数 组成的一行listitem * @class BI.Input 一个button和一行数 组成的一行listitem
* @extends BI.Single * @extends BI.Single
* @type {*|void|Object} * @type {*|void|Object}
*/ */
import { shortcut, Controller, extend, debounce, bind, isNull, isEmptyString, isKey, delay, trim, isEqual, nextTick, isEndWithBlank } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class Input extends Single { export class Input extends Single {
@ -37,7 +52,7 @@ export class Input extends Single {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-input display-block overflow-dot", baseCls: `${conf.baseCls || ""} bi-input display-block overflow-dot`,
tagName: "input", tagName: "input",
validationChecker: BI.emptyFn, validationChecker: BI.emptyFn,
quitChecker: BI.emptyFn, // 按确定键能否退出编辑 quitChecker: BI.emptyFn, // 按确定键能否退出编辑
@ -49,37 +64,37 @@ export class Input extends Single {
let ctrlKey = false; let ctrlKey = false;
let keyCode = null; let keyCode = null;
let inputEventValid = false; let inputEventValid = false;
const _keydown = debounce((keyCode) => { const _keydown = debounce(keyCode => {
this.onKeyDown(keyCode, ctrlKey); this.onKeyDown(keyCode, ctrlKey);
this._keydown_ = false; this._keydown_ = false;
}, BI.EVENT_RESPONSE_TIME); }, BI.EVENT_RESPONSE_TIME);
const _clk = debounce(bind(this._click, this), BI.EVENT_RESPONSE_TIME, { const _clk = debounce(bind(this._click, this), BI.EVENT_RESPONSE_TIME, {
"leading": true, leading: true,
"trailing": false, trailing: false,
}); });
this._focusDebounce = debounce(bind(this._focus, this), BI.EVENT_RESPONSE_TIME, { this._focusDebounce = debounce(bind(this._focus, this), BI.EVENT_RESPONSE_TIME, {
"leading": true, leading: true,
"trailing": false, trailing: false,
}); });
this._blurDebounce = debounce(bind(this._blur, this), BI.EVENT_RESPONSE_TIME, { this._blurDebounce = debounce(bind(this._blur, this), BI.EVENT_RESPONSE_TIME, {
"leading": true, leading: true,
"trailing": false, trailing: false,
}); });
this.element this.element
.keydown((e) => { .keydown(e => {
inputEventValid = false; inputEventValid = false;
ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下 ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下
keyCode = e.keyCode; keyCode = e.keyCode;
this.fireEvent(Input.EVENT_QUICK_DOWN, e); this.fireEvent(Input.EVENT_QUICK_DOWN, e);
}) })
.keyup((e) => { .keyup(e => {
keyCode = null; keyCode = null;
if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) {
this._keydown_ = true; this._keydown_ = true;
_keydown(e.keyCode); _keydown(e.keyCode);
} }
}) })
.on("input propertychange", (e) => { .on("input propertychange", e => {
// 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了 // 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了
// 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8 // 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8
// 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓) // 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓)
@ -91,17 +106,18 @@ export class Input extends Single {
keyCode = null; keyCode = null;
} }
}) })
.click((e) => { .click(e => {
e.stopPropagation(); e.stopPropagation();
_clk(); _clk();
}) })
.mousedown((e) => { .mousedown(e => {
this.element.val(this.element.val()); this.element.val(this.element.val());
}) })
.focus((e) => { // 可以不用冒泡 .focus(e => {
// 可以不用冒泡
this._focusDebounce(); this._focusDebounce();
}) })
.blur((e) => { .blur(e => {
// DEC-14919 IE11在浏览器重新获得焦点之后会先触发focusout再触发focus,要保持先获得焦点再失去焦点的顺序不变,因此采用blur // DEC-14919 IE11在浏览器重新获得焦点之后会先触发focusout再触发focus,要保持先获得焦点再失去焦点的顺序不变,因此采用blur
this._blurDebounce(); this._blurDebounce();
}); });
@ -141,7 +157,7 @@ export class Input extends Single {
} }
} }
this.fireEvent(Input.EVENT_BLUR); this.fireEvent(Input.EVENT_BLUR);
} };
if (this._keydown_ === true) { if (this._keydown_ === true) {
delay(blur, BI.EVENT_RESPONSE_TIME); delay(blur, BI.EVENT_RESPONSE_TIME);
@ -166,8 +182,11 @@ export class Input extends Single {
this._checkValidationOnValueChange(); this._checkValidationOnValueChange();
} }
if (this.isValid() && trim(this.getValue()) !== "") { if (this.isValid() && trim(this.getValue()) !== "") {
if (trim(this.getValue()) !== this._lastValue && (!this._start || isNull(this._lastValue) || this._lastValue === "") if (
|| (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { (trim(this.getValue()) !== this._lastValue &&
(!this._start || isNull(this._lastValue) || this._lastValue === "")) ||
(this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))
) {
this._start = true; this._start = true;
this._pause = false; this._pause = false;
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this);
@ -203,8 +222,12 @@ export class Input extends Single {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this);
this.fireEvent(Input.EVENT_PAUSE); this.fireEvent(Input.EVENT_PAUSE);
this._defaultState(); this._defaultState();
} else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && } else if (
trim(this.getValue()) === "" && (lastValue !== null && trim(lastValue) !== "")) { (keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) &&
trim(this.getValue()) === "" &&
lastValue !== null &&
trim(lastValue) !== ""
) {
this.fireEvent(Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); this.fireEvent(Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this);
this.fireEvent(Input.EVENT_STOP); this.fireEvent(Input.EVENT_STOP);
} }
@ -250,7 +273,7 @@ export class Input extends Single {
} }
const checker = validationChecker.apply(this, [trim(v)]); const checker = validationChecker.apply(this, [trim(v)]);
if (checker instanceof Promise) { if (checker instanceof Promise) {
checker.then((validate) => { checker.then(validate => {
this.setValid(validate !== false); this.setValid(validate !== false);
callback && callback(); callback && callback();
}); });

7
src/base/single/input/radio/radio.image.js

@ -1,10 +1,11 @@
import { IconButton } from "../../button";
import { shortcut, extend } from "@/core";
/** /**
* guy * guy
* @extends Single * @extends Single
* @type {*|void|Object} * @type {*|void|Object}
*/ */
import { shortcut, extend } from "../../../../core";
import { IconButton } from "../../button";
@shortcut() @shortcut()
export class ImageRadio extends IconButton { export class ImageRadio extends IconButton {
@ -16,7 +17,7 @@ export class ImageRadio extends IconButton {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-radio radio-icon", baseCls: `${conf.baseCls || ""} bi-radio radio-icon`,
selected: false, selected: false,
handler: BI.emptyFn, handler: BI.emptyFn,
width: 16, width: 16,

21
src/base/single/input/radio/radio.js

@ -1,10 +1,11 @@
import { CenterAdaptLayout, Layout, shortcut } from "@/core";
import { BasicButton } from "../../button";
/** /**
* guy * guy
* @extends Single * @extends Single
* @type {*|void|Object} * @type {*|void|Object}
*/ */
import { shortcut } from "../../../../core";
import { BasicButton } from "../../button";
@shortcut() @shortcut()
export class Radio extends BasicButton { export class Radio extends BasicButton {
@ -18,23 +19,25 @@ export class Radio extends BasicButton {
width: 16, width: 16,
height: 16, height: 16,
iconWidth: 16, iconWidth: 16,
iconHeight: 16 iconHeight: 16,
} };
render() { render() {
const { iconWidth, iconHeight } = this.options; const { iconWidth, iconHeight } = this.options;
return { return {
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
items: [{ items: [
type: "bi.layout", {
type: Layout.xtype,
cls: "radio-content", cls: "radio-content",
ref: (_ref) => { ref: _ref => {
this.radio = _ref; this.radio = _ref;
}, },
width: iconWidth, width: iconWidth,
height: iconHeight, height: iconHeight,
}], }
],
}; };
} }

16
src/base/single/instruction/instruction.js

@ -1,4 +1,5 @@
import { shortcut, Widget, extend } from "../../../core"; import { Label } from "../label";
import { shortcut, Widget, extend } from "@/core";
@shortcut() @shortcut()
export class Instruction extends Widget { export class Instruction extends Widget {
@ -6,13 +7,14 @@ export class Instruction extends Widget {
_defaultConfig() { _defaultConfig() {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-instruction", baseCls: `${conf.baseCls || ""} bi-instruction`,
height: 20, height: 20,
level: "error", level: "error",
textAlign: "left", textAlign: "left",
whiteSpace: "nowrap", whiteSpace: "nowrap",
hgap: 5 hgap: 5,
}); });
} }
@ -20,11 +22,11 @@ export class Instruction extends Widget {
const { level, textAlign, whiteSpace, height, hgap, rgap, lgap, vgap, text, keyword, value, py } = this.options; const { level, textAlign, whiteSpace, height, hgap, rgap, lgap, vgap, text, keyword, value, py } = this.options;
return { return {
type: "bi.label", type: Label.xtype,
ref: (_ref) => { ref: _ref => {
this.text = _ref; this.text = _ref;
}, },
cls: "instruction-" + level, cls: `instruction-${level}`,
textAlign, textAlign,
whiteSpace, whiteSpace,
textHeight: height, textHeight: height,
@ -36,7 +38,7 @@ export class Instruction extends Widget {
text, text,
keyword, keyword,
value, value,
py py,
}; };
} }

109
src/base/single/label/abstract.label.js

@ -1,11 +1,12 @@
import { Text } from "../1.text";
import { CenterAdaptLayout, isNumber, createWidget, extend } from "@/core";
import { Single } from "../0.single";
/** /**
* Created by dailer on 2019/6/19. * Created by dailer on 2019/6/19.
*/ */
import { isNumber, createWidget, extend } from "../../../core";
import { Single } from "../0.single";
export class AbstractLabel extends Single { export class AbstractLabel extends Single {
_defaultConfig(props) { _defaultConfig(props) {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
@ -30,7 +31,7 @@ export class AbstractLabel extends Single {
const { textAlign, whiteSpace, textHeight, text, value, py, keyword, highLight, handler } = this.options; const { textAlign, whiteSpace, textHeight, text, value, py, keyword, highLight, handler } = this.options;
return { return {
type: "bi.text", type: Text.xtype,
textAlign, textAlign,
whiteSpace, whiteSpace,
lineHeight: textHeight, lineHeight: textHeight,
@ -59,9 +60,10 @@ export class AbstractLabel extends Single {
if (isNumber(width) && width > 0) { if (isNumber(width) && width > 0) {
if (isNumber(textWidth) && textWidth > 0) { if (isNumber(textWidth) && textWidth > 0) {
json.maxWidth = textWidth; json.maxWidth = textWidth;
if (isNumber(height) && height > 0) { // 1.1 if (isNumber(height) && height > 0) {
// 1.1
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
height, height,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: whiteSpace === "normal", scrollable: whiteSpace === "normal",
@ -75,8 +77,9 @@ export class AbstractLabel extends Single {
return; return;
} }
createWidget({ // 1.2 createWidget({
type: "bi.center_adapt", // 1.2
type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: whiteSpace === "normal", scrollable: whiteSpace === "normal",
element: this, element: this,
@ -89,7 +92,8 @@ export class AbstractLabel extends Single {
return; return;
} }
if (whiteSpace === "normal") { // 1.3 if (whiteSpace === "normal") {
// 1.3
extend(json, { extend(json, {
hgap, hgap,
vgap, vgap,
@ -100,7 +104,7 @@ export class AbstractLabel extends Single {
}); });
this.text = createWidget(json); this.text = createWidget(json);
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: whiteSpace === "normal", scrollable: whiteSpace === "normal",
element: this, element: this,
@ -109,13 +113,15 @@ export class AbstractLabel extends Single {
return; return;
} }
if (isNumber(height) && height > 0) { // 1.4 if (isNumber(height) && height > 0) {
// 1.4
this.element.css({ this.element.css({
"line-height": BI.pixFormat(height), "line-height": BI.pixFormat(height),
}); });
json.textAlign = textAlign; json.textAlign = textAlign;
delete json.maxWidth; delete json.maxWidth;
this.text = createWidget(extend(json, { this.text = createWidget(
extend(json, {
element: this, element: this,
hgap, hgap,
vgap, vgap,
@ -123,11 +129,13 @@ export class AbstractLabel extends Single {
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
return; return;
} }
extend(json, { // 1.5 extend(json, {
// 1.5
hgap, hgap,
vgap, vgap,
lgap, lgap,
@ -138,7 +146,7 @@ export class AbstractLabel extends Single {
}); });
this.text = createWidget(json); this.text = createWidget(json);
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: whiteSpace === "normal", scrollable: whiteSpace === "normal",
element: this, element: this,
@ -147,10 +155,11 @@ export class AbstractLabel extends Single {
return; return;
} }
if (isNumber(textWidth) && textWidth > 0) { // 1.6 if (isNumber(textWidth) && textWidth > 0) {
// 1.6
json.maxWidth = textWidth; json.maxWidth = textWidth;
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: whiteSpace === "normal", scrollable: whiteSpace === "normal",
element: this, element: this,
@ -163,7 +172,8 @@ export class AbstractLabel extends Single {
return; return;
} }
if (whiteSpace === "normal") { // 1.7 if (whiteSpace === "normal") {
// 1.7
extend(json, { extend(json, {
hgap, hgap,
vgap, vgap,
@ -174,7 +184,7 @@ export class AbstractLabel extends Single {
}); });
this.text = createWidget(json); this.text = createWidget(json);
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
scrollable: true, scrollable: true,
element: this, element: this,
@ -183,13 +193,15 @@ export class AbstractLabel extends Single {
return; return;
} }
if (isNumber(height) && height > 0) { // 1.8 if (isNumber(height) && height > 0) {
// 1.8
this.element.css({ this.element.css({
"line-height": BI.pixFormat(height), "line-height": BI.pixFormat(height),
}); });
json.textAlign = textAlign; json.textAlign = textAlign;
delete json.maxWidth; delete json.maxWidth;
this.text = createWidget(extend(json, { this.text = createWidget(
extend(json, {
element: this, element: this,
hgap, hgap,
vgap, vgap,
@ -197,20 +209,23 @@ export class AbstractLabel extends Single {
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
return; return;
} }
this.text = createWidget(extend(json, { this.text = createWidget(
extend(json, {
hgap, hgap,
vgap, vgap,
lgap, lgap,
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
createWidget({ createWidget({
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
element: this, element: this,
items: [this.text], items: [this.text],
@ -224,7 +239,8 @@ export class AbstractLabel extends Single {
if (isNumber(width) && width > 0) { if (isNumber(width) && width > 0) {
if (isNumber(textWidth) && textWidth > 0) { if (isNumber(textWidth) && textWidth > 0) {
json.maxWidth = textWidth; json.maxWidth = textWidth;
if (isNumber(height) && height > 0) { // 2.1 if (isNumber(height) && height > 0) {
// 2.1
createWidget({ createWidget({
type: adaptLayout, type: adaptLayout,
horizontalAlign: textAlign, horizontalAlign: textAlign,
@ -241,7 +257,8 @@ export class AbstractLabel extends Single {
return; return;
} }
createWidget({ // 2.2 createWidget({
// 2.2
type: adaptLayout, type: adaptLayout,
horizontalAlign: textAlign, horizontalAlign: textAlign,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
@ -262,14 +279,16 @@ export class AbstractLabel extends Single {
return; return;
} }
if (isNumber(height) && height > 0) { // 2.3 if (isNumber(height) && height > 0) {
// 2.3
if (whiteSpace !== "normal") { if (whiteSpace !== "normal") {
this.element.css({ this.element.css({
"line-height": BI.pixFormat(height - (vgap * 2)), "line-height": BI.pixFormat(height - vgap * 2),
}); });
} }
delete json.maxWidth; delete json.maxWidth;
this.text = createWidget(extend(json, { this.text = createWidget(
extend(json, {
element: this, element: this,
hgap, hgap,
vgap, vgap,
@ -277,12 +296,14 @@ export class AbstractLabel extends Single {
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
return; return;
} }
json.maxWidth = width - 2 * hgap - lgap - rgap; json.maxWidth = width - 2 * hgap - lgap - rgap;
createWidget({ // 2.4 createWidget({
// 2.4
type: adaptLayout, type: adaptLayout,
horizontalAlign: textAlign, horizontalAlign: textAlign,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
@ -294,16 +315,19 @@ export class AbstractLabel extends Single {
tgap, tgap,
bgap, bgap,
element: this, element: this,
items: [{ items: [
{
el: (this.text = createWidget(json)), el: (this.text = createWidget(json)),
}], }
],
}); });
return; return;
} }
if (isNumber(textWidth) && textWidth > 0) { if (isNumber(textWidth) && textWidth > 0) {
json.maxWidth = textWidth; json.maxWidth = textWidth;
createWidget({ // 2.5 createWidget({
// 2.5
type: adaptLayout, type: adaptLayout,
horizontalAlign: textAlign, horizontalAlign: textAlign,
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1 columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
@ -327,11 +351,13 @@ export class AbstractLabel extends Single {
if (isNumber(height) && height > 0) { if (isNumber(height) && height > 0) {
if (whiteSpace !== "normal") { if (whiteSpace !== "normal") {
this.element.css({ this.element.css({
"line-height": BI.pixFormat(height - (vgap * 2)), "line-height": BI.pixFormat(height - vgap * 2),
}); });
} }
delete json.maxWidth; delete json.maxWidth;
this.text = createWidget(extend(json, { // 2.6 this.text = createWidget(
extend(json, {
// 2.6
element: this, element: this,
hgap, hgap,
vgap, vgap,
@ -339,18 +365,21 @@ export class AbstractLabel extends Single {
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
return; return;
} }
this.text = createWidget(extend(json, { this.text = createWidget(
extend(json, {
hgap, hgap,
vgap, vgap,
lgap, lgap,
rgap, rgap,
tgap, tgap,
bgap, bgap,
})); })
);
createWidget({ createWidget({
type: adaptLayout, type: adaptLayout,
horizontalAlign: textAlign, horizontalAlign: textAlign,

10
src/base/single/label/html.label.js

@ -1,8 +1,10 @@
import { Html } from "../html/html";
import { AbstractLabel } from "./abstract.label";
import { shortcut } from "@/core";
/** /**
* Created by GUY on 2015/6/26. * Created by GUY on 2015/6/26.
*/ */
import { shortcut } from "../../../core";
import { AbstractLabel } from "./abstract.label";
@shortcut() @shortcut()
export class HtmlLabel extends AbstractLabel { export class HtmlLabel extends AbstractLabel {
@ -10,13 +12,13 @@ export class HtmlLabel extends AbstractLabel {
props = { props = {
baseCls: "bi-html-label", baseCls: "bi-html-label",
} };
_createJson() { _createJson() {
const { textAlign, whiteSpace, textHeight, text, value, handler } = this.options; const { textAlign, whiteSpace, textHeight, text, value, handler } = this.options;
return { return {
type: "bi.html", type: Html.xtype,
textAlign, textAlign,
whiteSpace, whiteSpace,
lineHeight: textHeight, lineHeight: textHeight,

14
src/base/single/label/icon.label.js

@ -1,10 +1,12 @@
import { Icon } from "../icon/icon";
import { DefaultLayout, CenterAdaptLayout, shortcut, createWidget, isNumber, isNull } from "@/core";
import { Single } from "../0.single";
/** /**
* @class BI.IconLabel * @class BI.IconLabel
* @extends BI.Single * @extends BI.Single
* 图标标签 * 图标标签
*/ */
import { shortcut, createWidget, isNumber, isNull } from "../../../core";
import { Single } from "../0.single";
@shortcut() @shortcut()
export class IconLabel extends Single { export class IconLabel extends Single {
@ -21,7 +23,7 @@ export class IconLabel extends Single {
iconWidth: null, iconWidth: null,
iconHeight: null, iconHeight: null,
lineHeight: null, lineHeight: null,
} };
render() { render() {
const { iconWidth, iconHeight, height, lineHeight, hgap, vgap, lgap, rgap, tgap, bgap } = this.options; const { iconWidth, iconHeight, height, lineHeight, hgap, vgap, lgap, rgap, tgap, bgap } = this.options;
@ -29,14 +31,14 @@ export class IconLabel extends Single {
textAlign: "center", textAlign: "center",
}); });
this.icon = createWidget({ this.icon = createWidget({
type: "bi.icon", type: Icon.xtype,
width: iconWidth, width: iconWidth,
height: iconHeight, height: iconHeight,
}); });
if (isNumber(height) && height > 0 && isNull(iconWidth) && isNull(iconHeight)) { if (isNumber(height) && height > 0 && isNull(iconWidth) && isNull(iconHeight)) {
this.element.css("lineHeight", BI.pixFormat(lineHeight || height)); this.element.css("lineHeight", BI.pixFormat(lineHeight || height));
createWidget({ createWidget({
type: "bi.default", type: DefaultLayout.xtype,
element: this, element: this,
hgap, hgap,
vgap, vgap,
@ -50,7 +52,7 @@ export class IconLabel extends Single {
this.element.css("lineHeight", "1"); this.element.css("lineHeight", "1");
createWidget({ createWidget({
element: this, element: this,
type: "bi.center_adapt", type: CenterAdaptLayout.xtype,
hgap, hgap,
vgap, vgap,
lgap, lgap,

7
src/base/single/label/label.js

@ -1,8 +1,9 @@
import { AbstractLabel } from "./abstract.label";
import { shortcut, isFunction, isNotNull } from "@/core";
/** /**
* Created by GUY on 2015/6/26. * Created by GUY on 2015/6/26.
*/ */
import { shortcut, isFunction, isNotNull } from "../../../core";
import { AbstractLabel } from "./abstract.label";
@shortcut() @shortcut()
export class Label extends AbstractLabel { export class Label extends AbstractLabel {
@ -12,7 +13,7 @@ export class Label extends AbstractLabel {
baseCls: "bi-label", baseCls: "bi-label",
py: "", py: "",
keyword: "", keyword: "",
} };
getTitle() { getTitle() {
const title = this.options.title; const title = this.options.title;

10
src/base/single/link/link.js

@ -1,10 +1,12 @@
import { A } from "../a/a";
import { Label } from "../label/label";
import { shortcut, extend } from "@/core";
/** /**
* guy a元素 * guy a元素
* @class BI.Link * @class BI.Link
* @extends BI.Text * @extends BI.Text
*/ */
import { shortcut, extend } from "../../../core";
import { Label } from "../label/label";
@shortcut() @shortcut()
export class Link extends Label { export class Link extends Label {
@ -14,7 +16,7 @@ export class Link extends Label {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
return extend(conf, { return extend(conf, {
baseCls: (conf.baseCls || "") + " bi-link display-block", baseCls: `${conf.baseCls || ""} bi-link display-block`,
tagName: "a", tagName: "a",
href: "", href: "",
target: "_blank", target: "_blank",
@ -25,7 +27,7 @@ export class Link extends Label {
const { textAlign, whiteSpace, textHeight, text, keyword, value, py, href, target } = this.options; const { textAlign, whiteSpace, textHeight, text, keyword, value, py, href, target } = this.options;
return { return {
type: "bi.a", type: A.xtype,
textAlign, textAlign,
whiteSpace, whiteSpace,
lineHeight: textHeight, lineHeight: textHeight,

15
src/base/single/text.pure.js

@ -1,8 +1,9 @@
import { Text } from "./1.text";
import { Widget, shortcut, isFunction, isKey, isNotNull } from "@/core";
/** /**
* 没有html标签的纯文本 * 没有html标签的纯文本
*/ */
import { Widget, shortcut, isFunction, isKey, isNotNull } from "../../core";
import { Text } from "./1.text";
@shortcut() @shortcut()
export class PureText extends Widget { export class PureText extends Widget {
@ -10,13 +11,15 @@ export class PureText extends Widget {
props = { props = {
tagName: null, tagName: null,
} };
render() { render() {
const { text: optionsText, value } = this.options; const { text: optionsText, value } = this.options;
const text = isFunction(optionsText) ? this.__watch(optionsText, (context, newValue) => { const text = isFunction(optionsText)
? this.__watch(optionsText, (context, newValue) => {
this.setText(newValue); this.setText(newValue);
}) : optionsText; })
: optionsText;
if (isKey(text)) { if (isKey(text)) {
this.setText(text); this.setText(text);
} else if (isKey(value)) { } else if (isKey(value)) {
@ -32,7 +35,7 @@ export class PureText extends Widget {
return ""; return "";
} }
return Text.formatText(text + ""); return Text.formatText(`${text}`);
} }
setValue(value) { setValue(value) {

6
src/base/single/tip/0.tip.js

@ -1,3 +1,6 @@
import { Single } from "../0.single";
import { extend } from "@/core";
/** /**
* guy * guy
* tip提示 * tip提示
@ -7,8 +10,6 @@
* @abstract * @abstract
*/ */
import { Single } from "../0.single";
import { extend } from "../../../core";
export class Tip extends Single { export class Tip extends Single {
_defaultConfig() { _defaultConfig() {
const conf = super._defaultConfig(...arguments); const conf = super._defaultConfig(...arguments);
@ -24,4 +25,3 @@ export class Tip extends Single {
this.element.css({ zIndex: this.options.zIndex }); this.element.css({ zIndex: this.options.zIndex });
} }
} }

31
src/base/single/tip/tip.toast.js

@ -1,3 +1,8 @@
import { IconLabel, Label } from "../label";
import { IconButton } from "../button";
import { HorizontalLayout, shortcut, extend, isPlainObject } from "@/core";
import { Tip } from "./0.tip";
/** /**
* toast提示 * toast提示
* *
@ -6,8 +11,6 @@
* @extends BI.Tip * @extends BI.Tip
*/ */
import { shortcut, extend, isPlainObject } from "../../../core";
import { Tip } from "./0.tip";
@shortcut() @shortcut()
export class Toast extends Tip { export class Toast extends Tip {
_const = { _const = {
@ -15,7 +18,7 @@ export class Toast extends Tip {
minWidth: 100, minWidth: 100,
closableMaxWidth: 410, closableMaxWidth: 410,
maxWidth: 400, maxWidth: 400,
} };
static EVENT_DESTORY = "EVENT_DESTORY"; static EVENT_DESTORY = "EVENT_DESTORY";
static xtype = "bi.toast"; static xtype = "bi.toast";
@ -80,25 +83,30 @@ export class Toast extends Tip {
function hasCloseIcon() { function hasCloseIcon() {
return closable === true || (closable === null && autoClose === false); return closable === true || (closable === null && autoClose === false);
} }
const items = [{ const items = [
type: "bi.icon_label", {
type: IconLabel.xtype,
cls: `${cls} toast-icon`, cls: `${cls} toast-icon`,
height: textHeight, height: textHeight,
}, { },
el: isPlainObject(text) ? text : { {
type: "bi.label", el: isPlainObject(text)
? text
: {
type: Label.xtype,
whiteSpace: "normal", whiteSpace: "normal",
text, text,
textHeight, textHeight,
textAlign: "left", textAlign: "left",
}, },
}]; }
];
const columnSize = ["", "fill"]; const columnSize = ["", "fill"];
if (hasCloseIcon()) { if (hasCloseIcon()) {
items.push({ items.push({
type: "bi.icon_button", type: IconButton.xtype,
cls: "close-font toast-icon", cls: "close-font toast-icon",
handler: () => { handler: () => {
this.destroy(); this.destroy();
@ -109,7 +117,7 @@ export class Toast extends Tip {
} }
return { return {
type: "bi.horizontal", type: HorizontalLayout.xtype,
horizontalAlign: BI.HorizontalAlign.Stretch, horizontalAlign: BI.HorizontalAlign.Stretch,
items, items,
hgap, hgap,
@ -123,4 +131,3 @@ export class Toast extends Tip {
this.fireEvent(Toast.EVENT_DESTORY); this.fireEvent(Toast.EVENT_DESTORY);
} }
} }

16
src/base/single/tip/tip.tooltip.js

@ -1,3 +1,7 @@
import { VerticalLayout, shortcut, extend, createWidget, map } from "@/core";
import { Label } from "../label";
import { Tip } from "./0.tip";
/** /**
* title提示 * title提示
* *
@ -6,14 +10,12 @@
* @extends BI.Tip * @extends BI.Tip
*/ */
import { shortcut, extend, createWidget, map } from "../../../core";
import { Tip } from "./0.tip";
@shortcut() @shortcut()
export class Tooltip extends Tip { export class Tooltip extends Tip {
_const = { _const = {
hgap: 8, hgap: 8,
vgap: 4, vgap: 4,
} };
static xtype = "bi.tooltip"; static xtype = "bi.tooltip";
_defaultConfig() { _defaultConfig() {
@ -44,16 +46,16 @@ export class Tooltip extends Tip {
mousemove: fn, mousemove: fn,
}); });
const texts = (`${text}`).split("\n"); const texts = `${text}`.split("\n");
if (texts.length > 1) { if (texts.length > 1) {
createWidget({ createWidget({
type: "bi.vertical", type: VerticalLayout.xtype,
element: this, element: this,
hgap: this._const.hgap, hgap: this._const.hgap,
innerVgap: this._const.vgap, innerVgap: this._const.vgap,
items: map(texts, (i, text) => { items: map(texts, (i, text) => {
return { return {
type: "bi.label", type: Label.xtype,
textAlign, textAlign,
whiteSpace: "normal", whiteSpace: "normal",
text, text,
@ -64,7 +66,7 @@ export class Tooltip extends Tip {
}); });
} else { } else {
this.text = createWidget({ this.text = createWidget({
type: "bi.label", type: Label.xtype,
element: this, element: this,
textAlign, textAlign,
whiteSpace: "normal", whiteSpace: "normal",

13
src/base/single/trigger/trigger.js

@ -1,11 +1,12 @@
import { Single } from "../0.single";
import { extend } from "@/core";
/** /**
* 下拉 * 下拉
* @class BI.Trigger * @class BI.Trigger
* @extends BI.Single * @extends BI.Single
* @abstract * @abstract
*/ */
import { extend } from "../../../core";
import { Single } from "../0.single";
export class Trigger extends Single { export class Trigger extends Single {
_defaultConfig() { _defaultConfig() {
@ -17,11 +18,7 @@ export class Trigger extends Single {
}); });
} }
setKey() { setKey() {}
} getKey() {}
getKey() {
}
} }

58
src/base/tree/customtree.js

@ -1,3 +1,23 @@
import { ButtonTree, Expander } from "../combination";
import {
VerticalLayout,
Widget,
shortcut,
extend,
emptyFn,
Tree,
each,
isNotEmptyArray,
deepClone,
stripEL,
isWidget,
clone,
isNotNull,
isNull,
createWidget,
Controller
} from "@/core";
/** /**
* *
* 自定义树 * 自定义树
@ -6,7 +26,7 @@
* @class BI.CustomTree * @class BI.CustomTree
* @extends BI.Single * @extends BI.Single
*/ */
import { Widget, shortcut, extend, emptyFn, Tree, each, isNotEmptyArray, deepClone, stripEL, isWidget, clone, isNotNull, isNull, createWidget, Controller } from "../../core";
@shortcut() @shortcut()
export class CustomTree extends Widget { export class CustomTree extends Widget {
static xtype = "bi.custom_tree"; static xtype = "bi.custom_tree";
@ -18,7 +38,7 @@ export class CustomTree extends Widget {
expander: { expander: {
el: {}, el: {},
popup: { popup: {
type: "bi.custom_tree", type: CustomTree.xtype,
}, },
}, },
@ -26,11 +46,13 @@ export class CustomTree extends Widget {
itemsCreator: emptyFn, itemsCreator: emptyFn,
el: { el: {
type: "bi.button_tree", type: ButtonTree.xtype,
chooseType: 0, chooseType: 0,
layouts: [{ layouts: [
type: "bi.vertical", {
}], type: VerticalLayout.xtype,
}
],
}, },
}); });
} }
@ -46,16 +68,20 @@ export class CustomTree extends Widget {
const items = []; const items = [];
each(nodes, (i, node) => { each(nodes, (i, node) => {
if (isNotEmptyArray(node.children) || node.isParent === true) { if (isNotEmptyArray(node.children) || node.isParent === true) {
const item = extend({ const item = extend(
type: "bi.expander", {
type: Expander.xtype,
el: { el: {
value: node.value, value: node.value,
}, },
popup: { type: "bi.custom_tree" }, popup: { type: CustomTree.xtype },
}, deepClone(expander), { },
deepClone(expander),
{
id: node.id, id: node.id,
pId: node.pId, pId: node.pId,
}); }
);
let el = stripEL(node); let el = stripEL(node);
if (!isWidget(el)) { if (!isWidget(el)) {
el = clone(el); el = clone(el);
@ -67,7 +93,8 @@ export class CustomTree extends Widget {
item.popup.expander = deepClone(expander); item.popup.expander = deepClone(expander);
item.items = item.popup.items = node.children; item.items = item.popup.items = node.children;
item.itemsCreator = item.popup.itemsCreator = (op, ...arg) => { item.itemsCreator = item.popup.itemsCreator = (op, ...arg) => {
if (isNotNull(op.node)) {// 从子节点传过来的itemsCreator直接向上传递 if (isNotNull(op.node)) {
// 从子节点传过来的itemsCreator直接向上传递
return itemsCreator(op, ...arg); return itemsCreator(op, ...arg);
} }
const args = Array.prototype.slice.call([op, ...arg], 0); const args = Array.prototype.slice.call([op, ...arg], 0);
@ -91,11 +118,14 @@ export class CustomTree extends Widget {
element: this, element: this,
items: this._formatItems(nodes), items: this._formatItems(nodes),
itemsCreator: (op, callback) => { itemsCreator: (op, callback) => {
itemsCreator.apply(this, [op, items => { itemsCreator.apply(this, [
op,
items => {
const args = Array.prototype.slice.call(arguments, 0); const args = Array.prototype.slice.call(arguments, 0);
args[0] = this._formatItems(items); args[0] = this._formatItems(items);
callback(...args); callback(...args);
}]); }
]);
}, },
value, value,
}); });

3
src/case/combo/bubblecombo/popup.bubble.js

@ -1,5 +1,6 @@
import { shortcut, extend } from "@/core"; import { shortcut, extend } from "@/core";
import { PopupView, Label } from "@/base"; import { PopupView } from "@/base/layer/layer.popup";
import { Label } from "@/base/single/label/label";
@shortcut() @shortcut()
export class BubblePopupView extends PopupView { export class BubblePopupView extends PopupView {

Loading…
Cancel
Save