Treecat
2 years ago
71 changed files with 4231 additions and 4283 deletions
@ -1,374 +1,374 @@
|
||||
!(function () { |
||||
var needHideWhenAnotherComboOpen = {}; |
||||
var currentOpenedCombos = {}; |
||||
/** |
||||
* @class BI.Combo |
||||
* @extends BI.Widget |
||||
*/ |
||||
|
||||
/** |
||||
* @class BI.Combo |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Combo = BI.inherit(BI.Bubble, { |
||||
_const: { |
||||
TRIANGLE_LENGTH: 12, |
||||
}, |
||||
_defaultConfig: function () { |
||||
var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); |
||||
import { shortcut, Widget, Controller, extend, createWidget, nextTick, bind, isNotNull, isNull, isFunction, each } from "../../core"; |
||||
import { Bubble } from "./bubble"; |
||||
import { Resizers } from "../0.base"; |
||||
|
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), |
||||
attributes: { |
||||
tabIndex: -1, |
||||
}, |
||||
trigger: "click", // click || hover || click-hover || ""
|
||||
toggle: true, |
||||
direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right||right,innerRight||right,innerLeft||innerRight||innerLeft
|
||||
logic: { |
||||
dynamic: true, |
||||
}, |
||||
container: null, // popupview放置的容器,默认为this.element
|
||||
isDefaultInit: false, |
||||
destroyWhenHide: false, |
||||
hideWhenBlur: true, |
||||
hideWhenAnotherComboOpen: false, |
||||
hideWhenClickOutside: true, |
||||
showArrow: false, |
||||
isNeedAdjustHeight: true, // 是否需要高度调整
|
||||
isNeedAdjustWidth: true, |
||||
stopEvent: false, |
||||
stopPropagation: false, |
||||
adjustLength: 0, // 调整的距离
|
||||
adjustXOffset: 0, |
||||
adjustYOffset: 0, |
||||
supportCSSTransform: true, |
||||
hideChecker: BI.emptyFn, |
||||
offsetStyle: "", // "",center,middle
|
||||
el: {}, |
||||
popup: {}, |
||||
comboClass: "bi-combo-popup", |
||||
hoverClass: "bi-combo-hover", |
||||
belowMouse: false, |
||||
}); |
||||
}, |
||||
let needHideWhenAnotherComboOpen = {}; |
||||
let currentOpenedCombos = {}; |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this._initCombo(); |
||||
// 延迟绑定事件,这样可以将自己绑定的事情优先执行
|
||||
BI.nextTick(() => { |
||||
!this.isDestroyed() && this._initPullDownAction(); |
||||
}); |
||||
this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (self.isEnabled() && self.isValid()) { |
||||
if (type === BI.Events.TOGGLE) { |
||||
self._toggle(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
self._popupView(); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self._hideView(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.fireEvent(BI.Combo.EVENT_EXPAND); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.isViewVisible() && self.fireEvent(BI.Combo.EVENT_COLLAPSE); |
||||
} |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); |
||||
} |
||||
} |
||||
}); |
||||
@shortcut() |
||||
export class Combo extends Bubble { |
||||
static xtype = "bi.combo"; |
||||
|
||||
self.element.on("mouseenter." + self.getName(), function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
self.element.addClass(o.hoverClass); |
||||
static EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; |
||||
static EVENT_CHANGE = "EVENT_CHANGE"; |
||||
static EVENT_EXPAND = "EVENT_EXPAND"; |
||||
static EVENT_COLLAPSE = "EVENT_COLLAPSE"; |
||||
static EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
|
||||
static EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; |
||||
static EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; |
||||
static EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; |
||||
static EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; |
||||
|
||||
_defaultConfig() { |
||||
const conf = super._defaultConfig(arguments); |
||||
|
||||
return extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), |
||||
attributes: { |
||||
tabIndex: -1, |
||||
}, |
||||
trigger: "click", // click || hover || click-hover || ""
|
||||
toggle: true, |
||||
direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right||right,innerRight||right,innerLeft||innerRight||innerLeft
|
||||
logic: { |
||||
dynamic: true, |
||||
}, |
||||
container: null, // popupview放置的容器,默认为this.element
|
||||
isDefaultInit: false, |
||||
destroyWhenHide: false, |
||||
hideWhenBlur: true, |
||||
hideWhenAnotherComboOpen: false, |
||||
hideWhenClickOutside: true, |
||||
showArrow: false, |
||||
isNeedAdjustHeight: true, // 是否需要高度调整
|
||||
isNeedAdjustWidth: true, |
||||
stopEvent: false, |
||||
stopPropagation: false, |
||||
adjustLength: 0, // 调整的距离
|
||||
adjustXOffset: 0, |
||||
adjustYOffset: 0, |
||||
supportCSSTransform: true, |
||||
hideChecker: BI.emptyFn, |
||||
offsetStyle: "", // "",center,middle
|
||||
el: {}, |
||||
popup: {}, |
||||
comboClass: "bi-combo-popup", |
||||
hoverClass: "bi-combo-hover", |
||||
belowMouse: false, |
||||
}); |
||||
} |
||||
|
||||
render() { |
||||
const { hoverClass, logic, isDefaultInit } = this.options; |
||||
this._initCombo(); |
||||
// 延迟绑定事件,这样可以将自己绑定的事情优先执行
|
||||
nextTick(() => { |
||||
!this.isDestroyed() && this._initPullDownAction(); |
||||
}); |
||||
this.combo.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { |
||||
if (this.isEnabled() && this.isValid()) { |
||||
if (type === BI.Events.TOGGLE) { |
||||
this._toggle(); |
||||
} |
||||
}); |
||||
self.element.on("mouseleave." + self.getName(), function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
self.element.removeClass(o.hoverClass); |
||||
if (type === BI.Events.EXPAND) { |
||||
this._popupView(); |
||||
} |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this, |
||||
scrolly: false, |
||||
}, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { |
||||
items: [ |
||||
{ el: this.combo } |
||||
], |
||||
})))); |
||||
o.isDefaultInit && (this._assertPopupView()); |
||||
BI.Resizers.add(this.getName(), BI.bind(function (e) { |
||||
// 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理
|
||||
if (this.isViewVisible()) { |
||||
BI.isNotNull(e) ? this._hideIf(e) : this._hideView(); |
||||
if (type === BI.Events.COLLAPSE) { |
||||
this._hideView(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); |
||||
this.fireEvent(Combo.EVENT_EXPAND); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); |
||||
this.isViewVisible() && this.fireEvent(Combo.EVENT_COLLAPSE); |
||||
} |
||||
if (type === BI.Events.CLICK) { |
||||
this.fireEvent(Combo.EVENT_TRIGGER_CHANGE, obj); |
||||
} |
||||
}, this)); |
||||
}, |
||||
|
||||
_assertPopupView: function () { |
||||
var self = this, o = this.options; |
||||
if (BI.isNull(this.popupView)) { |
||||
this.popupView = BI.createWidget(BI.isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { |
||||
type: "bi.popup_view", |
||||
showArrow: o.showArrow, |
||||
value: o.value, |
||||
}, this); |
||||
this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (type === BI.Events.CLICK) { |
||||
self.combo.setValue(self.getValue()); |
||||
self.fireEvent(BI.Bubble.EVENT_CHANGE, value, obj); |
||||
} |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.popupView.setVisible(false); |
||||
BI.nextTick(function () { |
||||
self.fireEvent(BI.Bubble.EVENT_AFTER_INIT); |
||||
}); |
||||
} |
||||
}, |
||||
}); |
||||
|
||||
_hideView: function (e) { |
||||
var o = this.options; |
||||
this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); |
||||
if (this.options.destroyWhenHide === true) { |
||||
this.popupView && this.popupView.destroy(); |
||||
this.popupView = null; |
||||
this._rendered = false; |
||||
} else { |
||||
this.popupView && this.popupView.invisible(); |
||||
this.element.on("mouseenter." + this.getName(), (e) => { |
||||
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { |
||||
this.element.addClass(hoverClass); |
||||
} |
||||
|
||||
if (!e || !this.combo.element.__isMouseInBounds__(e)) { |
||||
this.element.removeClass(this.options.hoverClass); |
||||
// 应对bi-focus-shadow在收起时不失焦
|
||||
this.element.blur(); |
||||
}); |
||||
this.element.on("mouseleave." + this.getName(), (e) => { |
||||
if (this.isEnabled() && this.isValid() && this.combo.isEnabled() && this.combo.isValid()) { |
||||
this.element.removeClass(hoverClass); |
||||
} |
||||
}); |
||||
|
||||
this.element.removeClass(this.options.comboClass); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
delete currentOpenedCombos[this.getName()]; |
||||
|
||||
o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); |
||||
BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); |
||||
this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW, e); |
||||
}, |
||||
createWidget(extend({ |
||||
element: this, |
||||
scrolly: false, |
||||
}, BI.LogicFactory.createLogic("vertical", extend(logic, { |
||||
items: [ |
||||
{ el: this.combo } |
||||
], |
||||
})))); |
||||
isDefaultInit && (this._assertPopupView()); |
||||
Resizers.add(this.getName(), bind((e) => { |
||||
// 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理
|
||||
if (this.isViewVisible()) { |
||||
isNotNull(e) ? this._hideIf(e) : this._hideView(); |
||||
} |
||||
}, this)); |
||||
} |
||||
|
||||
_popupView: function (e) { |
||||
var self = this, o = this.options; |
||||
this._assertPopupViewRender(); |
||||
this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); |
||||
// popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下
|
||||
this.popupView.css({ left: -99999, top: -99999 }); |
||||
this.popupView.visible(); |
||||
BI.each(needHideWhenAnotherComboOpen, function (i, combo) { |
||||
if (i !== self.getName()) { |
||||
if (combo && combo._hideIf(e, true) === true) { |
||||
delete needHideWhenAnotherComboOpen[i]; |
||||
} |
||||
_assertPopupView() { |
||||
const { showArrow, value, hideWhenClickOutside, hideWhenBlur } = this.options; |
||||
if (isNull(this.popupView)) { |
||||
this.popupView = createWidget(isFunction(this.options.popup) ? this.options.popup() : this.options.popup, { |
||||
type: "bi.popup_view", |
||||
showArrow, |
||||
value, |
||||
}, this); |
||||
this.popupView.on(Controller.EVENT_CHANGE, (type, value, obj, ...args) => { |
||||
if (type === BI.Events.CLICK) { |
||||
this.combo.setValue(this.getValue()); |
||||
this.fireEvent(Bubble.EVENT_CHANGE, value, obj); |
||||
} |
||||
this.fireEvent(Controller.EVENT_CHANGE, type, value, obj, ...args); |
||||
}); |
||||
this.popupView.setVisible(false); |
||||
nextTick(() => { |
||||
this.fireEvent(Bubble.EVENT_AFTER_INIT); |
||||
}); |
||||
currentOpenedCombos[this.getName()] = this; |
||||
this.options.hideWhenAnotherComboOpen && (needHideWhenAnotherComboOpen[this.getName()] = this); |
||||
this.adjustWidth(e); |
||||
this.adjustHeight(e); |
||||
} |
||||
} |
||||
|
||||
this.element.addClass(this.options.comboClass); |
||||
o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); |
||||
o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).unbind("mousewheel." + this.getName()); |
||||
BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); |
||||
_hideView(e) { |
||||
const { hideWhenClickOutside, hideWhenBlur } = this.options; |
||||
this.fireEvent(Combo.EVENT_BEFORE_HIDEVIEW); |
||||
if (this.options.destroyWhenHide === true) { |
||||
this.popupView && this.popupView.destroy(); |
||||
this.popupView = null; |
||||
this._rendered = false; |
||||
} else { |
||||
this.popupView && this.popupView.invisible(); |
||||
} |
||||
|
||||
o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); |
||||
o.hideWhenClickOutside && BI.Widget._renderEngine.createElement(document).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); |
||||
BI.EVENT_BLUR && o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); |
||||
this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); |
||||
}, |
||||
if (!e || !this.combo.element.__isMouseInBounds__(e)) { |
||||
this.element.removeClass(this.options.hoverClass); |
||||
// 应对bi-focus-shadow在收起时不失焦
|
||||
this.element.blur(); |
||||
} |
||||
|
||||
adjustHeight: function (e) { |
||||
var o = this.options, p = {}; |
||||
if (!this.popupView) { |
||||
return; |
||||
} |
||||
var isVisible = this.popupView.isVisible(); |
||||
this.popupView.visible(); |
||||
var combo = (o.belowMouse && BI.isNotNull(e)) ? { |
||||
element: { |
||||
0: BI.extend({}, e.target, { |
||||
getBoundingClientRect: function () { |
||||
return { |
||||
left: e.pageX, |
||||
top: e.pageY, |
||||
width: 0, |
||||
height: 0, |
||||
}; |
||||
} |
||||
}), |
||||
offset: function () { |
||||
return { |
||||
left: e.pageX, |
||||
top: e.pageY, |
||||
}; |
||||
}, |
||||
}, |
||||
} : this.combo; |
||||
this.element.removeClass(this.options.comboClass); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
delete currentOpenedCombos[this.getName()]; |
||||
|
||||
var positionRelativeElement = BI.DOM.getPositionRelativeContainingBlock( |
||||
BI.isNull(o.container) |
||||
? this.element[0] |
||||
: BI.isWidget(o.container) |
||||
? o.container.element[0] |
||||
: BI.Widget._renderEngine.createElement(BI.isFunction(o.container) ? o.container() : o.container)[0] |
||||
); |
||||
hideWhenClickOutside && 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); |
||||
} |
||||
|
||||
switch (o.direction) { |
||||
case "bottom": |
||||
case "bottom,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "right", "left"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "top": |
||||
case "top,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "right", "left"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "left": |
||||
case "left,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right": |
||||
case "right,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "top,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["top", "bottom", "left", "right"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "bottom,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight, ["bottom", "top", "left", "right"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "left,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "top", "bottom"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "top", "bottom"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right,innerRight": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right,innerLeft": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "innerRight": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "innerLeft": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.adjustYOffset, o.isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], o.offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "top,custom": |
||||
case "custom,top": |
||||
p = BI.DOM.getTopAdaptPosition(combo, this.popupView, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight); |
||||
p.dir = "top"; |
||||
break; |
||||
case "custom,bottom": |
||||
case "bottom,custom": |
||||
p = BI.DOM.getBottomAdaptPosition(combo, this.popupView, (o.adjustYOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0), o.isNeedAdjustHeight); |
||||
p.dir = "bottom"; |
||||
break; |
||||
case "left,custom": |
||||
case "custom,left": |
||||
p = BI.DOM.getLeftAdaptPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0)); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
p.dir = "left"; |
||||
break; |
||||
case "custom,right": |
||||
case "right,custom": |
||||
p = BI.DOM.getRightAdaptPosition(combo, this.popupView, (o.adjustXOffset + o.adjustLength) + (o.showArrow ? this._const.TRIANGLE_LENGTH : 0)); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
p.dir = "right"; |
||||
break; |
||||
default: |
||||
break; |
||||
_popupView(e) { |
||||
const { hideWhenClickOutside, hideWhenBlur } = this.options; |
||||
this._assertPopupViewRender(); |
||||
this.fireEvent(Combo.EVENT_BEFORE_POPUPVIEW); |
||||
// popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下
|
||||
this.popupView.css({ left: -99999, top: -99999 }); |
||||
this.popupView.visible(); |
||||
each(needHideWhenAnotherComboOpen, (i, combo) => { |
||||
if (i !== this.getName()) { |
||||
if (combo && combo._hideIf(e, true) === true) { |
||||
delete needHideWhenAnotherComboOpen[i]; |
||||
} |
||||
} |
||||
}); |
||||
currentOpenedCombos[this.getName()] = this; |
||||
this.options.hideWhenAnotherComboOpen && (needHideWhenAnotherComboOpen[this.getName()] = this); |
||||
this.adjustWidth(e); |
||||
this.adjustHeight(e); |
||||
|
||||
var width = this.combo.element.outerWidth(); |
||||
var height = this.combo.element.outerHeight(); |
||||
this.popupView.setDirection && this.popupView.setDirection(p.dir, { |
||||
width: width, |
||||
height: height, |
||||
offsetStyle: o.offsetStyle, |
||||
adjustXOffset: o.adjustXOffset, |
||||
adjustYOffset: o.adjustYOffset, |
||||
offset: this.combo.element.offset(), |
||||
}); |
||||
this.element.addClass(this.options.comboClass); |
||||
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); |
||||
hideWhenClickOutside && Widget._renderEngine.createElement(document).unbind("mousewheel." + this.getName()); |
||||
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); |
||||
|
||||
if (o.supportCSSTransform) { |
||||
hideWhenClickOutside && Widget._renderEngine.createElement(document).bind("mousewheel." + this.getName(), bind(this._hideIf, this)); |
||||
hideWhenClickOutside && Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), bind(this._hideIf, this)).bind("mousewheel." + this.getName(), bind(this._hideIf, this)); |
||||
BI.EVENT_BLUR && hideWhenBlur && Widget._renderEngine.createElement(window).bind("blur." + this.getName(), bind(this._hideIf, this)); |
||||
this.fireEvent(Combo.EVENT_AFTER_POPUPVIEW); |
||||
} |
||||
|
||||
var positonedRect = positionRelativeElement.getBoundingClientRect(); |
||||
adjustHeight(e) { |
||||
const { belowMouse, supportCSSTransform, container, direction, adjustXOffset, adjustYOffset, adjustLength, showArrow, isNeedAdjustHeight, offsetStyle } = this.options; |
||||
let p = {}; |
||||
if (!this.popupView) { |
||||
return; |
||||
} |
||||
const isVisible = this.popupView.isVisible(); |
||||
this.popupView.visible(); |
||||
const combo = (belowMouse && isNotNull(e)) ? { |
||||
element: { |
||||
0: e.target, |
||||
offset: () => { |
||||
return { |
||||
left: e.pageX, |
||||
top: e.pageY, |
||||
}; |
||||
}, |
||||
bounds: () => { |
||||
// offset为其相对于父定位元素的偏移
|
||||
return { |
||||
x: e.offsetX, |
||||
y: e.offsetY, |
||||
width: 0, |
||||
height: 24, |
||||
}; |
||||
}, |
||||
outerWidth: () => { |
||||
return 0; |
||||
}, |
||||
outerHeight: () => { |
||||
return 24; |
||||
}, |
||||
}, |
||||
} : this.combo; |
||||
const positionRelativeElement = supportCSSTransform ? BI.DOM.getPositionRelativeContainingBlock(isNull(container) ? this.element[0] : Widget._renderEngine.createElement(isFunction(container) ? container() : container)[0]) : null; |
||||
const TRIANGLE_LENGTH = 12; |
||||
switch (direction) { |
||||
case "bottom": |
||||
case "bottom,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["bottom", "top", "right", "left"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "top": |
||||
case "top,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["top", "bottom", "right", "left"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "left": |
||||
case "left,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["left", "right", "bottom", "top"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right": |
||||
case "right,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "bottom", "top"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "top,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["top", "bottom", "left", "right"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "bottom,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, adjustXOffset, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight, ["bottom", "top", "left", "right"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "left,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["left", "right", "top", "bottom"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
case "right,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), adjustYOffset, isNeedAdjustHeight, ["right", "left", "top", "bottom"], offsetStyle, positionRelativeElement); |
||||
break; |
||||
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); |
||||
break; |
||||
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); |
||||
break; |
||||
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); |
||||
break; |
||||
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); |
||||
break; |
||||
case "top,custom": |
||||
case "custom,top": |
||||
p = BI.DOM.getTopAdaptPosition(combo, this.popupView, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight); |
||||
p.dir = "top"; |
||||
break; |
||||
case "custom,bottom": |
||||
case "bottom,custom": |
||||
p = BI.DOM.getBottomAdaptPosition(combo, this.popupView, (adjustYOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0), isNeedAdjustHeight); |
||||
p.dir = "bottom"; |
||||
break; |
||||
case "left,custom": |
||||
case "custom,left": |
||||
p = BI.DOM.getLeftAdaptPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0)); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
p.dir = "left"; |
||||
break; |
||||
case "custom,right": |
||||
case "right,custom": |
||||
p = BI.DOM.getRightAdaptPosition(combo, this.popupView, (adjustXOffset + adjustLength) + (showArrow ? TRIANGLE_LENGTH : 0)); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
p.dir = "right"; |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
var scaleX = positonedRect.width / positionRelativeElement.offsetWidth; |
||||
var scaleY = positonedRect.height / positionRelativeElement.offsetHeight; |
||||
if ("adaptHeight" in p) { |
||||
this.resetListHeight(p.adaptHeight); |
||||
} |
||||
|
||||
p.top && (p.top = Math.round(p.top / scaleY + positionRelativeElement.scrollTop)); |
||||
p.left && (p.left = Math.round(p.left / scaleX + positionRelativeElement.scrollLeft)); |
||||
const width = this.combo.element.outerWidth(); |
||||
const height = this.combo.element.outerHeight(); |
||||
this.popupView.setDirection && this.popupView.setDirection(p.dir, { |
||||
width, |
||||
height, |
||||
offsetStyle, |
||||
adjustXOffset, |
||||
adjustYOffset, |
||||
offset: this.combo.element.offset(), |
||||
}); |
||||
|
||||
p.adaptHeight && (p.adaptHeight = Math.round(p.adaptHeight / scaleY)); |
||||
} |
||||
if (supportCSSTransform) { |
||||
|
||||
if ("adaptHeight" in p) { |
||||
this.resetListHeight(p.adaptHeight); |
||||
} |
||||
const positonedRect = positionRelativeElement.getBoundingClientRect(); |
||||
|
||||
if ("left" in p) { |
||||
this.popupView.element.css({ |
||||
left: p.left, |
||||
}); |
||||
} |
||||
if ("top" in p) { |
||||
this.popupView.element.css({ |
||||
top: p.top, |
||||
}); |
||||
} |
||||
this.position = p; |
||||
this.popupView.setVisible(isVisible); |
||||
}, |
||||
const scaleX = positonedRect.width / positionRelativeElement.offsetWidth; |
||||
const scaleY = positonedRect.height / positionRelativeElement.offsetHeight; |
||||
|
||||
destroyed: function () { |
||||
BI.Widget._renderEngine.createElement(document) |
||||
.unbind("click." + this.getName()) |
||||
.unbind("mousedown." + this.getName()) |
||||
.unbind("mousewheel." + this.getName()) |
||||
.unbind("mouseenter." + this.getName()) |
||||
.unbind("mouseleave." + this.getName()); |
||||
BI.Widget._renderEngine.createElement(window) |
||||
.unbind("blur." + this.getName()); |
||||
BI.Resizers.remove(this.getName()); |
||||
this.popupView && this.popupView._destroy(); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
delete currentOpenedCombos[this.getName()]; |
||||
}, |
||||
}); |
||||
BI.Combo.closeAll = function () { |
||||
BI.each(currentOpenedCombos, function (i, combo) { |
||||
if (combo) { |
||||
combo.hideView(); |
||||
} |
||||
}); |
||||
currentOpenedCombos = {}; |
||||
needHideWhenAnotherComboOpen = {}; |
||||
}; |
||||
BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; |
||||
BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; |
||||
BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; |
||||
BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
p.top && (p.top = p.top / scaleY); |
||||
p.left && (p.left = p.left / scaleX); |
||||
} |
||||
|
||||
if ("left" in p) { |
||||
this.popupView.element.css({ |
||||
left: p.left, |
||||
}); |
||||
} |
||||
if ("top" in p) { |
||||
this.popupView.element.css({ |
||||
top: p.top, |
||||
}); |
||||
} |
||||
this.position = p; |
||||
this.popupView.setVisible(isVisible); |
||||
} |
||||
|
||||
BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; |
||||
BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; |
||||
BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; |
||||
BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; |
||||
destroyed() { |
||||
Widget._renderEngine.createElement(document) |
||||
.unbind("click." + this.getName()) |
||||
.unbind("mousedown." + this.getName()) |
||||
.unbind("mousewheel." + this.getName()) |
||||
.unbind("mouseenter." + this.getName()) |
||||
.unbind("mouseleave." + this.getName()); |
||||
Widget._renderEngine.createElement(window) |
||||
.unbind("blur." + this.getName()); |
||||
Resizers.remove(this.getName()); |
||||
this.popupView && this.popupView._destroy(); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
delete currentOpenedCombos[this.getName()]; |
||||
} |
||||
} |
||||
|
||||
BI.shortcut("bi.combo", BI.Combo); |
||||
}()); |
||||
Combo.closeAll = () => { |
||||
each(currentOpenedCombos, (i, combo) => { |
||||
if (combo) { |
||||
combo.hideView(); |
||||
} |
||||
}); |
||||
currentOpenedCombos = {}; |
||||
needHideWhenAnotherComboOpen = {}; |
||||
}; |
||||
|
@ -0,0 +1,12 @@
|
||||
export { Bubble } from "./bubble"; |
||||
export { Combo } from "./combo"; |
||||
export { Expander } from "./expander"; |
||||
export { ButtonGroup } from "./group.button"; |
||||
export { ComboGroup } from "./group.combo"; |
||||
export { VirtualGroup } from "./group.virtual"; |
||||
export { Loader } from "./loader"; |
||||
export { Navigation } from "./navigation"; |
||||
export { Searcher } from "./searcher"; |
||||
export { Switcher } from "./switcher"; |
||||
export { Tab } from "./tab"; |
||||
export { ButtonTree } from "./tree.button"; |
@ -1,95 +1,31 @@
|
||||
import Pane from "./1.pane"; |
||||
import Single from "./single/0.single"; |
||||
import Text from "./single/1.text"; |
||||
import A from "./single/a/a"; |
||||
import Tip from "./single/tip/0.tip"; |
||||
import Toast from "./single/tip/tip.toast"; |
||||
import Tooltip from "./single/tip/tip.tooltip"; |
||||
import Drawer from "./layer/layer.drawer"; |
||||
import { Popover, BarPopover } from "./layer/layer.popover"; |
||||
import PopupView from "./layer/layer.popup"; |
||||
import SearcherView from "./layer/layer.searcher"; |
||||
import ListView from "./list/listview"; |
||||
import VirtualGroupList from "./list/virtualgrouplist"; |
||||
import VirtualList from "./list/virtuallist"; |
||||
import { Pane } from "./1.pane"; |
||||
import * as single from "./single"; |
||||
import * as layer from "./layer"; |
||||
import * as list from "./list"; |
||||
import GridView from "./grid/grid"; |
||||
import Pager from "./pager/pager"; |
||||
import * as combination from "./combination"; |
||||
import { Msg } from "./foundation/message"; |
||||
|
||||
import { BasicButton } from "./single/button/button.basic"; |
||||
import { NodeButton } from "./single/button/button.node"; |
||||
import { Button } from "./single/button/buttons/button"; |
||||
import { IconButton } from "./single/button/buttons/button.icon"; |
||||
import { ImageButton } from "./single/button/buttons/button.image"; |
||||
import { TextButton } from "./single/button/buttons/button.text"; |
||||
import { BlankIconIconTextItem } from "./single/button/listitem/blankiconicontextitem"; |
||||
import { BlankIconTextIconItem } from "./single/button/listitem/blankicontexticonitem"; |
||||
import { BlankIconTextItem } from "./single/button/listitem/blankicontextitem"; |
||||
import { IconTextIconItem } from "./single/button/listitem/icontexticonitem"; |
||||
import { IconTextItem } from "./single/button/listitem/icontextitem"; |
||||
import { TextIconItem } from "./single/button/listitem/texticonitem"; |
||||
import { TextItem } from "./single/button/listitem/textitem"; |
||||
import { IconTextIconNode } from "./single/button/node/icontexticonnode"; |
||||
import { IconTextNode } from "./single/button/node/icontextnode"; |
||||
import { TextIconNode } from "./single/button/node/texticonnode"; |
||||
import { TextNode } from "./single/button/node/textnode"; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BI.extend(BI, { |
||||
NodeButton, |
||||
BasicButton, |
||||
Button, |
||||
IconButton, |
||||
ImageButton, |
||||
TextButton, |
||||
BlankIconIconTextItem, |
||||
BlankIconTextIconItem, |
||||
BlankIconTextItem, |
||||
IconTextIconItem, |
||||
IconTextItem, |
||||
TextIconItem, |
||||
TextItem, |
||||
IconTextIconNode, |
||||
IconTextNode, |
||||
TextIconNode, |
||||
TextNode, |
||||
Object.assign(BI, { |
||||
Pane, |
||||
Single, |
||||
Text, |
||||
A, |
||||
Tip, |
||||
Toast, |
||||
Tooltip, |
||||
Drawer, |
||||
Popover, |
||||
BarPopover, |
||||
PopupView, |
||||
SearcherView, |
||||
ListView, |
||||
VirtualGroupList, |
||||
VirtualList, |
||||
...layer, |
||||
...list, |
||||
...single, |
||||
GridView, |
||||
Pager, |
||||
...combination, |
||||
Msg, |
||||
}); |
||||
|
||||
export * from "./0.base"; |
||||
export * from "./combination"; |
||||
export * from "./layer"; |
||||
export * from "./list"; |
||||
export * from "./single"; |
||||
export { |
||||
Pane, |
||||
Single, |
||||
Text, |
||||
A, |
||||
Tip, |
||||
Toast, |
||||
Tooltip, |
||||
Drawer, |
||||
Popover, |
||||
BarPopover, |
||||
PopupView, |
||||
SearcherView, |
||||
ListView, |
||||
VirtualGroupList, |
||||
VirtualList, |
||||
GridView, |
||||
Pager, |
||||
Msg, |
||||
} |
@ -0,0 +1,4 @@
|
||||
export { Drawer } from "./layer.drawer"; |
||||
export { Popover, BarPopover } from "./layer.popover"; |
||||
export { PopupView } from "./layer.popup"; |
||||
export { SearcherView } from "./layer.searcher"; |
@ -0,0 +1,3 @@
|
||||
export { ListView } from "./listview"; |
||||
export { VirtualGroupList } from "./virtualgrouplist"; |
||||
export { VirtualList } from "./virtuallist"; |
@ -0,0 +1,17 @@
|
||||
export { BasicButton } from "./button.basic"; |
||||
export { NodeButton } from "./button.node"; |
||||
export { Button } from "./buttons/button"; |
||||
export { IconButton } from "./buttons/button.icon"; |
||||
export { ImageButton } from "./buttons/button.image"; |
||||
export { TextButton } from "./buttons/button.text"; |
||||
export { BlankIconIconTextItem } from "./listitem/blankiconicontextitem"; |
||||
export { BlankIconTextIconItem } from "./listitem/blankicontexticonitem"; |
||||
export { BlankIconTextItem } from "./listitem/blankicontextitem"; |
||||
export { IconTextIconItem } from "./listitem/icontexticonitem"; |
||||
export { IconTextItem } from "./listitem/icontextitem"; |
||||
export { TextIconItem } from "./listitem/texticonitem"; |
||||
export { TextItem } from "./listitem/textitem"; |
||||
export { IconTextIconNode } from "./node/icontexticonnode"; |
||||
export { IconTextNode } from "./node/icontextnode"; |
||||
export { TextIconNode } from "./node/texticonnode"; |
||||
export { TextNode } from "./node/textnode"; |
@ -0,0 +1,5 @@
|
||||
export { Single } from "./0.single"; |
||||
export { Text } from "./1.text"; |
||||
export { A } from "./a/a"; |
||||
export * from "./tip"; |
||||
export * from "./button" |
@ -0,0 +1,3 @@
|
||||
export { Tip } from "./0.tip"; |
||||
export { Toast } from "./tip.toast"; |
||||
export { Tooltip } from "./tip.tooltip"; |
@ -0,0 +1,2 @@
|
||||
export { Action } from "./action"; |
||||
export { ShowAction } from "./action.show"; |
@ -0,0 +1,3 @@
|
||||
export { Behavior } from "./0.behavior"; |
||||
export { HighlightBehavior } from "./behavior.highlight"; |
||||
export { RedMarkBehavior } from "./behavior.redmark"; |
@ -0,0 +1,9 @@
|
||||
export { Controller } from "./0.controller"; |
||||
export { BroadcastController } from "./controller.broadcast"; |
||||
export { BubblesController } from "./controller.bubbles"; |
||||
export { DrawerController } from "./controller.drawer"; |
||||
export { LayerController } from "./controller.layer"; |
||||
export { MaskersController } from "./controller.masker"; |
||||
export { PopoverController } from "./controller.popover"; |
||||
export { ResizeController } from "./controller.resizer"; |
||||
export { TooltipsController } from "./controller.tooltips"; |
@ -0,0 +1,6 @@
|
||||
export * from "./alias"; |
||||
export * from "./array"; |
||||
export * from "./date"; |
||||
export * from "./function"; |
||||
export * from "./number"; |
||||
export * from "./string"; |
@ -1,156 +1,154 @@
|
||||
BI._.extend(BI, { |
||||
// 给Number类型增加一个add方法,调用起来更加方便。
|
||||
add: function (num, arg) { |
||||
return accAdd(arg, num); |
||||
// 给Number类型增加一个add方法,调用起来更加方便。
|
||||
export function add(num, arg) { |
||||
return accAdd(arg, num); |
||||
|
||||
/** |
||||
** 加法函数,用来得到精确的加法结果 |
||||
** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 |
||||
** 调用:accAdd(arg1,arg2) |
||||
** 返回值:arg1加上arg2的精确结果 |
||||
**/ |
||||
function accAdd (arg1, arg2) { |
||||
var r1, r2, m, c; |
||||
try { |
||||
r1 = arg1.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r1 = 0; |
||||
} |
||||
try { |
||||
r2 = arg2.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r2 = 0; |
||||
} |
||||
c = Math.abs(r1 - r2); |
||||
m = Math.pow(10, Math.max(r1, r2)); |
||||
if (c > 0) { |
||||
var cm = Math.pow(10, c); |
||||
if (r1 > r2) { |
||||
arg1 = Number(arg1.toString().replace(".", "")); |
||||
arg2 = Number(arg2.toString().replace(".", "")) * cm; |
||||
} else { |
||||
arg1 = Number(arg1.toString().replace(".", "")) * cm; |
||||
arg2 = Number(arg2.toString().replace(".", "")); |
||||
} |
||||
} else { |
||||
/** |
||||
** 加法函数,用来得到精确的加法结果 |
||||
** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 |
||||
** 调用:accAdd(arg1,arg2) |
||||
** 返回值:arg1加上arg2的精确结果 |
||||
**/ |
||||
function accAdd(arg1, arg2) { |
||||
let r1, r2, m, c; |
||||
try { |
||||
r1 = arg1.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r1 = 0; |
||||
} |
||||
try { |
||||
r2 = arg2.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r2 = 0; |
||||
} |
||||
c = Math.abs(r1 - r2); |
||||
m = Math.pow(10, Math.max(r1, r2)); |
||||
if (c > 0) { |
||||
const cm = Math.pow(10, c); |
||||
if (r1 > r2) { |
||||
arg1 = Number(arg1.toString().replace(".", "")); |
||||
arg2 = Number(arg2.toString().replace(".", "")) * cm; |
||||
} else { |
||||
arg1 = Number(arg1.toString().replace(".", "")) * cm; |
||||
arg2 = Number(arg2.toString().replace(".", "")); |
||||
} |
||||
return (arg1 + arg2) / m; |
||||
} else { |
||||
arg1 = Number(arg1.toString().replace(".", "")); |
||||
arg2 = Number(arg2.toString().replace(".", "")); |
||||
} |
||||
}, |
||||
return (arg1 + arg2) / m; |
||||
} |
||||
} |
||||
|
||||
// 给Number类型增加一个sub方法,调用起来更加方便。
|
||||
sub: function (num, arg) { |
||||
return accSub(num, arg); |
||||
// 给Number类型增加一个sub方法,调用起来更加方便。
|
||||
export function sub(num, arg) { |
||||
return accSub(num, arg); |
||||
|
||||
/** |
||||
** 减法函数,用来得到精确的减法结果 |
||||
** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 |
||||
** 调用:accSub(arg1,arg2) |
||||
** 返回值:arg1加上arg2的精确结果 |
||||
**/ |
||||
function accSub (arg1, arg2) { |
||||
var r1, r2, m, n; |
||||
try { |
||||
r1 = arg1.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r1 = 0; |
||||
} |
||||
try { |
||||
r2 = arg2.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r2 = 0; |
||||
} |
||||
m = Math.pow(10, Math.max(r1, r2)); // last modify by deeka //动态控制精度长度
|
||||
n = (r1 >= r2) ? r1 : r2; |
||||
return ((arg1 * m - arg2 * m) / m).toFixed(n); |
||||
/** |
||||
** 减法函数,用来得到精确的减法结果 |
||||
** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 |
||||
** 调用:accSub(arg1,arg2) |
||||
** 返回值:arg1加上arg2的精确结果 |
||||
**/ |
||||
function accSub(arg1, arg2) { |
||||
let r1, r2, m, n; |
||||
try { |
||||
r1 = arg1.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r1 = 0; |
||||
} |
||||
}, |
||||
|
||||
// 给Number类型增加一个mul方法,调用起来更加方便。
|
||||
mul: function (num, arg) { |
||||
return accMul(arg, num); |
||||
|
||||
/** |
||||
** 乘法函数,用来得到精确的乘法结果 |
||||
** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 |
||||
** 调用:accMul(arg1,arg2) |
||||
** 返回值:arg1乘以 arg2的精确结果 |
||||
**/ |
||||
function accMul (arg1, arg2) { |
||||
var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); |
||||
try { |
||||
m += s1.split(".")[1].length; |
||||
} catch (e) { |
||||
} |
||||
try { |
||||
m += s2.split(".")[1].length; |
||||
} catch (e) { |
||||
} |
||||
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); |
||||
try { |
||||
r2 = arg2.toString().split(".")[1].length; |
||||
} catch (e) { |
||||
r2 = 0; |
||||
} |
||||
}, |
||||
m = Math.pow(10, Math.max(r1, r2)); // last modify by deeka //动态控制精度长度
|
||||
n = (r1 >= r2) ? r1 : r2; |
||||
return ((arg1 * m - arg2 * m) / m).toFixed(n); |
||||
} |
||||
} |
||||
|
||||
// 给Number类型增加一个div方法,调用起来更加方便。
|
||||
div: function (num, arg) { |
||||
return accDivide(num, arg); |
||||
// 给Number类型增加一个mul方法,调用起来更加方便。
|
||||
export function mul(num, arg) { |
||||
return accMul(arg, num); |
||||
|
||||
/** |
||||
* Return digits length of a number |
||||
* @param {*number} num Input number |
||||
*/ |
||||
function digitLength (num) { |
||||
// Get digit length of e
|
||||
var eSplit = num.toString().split(/[eE]/); |
||||
var len = (eSplit[0].split(".")[1] || "").length - (+(eSplit[1] || 0)); |
||||
return len > 0 ? len : 0; |
||||
/** |
||||
** 乘法函数,用来得到精确的乘法结果 |
||||
** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 |
||||
** 调用:accMul(arg1,arg2) |
||||
** 返回值:arg1乘以 arg2的精确结果 |
||||
**/ |
||||
function accMul(arg1, arg2) { |
||||
let m = 0, s1 = arg1.toString(), s2 = arg2.toString(); |
||||
try { |
||||
m += s1.split(".")[1].length; |
||||
} catch (e) { |
||||
} |
||||
/** |
||||
* 把小数转成整数,支持科学计数法。如果是小数则放大成整数 |
||||
* @param {*number} num 输入数 |
||||
*/ |
||||
function float2Fixed (num) { |
||||
if (num.toString().indexOf("e") === -1) { |
||||
return Number(num.toString().replace(".", "")); |
||||
} |
||||
var dLen = digitLength(num); |
||||
return dLen > 0 ? num * Math.pow(10, dLen) : num; |
||||
try { |
||||
m += s2.split(".")[1].length; |
||||
} catch (e) { |
||||
} |
||||
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 精确乘法 |
||||
*/ |
||||
function times (num1, num2) { |
||||
var others = []; |
||||
for (var _i = 2; _i < arguments.length; _i++) { |
||||
others[_i - 2] = arguments[_i]; |
||||
} |
||||
if (others.length > 0) { |
||||
return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1))); |
||||
} |
||||
var num1Changed = float2Fixed(num1); |
||||
var num2Changed = float2Fixed(num2); |
||||
var baseNum = digitLength(num1) + digitLength(num2); |
||||
var leftValue = num1Changed * num2Changed; |
||||
return leftValue / Math.pow(10, baseNum); |
||||
// 给Number类型增加一个div方法,调用起来更加方便。
|
||||
export function div(num, arg) { |
||||
return accDivide(num, arg); |
||||
|
||||
/** |
||||
* Return digits length of a number |
||||
* @param {*number} num Input number |
||||
*/ |
||||
function digitLength(num) { |
||||
// Get digit length of e
|
||||
const eSplit = num.toString().split(/[eE]/); |
||||
const len = (eSplit[0].split(".")[1] || "").length - (+(eSplit[1] || 0)); |
||||
return len > 0 ? len : 0; |
||||
} |
||||
|
||||
/** |
||||
* 把小数转成整数,支持科学计数法。如果是小数则放大成整数 |
||||
* @param {*number} num 输入数 |
||||
*/ |
||||
function float2Fixed(num) { |
||||
if (num.toString().indexOf("e") === -1) { |
||||
return Number(num.toString().replace(".", "")); |
||||
} |
||||
const dLen = digitLength(num); |
||||
return dLen > 0 ? num * Math.pow(10, dLen) : num; |
||||
} |
||||
|
||||
/** |
||||
* 精确除法 |
||||
*/ |
||||
function accDivide (num1, num2) { |
||||
var others = []; |
||||
for (var _i = 2; _i < arguments.length; _i++) { |
||||
others[_i - 2] = arguments[_i]; |
||||
} |
||||
if (others.length > 0) { |
||||
return accDivide.apply(void 0, [accDivide(num1, num2), others[0]].concat(others.slice(1))); |
||||
} |
||||
var num1Changed = float2Fixed(num1); |
||||
var num2Changed = float2Fixed(num2); |
||||
return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1))); |
||||
/** |
||||
* 精确乘法 |
||||
*/ |
||||
function times(num1, num2) { |
||||
const others = []; |
||||
for (let _i = 2; _i < arguments.length; _i++) { |
||||
others[_i - 2] = arguments[_i]; |
||||
} |
||||
if (others.length > 0) { |
||||
return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1))); |
||||
} |
||||
const num1Changed = float2Fixed(num1); |
||||
const num2Changed = float2Fixed(num2); |
||||
const baseNum = digitLength(num1) + digitLength(num2); |
||||
const leftValue = num1Changed * num2Changed; |
||||
return leftValue / Math.pow(10, baseNum); |
||||
} |
||||
|
||||
}); |
||||
/** |
||||
* 精确除法 |
||||
*/ |
||||
function accDivide(num1, num2) { |
||||
const others = []; |
||||
for (let _i = 2; _i < arguments.length; _i++) { |
||||
others[_i - 2] = arguments[_i]; |
||||
} |
||||
if (others.length > 0) { |
||||
return accDivide.apply(void 0, [accDivide(num1, num2), others[0]].concat(others.slice(1))); |
||||
} |
||||
const num1Changed = float2Fixed(num1); |
||||
const num2Changed = float2Fixed(num2); |
||||
return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1))); |
||||
} |
||||
} |
||||
|
@ -1,123 +1,121 @@
|
||||
import {isString} from "../2.base"; |
||||
|
||||
/** |
||||
* 对字符串对象的扩展 |
||||
* @class String |
||||
* 判断字符串是否已指定的字符串开始 |
||||
* @param str source字符串 |
||||
* @param {String} startTag 指定的开始字符串 |
||||
* @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false |
||||
*/ |
||||
BI._.extend(BI, { |
||||
export function startWith(str, startTag) { |
||||
str = str || ""; |
||||
if (startTag == null || startTag == "" || str.length === 0 || startTag.length > str.length) { |
||||
return false; |
||||
} |
||||
return str.substring(0, startTag.length) == startTag; |
||||
} |
||||
|
||||
/** |
||||
* 判断字符串是否已指定的字符串开始 |
||||
* @param str source字符串 |
||||
* @param {String} startTag 指定的开始字符串 |
||||
* @return {Boolean} 如果字符串以指定字符串开始则返回true,否则返回false |
||||
*/ |
||||
startWith: function (str, startTag) { |
||||
str = str || ""; |
||||
if (startTag == null || startTag == "" || str.length === 0 || startTag.length > str.length) { |
||||
return false; |
||||
} |
||||
return str.substr(0, startTag.length) == startTag; |
||||
}, |
||||
/** |
||||
* 判断字符串是否以指定的字符串结束 |
||||
* @param str source字符串 |
||||
* @param {String} endTag 指定的字符串 |
||||
* @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false |
||||
*/ |
||||
endWith: function (str, endTag) { |
||||
if (endTag == null || endTag == "" || str.length === 0 || endTag.length > str.length) { |
||||
return false; |
||||
} |
||||
return str.substring(str.length - endTag.length) == endTag; |
||||
}, |
||||
/** |
||||
* 判断字符串是否以指定的字符串结束 |
||||
* @param str source字符串 |
||||
* @param {String} endTag 指定的字符串 |
||||
* @return {Boolean} 如果字符串以指定字符串结束则返回true,否则返回false |
||||
*/ |
||||
export function endWith(str, endTag) { |
||||
if (endTag == null || endTag == "" || str.length === 0 || endTag.length > str.length) { |
||||
return false; |
||||
} |
||||
return str.substring(str.length - endTag.length) == endTag; |
||||
} |
||||
|
||||
/** |
||||
* 获取url中指定名字的参数 |
||||
* @param str source字符串 |
||||
* @param {String} name 参数的名字 |
||||
* @return {String} 参数的值 |
||||
*/ |
||||
getQuery: function (str, name) { |
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
||||
var r = str.substr(str.indexOf("?") + 1).match(reg); |
||||
if (r) { |
||||
return unescape(r[2]); |
||||
} |
||||
return null; |
||||
}, |
||||
/** |
||||
* 获取url中指定名字的参数 |
||||
* @param str source字符串 |
||||
* @param {String} name 参数的名字 |
||||
* @return {String} 参数的值 |
||||
*/ |
||||
export function getQuery(str, name) { |
||||
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
||||
const r = str.substr(str.indexOf("?") + 1).match(reg); |
||||
if (r) { |
||||
return unescape(r[2]); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 给url加上给定的参数 |
||||
* @param str source字符串 |
||||
* @param {Object} paras 参数对象,是一个键值对对象 |
||||
* @return {String} 添加了给定参数的url |
||||
*/ |
||||
appendQuery: function (str, paras) { |
||||
if (!paras) { |
||||
return str; |
||||
} |
||||
var src = str; |
||||
// 没有问号说明还没有参数
|
||||
if (src.indexOf("?") === -1) { |
||||
src += "?"; |
||||
} |
||||
// 如果以问号结尾,说明没有其他参数
|
||||
if (BI.endWith(src, "?") !== false) { |
||||
} else { |
||||
src += "&"; |
||||
} |
||||
BI._.each(paras, function (value, name) { |
||||
if (typeof(name) === "string") { |
||||
src += name + "=" + value + "&"; |
||||
} |
||||
}); |
||||
src = src.substr(0, src.length - 1); |
||||
return src; |
||||
}, |
||||
/** |
||||
* 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 |
||||
* @param str source字符串 |
||||
* @param {String} s1 要替换的字符串的正则表达式 |
||||
* @param {String} s2 替换的结果字符串 |
||||
* @returns {String} 替换后的字符串 |
||||
*/ |
||||
replaceAll: function (str, s1, s2) { |
||||
return BI.isString(str) ? str.replace(new RegExp(s1, "gm"), s2) : str; |
||||
}, |
||||
/** |
||||
* 总是让字符串以指定的字符开头 |
||||
* @param str source字符串 |
||||
* @param {String} start 指定的字符 |
||||
* @returns {String} 以指定字符开头的字符串 |
||||
*/ |
||||
perfectStart: function (str, start) { |
||||
if (BI.startWith(str, start)) { |
||||
return str; |
||||
/** |
||||
* 给url加上给定的参数 |
||||
* @param str source字符串 |
||||
* @param {Object} paras 参数对象,是一个键值对对象 |
||||
* @return {String} 添加了给定参数的url |
||||
*/ |
||||
export function appendQuery(str, paras) { |
||||
if (!paras) { |
||||
return str; |
||||
} |
||||
let src = str; |
||||
// 没有问号说明还没有参数
|
||||
if (src.indexOf("?") === -1) { |
||||
src += "?"; |
||||
} |
||||
// 如果以问号结尾,说明没有其他参数
|
||||
if (BI.endWith(src, "?") !== false) { |
||||
} else { |
||||
src += "&"; |
||||
} |
||||
BI._.each(paras, function (value, name) { |
||||
if (typeof (name) === "string") { |
||||
src += name + "=" + value + "&"; |
||||
} |
||||
return start + str; |
||||
}); |
||||
src = src.substr(0, src.length - 1); |
||||
return src; |
||||
} |
||||
|
||||
}, |
||||
/** |
||||
* 将所有符合第一个字符串所表示的字符串替换成为第二个字符串 |
||||
* @param str source字符串 |
||||
* @param {String} s1 要替换的字符串的正则表达式 |
||||
* @param {String} s2 替换的结果字符串 |
||||
* @returns {String} 替换后的字符串 |
||||
*/ |
||||
export function replaceAll(str, s1, s2) { |
||||
return isString(str) ? str.replace(new RegExp(s1, "gm"), s2) : str; |
||||
} |
||||
|
||||
/** |
||||
* 获取字符串中某字符串的所有项位置数组 |
||||
* @param str source字符串 |
||||
* @param {String} sub 子字符串 |
||||
* @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 |
||||
*/ |
||||
allIndexOf: function (str, sub) { |
||||
if (typeof sub !== "string") { |
||||
return []; |
||||
} |
||||
var location = []; |
||||
var offset = 0; |
||||
while (str.length > 0) { |
||||
var loc = str.indexOf(sub); |
||||
if (loc === -1) { |
||||
break; |
||||
} |
||||
location.push(offset + loc); |
||||
str = str.substring(loc + sub.length, str.length); |
||||
offset += loc + sub.length; |
||||
/** |
||||
* 总是让字符串以指定的字符开头 |
||||
* @param str source字符串 |
||||
* @param {String} start 指定的字符 |
||||
* @returns {String} 以指定字符开头的字符串 |
||||
*/ |
||||
export function perfectStart(str, start) { |
||||
if (BI.startWith(str, start)) { |
||||
return str; |
||||
} |
||||
return start + str; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 获取字符串中某字符串的所有项位置数组 |
||||
* @param str source字符串 |
||||
* @param {String} sub 子字符串 |
||||
* @return {Number[]} 子字符串在父字符串中出现的所有位置组成的数组 |
||||
*/ |
||||
export function allIndexOf(str, sub) { |
||||
if (typeof sub !== "string") { |
||||
return []; |
||||
} |
||||
const location = []; |
||||
let offset = 0; |
||||
while (str.length > 0) { |
||||
const loc = str.indexOf(sub); |
||||
if (loc === -1) { |
||||
break; |
||||
} |
||||
return location; |
||||
location.push(offset + loc); |
||||
str = str.substring(loc + sub.length, str.length); |
||||
offset += loc + sub.length; |
||||
} |
||||
}); |
||||
return location; |
||||
} |
||||
|
@ -1,66 +1,45 @@
|
||||
import { shortcut } from "./decorator"; |
||||
import OB from "./3.ob"; |
||||
import Widget from "./4.widget"; |
||||
import Action from "./action/action"; |
||||
import ShowAction from "./action/action.show"; |
||||
import Behavior from "./behavior/0.behavior"; |
||||
import HighlightBehavior from "./behavior/behavior.highlight"; |
||||
import RedMarkBehavior from "./behavior/behavior.redmark"; |
||||
import Controller from "./controller/0.controller"; |
||||
import BroadcastController from "./controller/controller.broadcast"; |
||||
import BubblesController from "./controller/controller.bubbles"; |
||||
import DrawerController from "./controller/controller.drawer"; |
||||
import LayerController from "./controller/controller.layer"; |
||||
import MaskersController from "./controller/controller.masker"; |
||||
import PopoverController from "./controller/controller.popover"; |
||||
import ResizeController from "./controller/controller.resizer"; |
||||
import TooltipsController from "./controller/controller.tooltips"; |
||||
import StyleLoaderManager from "./loader/loader.style"; |
||||
|
||||
BI.extend(BI, { |
||||
OB, |
||||
Widget, |
||||
Action, |
||||
ShowAction, |
||||
Behavior, |
||||
HighlightBehavior, |
||||
RedMarkBehavior, |
||||
Controller, |
||||
BroadcastController, |
||||
BubblesController, |
||||
DrawerController, |
||||
LayerController, |
||||
MaskersController, |
||||
PopoverController, |
||||
ResizeController, |
||||
TooltipsController, |
||||
StyleLoaderManager, |
||||
}); |
||||
import * as base from "./2.base"; |
||||
import * as ob from "./3.ob"; |
||||
import * as widget from "./4.widget"; |
||||
import * as inject from "./5.inject"; |
||||
import * as action from "./action"; |
||||
import * as behavior from "./behavior"; |
||||
import * as controllers from "./controller"; |
||||
import * as func from "./func"; |
||||
import { StyleLoaderManager } from "./loader/loader.style"; |
||||
import "./h"; |
||||
import { ShowListener } from "./listener/listener.show"; |
||||
import { shortcut } from "./decorator"; |
||||
|
||||
export * from './2.base'; |
||||
export * from './4.widget'; |
||||
export * from './5.inject'; |
||||
export * from "./2.base"; |
||||
export * from "./3.ob"; |
||||
export * from "./4.widget"; |
||||
export * from "./5.inject"; |
||||
export * from "./action"; |
||||
export * from "./behavior"; |
||||
export * from "./controller"; |
||||
export * from "./func"; |
||||
|
||||
// 有了后删掉
|
||||
export const emptyFn = () => { } |
||||
|
||||
export { |
||||
shortcut, |
||||
OB, |
||||
Widget, |
||||
Action, |
||||
ShowAction, |
||||
Behavior, |
||||
HighlightBehavior, |
||||
RedMarkBehavior, |
||||
Controller, |
||||
BroadcastController, |
||||
BubblesController, |
||||
DrawerController, |
||||
LayerController, |
||||
MaskersController, |
||||
PopoverController, |
||||
ResizeController, |
||||
TooltipsController, |
||||
StyleLoaderManager, |
||||
ShowListener, |
||||
shortcut, |
||||
} |
||||
|
||||
Object.assign(BI, { |
||||
...base, |
||||
...ob, |
||||
...widget, |
||||
...inject, |
||||
...behavior, |
||||
component: inject.shortcut, |
||||
...action, |
||||
...controllers, |
||||
...func, |
||||
StyleLoaderManager, |
||||
ShowListener, |
||||
}); |
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue