diff --git a/src/core/func/function.js b/src/core/func/function.js index ecbd78f2d..5977e24d7 100644 --- a/src/core/func/function.js +++ b/src/core/func/function.js @@ -2,8 +2,8 @@ * 基本的函数 * Created by GUY on 2015/6/24. */ -import {every, isKey, isArray, toUpperCase, each, stripEL, isNotNull, isNull, isObject} from "../2.base"; -import {makeFirstPY} from "../utils/chinesePY"; +import { every, isKey, isArray, toUpperCase, each, stripEL, isNotNull, isNull, isObject } from "../2.base"; +import { makeFirstPY } from "../utils/chinesePY"; /** * 创建唯一的名字 diff --git a/src/core/index.js b/src/core/index.js index 34ab918cd..eca5e3e99 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -16,6 +16,7 @@ import * as constant from "./constant"; import * as logic from "./logic"; import { Element } from "./element"; import * as utils from "./utils"; +import * as platform from "./platform/web"; export * from "./decorator"; export * from "./2.base"; @@ -31,6 +32,7 @@ export * from "./h"; export * from "./constant"; export * from "./logic"; export * from "./utils"; +export * from "./platform/web"; export { StyleLoaderManager, @@ -60,4 +62,5 @@ Object.assign(BI, { useInWorker, ...h, ...utils, + ...platform, }); diff --git a/src/core/platform/web/index.js b/src/core/platform/web/index.js index 6dcaf06ba..db216134b 100644 --- a/src/core/platform/web/index.js +++ b/src/core/platform/web/index.js @@ -2,3 +2,6 @@ export * as DOM from "./dom"; export * from "./detectElementResize"; export * from "./function"; export * from "./load"; + +import "./jquery/index"; +import "./config"; diff --git a/src/core/platform/web/jquery/event.js b/src/core/platform/web/jquery/event.js index b7a9500f3..ea3ec568f 100644 --- a/src/core/platform/web/jquery/event.js +++ b/src/core/platform/web/jquery/event.js @@ -3,8 +3,8 @@ */ BI.$.extend(BI.$.Event.prototype, { // event.stopEvent - stopEvent: function () { + stopEvent() { this.stopPropagation(); this.preventDefault(); - } -}); \ No newline at end of file + }, +}); diff --git a/src/core/platform/web/jquery/fn.js b/src/core/platform/web/jquery/fn.js index 33584d838..16041a83e 100644 --- a/src/core/platform/web/jquery/fn.js +++ b/src/core/platform/web/jquery/fn.js @@ -1,247 +1,252 @@ -if (BI.jQuery) { - (function ($) { - // richer:容器在其各个边缘留出的空间 - if (!$.fn.insets) { - $.fn.insets = function () { - var p = this.padding(), - b = this.border(); - return { - top: p.top, - bottom: p.bottom + b.bottom + b.top, - left: p.left, - right: p.right + b.right + b.left - }; - }; - } - - // richer:获取 && 设置jQuery元素的边界 - if (!$.fn.bounds) { - $.fn.bounds = function (value) { - var tmp = {hasIgnoredBounds: true}; - - if (value) { - if (!isNaN(value.x)) { - tmp.left = value.x; - } - if (!isNaN(value.y)) { - tmp.top = value.y; - } - if (value.width != null) { - tmp.width = (value.width - (this.outerWidth(true) - this.width())); - tmp.width = (tmp.width >= 0) ? tmp.width : value.width; - // fix chrome - // tmp.width = (tmp.width >= 0) ? tmp.width : 0; - } - if (value.height != null) { - tmp.height = value.height - (this.outerHeight(true) - this.height()); - tmp.height = (tmp.height >= 0) ? tmp.height : value.height; - // fix chrome - // tmp.height = (tmp.height >= 0) ? tmp.height : value.0; - } - this.css(tmp); - return this; - } - - // richer:注意此方法只对可见元素有效 - tmp = this.position(); - return { - x: tmp.left, - y: tmp.top, - // richer:这里计算外部宽度和高度的时候,都不包括边框 - width: this.outerWidth(), - height: this.outerHeight() - }; - - }; - } - })(BI.jQuery); - - BI.extend(BI.jQuery.fn, { - - destroy: function () { - this.remove(); - if (BI.isIE() === true) { - this[0].outerHTML = ""; +import { isIE, isIE9Below } from "../function"; +import { htmlEncode } from "../../../func"; +import { toUpperCase, remove, camelize, isKey, isNull, isNotEmptyString, map, hyphenate } from "../../../2.base"; +import { makeFirstPY } from "../../../utils"; +import { createWidget } from "../../../5.inject"; + +BI.jQuery.fn.extend({ + + insets() { + const p = this.padding(), + b = this.border(); + + return { + top: p.top, + bottom: p.bottom + b.bottom + b.top, + left: p.left, + right: p.right + b.right + b.left, + }; + }, + + bounds(value) { + let tmp = { hasIgnoredBounds: true }; + + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; } - }, - /** - * 高亮显示 - * @param text 必需 - * @param keyword - * @param py - * @returns {*} - * @private - * 原理: - * 1、得到text的拼音py, 分别看是否匹配关键字keyword, 得到匹配索引tidx和pidx - * 2、比较tidx和pidx, 取大于-1且较小的索引,标红[索引,索引 + keyword.length - 1]的文本 - * 3、text和py各自取tidx/pidx + keyword.length索引开始的子串作为新的text和py, 重复1, 直到text和py有一个为"" - */ - __textKeywordMarked__: function (text, keyword, py) { - if (BI.isNull(text)) { - text = ""; + if (!isNaN(value.y)) { + tmp.top = value.y; } - if (!BI.isKey(keyword) || (text + "").length > 100) { - if (BI.isIE9Below()) { - return this.html(BI.htmlEncode(text)); - } - // textContent性能更好,并且原生防xss - this[0].textContent = text; - return this; + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + // tmp.width = (tmp.width >= 0) ? tmp.width : 0; } - keyword = keyword + ""; - keyword = BI.toUpperCase(keyword); - var textLeft = text + ""; - py = (py || BI.makeFirstPY(text, { - splitChar: "\u200b" - })) + ""; - py = BI.toUpperCase(py); - this.empty(); - // BI-48487 性能: makeFirstPY出来的py中包含多音字是必要的,但虽然此方法中做了限制。但是对于一个长度为60,包含14个多音字的字符串 - // 获取的的py长度将达到1966080, 远超过text的长度,到后面都是在做"".substring的无用功,所以此循环应保证py和textLeft长度不为0 - while (py.length > 0 && textLeft.length > 0) { - var tidx = BI.toUpperCase(textLeft).indexOf(keyword); - var pidx = py.indexOf(keyword); - if (pidx >= 0) { - pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length; - } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + // tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); - // BI-56945 场景: 对'啊a'标红, a为keyword, 此时tidx为1, pidx为0, 此时使用tidx显然'啊'就无法标红了 - if (tidx >= 0 && (pidx > tidx || pidx === -1)) { - // 标红的text未encode - this.append(BI.htmlEncode(textLeft.substr(0, tidx))); - this.append(BI.$("").addClass("bi-keyword-red-mark") - .html(BI.htmlEncode(textLeft.substr(tidx, keyword.length)))); - - textLeft = textLeft.substr(tidx + keyword.length); - if (BI.isNotEmptyString(py)) { - // 每一组拼音都应该前进,而不是只是当前的 - py = BI.map(py.split("\u200b"), function (idx, ps) { - return ps.slice(tidx + keyword.length); - }).join("\u200b"); - } - } else if (pidx >= 0) { - // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 - // 标红的text未encode - this.append(BI.htmlEncode(textLeft.substr(0, pidx))); - this.append(BI.$("").addClass("bi-keyword-red-mark") - .html(BI.htmlEncode(textLeft.substr(pidx, keyword.length)))); - if (BI.isNotEmptyString(py)) { - // 每一组拼音都应该前进,而不是只是当前的 - py = BI.map(py.split("\u200b"), function (idx, ps) { - return ps.slice(pidx + keyword.length); - }).join("\u200b"); - } - textLeft = textLeft.substr(pidx + keyword.length); - } else { - // 标红的text未encode - this.append(BI.htmlEncode(textLeft)); - break; - } + return this; + } + + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + + return { + x: tmp.left, + y: tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + width: this.outerWidth(), + height: this.outerHeight(), + }; + }, + + destroy() { + this.remove(); + if (isIE() === true) { + this[0].outerHTML = ""; + } + }, + + /** + * 高亮显示 + * @param text 必需 + * @param keyword + * @param py + * @returns {*} + * @private + * 原理: + * 1、得到text的拼音py, 分别看是否匹配关键字keyword, 得到匹配索引tidx和pidx + * 2、比较tidx和pidx, 取大于-1且较小的索引,标红[索引,索引 + keyword.length - 1]的文本 + * 3、text和py各自取tidx/pidx + keyword.length索引开始的子串作为新的text和py, 重复1, 直到text和py有一个为"" + */ + __textKeywordMarked__(text, keyword, py) { + if (isNull(text)) { + text = ""; + } + if (!isKey(keyword) || (`${text}`).length > 100) { + if (isIE9Below()) { + return this.html(htmlEncode(text)); } + // textContent性能更好,并且原生防xss + this[0].textContent = text; return this; - }, - - getDomHeight: function (parent) { - var clone = BI.$(this).clone(); - clone.appendTo(BI.$(parent || "body")); - var height = clone.height(); - clone.remove(); - return height; - }, - - // 是否有竖直滚动条 - hasVerticalScroll: function () { - return this.height() > 0 && this[0].clientWidth < this[0].offsetWidth; - }, - - // 是否有水平滚动条 - hasHorizonScroll: function () { - return this.width() > 0 && this[0].clientHeight < this[0].offsetHeight; - }, - - // 获取计算后的样式 - getStyle: function (name) { - var node = this[0]; - var computedStyle = void 0; - - // W3C Standard - if (_global.getComputedStyle) { - // In certain cases such as within an iframe in FF3, this returns null. - computedStyle = _global.getComputedStyle(node, null); - if (computedStyle) { - return computedStyle.getPropertyValue(BI.hyphenate(name)); - } + } + keyword = `${keyword}`; + keyword = toUpperCase(keyword); + let textLeft = `${text}`; + py = `${py || makeFirstPY(text, { + splitChar: "\u200b", + })}`; + py = toUpperCase(py); + this.empty(); + // BI-48487 性能: makeFirstPY出来的py中包含多音字是必要的,但虽然此方法中做了限制。但是对于一个长度为60,包含14个多音字的字符串 + // 获取的的py长度将达到1966080, 远超过text的长度,到后面都是在做"".substring的无用功,所以此循环应保证py和textLeft长度不为0 + while (py.length > 0 && textLeft.length > 0) { + const tidx = toUpperCase(textLeft).indexOf(keyword); + let pidx = py.indexOf(keyword); + if (pidx >= 0) { + pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length; } - // Safari - if (document.defaultView && document.defaultView.getComputedStyle) { - computedStyle = document.defaultView.getComputedStyle(node, null); - // A Safari bug causes this to return null for `display: none` elements. - if (computedStyle) { - return computedStyle.getPropertyValue(BI.hyphenate(name)); + + // BI-56945 场景: 对'啊a'标红, a为keyword, 此时tidx为1, pidx为0, 此时使用tidx显然'啊'就无法标红了 + if (tidx >= 0 && (pidx > tidx || pidx === -1)) { + // 标红的text未encode + this.append(htmlEncode(textLeft.substr(0, tidx))); + this.append(BI.$("").addClass("bi-keyword-red-mark") + .html(htmlEncode(textLeft.substr(tidx, keyword.length)))); + + textLeft = textLeft.substr(tidx + keyword.length); + if (isNotEmptyString(py)) { + // 每一组拼音都应该前进,而不是只是当前的 + py = map(py.split("\u200b"), (idx, ps) => ps.slice(tidx + keyword.length)).join("\u200b"); } - if (name === "display") { - return "none"; + } else if (pidx >= 0) { + // BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件 + // 标红的text未encode + this.append(htmlEncode(textLeft.substr(0, pidx))); + this.append(BI.$("").addClass("bi-keyword-red-mark") + .html(htmlEncode(textLeft.substr(pidx, keyword.length)))); + if (isNotEmptyString(py)) { + // 每一组拼音都应该前进,而不是只是当前的 + py = map(py.split("\u200b"), (idx, ps) => ps.slice(pidx + keyword.length)).join("\u200b"); } + textLeft = textLeft.substr(pidx + keyword.length); + } else { + // 标红的text未encode + this.append(htmlEncode(textLeft)); + break; } - // Internet Explorer - if (node.currentStyle) { - if (name === "float") { - return node.currentStyle.cssFloat || node.currentStyle.styleFloat; - } - return node.currentStyle[BI.camelize(name)]; + } + + return this; + }, + + getDomHeight(parent) { + const clone = BI.$(this).clone(); + clone.appendTo(BI.$(parent || "body")); + const height = clone.height(); + clone.remove(); + + return height; + }, + + // 是否有竖直滚动条 + hasVerticalScroll() { + return this.height() > 0 && this[0].clientWidth < this[0].offsetWidth; + }, + + // 是否有水平滚动条 + hasHorizonScroll() { + return this.width() > 0 && this[0].clientHeight < this[0].offsetHeight; + }, + + // 获取计算后的样式 + getStyle(name) { + const node = this[0]; + let computedStyle = void 0; + + // W3C Standard + if (_global.getComputedStyle) { + // In certain cases such as within an iframe in FF3, this returns null. + computedStyle = _global.getComputedStyle(node, null); + if (computedStyle) { + return computedStyle.getPropertyValue(hyphenate(name)); + } + } + // Safari + if (document.defaultView && document.defaultView.getComputedStyle) { + computedStyle = document.defaultView.getComputedStyle(node, null); + // A Safari bug causes this to return null for `display: none` elements. + if (computedStyle) { + return computedStyle.getPropertyValue(hyphenate(name)); + } + if (name === "display") { + return "none"; + } + } + // Internet Explorer + if (node.currentStyle) { + if (name === "float") { + return node.currentStyle.cssFloat || node.currentStyle.styleFloat; } - return node.style && node.style[BI.camelize(name)]; - }, - - __isMouseInBounds__: function (e) { - var offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); - var width = offset2Body.width || this.outerWidth(); - var height = offset2Body.height || this.outerHeight(); - // offset2Body.left的值可能会有小数,导致某点出现false - return !(e.pageX < Math.floor(offset2Body.left) || e.pageX > offset2Body.left + width - || e.pageY < Math.floor(offset2Body.top) || e.pageY > offset2Body.top + height); - }, - - __hasZIndexMask__: function (zindex) { - return zindex && this.zIndexMask[zindex] != null; - }, - - __buildZIndexMask__: function (zindex, domArray) { - this.zIndexMask = this.zIndexMask || {};// 存储z-index的mask - this.indexMask = this.indexMask || [];// 存储mask - var mask = BI.createWidget({ - type: "bi.center_adapt", - cls: "bi-z-index-mask", - items: domArray - }); - - mask.element.css({"z-index": zindex}); - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ + + return node.currentStyle[camelize(name)]; + } + + return node.style && node.style[camelize(name)]; + }, + + __isMouseInBounds__(e) { + const offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); + const width = offset2Body.width || this.outerWidth(); + const height = offset2Body.height || this.outerHeight(); + + // offset2Body.left的值可能会有小数,导致某点出现false + return !(e.pageX < Math.floor(offset2Body.left) || e.pageX > offset2Body.left + width + || e.pageY < Math.floor(offset2Body.top) || e.pageY > offset2Body.top + height); + }, + + __hasZIndexMask__(zindex) { + return zindex && this.zIndexMask[zindex] != null; + }, + + __buildZIndexMask__(zindex, domArray) { + this.zIndexMask = this.zIndexMask || {};// 存储z-index的mask + this.indexMask = this.indexMask || [];// 存储mask + const mask = createWidget({ + type: "bi.center_adapt", + cls: "bi-z-index-mask", + items: domArray, + }); + + mask.element.css({ "z-index": zindex }); + createWidget({ + type: "bi.absolute", + element: this, + items: [ + { el: mask, left: 0, right: 0, top: 0, - bottom: 0 - }] - }); - this.indexMask.push(mask); - zindex && (this.zIndexMask[zindex] = mask); - return mask.element; - }, - - __releaseZIndexMask__: function (zindex) { - if (zindex && this.zIndexMask[zindex]) { - BI.remove(this.indexMask, this.zIndexMask[zindex]); - this.zIndexMask[zindex].destroy(); - return; - } - this.indexMask = this.indexMask || []; - var indexMask = this.indexMask.pop(); - indexMask && indexMask.destroy(); + bottom: 0, + } + ], + }); + this.indexMask.push(mask); + zindex && (this.zIndexMask[zindex] = mask); + + return mask.element; + }, + + __releaseZIndexMask__(zindex) { + if (zindex && this.zIndexMask[zindex]) { + remove(this.indexMask, this.zIndexMask[zindex]); + this.zIndexMask[zindex].destroy(); + + return; } - }); -} + this.indexMask = this.indexMask || []; + const indexMask = this.indexMask.pop(); + indexMask && indexMask.destroy(); + }, +}); + diff --git a/src/core/platform/web/jquery/index.js b/src/core/platform/web/jquery/index.js new file mode 100644 index 000000000..4c523e052 --- /dev/null +++ b/src/core/platform/web/jquery/index.js @@ -0,0 +1,4 @@ +import "./_jquery"; +import "./event"; +import "./fn"; +import "./jquery.mousewheel";