/** * Created by GUY on 2015/4/15. * @class BI.Editor * @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() export class Editor extends Single { static xtype = "bi.editor"; static EVENT_CHANGE = "EVENT_CHANGE"; static EVENT_FOCUS = "EVENT_FOCUS"; static EVENT_BLUR = "EVENT_BLUR"; static EVENT_CLICK = "EVENT_CLICK"; static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; static EVENT_SPACE = "EVENT_SPACE"; static EVENT_BACKSPACE = "EVENT_BACKSPACE"; static EVENT_START = "EVENT_START"; static EVENT_PAUSE = "EVENT_PAUSE"; static EVENT_STOP = "EVENT_STOP"; static EVENT_CONFIRM = "EVENT_CONFIRM"; static EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; static EVENT_VALID = "EVENT_VALID"; static EVENT_ERROR = "EVENT_ERROR"; static EVENT_ENTER = "EVENT_ENTER"; static EVENT_RESTRICT = "EVENT_RESTRICT"; static EVENT_REMOVE = "EVENT_REMOVE"; static EVENT_EMPTY = "EVENT_EMPTY"; _defaultConfig() { const conf = super._defaultConfig(arguments); return extend(conf, { baseCls: "bi-editor bi-focus-shadow", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, // title,warningTitle这两个属性没用 tipType: "warning", inputType: "text", validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: false, watermark: "", errorText: "", autoTrim: true, }); } render() { const { value, watermark, validationChecker, quitChecker, allowBlank, inputType, hgap, vgap, lgap, rgap, tgap, bgap } = this.options; // 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码 const autocomplete = this.options.autocomplete ? " autocomplete=" + this.options.autocomplete : ""; this.editor = this.addWidget(createWidget({ type: "bi.input", element: "", root: true, value, watermark, validationChecker, quitChecker, allowBlank, })); this.editor.element.css({ width: "100%", height: "100%", border: "none", outline: "none", padding: "0", margin: "0", }); const items = [ { el: { type: "bi.absolute", ref: (_ref) => { this.contentWrapper = _ref; }, items: [ { el: this.editor, left: 0, right: 0, top: 0, bottom: 0, } ], }, left: hgap + lgap, right: hgap + rgap, top: vgap + tgap, bottom: vgap + bgap, } ]; createWidget({ type: "bi.absolute", element: this, items, }); this.setWaterMark(this.options.watermark); this.editor.on(Controller.EVENT_CHANGE, (...args) => { this.fireEvent(Controller.EVENT_CHANGE, ...args); }); this.editor.on(Input.EVENT_FOCUS, (...args) => { this._checkError(); this.element.addClass("bi-editor-focus"); this.fireEvent(Editor.EVENT_FOCUS, ...args); }); this.editor.on(Input.EVENT_BLUR, (...args) => { this._setErrorVisible(false); this.element.removeClass("bi-editor-focus"); this.fireEvent(Editor.EVENT_BLUR, ...args); }); this.editor.on(Input.EVENT_CLICK, (...args) => { this.fireEvent(Editor.EVENT_CLICK, ...args); }); this.editor.on(Input.EVENT_CHANGE, (...args) => { this.fireEvent(Editor.EVENT_CHANGE, ...args); }); this.editor.on(Input.EVENT_KEY_DOWN, (v, ...args) => { this.fireEvent(Editor.EVENT_KEY_DOWN, v, ...args); }); this.editor.on(Input.EVENT_QUICK_DOWN, (e) => { // tab键就不要隐藏了 if (e.keyCode !== BI.KeyCode.TAB && this.watermark) { this.watermark.invisible(); } }); this.editor.on(Input.EVENT_VALID, (...args) => { this._checkWaterMark(); this._setErrorVisible(false); this.element.removeClass("error"); this.fireEvent(Editor.EVENT_VALID, ...args); }); this.editor.on(Input.EVENT_ERROR, (...args) => { this._checkWaterMark(); this.fireEvent(Editor.EVENT_ERROR, ...args); this._setErrorVisible(this.isEditing()); this.element.addClass("error"); }); this.editor.on(Input.EVENT_RESTRICT, (...args) => { this._checkWaterMark(); const tip = this._setErrorVisible(true); tip && tip.element.fadeOut(100, () => { tip.element.fadeIn(100); }); this.fireEvent(Editor.EVENT_RESTRICT, ...args); }); this.editor.on(Input.EVENT_EMPTY, (...args) => { this._checkWaterMark(); this.fireEvent(Editor.EVENT_EMPTY, ...args); }); this.editor.on(Input.EVENT_ENTER, (...args) => { this.fireEvent(Editor.EVENT_ENTER, ...args); }); this.editor.on(Input.EVENT_SPACE, (...args) => { this.fireEvent(Editor.EVENT_SPACE, ...args); }); this.editor.on(Input.EVENT_BACKSPACE, (...args) => { this.fireEvent(Editor.EVENT_BACKSPACE, ...args); }); this.editor.on(Input.EVENT_REMOVE, (...args) => { this.fireEvent(Editor.EVENT_REMOVE, ...args); }); this.editor.on(Input.EVENT_START, (...args) => { this.fireEvent(Editor.EVENT_START, ...args); }); this.editor.on(Input.EVENT_PAUSE, (...args) => { this.fireEvent(Editor.EVENT_PAUSE, ...args); }); this.editor.on(Input.EVENT_STOP, (...args) => { this.fireEvent(Editor.EVENT_STOP, ...args); }); this.editor.on(Input.EVENT_CONFIRM, (...args) => { this.fireEvent(Editor.EVENT_CONFIRM, ...args); }); this.editor.on(Input.EVENT_CHANGE_CONFIRM, (...args) => { this.fireEvent(Editor.EVENT_CHANGE_CONFIRM, ...args); }); this.element.click((e) => { e.stopPropagation(); return false; }); if (isKey(this.options.value) || isEmptyString(this.options.value)) { this._checkError(); this._checkWaterMark(); } else { this._checkWaterMark(); } } _checkToolTip() { const { errorText } = this.options; if (isFunction(errorText)) { this.options.errorText = errorText(this.editor.getValue()); } if (isKey(errorText)) { if (!this.isEnabled() || this.isValid() || Bubbles.has(this.getName())) { this.setTitle(""); } else { this.setTitle(errorText); } } } _assertWaterMark() { const { height, vgap, tgap } = this.options; if (isNull(this.watermark)) { this.watermark = createWidget({ type: "bi.label", cls: "bi-water-mark", text: this.options.watermark, height: height - 2 * vgap - tgap, hgap: 2, whiteSpace: "nowrap", textAlign: "left", }); this.watermark.element.bind({ mousedown: (e) => { if (this.isEnabled()) { this.editor.isEditing() || this.editor.focus(); } else { this.editor.isEditing() && this.editor.blur(); } e.stopEvent(); }, }); this.watermark.element.bind("click", (e) => { if (this.isEnabled()) { this.editor.isEditing() || this.editor.focus(); } else { this.editor.isEditing() && this.editor.blur(); } e.stopEvent(); }); } } _checkError() { this._setErrorVisible(this.isEnabled() && !this.isValid()); this._checkToolTip(); } _checkWaterMark() { const { watermark } = this.options; if (!this.disabledWaterMark && this.editor.getValue() === "" && isKey(watermark)) { this.watermark && this.watermark.visible(); } else { this.watermark && this.watermark.invisible(); } } setErrorText(text) { this.options.errorText = text; } getErrorText() { return this.options.errorText; } setWaterMark(v) { this.options.watermark = v; if (isNull(this.watermark)) { this._assertWaterMark(); createWidget({ type: "bi.absolute", element: this.contentWrapper, items: [ { el: this.watermark, left: 0, right: 0, top: 0, bottom: 0, } ], }); } this.watermark.setText(v); this._checkWaterMark(); } _setErrorVisible(b) { const { errorText, autoTrim, simple } = this.options; if (isFunction(errorText)) { this.options.errorText = errorText(autoTrim ? trim(this.editor.getValue()) : this.editor.getValue()); } if (!this.disabledError && isKey(errorText)) { Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { adjustYOffset: simple ? 1 : 2, }); this._checkToolTip(); } } disableError() { this.disabledError = true; this._checkError(); } enableError() { this.disabledError = false; this._checkError(); } disableWaterMark() { this.disabledWaterMark = true; this._checkWaterMark(); } enableWaterMark() { this.disabledWaterMark = false; this._checkWaterMark(); } focus() { this.element.addClass("text-editor-focus"); this.editor.focus(); } blur() { this.element.removeClass("text-editor-focus"); this.editor.blur(); } selectAll() { this.editor.selectAll(); } onKeyDown(k) { this.editor.onKeyDown(k); } setValue(v) { super.setValue(v); this.editor.setValue(v); this._checkError(); this._checkWaterMark(); } getLastValidValue() { return this.editor.getLastValidValue(); } getLastChangedValue() { return this.editor.getLastChangedValue(); } getValue() { if (!this.isValid()) { return this.options.autoTrim ? trim(this.editor.getLastValidValue()) : this.editor.getLastValidValue(); } return this.options.autoTrim ? trim(this.editor.getValue()) : this.editor.getValue(); } isEditing() { return this.editor.isEditing(); } isValid() { return this.editor.isValid(); } destroyed() { Bubbles.remove(this.getName()); } }