Bug 1517334 - [release 114] [search] Don't send whole line across (#7561). r=dwalsh
authorJason Laster <jlaster@mozilla.com>
Wed, 02 Jan 2019 16:00:35 -0500
changeset 509427 a5c776c629f449dade37cb6711d7516dc1141120
parent 509426 0c91bc0bcba36bf275f3377ddaa7dd28a9d8a263
child 509428 ecae10357d92fc9e6f8d3d7bd9ebb10db04ff160
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdwalsh
bugs1517334
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1517334 - [release 114] [search] Don't send whole line across (#7561). r=dwalsh
devtools/client/debugger/new/dist/debugger.css
devtools/client/debugger/new/dist/search-worker.js
devtools/client/debugger/new/src/components/ProjectSearch.js
devtools/client/debugger/new/src/utils/project-search.js
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -1612,16 +1612,18 @@ html .toggle-button.end.vertical svg {
   width: 100%;
   text-align: right;
   grid-column: 1/2;
 }
 
 .project-text-search .result .line-value {
   grid-column: 2/3;
   padding-left: 5px;
+  text-overflow: ellipsis;
+  overflow-x: hidden;
 }
 
 .project-text-search .tree-indent {
   display: none;
 }
 
 .project-text-search .no-result-msg {
   color: var(--theme-body-color-inactive);
@@ -1666,16 +1668,17 @@ html .toggle-button.end.vertical svg {
   overflow-y: auto;
   height: 100%;
 }
 
 .project-text-search .managed-tree .tree {
   height: 100%;
   display: grid;
   grid-template-columns: auto 1fr;
+  overflow-x: hidden;
 }
 
 .project-text-search .managed-tree .tree .tree-node {
   display: contents;
 }
 
 /* Focus values */
 
--- a/devtools/client/debugger/new/dist/search-worker.js
+++ b/devtools/client/debugger/new/dist/search-worker.js
@@ -605,48 +605,90 @@ function getMatches(query, text, modifie
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.findSourceMatches = findSourceMatches;
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+var _getMatches = __webpack_require__(1632);
 
-// Maybe reuse file search's functions?
+var _getMatches2 = _interopRequireDefault(_getMatches);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function findSourceMatches(source, queryText) {
   const { id, loadedState, text } = source;
   if (loadedState != "loaded" || !text || queryText == "") {
     return [];
   }
 
+  const modifiers = {
+    caseSensitive: false,
+    regexMatch: false,
+    wholeWord: false
+  };
+
   const lines = text.split("\n");
-  let result = undefined;
-  const query = new RegExp(queryText, "g");
 
-  const matches = lines.map((_text, line) => {
-    const indices = [];
+  return (0, _getMatches2.default)(queryText, text, modifiers).map(({ line, ch }) => {
+    const { value, matchIndex } = truncateLine(lines[line], ch);
+    return {
+      sourceId: id,
+      line: line + 1,
+      column: ch,
+      matchIndex,
+      match: queryText,
+      value
+    };
+  });
+}
+
+// This is used to find start of a word, so that cropped string look nice
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+// Maybe reuse file search's functions?
 
-    while (result = query.exec(_text)) {
-      indices.push({
-        sourceId: id,
-        line: line + 1,
-        column: result.index,
-        match: result[0],
-        value: _text
-      });
-    }
-    return indices;
-  }).filter(_matches => _matches.length > 0);
+const startRegex = /([ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])/g;
+// Similarly, find
+const endRegex = new RegExp(["([ !@#$%^&*()_+-=[]{};':\"\\|,.<>/?])", '[^ !@#$%^&*()_+-=[]{};\':"\\|,.<>/?]*$"/'].join(""));
+
+function truncateLine(text, column) {
+  if (text.length < 100) {
+    return {
+      matchIndex: column,
+      value: text
+    };
+  }
 
-  return [].concat(...matches);
+  // Initially take 40 chars left to the match
+  const offset = Math.max(column - 40, 0);
+  // 400 characters should be enough to figure out the context of the match
+  const truncStr = text.slice(offset, column + 400);
+  let start = truncStr.search(startRegex);
+  let end = truncStr.search(endRegex);
+
+  if (start > column) {
+    // No word separator found before the match, so we take all characters
+    // before the match
+    start = -1;
+  }
+  if (end < column) {
+    end = truncStr.length;
+  }
+  const value = truncStr.slice(start + 1, end);
+
+  return {
+    matchIndex: column - start - offset - 1,
+    value
+  };
 }
 
 /***/ }),
 
 /***/ 259:
 /***/ (function(module, exports, __webpack_require__) {
 
 var toString = __webpack_require__(108);
--- a/devtools/client/debugger/new/src/components/ProjectSearch.js
+++ b/devtools/client/debugger/new/src/components/ProjectSearch.js
@@ -34,16 +34,17 @@ import type { StatusType } from "../redu
 
 import "./ProjectSearch.css";
 
 export type Match = {
   type: "MATCH",
   sourceId: string,
   line: number,
   column: number,
+  matchIndex: number,
   match: string,
   value: string,
   text: string
 };
 
 type Result = {
   type: "RESULT",
   filepath: string,
@@ -258,17 +259,17 @@ export class ProjectSearch extends Compo
     return this.renderMatch(item, focused);
   };
 
   renderResults = () => {
     const { status, results } = this.props;
     if (!this.props.query) {
       return;
     }
-    if (results.length && status === statusType.done) {
+    if (results.length) {
       return (
         <ManagedTree
           getRoots={() => results}
           getChildren={file => file.matches || []}
           itemHeight={24}
           autoExpandAll={true}
           autoExpandDepth={1}
           getParent={item => null}
--- a/devtools/client/debugger/new/src/utils/project-search.js
+++ b/devtools/client/debugger/new/src/utils/project-search.js
@@ -5,25 +5,25 @@
 // @flow
 
 // Maybe reuse file search's functions?
 
 import React from "react";
 import type { Match } from "../components/ProjectSearch";
 
 export function highlightMatches(lineMatch: Match) {
-  const { value, column, match } = lineMatch;
+  const { value, matchIndex, match } = lineMatch;
   const len = match.length;
 
   return (
     <span className="line-value">
       <span className="line-match" key={0}>
-        {value.slice(0, column)}
+        {value.slice(0, matchIndex)}
       </span>
       <span className="query-match" key={1}>
-        {value.substr(column, len)}
+        {value.substr(matchIndex, len)}
       </span>
       <span className="line-match" key={2}>
-        {value.slice(column + len, value.length)}
+        {value.slice(matchIndex + len, value.length)}
       </span>
     </span>
   );
 }