1d0825bca7fe65beaee391d30da42e937db621564Steve Block/* 2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2009 Google Inc. All rights reserved. 3d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2009 Apple Inc. All rights reserved. 4d0825bca7fe65beaee391d30da42e937db621564Steve Block * 5d0825bca7fe65beaee391d30da42e937db621564Steve Block * Redistribution and use in source and binary forms, with or without 6d0825bca7fe65beaee391d30da42e937db621564Steve Block * modification, are permitted provided that the following conditions are 7d0825bca7fe65beaee391d30da42e937db621564Steve Block * met: 8d0825bca7fe65beaee391d30da42e937db621564Steve Block * 9d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions of source code must retain the above copyright 10d0825bca7fe65beaee391d30da42e937db621564Steve Block * notice, this list of conditions and the following disclaimer. 11d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions in binary form must reproduce the above 12d0825bca7fe65beaee391d30da42e937db621564Steve Block * copyright notice, this list of conditions and the following disclaimer 13d0825bca7fe65beaee391d30da42e937db621564Steve Block * in the documentation and/or other materials provided with the 14d0825bca7fe65beaee391d30da42e937db621564Steve Block * distribution. 15d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Neither the name of Google Inc. nor the names of its 16d0825bca7fe65beaee391d30da42e937db621564Steve Block * contributors may be used to endorse or promote products derived from 17d0825bca7fe65beaee391d30da42e937db621564Steve Block * this software without specific prior written permission. 18d0825bca7fe65beaee391d30da42e937db621564Steve Block * 19d0825bca7fe65beaee391d30da42e937db621564Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20d0825bca7fe65beaee391d30da42e937db621564Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22d0825bca7fe65beaee391d30da42e937db621564Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23d0825bca7fe65beaee391d30da42e937db621564Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24d0825bca7fe65beaee391d30da42e937db621564Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26d0825bca7fe65beaee391d30da42e937db621564Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27d0825bca7fe65beaee391d30da42e937db621564Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28d0825bca7fe65beaee391d30da42e937db621564Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29d0825bca7fe65beaee391d30da42e937db621564Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30d0825bca7fe65beaee391d30da42e937db621564Steve Block */ 31d0825bca7fe65beaee391d30da42e937db621564Steve Block 32d0825bca7fe65beaee391d30da42e937db621564Steve BlockWebInspector.TextEditorHighlighter = function(textModel, damageCallback) 33d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 34d0825bca7fe65beaee391d30da42e937db621564Steve Block this._textModel = textModel; 35692e5dbf12901edacf14812a6fae25462920af42Steve Block this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html"); 36692e5dbf12901edacf14812a6fae25462920af42Steve Block this._damageCallback = damageCallback; 3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch this._highlightChunkLimit = 1000; 38d0825bca7fe65beaee391d30da42e937db621564Steve Block} 39d0825bca7fe65beaee391d30da42e937db621564Steve Block 40d0825bca7fe65beaee391d30da42e937db621564Steve BlockWebInspector.TextEditorHighlighter.prototype = { 41d0825bca7fe65beaee391d30da42e937db621564Steve Block set mimeType(mimeType) 42d0825bca7fe65beaee391d30da42e937db621564Steve Block { 43d0825bca7fe65beaee391d30da42e937db621564Steve Block var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType); 442bde8e466a4451c7319e3a072d118917957d6554Steve Block if (tokenizer) 45d0825bca7fe65beaee391d30da42e937db621564Steve Block this._tokenizer = tokenizer; 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block }, 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch set highlightChunkLimit(highlightChunkLimit) 4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch this._highlightChunkLimit = highlightChunkLimit; 5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch }, 5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch highlight: function(endLine, opt_forceRun) 54d0825bca7fe65beaee391d30da42e937db621564Steve Block { 55d0825bca7fe65beaee391d30da42e937db621564Steve Block // First check if we have work to do. 562bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(endLine - 1, "highlight"); 572bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state && state.postConditionStringified) { 582bde8e466a4451c7319e3a072d118917957d6554Steve Block // Last line is highlighted, just exit. 59d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 602bde8e466a4451c7319e3a072d118917957d6554Steve Block } 61d0825bca7fe65beaee391d30da42e937db621564Steve Block 62d0825bca7fe65beaee391d30da42e937db621564Steve Block this._requestedEndLine = endLine; 63d0825bca7fe65beaee391d30da42e937db621564Steve Block 6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (this._highlightTimer && !opt_forceRun) { 65d0825bca7fe65beaee391d30da42e937db621564Steve Block // There is a timer scheduled, it will catch the new job based on the new endLine set. 66d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 67d0825bca7fe65beaee391d30da42e937db621564Steve Block } 68d0825bca7fe65beaee391d30da42e937db621564Steve Block 692bde8e466a4451c7319e3a072d118917957d6554Steve Block // We will be highlighting. First rewind to the last highlighted line to gain proper highlighter context. 702bde8e466a4451c7319e3a072d118917957d6554Steve Block var startLine = endLine; 712bde8e466a4451c7319e3a072d118917957d6554Steve Block while (startLine > 0) { 722bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(startLine - 1, "highlight"); 732bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state && state.postConditionStringified) 742bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 752bde8e466a4451c7319e3a072d118917957d6554Steve Block startLine--; 762bde8e466a4451c7319e3a072d118917957d6554Steve Block } 77d0825bca7fe65beaee391d30da42e937db621564Steve Block 782bde8e466a4451c7319e3a072d118917957d6554Steve Block // Do small highlight synchronously. This will provide instant highlight on PageUp / PageDown, gentle scrolling. 792bde8e466a4451c7319e3a072d118917957d6554Steve Block this._highlightInChunks(startLine, endLine); 80d0825bca7fe65beaee391d30da42e937db621564Steve Block }, 81d0825bca7fe65beaee391d30da42e937db621564Steve Block 8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch updateHighlight: function(startLine, endLine) 8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 842bde8e466a4451c7319e3a072d118917957d6554Steve Block // Start line was edited, we should highlight everything until endLine. 852bde8e466a4451c7319e3a072d118917957d6554Steve Block this._clearHighlightState(startLine); 862bde8e466a4451c7319e3a072d118917957d6554Steve Block 872bde8e466a4451c7319e3a072d118917957d6554Steve Block if (startLine) { 882bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(startLine - 1, "highlight"); 892bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!state || !state.postConditionStringified) { 902bde8e466a4451c7319e3a072d118917957d6554Steve Block // Highlighter did not reach this point yet, nothing to update. It will reach it on subsequent timer tick and do the job. 912bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 922bde8e466a4451c7319e3a072d118917957d6554Steve Block } 9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 952bde8e466a4451c7319e3a072d118917957d6554Steve Block var restored = this._highlightLines(startLine, endLine); 962bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!restored) { 972bde8e466a4451c7319e3a072d118917957d6554Steve Block for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) { 982bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(i, "highlight"); 992bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!state && i > endLine) 1002bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 1012bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.setAttribute(i, "highlight-outdated", state); 10281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch this._textModel.removeAttribute(i, "highlight"); 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block } 10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1052bde8e466a4451c7319e3a072d118917957d6554Steve Block if (this._highlightTimer) { 1062bde8e466a4451c7319e3a072d118917957d6554Steve Block clearTimeout(this._highlightTimer); 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block this._requestedEndLine = endLine; 1082bde8e466a4451c7319e3a072d118917957d6554Steve Block this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10); 1092bde8e466a4451c7319e3a072d118917957d6554Steve Block } 11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 1112bde8e466a4451c7319e3a072d118917957d6554Steve Block return restored; 11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch }, 11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1142bde8e466a4451c7319e3a072d118917957d6554Steve Block _highlightInChunks: function(startLine, endLine) 115d0825bca7fe65beaee391d30da42e937db621564Steve Block { 116d0825bca7fe65beaee391d30da42e937db621564Steve Block delete this._highlightTimer; 117d0825bca7fe65beaee391d30da42e937db621564Steve Block 118d0825bca7fe65beaee391d30da42e937db621564Steve Block // First we always check if we have work to do. Could be that user scrolled back and we can quit. 1192bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight"); 1202bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state && state.postConditionStringified) 121d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 122d0825bca7fe65beaee391d30da42e937db621564Steve Block 123d0825bca7fe65beaee391d30da42e937db621564Steve Block if (this._requestedEndLine !== endLine) { 124d0825bca7fe65beaee391d30da42e937db621564Steve Block // User keeps updating the job in between of our timer ticks. Just reschedule self, don't eat CPU (they must be scrolling). 1252bde8e466a4451c7319e3a072d118917957d6554Steve Block this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100); 126d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 127d0825bca7fe65beaee391d30da42e937db621564Steve Block } 128d0825bca7fe65beaee391d30da42e937db621564Steve Block 12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // The textModel may have been already updated. 13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (this._requestedEndLine > this._textModel.linesCount) 13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch this._requestedEndLine = this._textModel.linesCount; 13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1332bde8e466a4451c7319e3a072d118917957d6554Steve Block this._highlightLines(startLine, this._requestedEndLine); 134d0825bca7fe65beaee391d30da42e937db621564Steve Block 135d0825bca7fe65beaee391d30da42e937db621564Steve Block // Schedule tail highlight if necessary. 136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (this._lastHighlightedLine < this._requestedEndLine) 1372bde8e466a4451c7319e3a072d118917957d6554Steve Block this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10); 138d0825bca7fe65beaee391d30da42e937db621564Steve Block }, 139d0825bca7fe65beaee391d30da42e937db621564Steve Block 1402bde8e466a4451c7319e3a072d118917957d6554Steve Block _highlightLines: function(startLine, endLine) 141d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1422bde8e466a4451c7319e3a072d118917957d6554Steve Block // Restore highlighter context taken from previous line. 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(startLine - 1, "highlight"); 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.initialCondition); 145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1462bde8e466a4451c7319e3a072d118917957d6554Steve Block var tokensCount = 0; 1472bde8e466a4451c7319e3a072d118917957d6554Steve Block for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) { 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._selectHighlightState(lineNumber, postConditionStringified); 1492bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state.postConditionStringified) { 1502bde8e466a4451c7319e3a072d118917957d6554Steve Block // This line is already highlighted. 1512bde8e466a4451c7319e3a072d118917957d6554Steve Block postConditionStringified = state.postConditionStringified; 15281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } else { 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block var lastHighlightedColumn = 0; 1542bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state.midConditionStringified) { 1552bde8e466a4451c7319e3a072d118917957d6554Steve Block lastHighlightedColumn = state.lastHighlightedColumn; 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block postConditionStringified = state.midConditionStringified; 1572bde8e466a4451c7319e3a072d118917957d6554Steve Block } 15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1592bde8e466a4451c7319e3a072d118917957d6554Steve Block var line = this._textModel.line(lineNumber); 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block this._tokenizer.line = line; 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block this._tokenizer.condition = JSON.parse(postConditionStringified); 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block 1632bde8e466a4451c7319e3a072d118917957d6554Steve Block // Highlight line. 1642bde8e466a4451c7319e3a072d118917957d6554Steve Block do { 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block var newColumn = this._tokenizer.nextToken(lastHighlightedColumn); 1662bde8e466a4451c7319e3a072d118917957d6554Steve Block var tokenType = this._tokenizer.tokenType; 1672bde8e466a4451c7319e3a072d118917957d6554Steve Block if (tokenType) 1682bde8e466a4451c7319e3a072d118917957d6554Steve Block state[lastHighlightedColumn] = { length: newColumn - lastHighlightedColumn, tokenType: tokenType }; 1692bde8e466a4451c7319e3a072d118917957d6554Steve Block lastHighlightedColumn = newColumn; 1702bde8e466a4451c7319e3a072d118917957d6554Steve Block if (++tokensCount > this._highlightChunkLimit) 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 1722bde8e466a4451c7319e3a072d118917957d6554Steve Block } while (lastHighlightedColumn < line.length); 1732bde8e466a4451c7319e3a072d118917957d6554Steve Block 1742bde8e466a4451c7319e3a072d118917957d6554Steve Block postConditionStringified = JSON.stringify(this._tokenizer.condition); 1752bde8e466a4451c7319e3a072d118917957d6554Steve Block 1762bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lastHighlightedColumn < line.length) { 1772bde8e466a4451c7319e3a072d118917957d6554Steve Block // Too much work for single chunk - exit. 1782bde8e466a4451c7319e3a072d118917957d6554Steve Block state.lastHighlightedColumn = lastHighlightedColumn; 1792bde8e466a4451c7319e3a072d118917957d6554Steve Block state.midConditionStringified = postConditionStringified; 18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch break; 1812bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 1822bde8e466a4451c7319e3a072d118917957d6554Steve Block delete state.lastHighlightedColumn; 1832bde8e466a4451c7319e3a072d118917957d6554Steve Block delete state.midConditionStringified; 1842bde8e466a4451c7319e3a072d118917957d6554Steve Block state.postConditionStringified = postConditionStringified; 1852bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1862bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1872bde8e466a4451c7319e3a072d118917957d6554Steve Block 1882bde8e466a4451c7319e3a072d118917957d6554Steve Block var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight"); 1892bde8e466a4451c7319e3a072d118917957d6554Steve Block if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) { 1902bde8e466a4451c7319e3a072d118917957d6554Steve Block // Following lines are up to date, no need re-highlight. 1912bde8e466a4451c7319e3a072d118917957d6554Steve Block ++lineNumber; 1922bde8e466a4451c7319e3a072d118917957d6554Steve Block this._damageCallback(startLine, lineNumber); 1932bde8e466a4451c7319e3a072d118917957d6554Steve Block 1942bde8e466a4451c7319e3a072d118917957d6554Steve Block // Advance the "pointer" to the last highlighted line within the given chunk. 1952bde8e466a4451c7319e3a072d118917957d6554Steve Block for (; lineNumber < endLine; ++lineNumber) { 1962bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(lineNumber, "highlight"); 1972bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!state || !state.postConditionStringified) 1982bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 19981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 2002bde8e466a4451c7319e3a072d118917957d6554Steve Block this._lastHighlightedLine = lineNumber; 2012bde8e466a4451c7319e3a072d118917957d6554Steve Block return true; 20281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 203d0825bca7fe65beaee391d30da42e937db621564Steve Block } 204d0825bca7fe65beaee391d30da42e937db621564Steve Block 2052bde8e466a4451c7319e3a072d118917957d6554Steve Block this._damageCallback(startLine, lineNumber); 206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block this._lastHighlightedLine = lineNumber; 2072bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 2082bde8e466a4451c7319e3a072d118917957d6554Steve Block }, 2092bde8e466a4451c7319e3a072d118917957d6554Steve Block 2102bde8e466a4451c7319e3a072d118917957d6554Steve Block _selectHighlightState: function(lineNumber, preConditionStringified) 2112bde8e466a4451c7319e3a072d118917957d6554Steve Block { 2122bde8e466a4451c7319e3a072d118917957d6554Steve Block var state = this._textModel.getAttribute(lineNumber, "highlight"); 2132bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state && state.preConditionStringified === preConditionStringified) 2142bde8e466a4451c7319e3a072d118917957d6554Steve Block return state; 2152bde8e466a4451c7319e3a072d118917957d6554Steve Block 2162bde8e466a4451c7319e3a072d118917957d6554Steve Block var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated"); 2172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) { 2182bde8e466a4451c7319e3a072d118917957d6554Steve Block // Swap states. 2192bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.setAttribute(lineNumber, "highlight", outdatedState); 2202bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.setAttribute(lineNumber, "highlight-outdated", state); 2212bde8e466a4451c7319e3a072d118917957d6554Steve Block return outdatedState; 2222bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2232bde8e466a4451c7319e3a072d118917957d6554Steve Block 2242bde8e466a4451c7319e3a072d118917957d6554Steve Block if (state) 2252bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.setAttribute(lineNumber, "highlight-outdated", state); 2262bde8e466a4451c7319e3a072d118917957d6554Steve Block 2272bde8e466a4451c7319e3a072d118917957d6554Steve Block state = {}; 2282bde8e466a4451c7319e3a072d118917957d6554Steve Block state.preConditionStringified = preConditionStringified; 2292bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.setAttribute(lineNumber, "highlight", state); 2302bde8e466a4451c7319e3a072d118917957d6554Steve Block return state; 2312bde8e466a4451c7319e3a072d118917957d6554Steve Block }, 2322bde8e466a4451c7319e3a072d118917957d6554Steve Block 2332bde8e466a4451c7319e3a072d118917957d6554Steve Block _clearHighlightState: function(lineNumber) 2342bde8e466a4451c7319e3a072d118917957d6554Steve Block { 2352bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.removeAttribute(lineNumber, "highlight"); 2362bde8e466a4451c7319e3a072d118917957d6554Steve Block this._textModel.removeAttribute(lineNumber, "highlight-outdated"); 237d0825bca7fe65beaee391d30da42e937db621564Steve Block } 238d0825bca7fe65beaee391d30da42e937db621564Steve Block} 239