浏览代码

Merge pull request #7425 from wenzhixin/fix/7194

Fixed search highlight not working bug
文翼 1 年之前
父节点
当前提交
4ccaf7ecfa
共有 2 个文件被更改,包括 31 次插入17 次删除
  1. 9 17
      src/bootstrap-table.js
  2. 22 0
      src/utils/index.js

+ 9 - 17
src/bootstrap-table.js

@@ -1659,8 +1659,12 @@ class BootstrapTable {
           this.options.undefinedText : value
       }
 
-      if (column.searchable && this.searchText && this.options.searchHighlight && !(column.checkbox || column.radio)) {
-        let defValue = ''
+      if (
+        column.searchable &&
+        this.searchText &&
+        this.options.searchHighlight &&
+        !(column.checkbox || column.radio)
+      ) {
         let searchText = this.searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
 
         if (this.options.searchAccentNeutralise) {
@@ -1672,22 +1676,10 @@ class BootstrapTable {
           }
         }
 
-        const regExp = new RegExp(`(${searchText})`, 'gim')
-        const marker = '<mark>$1</mark>'
-        const isHTML = value && /<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(value)
-
-        if (isHTML) {
-          // value can contains a HTML tags
-          let textContent = new DOMParser().parseFromString(value.toString(), 'text/html').documentElement.textContent
-          const textReplaced = textContent.replace(regExp, marker)
+        const defValue = Utils.replaceSearchMark(value, searchText)
 
-          textContent = textContent.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-          defValue = value.replace(new RegExp(`(>\\s*)(${textContent})(\\s*)`, 'gm'), `$1${textReplaced}$3`)
-        } else {
-          // but usually not
-          defValue = value.toString().replace(regExp, marker)
-        }
-        value = Utils.calculateObjectValue(column, column.searchHighlightFormatter, [value, this.searchText], defValue)
+        value = Utils.calculateObjectValue(column, column.searchHighlightFormatter,
+          [value, this.searchText], defValue)
       }
 
       if (item[`_${field}_data`] && !Utils.isEmptyObject(item[`_${field}_data`])) {

+ 22 - 0
src/utils/index.js

@@ -665,5 +665,27 @@ export default {
 
       if (callNow) func.apply(context, args)
     }
+  },
+
+  replaceSearchMark (html, searchText) {
+    const node = document.createElement('div')
+    const replaceMark = (node, searchText) => {
+      const regExp = new RegExp(searchText, 'gim')
+
+      for (const child of node.childNodes) {
+        if (child.nodeType === document.TEXT_NODE) {
+          child.data = child.data.replace(regExp, match => `___${match}___`)
+        }
+        if (child.nodeType === document.ELEMENT_NODE) {
+          replaceMark(child, searchText)
+        }
+      }
+    }
+
+    node.innerHTML = html
+    replaceMark(node, searchText)
+
+    return node.innerHTML.replace(new RegExp(`___${searchText}___`, 'gim'),
+      match => `<mark>${match.slice(3, -3)}</mark>`)
   }
 }