From baf98653f359c95da46470882b07ce0357595565 Mon Sep 17 00:00:00 2001
From: windy <1374721899@qq.com>
Date: Mon, 9 Dec 2019 16:15:29 +0800
Subject: [PATCH] =?UTF-8?q?BI-56945=20hidden=20danger=20=E6=A2=B3=E7=90=86?=
=?UTF-8?q?=E6=A0=87=E7=BA=A2=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../platform/web/jquery/__test__/fn.test.js | 64 +++++++++++++++++++
src/core/platform/web/jquery/fn.js | 28 ++++----
2 files changed, 78 insertions(+), 14 deletions(-)
create mode 100644 src/core/platform/web/jquery/__test__/fn.test.js
diff --git a/src/core/platform/web/jquery/__test__/fn.test.js b/src/core/platform/web/jquery/__test__/fn.test.js
new file mode 100644
index 000000000..8a2b475f7
--- /dev/null
+++ b/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("无多音字");
+ 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("长期协议");
+ a.element.__textKeywordMarked__("长期协议", "c");
+ expect(a.element.html()).to.equal("长期协议");
+ 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("呵呵呵");
+ a.element.__textKeywordMarked__("呵呵呵", "hh");
+ expect(a.element.html()).to.equal("呵呵呵");
+ a.element.__textKeywordMarked__("呵呵呵", "hhh");
+ expect(a.element.html()).to.equal("呵呵呵");
+ 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("啊a");
+ a.element.__textKeywordMarked__("a啊", "a");
+ expect(a.element.html()).to.equal("a啊");
+ a.destroy();
+ });
+});
\ 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 9d94719c6..d19cf68bc 100644
--- a/src/core/platform/web/jquery/fn.js
+++ b/src/core/platform/web/jquery/fn.js
@@ -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]的文本
+ * 3、text和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.$("").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.$("").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);