Browse Source

Merge pull request #1211 in VISUAL/fineui from ~WINDY/fineui:master to master

* commit '229dfd7a8d51ba2f1f872466c46ad413768f4829':
  BI-56945 hidden danger 梳理标红逻辑
master
windy 5 years ago
parent
commit
53e250a2e6
  1. 64
      src/core/platform/web/jquery/__test__/fn.test.js
  2. 28
      src/core/platform/web/jquery/fn.js

64
src/core/platform/web/jquery/__test__/fn.test.js

@ -0,0 +1,64 @@
/**
* @author windy
* @version 2.0
* Created by windy on 2019/12/9
*/
describe("标红test", function () {
/**
* test_author_windy
*/
it("无多音字标红", function () {
var a = BI.Test.createWidget({
type: "bi.layout",
});
a.element.__textKeywordMarked__("无多音字", "w");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">无</span>多音字");
a.destroy();
});
/**
* test_author_windy
*/
it("含有多音字标红", function () {
var a = BI.Test.createWidget({
type: "bi.layout",
});
a.element.__textKeywordMarked__("长期协议", "z");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">长</span>期协议");
a.element.__textKeywordMarked__("长期协议", "c");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">长</span>期协议");
a.destroy();
});
/**
* test_author_windy
*/
it("多音字错位标红", function () {
var a = BI.Test.createWidget({
type: "bi.layout",
});
a.element.__textKeywordMarked__("呵呵呵", "h");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">呵</span><span class=\"bi-keyword-red-mark\">呵</span><span class=\"bi-keyword-red-mark\">呵</span>");
a.element.__textKeywordMarked__("呵呵呵", "hh");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">呵呵</span>呵");
a.element.__textKeywordMarked__("呵呵呵", "hhh");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">呵呵呵</span>");
a.destroy();
});
/**
* test_author_windy
*/
it("原文和拼音都匹配标红", function () {
var a = BI.Test.createWidget({
type: "bi.layout",
});
a.element.__textKeywordMarked__("啊a", "a");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">啊</span><span class=\"bi-keyword-red-mark\">a</span>");
a.element.__textKeywordMarked__("a啊", "a");
expect(a.element.html()).to.equal("<span class=\"bi-keyword-red-mark\">a</span><span class=\"bi-keyword-red-mark\">啊</span>");
a.destroy();
});
});

28
src/core/platform/web/jquery/fn.js vendored

@ -68,9 +68,13 @@ if (BI.jQuery) {
* 高亮显示
* @param text 必需
* @param keyword
* @param py 必需
* @param py
* @returns {*}
* @private
* 原理:
* 1得到text的拼音py, 分别看是否匹配关键字keyword, 得到匹配索引tidx和pidx
* 2比较tidx和pidx, 取大于-1且较小的索引标红[索引索引 + keyword.length - 1]的文本
* 3text和py各自取tidx/pidx + keyword.length索引开始的子串作为新的text和py, 重复1, 直到text和py有一个为""
*/
__textKeywordMarked__: function (text, keyword, py) {
if (!BI.isKey(keyword) || (text + "").length > 100) {
@ -82,42 +86,38 @@ if (BI.jQuery) {
py = (py || BI.makeFirstPY(text, {
splitChar: "\u200b"
})) + "";
if (py != null) {
py = BI.toUpperCase(py);
}
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 = null;
if (py != null) {
pidx = py.indexOf(keyword);
if (pidx >= 0) {
pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length;
}
var pidx = py.indexOf(keyword);
if (pidx >= 0) {
pidx = (pidx - Math.floor(pidx / (textLeft.length + 1))) % textLeft.length;
}
if (tidx >= 0) {
// BI-56945 场景: 对'啊a'标红, a为keyword, 此时tidx为1, pidx为0, 此时使用tidx显然'啊'就无法标红了
if (tidx >= 0 && pidx > tidx) {
// 标红的text未encode
this.append(BI.htmlEncode(textLeft.substr(0, tidx)));
this.append(BI.$("<span>").addClass("bi-keyword-red-mark")
.html(BI.htmlEncode(textLeft.substr(tidx, keyword.length))));
textLeft = textLeft.substr(tidx + keyword.length);
if (py != null) {
if (BI.isNotEmptyString(py)) {
// 每一组拼音都应该前进,而不是只是当前的
py = BI.map(py.split("\u200b"), function (idx, ps) {
return ps.slice(tidx + keyword.length);
}).join("\u200b");
}
} else if (pidx != null && pidx >= 0) {
} else if (pidx >= 0) {
// BI-56386 这边两个pid / text.length是为了防止截取的首字符串不是完整的,但光这样做还不够,即时错位了,也不能说明就不符合条件
// 标红的text未encode
this.append(BI.htmlEncode(textLeft.substr(0, pidx)));
this.append(BI.$("<span>").addClass("bi-keyword-red-mark")
.html(BI.htmlEncode(textLeft.substr(pidx, keyword.length))));
if (py != null) {
if (BI.isNotEmptyString(py)) {
// 每一组拼音都应该前进,而不是只是当前的
py = BI.map(py.split("\u200b"), function (idx, ps) {
return ps.slice(pidx + keyword.length);

Loading…
Cancel
Save